kicad/pcbnew/zones.cpp

879 lines
25 KiB
C++
Raw Normal View History

2007-05-06 16:03:28 +00:00
/////////////////////////////////////////////////////////////////////////////
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
// 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
2007-08-10 19:14:51 +00:00
#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA)
2007-05-06 16:03:28 +00:00
#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 */
2007-08-10 19:14:51 +00:00
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 );
2007-05-06 16:03:28 +00:00
/* Local variables */
2007-08-10 19:14:51 +00:00
static bool Zone_45_Only = FALSE;
static bool Zone_Exclude_Pads = TRUE;
static bool s_Zone_Create_Thermal_Relief = TRUE;
2007-05-06 16:03:28 +00:00
/* Time stamp common to all segments relative to the new created zone */
static unsigned long s_TimeStamp;
2007-05-06 16:03:28 +00:00
/*!
* 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
2007-08-10 19:14:51 +00:00
EVT_BUTTON( ID_FILL_ZONE, WinEDA_ZoneFrame::ExecFillZone )
2007-05-06 16:03:28 +00:00
2007-08-10 19:14:51 +00:00
EVT_BUTTON( wxID_CANCEL, WinEDA_ZoneFrame::OnCancelClick )
2007-05-06 16:03:28 +00:00
2007-08-10 19:14:51 +00:00
EVT_BUTTON( ID_SET_OPTIONS_ZONE, WinEDA_ZoneFrame::ExecFillZone )
2007-05-06 16:03:28 +00:00
////@end WinEDA_ZoneFrame event table entries
END_EVENT_TABLE()
/*!
* WinEDA_ZoneFrame constructors
*/
2007-08-10 19:14:51 +00:00
WinEDA_ZoneFrame::WinEDA_ZoneFrame()
2007-05-06 16:03:28 +00:00
{
}
2007-08-10 19:14:51 +00:00
WinEDA_ZoneFrame::WinEDA_ZoneFrame( WinEDA_PcbFrame* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
2007-05-06 16:03:28 +00:00
{
2007-08-10 19:14:51 +00:00
m_Parent = parent;
Create( parent, id, caption, pos, size, style );
2007-05-06 16:03:28 +00:00
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*!
* WinEDA_ZoneFrame creator
*/
bool WinEDA_ZoneFrame::Create( wxWindow* parent,
wxWindowID id,
2007-08-10 19:14:51 +00:00
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
2007-05-06 16:03:28 +00:00
{
////@begin WinEDA_ZoneFrame member initialisation
m_GridCtrl = NULL;
m_ClearanceValueTitle = NULL;
2007-08-10 19:14:51 +00:00
m_ZoneClearanceCtrl = NULL;
2007-05-06 16:03:28 +00:00
m_FillOpt = NULL;
m_OrientEdgesOpt = NULL;
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
////@end WinEDA_ZoneFrame member initialisation
////@begin WinEDA_ZoneFrame creation
2007-08-10 19:14:51 +00:00
SetExtraStyle( GetExtraStyle() | wxWS_EX_BLOCK_EVENTS );
2007-05-06 16:03:28 +00:00
wxDialog::Create( parent, id, caption, pos, size, style );
CreateControls();
2007-08-10 19:14:51 +00:00
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
2007-05-06 16:03:28 +00:00
Centre();
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
////@end WinEDA_ZoneFrame creation
2007-08-10 19:14:51 +00:00
return true;
2007-05-06 16:03:28 +00:00
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*!
* Control creation for WinEDA_ZoneFrame
*/
void WinEDA_ZoneFrame::CreateControls()
{
2007-08-10 19:14:51 +00:00
SetFont( *g_DialogFont );
2007-05-06 16:03:28 +00:00
////@begin WinEDA_ZoneFrame content construction
// Generated by DialogBlocks, 03/03/2006 13:36:21 (unregistered)
WinEDA_ZoneFrame* itemDialog1 = this;
2007-05-06 16:03:28 +00:00
wxBoxSizer* itemBoxSizer2 = new wxBoxSizer( wxHORIZONTAL );
2007-08-10 19:14:51 +00:00
itemDialog1->SetSizer( itemBoxSizer2 );
2007-05-06 16:03:28 +00:00
wxBoxSizer* itemBoxSizer3 = new wxBoxSizer( wxVERTICAL );
2007-08-10 19:14:51 +00:00
itemBoxSizer2->Add( itemBoxSizer3, 0, wxGROW | wxALL, 5 );
2007-05-06 16:03:28 +00:00
2007-08-10 19:14:51 +00:00
static const wxString m_GridCtrlStrings[] = {
_( "0.00000" ),
_( "0.00000" ),
_( "0.00000" ),
_( "0.00000" )
2007-05-06 16:03:28 +00:00
};
2007-08-10 19:14:51 +00:00
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):" ),
2007-08-10 19:14:51 +00:00
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 );
2007-08-10 19:14:51 +00:00
itemBoxSizer2->Add( itemBoxSizer8, 0, wxGROW | wxALL, 5 );
static const wxString m_FillOptStrings[] = {
2007-08-10 19:14:51 +00:00
_( "Include Pads" ),
_( "Thermal" ),
_( "Exclude Pads" )
2007-05-06 16:03:28 +00:00
};
2007-08-10 19:14:51 +00:00
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" )
2007-05-06 16:03:28 +00:00
};
m_OrientEdgesOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX2,
_( "Zone edges orient:" ), wxDefaultPosition,
wxDefaultSize, 2, m_OrientEdgesOptStrings, 1,
wxRA_SPECIFY_COLS );
2007-08-10 19:14:51 +00:00
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 );
2007-05-06 16:03:28 +00:00
itemButton13->SetDefault();
2007-08-10 19:14:51 +00:00
itemButton13->SetForegroundColour( wxColour( 204, 0, 0 ) );
itemBoxSizer12->Add( itemButton13, 0, wxGROW | wxALL, 5 );
2007-05-06 16:03:28 +00:00
wxButton* itemButton14 = new wxButton( itemDialog1, wxID_CANCEL,
_( "&Cancel" ), wxDefaultPosition, wxDefaultSize, 0 );
2007-08-10 19:14:51 +00:00
itemButton14->SetForegroundColour( wxColour( 0, 0, 255 ) );
itemBoxSizer12->Add( itemButton14, 0, wxGROW | wxALL, 5 );
2007-05-06 16:03:28 +00:00
wxButton* itemButton15 = new wxButton( itemDialog1, ID_SET_OPTIONS_ZONE,
_(
"Update Options" ), wxDefaultPosition,
wxDefaultSize, 0 );
2007-08-10 19:14:51 +00:00
itemButton15->SetForegroundColour( wxColour( 0, 100, 0 ) );
itemBoxSizer12->Add( itemButton15, 0, wxGROW | wxALL, 5 );
2007-05-06 16:03:28 +00:00
2007-08-10 19:14:51 +00:00
itemBoxSizer2->Add( 5, 5, 0, wxGROW | wxALL, 5 );
2007-05-06 16:03:28 +00:00
////@end WinEDA_ZoneFrame content construction
2007-08-10 19:14:51 +00:00
wxString title = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric );
2007-05-06 16:03:28 +00:00
m_ClearanceValueTitle->SetLabel( title );
2007-08-10 19:14:51 +00:00
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++ )
2007-08-10 19:14:51 +00:00
{
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 )
2007-08-10 19:14:51 +00:00
m_FillOpt->SetSelection( 1 );
else
m_FillOpt->SetSelection( 2 );
}
2007-05-06 16:03:28 +00:00
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*!
* Should we show tooltips?
*/
bool WinEDA_ZoneFrame::ShowToolTips()
{
return true;
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*!
* Get bitmap resources
*/
wxBitmap WinEDA_ZoneFrame::GetBitmapResource( const wxString& name )
{
// Bitmap retrieval
////@begin WinEDA_ZoneFrame bitmap retrieval
2007-08-10 19:14:51 +00:00
wxUnusedVar( name );
2007-05-06 16:03:28 +00:00
return wxNullBitmap;
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
////@end WinEDA_ZoneFrame bitmap retrieval
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*!
* Get icon resources
*/
wxIcon WinEDA_ZoneFrame::GetIconResource( const wxString& name )
{
// Icon retrieval
////@begin WinEDA_ZoneFrame icon retrieval
2007-08-10 19:14:51 +00:00
wxUnusedVar( name );
2007-05-06 16:03:28 +00:00
return wxNullIcon;
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
////@end WinEDA_ZoneFrame icon retrieval
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*!
* 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();
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
////@end wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame.
}
/*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON2
*/
/***********************************************************/
2007-08-10 19:14:51 +00:00
void WinEDA_ZoneFrame::ExecFillZone( wxCommandEvent& event )
2007-05-06 16:03:28 +00:00
/***********************************************************/
{
2007-08-10 19:14:51 +00:00
switch( m_FillOpt->GetSelection() )
{
case 0:
Zone_Exclude_Pads = FALSE;
s_Zone_Create_Thermal_Relief = FALSE;
2007-08-10 19:14:51 +00:00
break;
case 1:
Zone_Exclude_Pads = TRUE;
s_Zone_Create_Thermal_Relief = TRUE;
2007-08-10 19:14:51 +00:00
break;
case 2:
Zone_Exclude_Pads = TRUE;
s_Zone_Create_Thermal_Relief = FALSE;
2007-08-10 19:14:51 +00:00
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 );
2007-05-06 16:03:28 +00:00
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/**************************************************************/
2007-10-30 21:30:58 +00:00
void WinEDA_PcbFrame::Edit_Zone_Width( wxDC* DC, SEGZONE* aZone )
2007-05-06 16:03:28 +00:00
/**************************************************************/
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/* Edite (change la largeur des segments) la zone Zone.
2007-08-10 19:14:51 +00:00
* La zone est constituee des segments zones de meme TimeStamp
*/
2007-05-06 16:03:28 +00:00
{
2007-08-10 19:14:51 +00:00
bool modify = FALSE;
double f_new_width;
int w_tmp;
wxString Line;
wxString Msg( _( "New zone segment width: " ) );
2007-10-30 21:30:58 +00:00
if( aZone == NULL )
2007-08-10 19:14:51 +00:00
return;
2007-10-30 21:30:58 +00:00
f_new_width = To_User_Unit( g_UnitMetric, aZone->m_Width, GetScreen()->GetInternalUnits() );
2007-08-10 19:14:51 +00:00
Line.Printf( wxT( "%.4f" ), f_new_width );
2007-08-10 19:14:51 +00:00
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,
2007-10-31 06:40:15 +00:00
f_new_width, GetScreen()->GetInternalUnits() );
2007-08-10 19:14:51 +00:00
2007-10-30 21:30:58 +00:00
for( SEGZONE* zone = m_Pcb->m_Zone; zone; zone = zone->Next() )
2007-08-10 19:14:51 +00:00
{
2007-10-30 21:30:58 +00:00
if( zone->m_TimeStamp == aZone->m_TimeStamp )
2007-08-10 19:14:51 +00:00
{
modify = TRUE;
2007-10-30 21:30:58 +00:00
Edit_TrackSegm_Width( DC, zone );
2007-08-10 19:14:51 +00:00
}
}
g_DesignSettings.m_CurrentTrackWidth = w_tmp;
if( modify )
{
GetScreen()->SetModify();
DrawPanel->Refresh();
}
2007-05-06 16:03:28 +00:00
}
/**********************************************************/
2007-10-31 20:02:34 +00:00
void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone )
2007-05-06 16:03:28 +00:00
/**********************************************************/
2007-08-10 19:14:51 +00:00
/* Remove the zone which include the segment aZone.
* A zone is a group of segments which have the same TimeStamp
2007-08-10 19:14:51 +00:00
*/
2007-05-06 16:03:28 +00:00
{
if ( aZone == NULL ) return;
2007-08-10 19:14:51 +00:00
int nb_segm = 0;
bool modify = FALSE;
unsigned long TimeStamp = aZone->m_TimeStamp; // Save reference time stamp (aZone will be deleted)
2007-08-10 19:14:51 +00:00
2007-10-30 21:30:58 +00:00
SEGZONE* next;
for( SEGZONE* zone = m_Pcb->m_Zone; zone != NULL; zone = next )
2007-08-10 19:14:51 +00:00
{
2007-10-30 21:30:58 +00:00
next = zone->Next();
if( zone->m_TimeStamp == TimeStamp )
2007-08-10 19:14:51 +00:00
{
modify = TRUE;
2007-10-30 21:30:58 +00:00
/* Erase segment from screen */
2007-10-30 21:30:58 +00:00
Trace_Une_Piste( DrawPanel, DC, zone, nb_segm, GR_XOR );
/* remove item from linked list and free memory */
2007-10-30 21:30:58 +00:00
zone->DeleteStructure();
2007-08-10 19:14:51 +00:00
}
}
if( modify )
{
GetScreen()->SetModify();
GetScreen()->SetRefreshReq();
}
2007-05-06 16:03:28 +00:00
}
/*****************************************************************************/
2007-08-10 19:14:51 +00:00
EDGE_ZONE* WinEDA_PcbFrame::Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone )
2007-05-06 16:03:28 +00:00
/*****************************************************************************/
/* Routine d'effacement du segment de limite zone en cours de trace */
{
2007-10-31 20:02:34 +00:00
EDGE_ZONE* segm;
2007-08-10 19:14:51 +00:00
if( m_Pcb->m_CurrentLimitZone )
2007-10-31 20:02:34 +00:00
segm = m_Pcb->m_CurrentLimitZone;
2007-08-10 19:14:51 +00:00
else
2007-10-31 20:02:34 +00:00
segm = edge_zone;
2007-08-10 19:14:51 +00:00
2007-10-31 20:02:34 +00:00
if( segm == NULL )
2007-08-10 19:14:51 +00:00
return NULL;
2007-10-31 20:02:34 +00:00
Trace_DrawSegmentPcb( DrawPanel, DC, segm, GR_XOR );
2007-08-10 19:14:51 +00:00
2007-10-31 20:02:34 +00:00
m_Pcb->m_CurrentLimitZone = segm->Next();
delete segm;
2007-08-10 19:14:51 +00:00
2007-10-31 20:02:34 +00:00
segm = m_Pcb->m_CurrentLimitZone;
SetCurItem( segm );
2007-08-10 19:14:51 +00:00
2007-10-31 20:02:34 +00:00
if( segm )
2007-08-10 19:14:51 +00:00
{
2007-10-31 20:02:34 +00:00
segm->Pback = NULL;
2007-08-10 19:14:51 +00:00
if( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
}
else
{
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
SetCurItem( NULL );
2007-08-10 19:14:51 +00:00
}
2007-10-31 20:02:34 +00:00
return segm;
2007-05-06 16:03:28 +00:00
}
/*********************************************/
2007-08-10 19:14:51 +00:00
void WinEDA_PcbFrame::CaptureNetName( wxDC* DC )
2007-05-06 16:03:28 +00:00
/*********************************************/
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/* routine permettant de capturer le nom net net (netcode) d'un pad
2007-08-10 19:14:51 +00:00
* ou d'une piste pour l'utiliser comme netcode de zone
*/
2007-05-06 16:03:28 +00:00
{
2007-08-10 19:14:51 +00:00
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 );
2007-10-13 06:18:44 +00:00
netcode = pt_pad->GetNet();
2007-08-10 19:14:51 +00:00
}
}
else
{
adrpiste->Display_Infos( this );
2007-10-13 06:18:44 +00:00
netcode = adrpiste->GetNet();
2007-08-10 19:14:51 +00:00
}
// 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 );
2007-05-06 16:03:28 +00:00
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*******************************************************/
2007-08-10 19:14:51 +00:00
static void Display_Zone_Netname( WinEDA_PcbFrame* frame )
2007-05-06 16:03:28 +00:00
/*******************************************************/
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*
2007-08-10 19:14:51 +00:00
* Affiche le net_code et le nom de net couramment selectionne
*/
2007-05-06 16:03:28 +00:00
{
2007-08-10 19:14:51 +00:00
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 )
{
2007-10-13 06:18:44 +00:00
if( pt_equipot->GetNet() == g_HightLigth_NetCode )
2007-08-10 19:14:51 +00:00
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 );
2007-05-06 16:03:28 +00:00
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/********************************************************/
2007-08-10 19:14:51 +00:00
static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC )
2007-05-06 16:03:28 +00:00
/********************************************************/
2007-08-10 19:14:51 +00:00
2007-10-31 06:40:15 +00:00
/**
* Function Exit_Zones
* cancels the Begin_Zone state if at least one EDGE_ZONE has been created.
2007-05-06 16:03:28 +00:00
*/
{
2007-08-10 19:14:51 +00:00
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent;
if( pcbframe->m_Pcb->m_CurrentLimitZone )
{
2007-10-31 06:40:15 +00:00
if( Panel->ManageCurseur ) // trace in progress
2007-08-10 19:14:51 +00:00
{
Panel->ManageCurseur( Panel, DC, 0 );
}
pcbframe->DelLimitesZone( DC, TRUE );
2007-08-10 19:14:51 +00:00
}
Panel->ManageCurseur = NULL;
Panel->ForceCloseManageCurseur = NULL;
pcbframe->SetCurItem( NULL );
2007-05-06 16:03:28 +00:00
}
/**************************************************************/
2007-08-10 19:14:51 +00:00
void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw )
2007-05-06 16:03:28 +00:00
/**************************************************************/
{
2007-10-31 06:40:15 +00:00
EDGE_ZONE* segment;
EDGE_ZONE* next;
2007-08-10 19:14:51 +00:00
if( m_Pcb->m_CurrentLimitZone == NULL )
return;
if( !IsOK( this, _( "Delete Current Zone Edges" ) ) )
return;
2007-10-31 06:40:15 +00:00
// erase the old zone border, one segment at a time
2007-10-31 20:02:34 +00:00
for( segment = m_Pcb->m_CurrentLimitZone; segment; segment = next )
2007-08-10 19:14:51 +00:00
{
2007-10-31 20:02:34 +00:00
next = segment->Next();
2007-10-31 06:40:15 +00:00
if( Redraw && DC )
2007-08-10 19:14:51 +00:00
Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR );
2007-10-31 06:40:15 +00:00
delete segment;
2007-08-10 19:14:51 +00:00
}
2007-10-31 20:02:34 +00:00
m_Pcb->m_CurrentLimitZone = NULL;
2007-08-10 19:14:51 +00:00
SetCurItem( NULL );
2007-05-06 16:03:28 +00:00
}
2007-08-10 19:14:51 +00:00
2007-10-31 06:40:15 +00:00
/**
* Function Begin_Zone
* either initializes the first segment of a new zone, or adds an
* intermediate segment.
2007-08-10 19:14:51 +00:00
*/
2007-10-31 06:40:15 +00:00
EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone()
2007-05-06 16:03:28 +00:00
{
2007-10-31 06:40:15 +00:00
EDGE_ZONE* oldedge;
EDGE_ZONE* newedge = NULL;
2007-08-10 19:14:51 +00:00
oldedge = m_Pcb->m_CurrentLimitZone;
2007-10-31 06:40:15 +00:00
// if first segment
2007-08-10 19:14:51 +00:00
if( (m_Pcb->m_CurrentLimitZone == NULL ) /* debut reel du trace */
2007-10-30 21:30:58 +00:00
|| (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */
2007-08-10 19:14:51 +00:00
{
2007-10-31 06:40:15 +00:00
newedge = new EDGE_ZONE( m_Pcb );
2007-08-10 19:14:51 +00:00
newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED;
2007-10-31 06:40:15 +00:00
newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur;
newedge->SetLayer( GetScreen()->m_Active_Layer );
// link into list:
2007-10-31 20:02:34 +00:00
newedge->Pnext = oldedge;
2007-10-31 06:40:15 +00:00
2007-08-10 19:14:51 +00:00
if( oldedge )
2007-10-31 20:02:34 +00:00
oldedge->Pback = newedge;
2007-10-31 06:40:15 +00:00
2007-08-10 19:14:51 +00:00
m_Pcb->m_CurrentLimitZone = newedge;
2007-10-31 06:40:15 +00:00
2007-08-10 19:14:51 +00:00
DrawPanel->ManageCurseur = Show_Zone_Edge_While_MoveMouse;
DrawPanel->ForceCloseManageCurseur = Exit_Zones;
}
2007-10-31 06:40:15 +00:00
// edge in progress:
2007-08-10 19:14:51 +00:00
else /* piste en cours : les coord du point d'arrivee ont ete mises
* a jour par la routine Show_Zone_Edge_While_MoveMouse*/
{
2007-10-30 21:30:58 +00:00
if( oldedge->m_Start != oldedge->m_End )
2007-08-10 19:14:51 +00:00
{
2007-12-12 06:02:43 +00:00
oldedge->m_Flags &= ~(IS_NEW | IS_MOVED);
2007-08-10 19:14:51 +00:00
newedge = new EDGE_ZONE( oldedge );
newedge->m_Flags = IS_NEW | IS_MOVED;
newedge->m_Start = newedge->m_End = oldedge->m_End;
2007-08-23 04:28:46 +00:00
newedge->SetLayer( GetScreen()->m_Active_Layer );
2007-10-31 06:40:15 +00:00
// link into list:
2007-10-31 20:02:34 +00:00
newedge->Pnext = oldedge;
oldedge->Pback = newedge;
2007-08-10 19:14:51 +00:00
m_Pcb->m_CurrentLimitZone = newedge;
}
}
return newedge;
2007-05-06 16:03:28 +00:00
}
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*********************************************/
2007-08-10 19:14:51 +00:00
void WinEDA_PcbFrame::End_Zone( wxDC* DC )
2007-05-06 16:03:28 +00:00
/*********************************************/
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/*
2007-08-10 19:14:51 +00:00
* Routine de fin de trace d'une zone (succession de segments)
*/
2007-05-06 16:03:28 +00:00
{
2007-10-31 20:02:34 +00:00
EDGE_ZONE* edge;
2007-08-10 19:14:51 +00:00
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 */
2007-10-31 20:02:34 +00:00
edge = m_Pcb->m_CurrentLimitZone;
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
2007-10-31 06:40:15 +00:00
2007-10-31 20:02:34 +00:00
while( edge && edge->Next() )
2007-08-10 19:14:51 +00:00
{
2007-10-31 20:02:34 +00:00
edge = edge->Next();
if( edge->m_Flags & STARTPOINT )
2007-08-10 19:14:51 +00:00
break;
2007-10-31 06:40:15 +00:00
2007-10-31 20:02:34 +00:00
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
2007-08-10 19:14:51 +00:00
}
2007-10-31 20:02:34 +00:00
if( edge )
2007-08-10 19:14:51 +00:00
{
2007-10-31 20:02:34 +00:00
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start;
2007-08-10 19:14:51 +00:00
}
Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR );
}
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
2007-05-06 16:03:28 +00:00
}
/******************************************************************************************/
2007-08-10 19:14:51 +00:00
static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
2007-05-06 16:03:28 +00:00
/******************************************************************************************/
2007-08-10 19:14:51 +00:00
2007-05-06 16:03:28 +00:00
/* redessin du contour de la piste lors des deplacements de la souris
2007-08-10 19:14:51 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-10-31 20:02:34 +00:00
EDGE_ZONE* edge;
EDGE_ZONE* currentEdge;
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) panel->m_Parent;
2007-08-10 19:14:51 +00:00
if( pcbframe->m_Pcb->m_CurrentLimitZone == NULL )
return;
/* efface ancienne position si elle a ete deja dessinee */
if( erase )
{
2007-10-31 20:02:34 +00:00
edge = pcbframe->m_Pcb->m_CurrentLimitZone;
// for( ; edge; edge = edge->Next() )
2007-08-10 19:14:51 +00:00
{
2007-10-31 20:02:34 +00:00
Trace_DrawSegmentPcb( panel, DC, edge, GR_XOR );
2007-08-10 19:14:51 +00:00
}
}
/* mise a jour de la couche */
2007-10-31 20:02:34 +00:00
for( edge = pcbframe->m_Pcb->m_CurrentLimitZone; edge; edge = edge->Next() )
2007-08-10 19:14:51 +00:00
{
2007-10-31 20:02:34 +00:00
edge->SetLayer( pcbframe->GetScreen()->m_Active_Layer );
2007-08-10 19:14:51 +00:00
}
/* dessin de la nouvelle piste : mise a jour du point d'arrivee */
2007-10-31 20:02:34 +00:00
currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone;
2007-08-10 19:14:51 +00:00
if( Zone_45_Only )
2007-10-31 20:02:34 +00:00
{
// 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,
&currentEdge->m_End.x, &currentEdge->m_End.y );
2007-08-10 19:14:51 +00:00
}
else /* ici l'angle d'inclinaison est quelconque */
{
2007-10-31 20:02:34 +00:00
currentEdge->m_End = pcbframe->GetScreen()->m_Curseur;
2007-08-10 19:14:51 +00:00
}
2007-10-31 20:02:34 +00:00
// for( ; currentEdge; currentEdge = currentEdge->Next() )
2007-08-10 19:14:51 +00:00
{
2007-10-31 20:02:34 +00:00
Trace_DrawSegmentPcb( panel, DC, currentEdge, GR_XOR );
2007-08-10 19:14:51 +00:00
}
2007-05-06 16:03:28 +00:00
}
/**********************************************/
2007-08-10 19:14:51 +00:00
void WinEDA_PcbFrame::Fill_Zone( wxDC* DC )
2007-05-06 16:03:28 +00:00
/**********************************************/
/** 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
2007-08-10 19:14:51 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-10 19:14:51 +00:00
EQUIPOT* pt_equipot;
wxPoint ZoneStartFill;
wxString msg;
MsgPanel->EraseMsgBox();
if( m_Pcb->ComputeBoundaryBox() == FALSE )
{
DisplayError( this, wxT( "Board is empty!" ), 10 );
return;
}
2007-10-30 21:30:58 +00:00
2007-08-10 19:14:51 +00:00
DrawPanel->m_IgnoreMouseEvents = TRUE;
WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this );
2007-10-30 21:30:58 +00:00
int abrd = frame->ShowModal();
2007-10-30 21:30:58 +00:00
frame->Destroy();
2007-08-10 19:14:51 +00:00
DrawPanel->MouseToCursorSchema();
DrawPanel->m_IgnoreMouseEvents = FALSE;
2007-10-30 21:30:58 +00:00
if( abrd )
2007-08-10 19:14:51 +00:00
return;
2007-11-01 04:48:14 +00:00
// set all the EDGE_ZONEs to the currently active layer and redraw them
// on that layer.
EDGE_ZONE* PtLim = m_Pcb->m_CurrentLimitZone;
2007-10-31 20:02:34 +00:00
for( ; PtLim != NULL; PtLim = PtLim->Next() )
2007-08-10 19:14:51 +00:00
{
Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR );
2007-08-23 04:28:46 +00:00
PtLim->SetLayer( GetScreen()->m_Active_Layer );
2007-08-10 19:14:51 +00:00
Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR );
}
/* Show the NetName */
2007-08-10 19:14:51 +00:00
if( g_HightLigth_NetCode > 0 )
{
pt_equipot = m_Pcb->FindNet( g_HightLigth_NetCode );
2007-08-10 19:14:51 +00:00
if( pt_equipot == NULL )
{
if( g_HightLigth_NetCode > 0 )
2007-11-01 04:48:14 +00:00
DisplayError( this, wxT( "Unable to find Net name" ) );
2007-08-10 19:14:51 +00:00
}
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 );
2007-08-10 19:14:51 +00:00
GetScreen()->SetModify();
2007-05-06 16:03:28 +00:00
}