///////////////////////////////////////////////////////////////////////////// // Name: zones.cpp // Purpose: // Author: jean-pierre Charras // Modified by: // Created: 25/01/2006 11:35:19 // RCS-ID: // Copyright: GNU License // Licence: GNU License ///////////////////////////////////////////////////////////////////////////// // Generated by DialogBlocks (unregistered), 25/01/2006 11:35:19 #if defined (__GNUG__) && !defined (NO_GCC_PRAGMA) #pragma implementation "zones.h" #endif // For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif ////@begin includes ////@end includes #include "zones.h" ////@begin XPM images ////@end XPM images /* Imported functions */ void Build_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code, bool Zone_Exclude_Pads, bool Zone_Create_Thermal_Relief ); /* Local functions */ static void Display_Zone_Netname( WinEDA_PcbFrame* frame ); static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC ); static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); /* Local variables */ static bool Zone_45_Only = FALSE; static bool Zone_Exclude_Pads = TRUE; static bool s_Zone_Create_Thermal_Relief = TRUE; /* Time stamp common to all segments relative to the new created zone */ static unsigned long s_TimeStamp; /*! * WinEDA_ZoneFrame type definition */ IMPLEMENT_DYNAMIC_CLASS( WinEDA_ZoneFrame, wxDialog ) /*! * WinEDA_ZoneFrame event table definition */ BEGIN_EVENT_TABLE( WinEDA_ZoneFrame, wxDialog ) ////@begin WinEDA_ZoneFrame event table entries EVT_BUTTON( ID_FILL_ZONE, WinEDA_ZoneFrame::ExecFillZone ) EVT_BUTTON( wxID_CANCEL, WinEDA_ZoneFrame::OnCancelClick ) EVT_BUTTON( ID_SET_OPTIONS_ZONE, WinEDA_ZoneFrame::ExecFillZone ) ////@end WinEDA_ZoneFrame event table entries END_EVENT_TABLE() /*! * WinEDA_ZoneFrame constructors */ WinEDA_ZoneFrame::WinEDA_ZoneFrame() { } WinEDA_ZoneFrame::WinEDA_ZoneFrame( WinEDA_PcbFrame* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) { m_Parent = parent; Create( parent, id, caption, pos, size, style ); } /*! * WinEDA_ZoneFrame creator */ bool WinEDA_ZoneFrame::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) { ////@begin WinEDA_ZoneFrame member initialisation m_GridCtrl = NULL; m_ClearanceValueTitle = NULL; m_ZoneClearanceCtrl = NULL; m_FillOpt = NULL; m_OrientEdgesOpt = NULL; ////@end WinEDA_ZoneFrame member initialisation ////@begin WinEDA_ZoneFrame creation SetExtraStyle( GetExtraStyle() | wxWS_EX_BLOCK_EVENTS ); wxDialog::Create( parent, id, caption, pos, size, style ); CreateControls(); GetSizer()->Fit( this ); GetSizer()->SetSizeHints( this ); Centre(); ////@end WinEDA_ZoneFrame creation return true; } /*! * Control creation for WinEDA_ZoneFrame */ void WinEDA_ZoneFrame::CreateControls() { SetFont( *g_DialogFont ); ////@begin WinEDA_ZoneFrame content construction // Generated by DialogBlocks, 03/03/2006 13:36:21 (unregistered) WinEDA_ZoneFrame* itemDialog1 = this; wxBoxSizer* itemBoxSizer2 = new wxBoxSizer( wxHORIZONTAL ); itemDialog1->SetSizer( itemBoxSizer2 ); wxBoxSizer* itemBoxSizer3 = new wxBoxSizer( wxVERTICAL ); itemBoxSizer2->Add( itemBoxSizer3, 0, wxGROW | wxALL, 5 ); static const wxString m_GridCtrlStrings[] = { _( "0.00000" ), _( "0.00000" ), _( "0.00000" ), _( "0.00000" ) }; m_GridCtrl = new wxRadioBox( itemDialog1, ID_RADIOBOX, _( "Grid size:" ), wxDefaultPosition, wxDefaultSize, 4, m_GridCtrlStrings, 1, wxRA_SPECIFY_COLS ); itemBoxSizer3->Add( m_GridCtrl, 0, wxALIGN_LEFT | wxALL, 5 ); m_ClearanceValueTitle = new wxStaticText( itemDialog1, wxID_STATIC, _( "Zone clearance value (mm):" ), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer3->Add( m_ClearanceValueTitle, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP | wxADJUST_MINSIZE, 5 ); m_ZoneClearanceCtrl = new wxTextCtrl( itemDialog1, ID_TEXTCTRL, _T( "" ), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer3->Add( m_ZoneClearanceCtrl, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM, 5 ); itemBoxSizer2->Add( 5, 5, 0, wxGROW | wxALL, 5 ); wxBoxSizer* itemBoxSizer8 = new wxBoxSizer( wxVERTICAL ); itemBoxSizer2->Add( itemBoxSizer8, 0, wxGROW | wxALL, 5 ); static const wxString m_FillOptStrings[] = { _( "Include Pads" ), _( "Thermal" ), _( "Exclude Pads" ) }; m_FillOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX1, _( "Pad options:" ), wxDefaultPosition, wxDefaultSize, 3, m_FillOptStrings, 1, wxRA_SPECIFY_COLS ); itemBoxSizer8->Add( m_FillOpt, 0, wxALIGN_LEFT | wxALL, 5 ); static const wxString m_OrientEdgesOptStrings[] = { _( "Any" ), _( "H , V and 45 deg" ) }; m_OrientEdgesOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX2, _( "Zone edges orient:" ), wxDefaultPosition, wxDefaultSize, 2, m_OrientEdgesOptStrings, 1, wxRA_SPECIFY_COLS ); itemBoxSizer8->Add( m_OrientEdgesOpt, 0, wxALIGN_RIGHT | wxALL, 5 ); itemBoxSizer2->Add( 5, 5, 0, wxGROW | wxALL, 5 ); wxBoxSizer* itemBoxSizer12 = new wxBoxSizer( wxVERTICAL ); itemBoxSizer2->Add( itemBoxSizer12, 0, wxALIGN_TOP | wxALL, 5 ); wxButton* itemButton13 = new wxButton( itemDialog1, ID_FILL_ZONE, _( "Fill" ), wxDefaultPosition, wxDefaultSize, 0 ); itemButton13->SetDefault(); itemButton13->SetForegroundColour( wxColour( 204, 0, 0 ) ); itemBoxSizer12->Add( itemButton13, 0, wxGROW | wxALL, 5 ); wxButton* itemButton14 = new wxButton( itemDialog1, wxID_CANCEL, _( "&Cancel" ), wxDefaultPosition, wxDefaultSize, 0 ); itemButton14->SetForegroundColour( wxColour( 0, 0, 255 ) ); itemBoxSizer12->Add( itemButton14, 0, wxGROW | wxALL, 5 ); wxButton* itemButton15 = new wxButton( itemDialog1, ID_SET_OPTIONS_ZONE, _( "Update Options" ), wxDefaultPosition, wxDefaultSize, 0 ); itemButton15->SetForegroundColour( wxColour( 0, 100, 0 ) ); itemBoxSizer12->Add( itemButton15, 0, wxGROW | wxALL, 5 ); itemBoxSizer2->Add( 5, 5, 0, wxGROW | wxALL, 5 ); ////@end WinEDA_ZoneFrame content construction wxString title = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric ); m_ClearanceValueTitle->SetLabel( title ); title = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric );; m_GridCtrl->SetLabel( title ); if( g_DesignSettings.m_ZoneClearence == 0 ) g_DesignSettings.m_ZoneClearence = g_DesignSettings.m_TrackClearence; title = ReturnStringFromValue( g_UnitMetric, g_DesignSettings.m_ZoneClearence, m_Parent->m_InternalUnits ); m_ZoneClearanceCtrl->SetValue( title ); if( Zone_45_Only ) m_OrientEdgesOpt->SetSelection( 1 ); static const int GridList[4] = { 50, 100, 250, 500 }; int selection = 0; for( unsigned ii = 0; ii < (unsigned)m_GridCtrl->GetCount(); ii++ ) { wxString msg = ReturnStringFromValue( g_UnitMetric, GridList[ii], m_Parent->m_InternalUnits ); m_GridCtrl->SetString( ii, msg ); if( g_GridRoutingSize == GridList[ii] ) selection = ii; } m_GridCtrl->SetSelection( selection ); if( Zone_Exclude_Pads ) { if( s_Zone_Create_Thermal_Relief ) m_FillOpt->SetSelection( 1 ); else m_FillOpt->SetSelection( 2 ); } } /*! * Should we show tooltips? */ bool WinEDA_ZoneFrame::ShowToolTips() { return true; } /*! * Get bitmap resources */ wxBitmap WinEDA_ZoneFrame::GetBitmapResource( const wxString& name ) { // Bitmap retrieval ////@begin WinEDA_ZoneFrame bitmap retrieval wxUnusedVar( name ); return wxNullBitmap; ////@end WinEDA_ZoneFrame bitmap retrieval } /*! * Get icon resources */ wxIcon WinEDA_ZoneFrame::GetIconResource( const wxString& name ) { // Icon retrieval ////@begin WinEDA_ZoneFrame icon retrieval wxUnusedVar( name ); return wxNullIcon; ////@end WinEDA_ZoneFrame icon retrieval } /*! * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL */ void WinEDA_ZoneFrame::OnCancelClick( wxCommandEvent& event ) { ////@begin wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame. // Before editing this code, remove the block markers. event.Skip(); ////@end wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame. } /*! * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON2 */ /***********************************************************/ void WinEDA_ZoneFrame::ExecFillZone( wxCommandEvent& event ) /***********************************************************/ { switch( m_FillOpt->GetSelection() ) { case 0: Zone_Exclude_Pads = FALSE; s_Zone_Create_Thermal_Relief = FALSE; break; case 1: Zone_Exclude_Pads = TRUE; s_Zone_Create_Thermal_Relief = TRUE; break; case 2: Zone_Exclude_Pads = TRUE; s_Zone_Create_Thermal_Relief = FALSE; break; } switch( m_GridCtrl->GetSelection() ) { case 0: g_GridRoutingSize = 50; break; case 1: g_GridRoutingSize = 100; break; case 2: g_GridRoutingSize = 250; break; case 3: g_GridRoutingSize = 500; break; } wxString txtvalue = m_ZoneClearanceCtrl->GetValue(); g_DesignSettings.m_ZoneClearence = ReturnValueFromString( g_UnitMetric, txtvalue, m_Parent->m_InternalUnits ); if( m_OrientEdgesOpt->GetSelection() == 0 ) Zone_45_Only = FALSE; else Zone_45_Only = TRUE; if( event.GetId() == ID_SET_OPTIONS_ZONE ) EndModal( 1 ); else EndModal( 0 ); } /**************************************************************/ void WinEDA_PcbFrame::Edit_Zone_Width( wxDC* DC, SEGZONE* aZone ) /**************************************************************/ /* Edite (change la largeur des segments) la zone Zone. * La zone est constituee des segments zones de meme TimeStamp */ { bool modify = FALSE; double f_new_width; int w_tmp; wxString Line; wxString Msg( _( "New zone segment width: " ) ); if( aZone == NULL ) return; f_new_width = To_User_Unit( g_UnitMetric, aZone->m_Width, GetScreen()->GetInternalUnits() ); Line.Printf( wxT( "%.4f" ), f_new_width ); Msg += g_UnitMetric ? wxT( "(mm)" ) : wxT( "(\")" ); if( Get_Message( Msg, Line, this ) != 0 ) return; w_tmp = g_DesignSettings.m_CurrentTrackWidth; Line.ToDouble( &f_new_width ); g_DesignSettings.m_CurrentTrackWidth = From_User_Unit( g_UnitMetric, f_new_width, GetScreen()->GetInternalUnits() ); for( SEGZONE* zone = m_Pcb->m_Zone; zone; zone = zone->Next() ) { if( zone->m_TimeStamp == aZone->m_TimeStamp ) { modify = TRUE; Edit_TrackSegm_Width( DC, zone ); } } g_DesignSettings.m_CurrentTrackWidth = w_tmp; if( modify ) { GetScreen()->SetModify(); DrawPanel->Refresh(); } } /**********************************************************/ void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone ) /**********************************************************/ /* Remove the zone which include the segment aZone. * A zone is a group of segments which have the same TimeStamp */ { if ( aZone == NULL ) return; int nb_segm = 0; bool modify = FALSE; unsigned long TimeStamp = aZone->m_TimeStamp; // Save reference time stamp (aZone will be deleted) SEGZONE* next; for( SEGZONE* zone = m_Pcb->m_Zone; zone != NULL; zone = next ) { next = zone->Next(); if( zone->m_TimeStamp == TimeStamp ) { modify = TRUE; /* Erase segment from screen */ Trace_Une_Piste( DrawPanel, DC, zone, nb_segm, GR_XOR ); /* remove item from linked list and free memory */ zone->DeleteStructure(); } } if( modify ) { GetScreen()->SetModify(); GetScreen()->SetRefreshReq(); } } /*****************************************************************************/ EDGE_ZONE* WinEDA_PcbFrame::Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone ) /*****************************************************************************/ /* Routine d'effacement du segment de limite zone en cours de trace */ { EDGE_ZONE* segm; if( m_Pcb->m_CurrentLimitZone ) segm = m_Pcb->m_CurrentLimitZone; else segm = edge_zone; if( segm == NULL ) return NULL; Trace_DrawSegmentPcb( DrawPanel, DC, segm, GR_XOR ); m_Pcb->m_CurrentLimitZone = segm->Next(); delete segm; segm = m_Pcb->m_CurrentLimitZone; SetCurItem( segm ); if( segm ) { segm->Pback = NULL; if( DrawPanel->ManageCurseur ) DrawPanel->ManageCurseur( DrawPanel, DC, TRUE ); } else { DrawPanel->ManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL; SetCurItem( NULL ); } return segm; } /*********************************************/ void WinEDA_PcbFrame::CaptureNetName( wxDC* DC ) /*********************************************/ /* routine permettant de capturer le nom net net (netcode) d'un pad * ou d'une piste pour l'utiliser comme netcode de zone */ { D_PAD* pt_pad = 0; TRACK* adrpiste; MODULE* Module; int masquelayer = g_TabOneLayerMask[GetScreen()->m_Active_Layer]; int netcode; netcode = -1; MsgPanel->EraseMsgBox(); adrpiste = Locate_Pistes( m_Pcb->m_Track, masquelayer, CURSEUR_OFF_GRILLE ); if( adrpiste == NULL ) { pt_pad = Locate_Any_Pad( m_Pcb, CURSEUR_OFF_GRILLE ); if( pt_pad ) /* Verif qu'il est bien sur la couche active */ { Module = (MODULE*) pt_pad->m_Parent; pt_pad = Locate_Pads( Module, g_TabOneLayerMask[GetScreen()->m_Active_Layer], CURSEUR_OFF_GRILLE ); } if( pt_pad ) { pt_pad->Display_Infos( this ); netcode = pt_pad->GetNet(); } } else { adrpiste->Display_Infos( this ); netcode = adrpiste->GetNet(); } // Mise en surbrillance du net if( g_HightLigt_Status ) Hight_Light( DC ); g_HightLigth_NetCode = netcode; if( g_HightLigth_NetCode >= 0 ) { Hight_Light( DC ); } /* Affichage du net selectionne pour la zone a tracer */ Display_Zone_Netname( this ); } /*******************************************************/ static void Display_Zone_Netname( WinEDA_PcbFrame* frame ) /*******************************************************/ /* * Affiche le net_code et le nom de net couramment selectionne */ { EQUIPOT* pt_equipot; wxString line; pt_equipot = frame->m_Pcb->m_Equipots; if( g_HightLigth_NetCode > 0 ) { for( ; pt_equipot != NULL; pt_equipot = (EQUIPOT*) pt_equipot->Pnext ) { if( pt_equipot->GetNet() == g_HightLigth_NetCode ) break; } if( pt_equipot ) { line.Printf( wxT( "Zone: Net[%d] <%s>" ), g_HightLigth_NetCode, pt_equipot->m_Netname.GetData() ); } else line.Printf( wxT( "Zone: NetCode[%d], Equipot not found" ), g_HightLigth_NetCode ); } line = _( "Zone: No net selected" ); frame->Affiche_Message( line ); } /********************************************************/ static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC ) /********************************************************/ /** * Function Exit_Zones * cancels the Begin_Zone state if at least one EDGE_ZONE has been created. */ { WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent; if( pcbframe->m_Pcb->m_CurrentLimitZone ) { if( Panel->ManageCurseur ) // trace in progress { Panel->ManageCurseur( Panel, DC, 0 ); } pcbframe->DelLimitesZone( DC, TRUE ); } Panel->ManageCurseur = NULL; Panel->ForceCloseManageCurseur = NULL; pcbframe->SetCurItem( NULL ); } /**************************************************************/ void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw ) /**************************************************************/ { EDGE_ZONE* segment; EDGE_ZONE* next; if( m_Pcb->m_CurrentLimitZone == NULL ) return; if( !IsOK( this, _( "Delete Current Zone Edges" ) ) ) return; // erase the old zone border, one segment at a time for( segment = m_Pcb->m_CurrentLimitZone; segment; segment = next ) { next = segment->Next(); if( Redraw && DC ) Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR ); delete segment; } m_Pcb->m_CurrentLimitZone = NULL; SetCurItem( NULL ); } /** * Function Begin_Zone * either initializes the first segment of a new zone, or adds an * intermediate segment. */ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone() { EDGE_ZONE* oldedge; EDGE_ZONE* newedge = NULL; oldedge = m_Pcb->m_CurrentLimitZone; // if first segment if( (m_Pcb->m_CurrentLimitZone == NULL ) /* debut reel du trace */ || (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */ { newedge = new EDGE_ZONE( m_Pcb ); newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED; newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur; newedge->SetLayer( GetScreen()->m_Active_Layer ); // link into list: newedge->Pnext = oldedge; if( oldedge ) oldedge->Pback = newedge; m_Pcb->m_CurrentLimitZone = newedge; DrawPanel->ManageCurseur = Show_Zone_Edge_While_MoveMouse; DrawPanel->ForceCloseManageCurseur = Exit_Zones; } // edge in progress: else /* piste en cours : les coord du point d'arrivee ont ete mises * a jour par la routine Show_Zone_Edge_While_MoveMouse*/ { if( oldedge->m_Start != oldedge->m_End ) { oldedge->m_Flags &= ~(IS_NEW | IS_MOVED); newedge = new EDGE_ZONE( oldedge ); newedge->m_Flags = IS_NEW | IS_MOVED; newedge->m_Start = newedge->m_End = oldedge->m_End; newedge->SetLayer( GetScreen()->m_Active_Layer ); // link into list: newedge->Pnext = oldedge; oldedge->Pback = newedge; m_Pcb->m_CurrentLimitZone = newedge; } } return newedge; } /*********************************************/ void WinEDA_PcbFrame::End_Zone( wxDC* DC ) /*********************************************/ /* * Routine de fin de trace d'une zone (succession de segments) */ { EDGE_ZONE* edge; if( m_Pcb->m_CurrentLimitZone ) { Begin_Zone(); /* le dernier point genere est de longueur tj nulle donc inutile. */ /* il sera raccorde au point de depart */ edge = m_Pcb->m_CurrentLimitZone; edge->m_Flags &= ~(IS_NEW | IS_MOVED); while( edge && edge->Next() ) { edge = edge->Next(); if( edge->m_Flags & STARTPOINT ) break; edge->m_Flags &= ~(IS_NEW | IS_MOVED); } if( edge ) { edge->m_Flags &= ~(IS_NEW | IS_MOVED); m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start; } Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR ); } DrawPanel->ManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL; } /******************************************************************************************/ static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) /******************************************************************************************/ /* redessin du contour de la piste lors des deplacements de la souris */ { EDGE_ZONE* edge; EDGE_ZONE* currentEdge; WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) panel->m_Parent; if( pcbframe->m_Pcb->m_CurrentLimitZone == NULL ) return; /* efface ancienne position si elle a ete deja dessinee */ if( erase ) { edge = pcbframe->m_Pcb->m_CurrentLimitZone; // for( ; edge; edge = edge->Next() ) { Trace_DrawSegmentPcb( panel, DC, edge, GR_XOR ); } } /* mise a jour de la couche */ for( edge = pcbframe->m_Pcb->m_CurrentLimitZone; edge; edge = edge->Next() ) { edge->SetLayer( pcbframe->GetScreen()->m_Active_Layer ); } /* dessin de la nouvelle piste : mise a jour du point d'arrivee */ currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone; if( Zone_45_Only ) { // Calcul de l'extremite de la piste pour orientations permises: // horiz,vertical ou 45 degre currentEdge->m_End = pcbframe->GetScreen()->m_Curseur; Calcule_Coord_Extremite_45( currentEdge->m_Start.x, currentEdge->m_Start.y, ¤tEdge->m_End.x, ¤tEdge->m_End.y ); } else /* ici l'angle d'inclinaison est quelconque */ { currentEdge->m_End = pcbframe->GetScreen()->m_Curseur; } // for( ; currentEdge; currentEdge = currentEdge->Next() ) { Trace_DrawSegmentPcb( panel, DC, currentEdge, GR_XOR ); } } /**********************************************/ void WinEDA_PcbFrame::Fill_Zone( wxDC* DC ) /**********************************************/ /** Function Fill_Zone() * Init the zone filling * If a zone edge is found, it is used. * Otherwise the whole board is filled by the zone * The zone edge is a frontier, and can be complex. So non filled zones can be achieved * The zone is put on the active layer * If a net is hightlighted, the zone will be attached to this net * The filling start from a starting point. * If a net is selected, all tracks attached to this net are also starting points */ { EQUIPOT* pt_equipot; wxPoint ZoneStartFill; wxString msg; MsgPanel->EraseMsgBox(); if( m_Pcb->ComputeBoundaryBox() == FALSE ) { DisplayError( this, wxT( "Board is empty!" ), 10 ); return; } DrawPanel->m_IgnoreMouseEvents = TRUE; WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this ); int abrd = frame->ShowModal(); frame->Destroy(); DrawPanel->MouseToCursorSchema(); DrawPanel->m_IgnoreMouseEvents = FALSE; if( abrd ) return; // set all the EDGE_ZONEs to the currently active layer and redraw them // on that layer. EDGE_ZONE* PtLim = m_Pcb->m_CurrentLimitZone; for( ; PtLim != NULL; PtLim = PtLim->Next() ) { Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR ); PtLim->SetLayer( GetScreen()->m_Active_Layer ); Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR ); } /* Show the NetName */ if( g_HightLigth_NetCode > 0 ) { pt_equipot = m_Pcb->FindNet( g_HightLigth_NetCode ); if( pt_equipot == NULL ) { if( g_HightLigth_NetCode > 0 ) DisplayError( this, wxT( "Unable to find Net name" ) ); } else msg = pt_equipot->m_Netname; } else msg = _( "No Net" ); Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED ); Build_Zone( this, DC, g_HightLigth_NetCode, Zone_Exclude_Pads, s_Zone_Create_Thermal_Relief ); GetScreen()->SetModify(); }