379 lines
11 KiB
C++
379 lines
11 KiB
C++
/******************************************************/
|
|
/* Edition des contours du pcb: Routines */
|
|
/* d'effacement et d'edition de segments et contours */
|
|
/* du type PCB, draw, edgePCB */
|
|
/******************************************************/
|
|
|
|
#include "fctsys.h"
|
|
#include "gr_basic.h"
|
|
|
|
#include "common.h"
|
|
#include "pcbnew.h"
|
|
|
|
#include "protos.h"
|
|
|
|
/* Routines Locales */
|
|
static void Exit_EditEdge(WinEDA_DrawPanel * Panel, wxDC * DC);
|
|
static void Montre_Position_NewSegment(WinEDA_DrawPanel * panel, wxDC * DC, bool erase);
|
|
static void Move_Segment(WinEDA_DrawPanel * panel, wxDC * DC, bool erase);
|
|
|
|
/* Variables locales : */
|
|
static wxPoint cursor_pos; // position originelle du curseur souris (fct deplacement)
|
|
static wxPoint cursor_pos0; // position courante du curseur souris
|
|
|
|
/****************************************************************************/
|
|
void WinEDA_PcbFrame::Start_Move_DrawItem(DRAWSEGMENT * drawitem, wxDC * DC)
|
|
/****************************************************************************/
|
|
/* Routine de preparation du deplacement d'un element graphique type DRAWSEGMENT
|
|
*/
|
|
{
|
|
if( drawitem == NULL ) return;
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, drawitem,GR_XOR) ;
|
|
drawitem->m_Flags |= IS_MOVED;
|
|
cursor_pos = cursor_pos0 = GetScreen()->m_Curseur;
|
|
Affiche_Infos_DrawSegment(this, drawitem);
|
|
DrawPanel->ManageCurseur = Move_Segment;
|
|
DrawPanel->ForceCloseManageCurseur = Exit_EditEdge;
|
|
GetScreen()->m_CurrentItem = drawitem;
|
|
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE);
|
|
}
|
|
|
|
/*********************************************************************/
|
|
void WinEDA_PcbFrame::Place_DrawItem(DRAWSEGMENT * drawitem, wxDC * DC)
|
|
/*********************************************************************/
|
|
/*
|
|
Routine de placement de l'element graphique type DRAWSEGMENT en cours de deplacement
|
|
*/
|
|
{
|
|
if( drawitem == NULL ) return;
|
|
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, drawitem,GR_OR) ;
|
|
DrawPanel->ManageCurseur = NULL;
|
|
DrawPanel->ForceCloseManageCurseur = NULL;
|
|
GetScreen()->m_CurrentItem = NULL;
|
|
GetScreen()->SetModify();
|
|
drawitem->m_Flags = 0;
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
static void Move_Segment(WinEDA_DrawPanel * panel, wxDC * DC, bool erase)
|
|
/************************************************************************/
|
|
/* redessin du contour du Segment Edge lors des deplacements de la souris */
|
|
{
|
|
DRAWSEGMENT * Segment = ( DRAWSEGMENT * )
|
|
panel->GetScreen()->m_CurrentItem ;
|
|
int t_fill = DisplayOpt.DisplayDrawItems;
|
|
|
|
if(Segment == NULL) return ;
|
|
|
|
DisplayOpt.DisplayDrawItems = SKETCH ;
|
|
|
|
/* efface ancienne position */
|
|
if( erase )
|
|
Trace_DrawSegmentPcb(panel, DC, Segment, GR_XOR);
|
|
|
|
wxPoint delta;
|
|
delta.x = panel->GetScreen()->m_Curseur.x - cursor_pos.x;
|
|
delta.y = panel->GetScreen()->m_Curseur.y - cursor_pos.y;
|
|
Segment->m_Start.x += delta.x;
|
|
Segment->m_Start.y += delta.y;
|
|
Segment->m_End.x += delta.x;
|
|
Segment->m_End.y += delta.y;
|
|
cursor_pos = panel->GetScreen()->m_Curseur;
|
|
|
|
Trace_DrawSegmentPcb(panel, DC, Segment,GR_XOR);
|
|
DisplayOpt.DisplayDrawItems = t_fill ;
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************/
|
|
void WinEDA_PcbFrame::Delete_Segment_Edge( DRAWSEGMENT* Segment, wxDC * DC)
|
|
/**************************************************************************/
|
|
{
|
|
EDA_BaseStruct * PtStruct;
|
|
int track_fill_copy = DisplayOpt.DisplayDrawItems;
|
|
|
|
if (Segment == NULL ) return;
|
|
|
|
if(Segment->m_Flags & IS_NEW) // Trace en cours, on peut effacer le dernier segment
|
|
{
|
|
/* effacement du segment en cours de trace */
|
|
DisplayOpt.DisplayDrawItems = SKETCH ;
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, Segment,GR_XOR) ;
|
|
PtStruct = Segment->Pback;
|
|
DeleteStructure(Segment);
|
|
if( PtStruct && (PtStruct->m_StructType == TYPEDRAWSEGMENT ) )
|
|
Segment = (DRAWSEGMENT*) PtStruct;
|
|
DisplayOpt.DisplayDrawItems = track_fill_copy ;
|
|
GetScreen()->m_CurrentItem = NULL;
|
|
}
|
|
|
|
else
|
|
{
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, (DRAWSEGMENT *)Segment,GR_XOR) ;
|
|
Segment->m_Flags = 0;
|
|
DeleteStructure(Segment);
|
|
GetScreen()->m_CurrentItem = NULL;
|
|
GetScreen()->SetModify();
|
|
}
|
|
}
|
|
|
|
|
|
/*************************************************************************/
|
|
void WinEDA_PcbFrame::Drawing_SetNewWidth(DRAWSEGMENT *DrawSegm, wxDC * DC)
|
|
/*************************************************************************/
|
|
/* Met a la largeur courante le segment pointe part la souris
|
|
*/
|
|
{
|
|
|
|
if( DrawSegm == NULL ) return;
|
|
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, DrawSegm, GR_XOR);
|
|
|
|
if(DrawSegm->m_Layer == EDGE_N) DrawSegm->m_Width = g_DesignSettings.m_EdgeSegmentWidth;
|
|
else DrawSegm->m_Width = g_DesignSettings.m_DrawSegmentWidth;
|
|
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, DrawSegm, GR_OR);
|
|
|
|
Affiche_Infos_DrawSegment(this, DrawSegm);
|
|
|
|
GetScreen()->SetModify();
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
void WinEDA_PcbFrame::Delete_Drawings_All_Layer(DRAWSEGMENT *Segment, wxDC * DC)
|
|
/******************************************************************************/
|
|
{
|
|
DRAWSEGMENT * pt_segm;
|
|
TEXTE_PCB* pt_txt;
|
|
EDA_BaseStruct * PtStruct, *PtNext;
|
|
COTATION * Cotation;
|
|
int layer = Segment->m_Layer;
|
|
|
|
if(layer <= CMP_N)
|
|
{
|
|
DisplayError(this, _("Copper layer global delete not allowed!"), 20);
|
|
return;
|
|
}
|
|
|
|
if ( Segment->m_Flags )
|
|
{
|
|
DisplayError(this, _("Segment is being edited"), 10);
|
|
return;
|
|
}
|
|
|
|
wxString msg = _("Delete Layer ") + ReturnPcbLayerName(layer);
|
|
if( !IsOK(this, msg) ) return ;
|
|
|
|
PtStruct = m_Pcb->m_Drawings;
|
|
for( ; PtStruct != NULL; PtStruct = PtNext )
|
|
{
|
|
GetScreen()->SetModify();
|
|
PtNext = PtStruct->Pnext;
|
|
switch( PtStruct->m_StructType)
|
|
{
|
|
case TYPEDRAWSEGMENT:
|
|
pt_segm = (DRAWSEGMENT*) PtStruct;
|
|
if(pt_segm->m_Layer == layer)
|
|
{
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, pt_segm,GR_XOR);
|
|
DeleteStructure(PtStruct);
|
|
}
|
|
break;
|
|
|
|
case TYPETEXTE:
|
|
pt_txt = (TEXTE_PCB*)PtStruct;
|
|
if(pt_txt->m_Layer == layer)
|
|
{
|
|
pt_txt->Draw(DrawPanel, DC, wxPoint(0, 0), GR_XOR);
|
|
DeleteStructure( PtStruct );
|
|
}
|
|
break;
|
|
|
|
|
|
case TYPECOTATION:
|
|
Cotation = (COTATION*)PtStruct;
|
|
if(Cotation->m_Layer == layer)
|
|
{
|
|
Cotation->Draw(DrawPanel, DC, wxPoint(0, 0), GR_XOR);
|
|
DeleteStructure(PtStruct);
|
|
}
|
|
break;
|
|
|
|
default: DisplayError(this, wxT("Type Drawing Inconnu") );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*************************************************************/
|
|
static void Exit_EditEdge(WinEDA_DrawPanel * Panel, wxDC * DC)
|
|
/*************************************************************/
|
|
{
|
|
DRAWSEGMENT *Segment = (DRAWSEGMENT *) Panel->GetScreen()->m_CurrentItem ;
|
|
|
|
if (Segment == NULL) return;
|
|
|
|
if( Segment->m_Flags & IS_NEW )
|
|
{
|
|
Panel->ManageCurseur(Panel, DC, FALSE);
|
|
DeleteStructure(Segment);
|
|
Segment = NULL;
|
|
}
|
|
|
|
else
|
|
{
|
|
wxPoint pos = Panel->GetScreen()->m_Curseur;
|
|
Panel->GetScreen()->m_Curseur = cursor_pos0;
|
|
Panel->ManageCurseur(Panel, DC, TRUE);
|
|
Panel->GetScreen()->m_Curseur = pos;
|
|
Segment->m_Flags = 0;
|
|
Trace_DrawSegmentPcb(Panel, DC, Segment,GR_OR) ;
|
|
}
|
|
Panel->ManageCurseur = NULL;
|
|
Panel->ForceCloseManageCurseur = NULL;
|
|
Panel->GetScreen()->m_CurrentItem = NULL;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
DRAWSEGMENT * WinEDA_PcbFrame::Begin_DrawSegment(DRAWSEGMENT * Segment,
|
|
int shape, wxDC * DC)
|
|
/**********************************************************************/
|
|
/* Routine d'initialisation du trace d'un segment de type autre que piste
|
|
*/
|
|
{
|
|
int s_large;
|
|
int angle = 0;
|
|
DRAWSEGMENT * DrawItem;
|
|
|
|
s_large = g_DesignSettings.m_DrawSegmentWidth;
|
|
if(GetScreen()->m_Active_Layer == EDGE_N)
|
|
{
|
|
s_large = g_DesignSettings.m_EdgeSegmentWidth;
|
|
}
|
|
|
|
if ( shape == S_ARC ) angle = 900;
|
|
|
|
if(Segment == NULL ) /* debut reel du trace */
|
|
{
|
|
GetScreen()->m_CurrentItem = Segment = new DRAWSEGMENT( m_Pcb);
|
|
Segment->m_Flags = IS_NEW;
|
|
Segment->m_Layer = GetScreen()->m_Active_Layer;
|
|
Segment->m_Width = s_large;
|
|
Segment->m_Shape = shape;
|
|
Segment->m_Angle = 900;
|
|
Segment->m_Start = Segment->m_End = GetScreen()->m_Curseur ;
|
|
DrawPanel->ManageCurseur = Montre_Position_NewSegment;
|
|
DrawPanel->ForceCloseManageCurseur = Exit_EditEdge;
|
|
}
|
|
|
|
else /* trace en cours : les coord du point d'arrivee ont ete mises
|
|
a jour par la routine Montre_Position_NewSegment*/
|
|
{
|
|
if( (Segment->m_Start.x != Segment->m_End.x )
|
|
|| (Segment->m_Start.y != Segment->m_End.y ) )
|
|
{
|
|
if ( Segment->m_Shape == S_SEGMENT )
|
|
{
|
|
Segment->Pnext = m_Pcb->m_Drawings;
|
|
Segment->Pback = m_Pcb;
|
|
if( m_Pcb->m_Drawings )
|
|
m_Pcb->m_Drawings->Pback = Segment;
|
|
m_Pcb->m_Drawings = Segment;
|
|
GetScreen()->SetModify();
|
|
Segment->m_Flags = 0;
|
|
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, Segment,GR_OR);
|
|
|
|
DrawItem = Segment;
|
|
|
|
GetScreen()->m_CurrentItem = Segment = new DRAWSEGMENT( m_Pcb );
|
|
|
|
Segment->m_Flags = IS_NEW;
|
|
Segment->m_Layer = DrawItem->m_Layer;
|
|
Segment->m_Width = s_large;
|
|
Segment->m_Shape = DrawItem->m_Shape;
|
|
Segment->m_Type = DrawItem->m_Type;
|
|
Segment->m_Angle = DrawItem->m_Angle;
|
|
Segment->m_Start = Segment->m_End = DrawItem->m_End;
|
|
Montre_Position_NewSegment(DrawPanel, DC, FALSE);
|
|
}
|
|
else
|
|
{
|
|
End_Edge(Segment, DC);
|
|
Segment = NULL;
|
|
}
|
|
}
|
|
}
|
|
return Segment;
|
|
}
|
|
|
|
|
|
/***************************************************************/
|
|
void WinEDA_PcbFrame::End_Edge(DRAWSEGMENT * Segment, wxDC * DC)
|
|
/***************************************************************/
|
|
{
|
|
|
|
if( Segment == NULL ) return ;
|
|
Trace_DrawSegmentPcb(DrawPanel, DC, (DRAWSEGMENT *)Segment,GR_OR);
|
|
|
|
/* Effacement si Longueur nulle */
|
|
if( (Segment->m_Start.x == Segment->m_End.x) &&
|
|
(Segment->m_Start.y == Segment->m_End.y) )
|
|
DeleteStructure(Segment);
|
|
|
|
else
|
|
{
|
|
Segment->m_Flags = 0;
|
|
Segment->Pnext = m_Pcb->m_Drawings;
|
|
Segment->Pback = m_Pcb;
|
|
if( m_Pcb->m_Drawings ) m_Pcb->m_Drawings->Pback = Segment;
|
|
m_Pcb->m_Drawings = Segment;
|
|
GetScreen()->SetModify();
|
|
}
|
|
|
|
DrawPanel->ManageCurseur = NULL;
|
|
DrawPanel->ForceCloseManageCurseur = NULL;
|
|
GetScreen()->m_CurrentItem = NULL;
|
|
}
|
|
|
|
|
|
/************************************************************/
|
|
static void Montre_Position_NewSegment(WinEDA_DrawPanel * panel,
|
|
wxDC * DC, bool erase)
|
|
/************************************************************/
|
|
/* redessin du contour du Segment Edge lors des deplacements de la souris */
|
|
{
|
|
DRAWSEGMENT * Segment = ( DRAWSEGMENT * )
|
|
panel->GetScreen()->m_CurrentItem ;
|
|
int t_fill = DisplayOpt.DisplayDrawItems;
|
|
|
|
if(Segment == NULL) return ;
|
|
|
|
DisplayOpt.DisplayDrawItems = SKETCH ;
|
|
|
|
/* efface ancienne position */
|
|
if( erase )
|
|
Trace_DrawSegmentPcb(panel, DC, Segment, GR_XOR);
|
|
|
|
if( Segments_45_Only && (Segment->m_Shape == S_SEGMENT ) )
|
|
{
|
|
Calcule_Coord_Extremite_45(Segment->m_Start.x,Segment->m_Start.y,
|
|
&Segment->m_End.x, &Segment->m_End.y);
|
|
}
|
|
|
|
else /* ici l'angle d'inclinaison est quelconque */
|
|
{
|
|
Segment->m_End = panel->GetScreen()->m_Curseur;
|
|
}
|
|
|
|
Trace_DrawSegmentPcb(panel, DC, Segment,GR_XOR);
|
|
DisplayOpt.DisplayDrawItems = t_fill ;
|
|
}
|
|
|
|
|