/******************************************************/ /* 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 ; }