18 changed files with 2822 additions and 2767 deletions
-
2common/class_layer_box_selector.cpp
-
69common/hotkeys_basic.cpp
-
370eeschema/menubar.cpp
-
12eeschema/tool_lib.cpp
-
14eeschema/tool_sch.cpp
-
8eeschema/tool_viewlib.cpp
-
1628gerbview/class_aperture_macro.cpp
-
580gerbview/class_gerbview_layer_widget.cpp
-
596gerbview/events_called_functions.cpp
-
8gerbview/toolbars_gerber.cpp
-
20include/hotkeys_basic.h
-
802pcbnew/class_netinfo.h
-
746pcbnew/class_pcb_layer_widget.cpp
-
350pcbnew/drc_marker_functions.cpp
-
38pcbnew/menubar_pcbframe.cpp
-
8pcbnew/tool_modedit.cpp
-
14pcbnew/tool_pcb.cpp
-
324pcbnew/zones_convert_to_polygons_aux_functions.cpp
1628
gerbview/class_aperture_macro.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,290 +1,290 @@ |
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr |
|||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> |
|||
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
/*********************************************************/ |
|||
/* class_gerbview_layer_widget.cpp - gerbview layers manager. */ |
|||
/*********************************************************/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "common.h"
|
|||
#include "class_drawpanel.h"
|
|||
#include "pcbstruct.h"
|
|||
#include "macros.h"
|
|||
#include "class_layer_box_selector.h"
|
|||
|
|||
#include "gerbview.h"
|
|||
#include "class_GERBER.h"
|
|||
#include "layer_widget.h"
|
|||
#include "class_gerbview_layer_widget.h"
|
|||
|
|||
|
|||
/*
|
|||
* Class GERBER_LAYER_WIDGET |
|||
* is here to implement the abtract functions of LAYER_WIDGET so they |
|||
* may be tied into the GERBVIEW_FRAME's data and so we can add a popup |
|||
* menu which is specific to PCBNEW's needs. |
|||
*/ |
|||
|
|||
|
|||
GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner, |
|||
int aPointSize ) : |
|||
LAYER_WIDGET( aParent, aFocusOwner, aPointSize ), |
|||
myframe( aParent ) |
|||
{ |
|||
ReFillRender(); |
|||
|
|||
// Update default tabs labels for gerbview
|
|||
SetLayersManagerTabsText( ); |
|||
|
|||
//-----<Popup menu>-------------------------------------------------
|
|||
// handle the popup menu over the layer window.
|
|||
m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN, |
|||
wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
|
|||
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
|
|||
// and not m_LayerScrolledWindow->Connect()
|
|||
Connect( ID_SHOW_ALL_COPPERS, ID_SHOW_NO_COPPERS, wxEVT_COMMAND_MENU_SELECTED, |
|||
wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), NULL, this ); |
|||
|
|||
// install the right click handler into each control at end of ReFill()
|
|||
// using installRightLayerClickHandler
|
|||
} |
|||
|
|||
/**
|
|||
* Function SetLayersManagerTabsText |
|||
* Update the layer manager tabs labels |
|||
* Useful when changing Language or to set labels to a non default value |
|||
*/ |
|||
void GERBER_LAYER_WIDGET::SetLayersManagerTabsText( ) |
|||
{ |
|||
m_notebook->SetPageText(0, _("Layer") ); |
|||
m_notebook->SetPageText(1, _("Render") ); |
|||
} |
|||
|
|||
/**
|
|||
* Function ReFillRender |
|||
* Rebuild Render for instance after the config is read |
|||
*/ |
|||
void GERBER_LAYER_WIDGET::ReFillRender() |
|||
{ |
|||
BOARD* board = myframe->GetBoard(); |
|||
ClearRenderRows(); |
|||
|
|||
// Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
|
|||
// is changed before appending to the LAYER_WIDGET. This is an automatic variable
|
|||
// not a static variable, change the color & state after copying from code to renderRows
|
|||
// on the stack.
|
|||
LAYER_WIDGET::ROW renderRows[2] = { |
|||
|
|||
#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
|
|||
|
|||
// text id color tooltip checked
|
|||
RR( _( "Grid" ), GERBER_GRID_VISIBLE, WHITE, _( "Show the (x,y) grid dots" ) ), |
|||
RR( _( "DCodes" ), DCODES_VISIBLE, WHITE, _( "Show DCodes identification" ) ), |
|||
}; |
|||
|
|||
for( unsigned row=0; row<DIM(renderRows); ++row ) |
|||
{ |
|||
if( renderRows[row].color != -1 ) // does this row show a color?
|
|||
{ |
|||
// this window frame must have an established BOARD, i.e. after SetBoard()
|
|||
renderRows[row].color = board->GetVisibleElementColor( renderRows[row].id ); |
|||
} |
|||
renderRows[row].state = board->IsElementVisible( renderRows[row].id ); |
|||
} |
|||
|
|||
AppendRenderRows( renderRows, DIM(renderRows) ); |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::installRightLayerClickHandler() |
|||
{ |
|||
int rowCount = GetLayerRowCount(); |
|||
for( int row=0; row<rowCount; ++row ) |
|||
{ |
|||
for( int col=0; col<LYR_COLUMN_COUNT; ++col ) |
|||
{ |
|||
wxWindow* w = getLayerComp( row, col ); |
|||
|
|||
w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( |
|||
GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event ) |
|||
{ |
|||
wxMenu menu; |
|||
|
|||
// menu text is capitalized:
|
|||
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
|
|||
menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_COPPERS, |
|||
_("Show All Layers") ) ); |
|||
|
|||
menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_COPPERS, |
|||
_( "Hide All Layers" ) ) ); |
|||
|
|||
PopupMenu( &menu ); |
|||
|
|||
passOnFocus(); |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event ) |
|||
{ |
|||
int rowCount; |
|||
int menuId = event.GetId(); |
|||
bool visible = (menuId == ID_SHOW_ALL_COPPERS) ? true : false;; |
|||
int visibleLayers = 0; |
|||
|
|||
switch( menuId ) |
|||
{ |
|||
case ID_SHOW_ALL_COPPERS: |
|||
case ID_SHOW_NO_COPPERS: |
|||
rowCount = GetLayerRowCount(); |
|||
for( int row=0; row < rowCount; ++row ) |
|||
{ |
|||
wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 ); |
|||
cb->SetValue( visible ); |
|||
if( visible ) |
|||
visibleLayers |= (1 << row); |
|||
else |
|||
visibleLayers &= ~(1 << row); |
|||
} |
|||
|
|||
myframe->GetBoard()->SetVisibleLayers( visibleLayers ); |
|||
myframe->DrawPanel->Refresh(); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
void GERBER_LAYER_WIDGET::ReFill() |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
int layer; |
|||
ClearLayerRows(); |
|||
for( layer = 0; layer < LAYER_COUNT; layer++ ) |
|||
{ |
|||
wxString msg; |
|||
msg.Printf( _("Layer %d"), layer+1 ); |
|||
AppendLayerRow( LAYER_WIDGET::ROW( msg, layer, |
|||
brd->GetLayerColor( layer ), wxEmptyString, true ) ); |
|||
} |
|||
|
|||
installRightLayerClickHandler(); |
|||
} |
|||
|
|||
//-----<LAYER_WIDGET callbacks>-------------------------------------------
|
|||
|
|||
void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, int aColor ) |
|||
{ |
|||
myframe->GetBoard()->SetLayerColor( aLayer, aColor ); |
|||
myframe->m_SelLayerBox->ResyncBitmapOnly(); |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
bool GERBER_LAYER_WIDGET::OnLayerSelect( int aLayer ) |
|||
{ |
|||
// the layer change from the GERBER_LAYER_WIDGET can be denied by returning
|
|||
// false from this function.
|
|||
int layer = myframe->getActiveLayer( ); |
|||
myframe->setActiveLayer( aLayer, false ); |
|||
myframe->syncLayerBox(); |
|||
if( layer != myframe->getActiveLayer( ) ) |
|||
myframe->DrawPanel->Refresh(); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
int visibleLayers = brd->GetVisibleLayers(); |
|||
|
|||
if( isVisible ) |
|||
visibleLayers |= (1 << aLayer); |
|||
else |
|||
visibleLayers &= ~(1 << aLayer); |
|||
|
|||
brd->SetVisibleLayers( visibleLayers ); |
|||
|
|||
if( isFinal ) |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::OnRenderColorChange( int aId, int aColor ) |
|||
{ |
|||
myframe->GetBoard()->SetVisibleElementColor( aId, aColor ); |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
brd->SetElementVisibility( aId, isEnabled ); |
|||
|
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
//-----</LAYER_WIDGET callbacks>------------------------------------------
|
|||
|
|||
/*
|
|||
* Virtual Function useAlternateBitmap |
|||
* return true if bitmaps shown in Render layer list |
|||
* must be alternate bitmaps, or false to use "normal" bitmaps |
|||
*/ |
|||
bool GERBER_LAYER_WIDGET::useAlternateBitmap(int aRow) |
|||
{ |
|||
bool inUse = false; |
|||
GERBER_IMAGE* gerber = g_GERBER_List[aRow]; |
|||
|
|||
if( gerber != NULL && gerber->m_InUse ) |
|||
inUse = true; |
|||
|
|||
return inUse; |
|||
} |
|||
|
|||
/**
|
|||
* Function UpdateLayerIcons |
|||
* Update the layer manager icons (layers only) |
|||
* Useful when loading a file or clearing a layer because they change |
|||
*/ |
|||
void GERBER_LAYER_WIDGET::UpdateLayerIcons() |
|||
{ |
|||
int row_count = GetLayerRowCount(); |
|||
for( int row = 0; row < row_count ; row++ ) |
|||
{ |
|||
wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row, 0 ); |
|||
if( bm == NULL) |
|||
continue; |
|||
|
|||
if( row == m_CurrentRow ) |
|||
bm->SetBitmap( useAlternateBitmap(row) ? *m_RightArrowAlternateBitmap : *m_RightArrowBitmap ); |
|||
else |
|||
bm->SetBitmap( useAlternateBitmap(row) ? *m_BlankAlternateBitmap : *m_BlankBitmap ); |
|||
} |
|||
} |
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr |
|||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> |
|||
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
/*********************************************************/ |
|||
/* class_gerbview_layer_widget.cpp - gerbview layers manager. */ |
|||
/*********************************************************/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "common.h"
|
|||
#include "class_drawpanel.h"
|
|||
#include "pcbstruct.h"
|
|||
#include "macros.h"
|
|||
#include "class_layer_box_selector.h"
|
|||
|
|||
#include "gerbview.h"
|
|||
#include "class_GERBER.h"
|
|||
#include "layer_widget.h"
|
|||
#include "class_gerbview_layer_widget.h"
|
|||
|
|||
|
|||
/*
|
|||
* Class GERBER_LAYER_WIDGET |
|||
* is here to implement the abtract functions of LAYER_WIDGET so they |
|||
* may be tied into the GERBVIEW_FRAME's data and so we can add a popup |
|||
* menu which is specific to PCBNEW's needs. |
|||
*/ |
|||
|
|||
|
|||
GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner, |
|||
int aPointSize ) : |
|||
LAYER_WIDGET( aParent, aFocusOwner, aPointSize ), |
|||
myframe( aParent ) |
|||
{ |
|||
ReFillRender(); |
|||
|
|||
// Update default tabs labels for gerbview
|
|||
SetLayersManagerTabsText( ); |
|||
|
|||
//-----<Popup menu>-------------------------------------------------
|
|||
// handle the popup menu over the layer window.
|
|||
m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN, |
|||
wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
|
|||
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
|
|||
// and not m_LayerScrolledWindow->Connect()
|
|||
Connect( ID_SHOW_ALL_COPPERS, ID_SHOW_NO_COPPERS, wxEVT_COMMAND_MENU_SELECTED, |
|||
wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), NULL, this ); |
|||
|
|||
// install the right click handler into each control at end of ReFill()
|
|||
// using installRightLayerClickHandler
|
|||
} |
|||
|
|||
/**
|
|||
* Function SetLayersManagerTabsText |
|||
* Update the layer manager tabs labels |
|||
* Useful when changing Language or to set labels to a non default value |
|||
*/ |
|||
void GERBER_LAYER_WIDGET::SetLayersManagerTabsText( ) |
|||
{ |
|||
m_notebook->SetPageText(0, _("Layer") ); |
|||
m_notebook->SetPageText(1, _("Render") ); |
|||
} |
|||
|
|||
/**
|
|||
* Function ReFillRender |
|||
* Rebuild Render for instance after the config is read |
|||
*/ |
|||
void GERBER_LAYER_WIDGET::ReFillRender() |
|||
{ |
|||
BOARD* board = myframe->GetBoard(); |
|||
ClearRenderRows(); |
|||
|
|||
// Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
|
|||
// is changed before appending to the LAYER_WIDGET. This is an automatic variable
|
|||
// not a static variable, change the color & state after copying from code to renderRows
|
|||
// on the stack.
|
|||
LAYER_WIDGET::ROW renderRows[2] = { |
|||
|
|||
#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
|
|||
|
|||
// text id color tooltip checked
|
|||
RR( _( "Grid" ), GERBER_GRID_VISIBLE, WHITE, _( "Show the (x,y) grid dots" ) ), |
|||
RR( _( "DCodes" ), DCODES_VISIBLE, WHITE, _( "Show DCodes identification" ) ), |
|||
}; |
|||
|
|||
for( unsigned row=0; row<DIM(renderRows); ++row ) |
|||
{ |
|||
if( renderRows[row].color != -1 ) // does this row show a color?
|
|||
{ |
|||
// this window frame must have an established BOARD, i.e. after SetBoard()
|
|||
renderRows[row].color = board->GetVisibleElementColor( renderRows[row].id ); |
|||
} |
|||
renderRows[row].state = board->IsElementVisible( renderRows[row].id ); |
|||
} |
|||
|
|||
AppendRenderRows( renderRows, DIM(renderRows) ); |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::installRightLayerClickHandler() |
|||
{ |
|||
int rowCount = GetLayerRowCount(); |
|||
for( int row=0; row<rowCount; ++row ) |
|||
{ |
|||
for( int col=0; col<LYR_COLUMN_COUNT; ++col ) |
|||
{ |
|||
wxWindow* w = getLayerComp( row, col ); |
|||
|
|||
w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( |
|||
GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event ) |
|||
{ |
|||
wxMenu menu; |
|||
|
|||
// menu text is capitalized:
|
|||
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
|
|||
menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_COPPERS, |
|||
_("Show All Layers") ) ); |
|||
|
|||
menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_COPPERS, |
|||
_( "Hide All Layers" ) ) ); |
|||
|
|||
PopupMenu( &menu ); |
|||
|
|||
passOnFocus(); |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event ) |
|||
{ |
|||
int rowCount; |
|||
int menuId = event.GetId(); |
|||
bool visible = (menuId == ID_SHOW_ALL_COPPERS) ? true : false;; |
|||
int visibleLayers = 0; |
|||
|
|||
switch( menuId ) |
|||
{ |
|||
case ID_SHOW_ALL_COPPERS: |
|||
case ID_SHOW_NO_COPPERS: |
|||
rowCount = GetLayerRowCount(); |
|||
for( int row=0; row < rowCount; ++row ) |
|||
{ |
|||
wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 ); |
|||
cb->SetValue( visible ); |
|||
if( visible ) |
|||
visibleLayers |= (1 << row); |
|||
else |
|||
visibleLayers &= ~(1 << row); |
|||
} |
|||
|
|||
myframe->GetBoard()->SetVisibleLayers( visibleLayers ); |
|||
myframe->DrawPanel->Refresh(); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
void GERBER_LAYER_WIDGET::ReFill() |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
int layer; |
|||
ClearLayerRows(); |
|||
for( layer = 0; layer < LAYER_COUNT; layer++ ) |
|||
{ |
|||
wxString msg; |
|||
msg.Printf( _("Layer %d"), layer+1 ); |
|||
AppendLayerRow( LAYER_WIDGET::ROW( msg, layer, |
|||
brd->GetLayerColor( layer ), wxEmptyString, true ) ); |
|||
} |
|||
|
|||
installRightLayerClickHandler(); |
|||
} |
|||
|
|||
//-----<LAYER_WIDGET callbacks>-------------------------------------------
|
|||
|
|||
void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, int aColor ) |
|||
{ |
|||
myframe->GetBoard()->SetLayerColor( aLayer, aColor ); |
|||
myframe->m_SelLayerBox->ResyncBitmapOnly(); |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
bool GERBER_LAYER_WIDGET::OnLayerSelect( int aLayer ) |
|||
{ |
|||
// the layer change from the GERBER_LAYER_WIDGET can be denied by returning
|
|||
// false from this function.
|
|||
int layer = myframe->getActiveLayer( ); |
|||
myframe->setActiveLayer( aLayer, false ); |
|||
myframe->syncLayerBox(); |
|||
if( layer != myframe->getActiveLayer( ) ) |
|||
myframe->DrawPanel->Refresh(); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
int visibleLayers = brd->GetVisibleLayers(); |
|||
|
|||
if( isVisible ) |
|||
visibleLayers |= (1 << aLayer); |
|||
else |
|||
visibleLayers &= ~(1 << aLayer); |
|||
|
|||
brd->SetVisibleLayers( visibleLayers ); |
|||
|
|||
if( isFinal ) |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::OnRenderColorChange( int aId, int aColor ) |
|||
{ |
|||
myframe->GetBoard()->SetVisibleElementColor( aId, aColor ); |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
brd->SetElementVisibility( aId, isEnabled ); |
|||
|
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
//-----</LAYER_WIDGET callbacks>------------------------------------------
|
|||
|
|||
/*
|
|||
* Virtual Function useAlternateBitmap |
|||
* return true if bitmaps shown in Render layer list |
|||
* must be alternate bitmaps, or false to use "normal" bitmaps |
|||
*/ |
|||
bool GERBER_LAYER_WIDGET::useAlternateBitmap(int aRow) |
|||
{ |
|||
bool inUse = false; |
|||
GERBER_IMAGE* gerber = g_GERBER_List[aRow]; |
|||
|
|||
if( gerber != NULL && gerber->m_InUse ) |
|||
inUse = true; |
|||
|
|||
return inUse; |
|||
} |
|||
|
|||
/**
|
|||
* Function UpdateLayerIcons |
|||
* Update the layer manager icons (layers only) |
|||
* Useful when loading a file or clearing a layer because they change |
|||
*/ |
|||
void GERBER_LAYER_WIDGET::UpdateLayerIcons() |
|||
{ |
|||
int row_count = GetLayerRowCount(); |
|||
for( int row = 0; row < row_count ; row++ ) |
|||
{ |
|||
wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row, 0 ); |
|||
if( bm == NULL) |
|||
continue; |
|||
|
|||
if( row == m_CurrentRow ) |
|||
bm->SetBitmap( useAlternateBitmap(row) ? *m_RightArrowAlternateBitmap : *m_RightArrowBitmap ); |
|||
else |
|||
bm->SetBitmap( useAlternateBitmap(row) ? *m_BlankAlternateBitmap : *m_BlankBitmap ); |
|||
} |
|||
} |
|||
@ -1,298 +1,298 @@ |
|||
/**
|
|||
* @file events_called_functions.cpp |
|||
* @brief Gerbview command event functions. |
|||
*/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "appl_wxstruct.h"
|
|||
#include "class_drawpanel.h"
|
|||
#include "confirm.h"
|
|||
#include "common.h"
|
|||
#include "gestfich.h"
|
|||
|
|||
#include "gerbview.h"
|
|||
#include "kicad_device_context.h"
|
|||
#include "gerbview_id.h"
|
|||
#include "class_GERBER.h"
|
|||
#include "dialog_helpers.h"
|
|||
#include "class_DCodeSelectionbox.h"
|
|||
#include "class_gerbview_layer_widget.h"
|
|||
|
|||
|
|||
// Event table:
|
|||
|
|||
BEGIN_EVENT_TABLE( GERBVIEW_FRAME, PCB_BASE_FRAME ) |
|||
EVT_CLOSE( GERBVIEW_FRAME::OnCloseWindow ) |
|||
EVT_SIZE( GERBVIEW_FRAME::OnSize ) |
|||
|
|||
EVT_TOOL( wxID_FILE, GERBVIEW_FRAME::Files_io ) |
|||
EVT_TOOL( ID_GERBVIEW_ERASE_ALL, GERBVIEW_FRAME::Files_io ) |
|||
EVT_TOOL( ID_GERBVIEW_LOAD_DRILL_FILE, GERBVIEW_FRAME::Files_io ) |
|||
EVT_TOOL( ID_GERBVIEW_LOAD_DCODE_FILE, GERBVIEW_FRAME::Files_io ) |
|||
EVT_TOOL( ID_NEW_BOARD, GERBVIEW_FRAME::Files_io ) |
|||
|
|||
// Menu Files:
|
|||
EVT_MENU( wxID_FILE, GERBVIEW_FRAME::Files_io ) |
|||
EVT_MENU( ID_NEW_BOARD, GERBVIEW_FRAME::Files_io ) |
|||
EVT_MENU( ID_GEN_PLOT, GERBVIEW_FRAME::ToPlotter ) |
|||
EVT_MENU( ID_GERBVIEW_EXPORT_TO_PCBNEW, GERBVIEW_FRAME::ExportDataInPcbnewFormat ) |
|||
|
|||
EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, GERBVIEW_FRAME::OnGbrFileHistory ) |
|||
EVT_MENU_RANGE( ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILE9, |
|||
GERBVIEW_FRAME::OnDrlFileHistory ) |
|||
|
|||
EVT_MENU( wxID_EXIT, GERBVIEW_FRAME::OnQuit ) |
|||
|
|||
// menu Preferences
|
|||
EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END, |
|||
GERBVIEW_FRAME::Process_Config ) |
|||
|
|||
EVT_MENU( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG, |
|||
GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_MENU( wxID_PREFERENCES, GERBVIEW_FRAME::InstallGerberOptionsDialog ) |
|||
|
|||
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, EDA_DRAW_FRAME::SetLanguage ) |
|||
|
|||
// menu Postprocess
|
|||
EVT_MENU( ID_GERBVIEW_SHOW_LIST_DCODES, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_MENU( ID_GERBVIEW_SHOW_SOURCE, GERBVIEW_FRAME::OnShowGerberSourceFile ) |
|||
EVT_MENU( ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR, |
|||
EDA_BASE_FRAME::OnSelectPreferredEditor ) |
|||
|
|||
// menu Miscellaneous
|
|||
EVT_MENU( ID_GERBVIEW_GLOBAL_DELETE, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
|
|||
// Menu Help
|
|||
EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp ) |
|||
EVT_MENU( wxID_ABOUT, EDA_DRAW_FRAME::GetKicadAbout ) |
|||
|
|||
EVT_TOOL( wxID_CUT, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_TOOL( wxID_COPY, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_TOOL( wxID_PASTE, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_TOOL( wxID_UNDO, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_TOOL( wxID_PRINT, GERBVIEW_FRAME::ToPrinter ) |
|||
EVT_COMBOBOX( ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER, |
|||
GERBVIEW_FRAME::OnSelectActiveLayer ) |
|||
|
|||
EVT_SELECT_DCODE( ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE, GERBVIEW_FRAME::OnSelectActiveDCode ) |
|||
|
|||
// Vertical toolbar:
|
|||
EVT_TOOL( ID_NO_TOOL_SELECTED, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
|
|||
EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE, |
|||
GERBVIEW_FRAME::Process_Special_Functions ) |
|||
|
|||
// Option toolbar
|
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_LINES_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR, |
|||
GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_DCODES, GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL_RANGE( ID_TB_OPTIONS_SHOW_GBR_MODE_0, ID_TB_OPTIONS_SHOW_GBR_MODE_2, |
|||
GERBVIEW_FRAME::OnSelectDisplayMode ) |
|||
|
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, |
|||
GERBVIEW_FRAME::OnUpdateFlashedItemsDrawMode ) |
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_LINES_SKETCH, GERBVIEW_FRAME::OnUpdateLinesDrawMode ) |
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, GERBVIEW_FRAME::OnUpdatePolygonsDrawMode ) |
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_DCODES, GERBVIEW_FRAME::OnUpdateShowDCodes ) |
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR, |
|||
GERBVIEW_FRAME::OnUpdateShowLayerManager ) |
|||
|
|||
EVT_UPDATE_UI( ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE, GERBVIEW_FRAME::OnUpdateSelectDCode ) |
|||
EVT_UPDATE_UI( ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER, |
|||
GERBVIEW_FRAME::OnUpdateLayerSelectBox ) |
|||
EVT_UPDATE_UI_RANGE( ID_TB_OPTIONS_SHOW_GBR_MODE_0, ID_TB_OPTIONS_SHOW_GBR_MODE_2, |
|||
GERBVIEW_FRAME::OnUpdateDrawMode ) |
|||
|
|||
END_EVENT_TABLE() |
|||
|
|||
|
|||
/* Handles the selection of tools, menu, and popup menu commands.
|
|||
*/ |
|||
void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event ) |
|||
{ |
|||
int id = event.GetId(); |
|||
|
|||
switch( id ) |
|||
{ |
|||
case wxID_CUT: |
|||
case wxID_COPY: |
|||
case ID_POPUP_DELETE_BLOCK: |
|||
case ID_POPUP_PLACE_BLOCK: |
|||
case ID_POPUP_ZOOM_BLOCK: |
|||
break; |
|||
|
|||
case ID_POPUP_CANCEL_CURRENT_COMMAND: |
|||
DrawPanel->EndMouseCapture(); |
|||
|
|||
if( GetScreen()->m_BlockLocate.m_Command != BLOCK_IDLE ) |
|||
{ |
|||
/* Should not be executed, except bug */ |
|||
GetScreen()->m_BlockLocate.m_Command = BLOCK_IDLE; |
|||
GetScreen()->m_BlockLocate.m_State = STATE_NO_BLOCK; |
|||
GetScreen()->m_BlockLocate.ClearItemsList(); |
|||
} |
|||
|
|||
if( GetToolId() == ID_NO_TOOL_SELECTED ) |
|||
SetToolID( ID_NO_TOOL_SELECTED, DrawPanel->GetDefaultCursor(), wxEmptyString ); |
|||
else |
|||
DrawPanel->SetCursor( DrawPanel->GetCurrentCursor() ); |
|||
break; |
|||
|
|||
default: |
|||
DrawPanel->EndMouseCapture(); |
|||
break; |
|||
} |
|||
|
|||
INSTALL_UNBUFFERED_DC( dc, DrawPanel ); |
|||
|
|||
switch( id ) |
|||
{ |
|||
case ID_GERBVIEW_GLOBAL_DELETE: |
|||
Erase_Current_Layer( true ); |
|||
ClearMsgPanel(); |
|||
break; |
|||
|
|||
case ID_NO_TOOL_SELECTED: |
|||
SetToolID( ID_NO_TOOL_SELECTED, DrawPanel->GetDefaultCursor(), wxEmptyString ); |
|||
break; |
|||
|
|||
case ID_POPUP_CLOSE_CURRENT_TOOL: |
|||
SetToolID( ID_NO_TOOL_SELECTED, DrawPanel->GetDefaultCursor(), wxEmptyString ); |
|||
break; |
|||
|
|||
case ID_POPUP_CANCEL_CURRENT_COMMAND: |
|||
break; |
|||
|
|||
case ID_GERBVIEW_SHOW_LIST_DCODES: |
|||
Liste_D_Codes(); |
|||
break; |
|||
|
|||
case ID_POPUP_PLACE_BLOCK: |
|||
GetScreen()->m_BlockLocate.m_Command = BLOCK_MOVE; |
|||
DrawPanel->m_AutoPAN_Request = FALSE; |
|||
HandleBlockPlace( &dc ); |
|||
break; |
|||
|
|||
case ID_POPUP_ZOOM_BLOCK: |
|||
GetScreen()->m_BlockLocate.m_Command = BLOCK_ZOOM; |
|||
GetScreen()->m_BlockLocate.SetMessageBlock( this ); |
|||
HandleBlockEnd( &dc ); |
|||
break; |
|||
|
|||
case ID_POPUP_DELETE_BLOCK: |
|||
GetScreen()->m_BlockLocate.m_Command = BLOCK_DELETE; |
|||
GetScreen()->m_BlockLocate.SetMessageBlock( this ); |
|||
HandleBlockEnd( &dc ); |
|||
break; |
|||
|
|||
default: |
|||
wxFAIL_MSG( wxT( "GERBVIEW_FRAME::Process_Special_Functions error" ) ); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
/* Selects the active DCode for the current active layer.
|
|||
* Items using this DCode are hightlighted |
|||
*/ |
|||
void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event ) |
|||
{ |
|||
GERBER_IMAGE* gerber_image = g_GERBER_List[getActiveLayer()]; |
|||
if( gerber_image ) |
|||
{ |
|||
int tool = m_DCodeSelector->GetSelectedDCodeId(); |
|||
if( tool != gerber_image->m_Selected_Tool ) |
|||
{ |
|||
gerber_image->m_Selected_Tool = tool; |
|||
DrawPanel->Refresh(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* Selects the active layer:
|
|||
* - if a file is loaded, it is loaded in this layer |
|||
* _ this layer is displayed on top of other layers |
|||
*/ |
|||
void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event ) |
|||
{ |
|||
int layer = getActiveLayer(); |
|||
|
|||
setActiveLayer( event.GetSelection() ); |
|||
if( layer != getActiveLayer() ) |
|||
DrawPanel->Refresh(); |
|||
} |
|||
|
|||
|
|||
/* Call preferred editor to show (and edit) the gerber source file
|
|||
* loaded in the active layer |
|||
*/ |
|||
void GERBVIEW_FRAME::OnShowGerberSourceFile( wxCommandEvent& event ) |
|||
{ |
|||
int layer = getActiveLayer(); |
|||
GERBER_IMAGE* gerber_layer = g_GERBER_List[layer]; |
|||
|
|||
if( gerber_layer ) |
|||
{ |
|||
wxString editorname = wxGetApp().GetEditorName(); |
|||
if( !editorname.IsEmpty() ) |
|||
{ |
|||
wxFileName fn( gerber_layer->m_FileName ); |
|||
ExecuteFile( this, editorname, QuoteFullPath( fn ) ); |
|||
} |
|||
else |
|||
{ |
|||
wxMessageBox( _( "No editor defined. Please select one" ) ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/* Function OnSelectDisplayMode: called to select display mode
|
|||
* (fast display, or exact mode with stacked images or with transparency |
|||
*/ |
|||
void GERBVIEW_FRAME::OnSelectDisplayMode( wxCommandEvent& event ) |
|||
{ |
|||
int oldMode = GetDisplayMode(); |
|||
|
|||
switch( event.GetId() ) |
|||
{ |
|||
case ID_TB_OPTIONS_SHOW_GBR_MODE_0: |
|||
SetDisplayMode( 0 ); |
|||
break; |
|||
|
|||
case ID_TB_OPTIONS_SHOW_GBR_MODE_1: |
|||
SetDisplayMode( 1 ); |
|||
break; |
|||
|
|||
case ID_TB_OPTIONS_SHOW_GBR_MODE_2: |
|||
SetDisplayMode( 2 ); |
|||
break; |
|||
} |
|||
|
|||
if( GetDisplayMode() != oldMode ) |
|||
DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void GERBVIEW_FRAME::OnQuit( wxCommandEvent& event ) |
|||
{ |
|||
Close( true ); |
|||
} |
|||
|
|||
/**
|
|||
* Function SetLanguage |
|||
* called on a language menu selection |
|||
* Update Layer manager title and tabs texts |
|||
*/ |
|||
void GERBVIEW_FRAME::SetLanguage( wxCommandEvent& event ) |
|||
{ |
|||
EDA_DRAW_FRAME::SetLanguage( event ); |
|||
m_LayersManager->SetLayersManagerTabsText(); |
|||
wxAuiPaneInfo& pane_info = m_auimgr.GetPane( m_LayersManager ); |
|||
pane_info.Caption( _( "Visibles" ) ); |
|||
m_auimgr.Update(); |
|||
|
|||
ReFillLayerWidget(); |
|||
} |
|||
/**
|
|||
* @file events_called_functions.cpp |
|||
* @brief Gerbview command event functions. |
|||
*/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "appl_wxstruct.h"
|
|||
#include "class_drawpanel.h"
|
|||
#include "confirm.h"
|
|||
#include "common.h"
|
|||
#include "gestfich.h"
|
|||
|
|||
#include "gerbview.h"
|
|||
#include "kicad_device_context.h"
|
|||
#include "gerbview_id.h"
|
|||
#include "class_GERBER.h"
|
|||
#include "dialog_helpers.h"
|
|||
#include "class_DCodeSelectionbox.h"
|
|||
#include "class_gerbview_layer_widget.h"
|
|||
|
|||
|
|||
// Event table:
|
|||
|
|||
BEGIN_EVENT_TABLE( GERBVIEW_FRAME, PCB_BASE_FRAME ) |
|||
EVT_CLOSE( GERBVIEW_FRAME::OnCloseWindow ) |
|||
EVT_SIZE( GERBVIEW_FRAME::OnSize ) |
|||
|
|||
EVT_TOOL( wxID_FILE, GERBVIEW_FRAME::Files_io ) |
|||
EVT_TOOL( ID_GERBVIEW_ERASE_ALL, GERBVIEW_FRAME::Files_io ) |
|||
EVT_TOOL( ID_GERBVIEW_LOAD_DRILL_FILE, GERBVIEW_FRAME::Files_io ) |
|||
EVT_TOOL( ID_GERBVIEW_LOAD_DCODE_FILE, GERBVIEW_FRAME::Files_io ) |
|||
EVT_TOOL( ID_NEW_BOARD, GERBVIEW_FRAME::Files_io ) |
|||
|
|||
// Menu Files:
|
|||
EVT_MENU( wxID_FILE, GERBVIEW_FRAME::Files_io ) |
|||
EVT_MENU( ID_NEW_BOARD, GERBVIEW_FRAME::Files_io ) |
|||
EVT_MENU( ID_GEN_PLOT, GERBVIEW_FRAME::ToPlotter ) |
|||
EVT_MENU( ID_GERBVIEW_EXPORT_TO_PCBNEW, GERBVIEW_FRAME::ExportDataInPcbnewFormat ) |
|||
|
|||
EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, GERBVIEW_FRAME::OnGbrFileHistory ) |
|||
EVT_MENU_RANGE( ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILE9, |
|||
GERBVIEW_FRAME::OnDrlFileHistory ) |
|||
|
|||
EVT_MENU( wxID_EXIT, GERBVIEW_FRAME::OnQuit ) |
|||
|
|||
// menu Preferences
|
|||
EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END, |
|||
GERBVIEW_FRAME::Process_Config ) |
|||
|
|||
EVT_MENU( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG, |
|||
GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_MENU( wxID_PREFERENCES, GERBVIEW_FRAME::InstallGerberOptionsDialog ) |
|||
|
|||
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, EDA_DRAW_FRAME::SetLanguage ) |
|||
|
|||
// menu Postprocess
|
|||
EVT_MENU( ID_GERBVIEW_SHOW_LIST_DCODES, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_MENU( ID_GERBVIEW_SHOW_SOURCE, GERBVIEW_FRAME::OnShowGerberSourceFile ) |
|||
EVT_MENU( ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR, |
|||
EDA_BASE_FRAME::OnSelectPreferredEditor ) |
|||
|
|||
// menu Miscellaneous
|
|||
EVT_MENU( ID_GERBVIEW_GLOBAL_DELETE, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
|
|||
// Menu Help
|
|||
EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp ) |
|||
EVT_MENU( wxID_ABOUT, EDA_DRAW_FRAME::GetKicadAbout ) |
|||
|
|||
EVT_TOOL( wxID_CUT, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_TOOL( wxID_COPY, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_TOOL( wxID_PASTE, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_TOOL( wxID_UNDO, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
EVT_TOOL( wxID_PRINT, GERBVIEW_FRAME::ToPrinter ) |
|||
EVT_COMBOBOX( ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER, |
|||
GERBVIEW_FRAME::OnSelectActiveLayer ) |
|||
|
|||
EVT_SELECT_DCODE( ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE, GERBVIEW_FRAME::OnSelectActiveDCode ) |
|||
|
|||
// Vertical toolbar:
|
|||
EVT_TOOL( ID_NO_TOOL_SELECTED, GERBVIEW_FRAME::Process_Special_Functions ) |
|||
|
|||
EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE, |
|||
GERBVIEW_FRAME::Process_Special_Functions ) |
|||
|
|||
// Option toolbar
|
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_LINES_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR, |
|||
GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL( ID_TB_OPTIONS_SHOW_DCODES, GERBVIEW_FRAME::OnSelectOptionToolbar ) |
|||
EVT_TOOL_RANGE( ID_TB_OPTIONS_SHOW_GBR_MODE_0, ID_TB_OPTIONS_SHOW_GBR_MODE_2, |
|||
GERBVIEW_FRAME::OnSelectDisplayMode ) |
|||
|
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, |
|||
GERBVIEW_FRAME::OnUpdateFlashedItemsDrawMode ) |
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_LINES_SKETCH, GERBVIEW_FRAME::OnUpdateLinesDrawMode ) |
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, GERBVIEW_FRAME::OnUpdatePolygonsDrawMode ) |
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_DCODES, GERBVIEW_FRAME::OnUpdateShowDCodes ) |
|||
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR, |
|||
GERBVIEW_FRAME::OnUpdateShowLayerManager ) |
|||
|
|||
EVT_UPDATE_UI( ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE, GERBVIEW_FRAME::OnUpdateSelectDCode ) |
|||
EVT_UPDATE_UI( ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER, |
|||
GERBVIEW_FRAME::OnUpdateLayerSelectBox ) |
|||
EVT_UPDATE_UI_RANGE( ID_TB_OPTIONS_SHOW_GBR_MODE_0, ID_TB_OPTIONS_SHOW_GBR_MODE_2, |
|||
GERBVIEW_FRAME::OnUpdateDrawMode ) |
|||
|
|||
END_EVENT_TABLE() |
|||
|
|||
|
|||
/* Handles the selection of tools, menu, and popup menu commands.
|
|||
*/ |
|||
void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event ) |
|||
{ |
|||
int id = event.GetId(); |
|||
|
|||
switch( id ) |
|||
{ |
|||
case wxID_CUT: |
|||
case wxID_COPY: |
|||
case ID_POPUP_DELETE_BLOCK: |
|||
case ID_POPUP_PLACE_BLOCK: |
|||
case ID_POPUP_ZOOM_BLOCK: |
|||
break; |
|||
|
|||
case ID_POPUP_CANCEL_CURRENT_COMMAND: |
|||
DrawPanel->EndMouseCapture(); |
|||
|
|||
if( GetScreen()->m_BlockLocate.m_Command != BLOCK_IDLE ) |
|||
{ |
|||
/* Should not be executed, except bug */ |
|||
GetScreen()->m_BlockLocate.m_Command = BLOCK_IDLE; |
|||
GetScreen()->m_BlockLocate.m_State = STATE_NO_BLOCK; |
|||
GetScreen()->m_BlockLocate.ClearItemsList(); |
|||
} |
|||
|
|||
if( GetToolId() == ID_NO_TOOL_SELECTED ) |
|||
SetToolID( ID_NO_TOOL_SELECTED, DrawPanel->GetDefaultCursor(), wxEmptyString ); |
|||
else |
|||
DrawPanel->SetCursor( DrawPanel->GetCurrentCursor() ); |
|||
break; |
|||
|
|||
default: |
|||
DrawPanel->EndMouseCapture(); |
|||
break; |
|||
} |
|||
|
|||
INSTALL_UNBUFFERED_DC( dc, DrawPanel ); |
|||
|
|||
switch( id ) |
|||
{ |
|||
case ID_GERBVIEW_GLOBAL_DELETE: |
|||
Erase_Current_Layer( true ); |
|||
ClearMsgPanel(); |
|||
break; |
|||
|
|||
case ID_NO_TOOL_SELECTED: |
|||
SetToolID( ID_NO_TOOL_SELECTED, DrawPanel->GetDefaultCursor(), wxEmptyString ); |
|||
break; |
|||
|
|||
case ID_POPUP_CLOSE_CURRENT_TOOL: |
|||
SetToolID( ID_NO_TOOL_SELECTED, DrawPanel->GetDefaultCursor(), wxEmptyString ); |
|||
break; |
|||
|
|||
case ID_POPUP_CANCEL_CURRENT_COMMAND: |
|||
break; |
|||
|
|||
case ID_GERBVIEW_SHOW_LIST_DCODES: |
|||
Liste_D_Codes(); |
|||
break; |
|||
|
|||
case ID_POPUP_PLACE_BLOCK: |
|||
GetScreen()->m_BlockLocate.m_Command = BLOCK_MOVE; |
|||
DrawPanel->m_AutoPAN_Request = FALSE; |
|||
HandleBlockPlace( &dc ); |
|||
break; |
|||
|
|||
case ID_POPUP_ZOOM_BLOCK: |
|||
GetScreen()->m_BlockLocate.m_Command = BLOCK_ZOOM; |
|||
GetScreen()->m_BlockLocate.SetMessageBlock( this ); |
|||
HandleBlockEnd( &dc ); |
|||
break; |
|||
|
|||
case ID_POPUP_DELETE_BLOCK: |
|||
GetScreen()->m_BlockLocate.m_Command = BLOCK_DELETE; |
|||
GetScreen()->m_BlockLocate.SetMessageBlock( this ); |
|||
HandleBlockEnd( &dc ); |
|||
break; |
|||
|
|||
default: |
|||
wxFAIL_MSG( wxT( "GERBVIEW_FRAME::Process_Special_Functions error" ) ); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
/* Selects the active DCode for the current active layer.
|
|||
* Items using this DCode are hightlighted |
|||
*/ |
|||
void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event ) |
|||
{ |
|||
GERBER_IMAGE* gerber_image = g_GERBER_List[getActiveLayer()]; |
|||
if( gerber_image ) |
|||
{ |
|||
int tool = m_DCodeSelector->GetSelectedDCodeId(); |
|||
if( tool != gerber_image->m_Selected_Tool ) |
|||
{ |
|||
gerber_image->m_Selected_Tool = tool; |
|||
DrawPanel->Refresh(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* Selects the active layer:
|
|||
* - if a file is loaded, it is loaded in this layer |
|||
* _ this layer is displayed on top of other layers |
|||
*/ |
|||
void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event ) |
|||
{ |
|||
int layer = getActiveLayer(); |
|||
|
|||
setActiveLayer( event.GetSelection() ); |
|||
if( layer != getActiveLayer() ) |
|||
DrawPanel->Refresh(); |
|||
} |
|||
|
|||
|
|||
/* Call preferred editor to show (and edit) the gerber source file
|
|||
* loaded in the active layer |
|||
*/ |
|||
void GERBVIEW_FRAME::OnShowGerberSourceFile( wxCommandEvent& event ) |
|||
{ |
|||
int layer = getActiveLayer(); |
|||
GERBER_IMAGE* gerber_layer = g_GERBER_List[layer]; |
|||
|
|||
if( gerber_layer ) |
|||
{ |
|||
wxString editorname = wxGetApp().GetEditorName(); |
|||
if( !editorname.IsEmpty() ) |
|||
{ |
|||
wxFileName fn( gerber_layer->m_FileName ); |
|||
ExecuteFile( this, editorname, QuoteFullPath( fn ) ); |
|||
} |
|||
else |
|||
{ |
|||
wxMessageBox( _( "No editor defined. Please select one" ) ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/* Function OnSelectDisplayMode: called to select display mode
|
|||
* (fast display, or exact mode with stacked images or with transparency |
|||
*/ |
|||
void GERBVIEW_FRAME::OnSelectDisplayMode( wxCommandEvent& event ) |
|||
{ |
|||
int oldMode = GetDisplayMode(); |
|||
|
|||
switch( event.GetId() ) |
|||
{ |
|||
case ID_TB_OPTIONS_SHOW_GBR_MODE_0: |
|||
SetDisplayMode( 0 ); |
|||
break; |
|||
|
|||
case ID_TB_OPTIONS_SHOW_GBR_MODE_1: |
|||
SetDisplayMode( 1 ); |
|||
break; |
|||
|
|||
case ID_TB_OPTIONS_SHOW_GBR_MODE_2: |
|||
SetDisplayMode( 2 ); |
|||
break; |
|||
} |
|||
|
|||
if( GetDisplayMode() != oldMode ) |
|||
DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void GERBVIEW_FRAME::OnQuit( wxCommandEvent& event ) |
|||
{ |
|||
Close( true ); |
|||
} |
|||
|
|||
/**
|
|||
* Function SetLanguage |
|||
* called on a language menu selection |
|||
* Update Layer manager title and tabs texts |
|||
*/ |
|||
void GERBVIEW_FRAME::SetLanguage( wxCommandEvent& event ) |
|||
{ |
|||
EDA_DRAW_FRAME::SetLanguage( event ); |
|||
m_LayersManager->SetLayersManagerTabsText(); |
|||
wxAuiPaneInfo& pane_info = m_auimgr.GetPane( m_LayersManager ); |
|||
pane_info.Caption( _( "Visibles" ) ); |
|||
m_auimgr.Update(); |
|||
|
|||
ReFillLayerWidget(); |
|||
} |
|||
@ -1,401 +1,401 @@ |
|||
/** |
|||
* @file class_netinfo.h |
|||
*/ |
|||
|
|||
/* |
|||
* Classes to handle info on nets |
|||
*/ |
|||
|
|||
#ifndef __CLASSES_NETINFO__ |
|||
#define __CLASSES_NETINFO__ |
|||
|
|||
#include "class_netclass.h" |
|||
|
|||
|
|||
class LINE_READER; |
|||
class EDA_DRAW_PANEL; |
|||
class EDA_DRAW_FRAME; |
|||
class NETINFO_ITEM; |
|||
class D_PAD; |
|||
class BOARD; |
|||
class BOARD_ITEM; |
|||
|
|||
|
|||
/* Class RATSNEST_ITEM: describes a ratsnest line: a straight line connecting 2 pads */ |
|||
|
|||
/*****************************/ |
|||
/* flags for a RATSNEST_ITEM */ |
|||
/*****************************/ |
|||
#define CH_VISIBLE 1 /* Visible */ |
|||
#define CH_UNROUTABLE 2 /* Don't use autorouter. */ |
|||
#define CH_ROUTE_REQ 4 /* Must be routed by the autorouter. */ |
|||
#define CH_ACTIF 8 /* Not routed. */ |
|||
#define LOCAL_RATSNEST_ITEM 0x8000 /* Line between two pads of a single module. */ |
|||
|
|||
class RATSNEST_ITEM |
|||
{ |
|||
private: |
|||
int m_NetCode; // netcode ( = 1.. n , 0 is the value used for not connected items) |
|||
|
|||
public: |
|||
int m_Status; // State: see previous defines (CH_ ...) |
|||
D_PAD* m_PadStart; // pointer to the starting pad |
|||
D_PAD* m_PadEnd; // pointer to ending pad |
|||
int m_Lenght; // length of the line (used in some calculations) |
|||
|
|||
RATSNEST_ITEM(); |
|||
|
|||
/** |
|||
* Function GetNet |
|||
* @return int - the net code. |
|||
*/ |
|||
int GetNet() const |
|||
{ |
|||
return m_NetCode; |
|||
} |
|||
|
|||
|
|||
void SetNet( int aNetCode ) |
|||
{ |
|||
m_NetCode = aNetCode; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function Draw |
|||
*/ |
|||
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const wxPoint& offset ); |
|||
}; |
|||
|
|||
|
|||
/***************************************************************/ |
|||
/******************* class NETINFO *****************************/ |
|||
/***************************************************************/ |
|||
|
|||
class NETINFO_LIST |
|||
{ |
|||
private: |
|||
BOARD* m_Parent; |
|||
std::vector<NETINFO_ITEM*> m_NetBuffer; // nets buffer list (name, design constraints .. |
|||
|
|||
public: |
|||
std::vector<D_PAD*> m_PadsFullList; // Entry for a sorted pad list (used in ratsnest |
|||
// calculations) |
|||
|
|||
public: NETINFO_LIST( BOARD* aParent ); |
|||
~NETINFO_LIST(); |
|||
|
|||
/** |
|||
* Function GetItem |
|||
* @param aNetcode = netcode to identify a given NETINFO_ITEM |
|||
* @return a NETINFO_ITEM pointer to the selected NETINFO_ITEM by its |
|||
* netcode, or NULL if not found |
|||
*/ |
|||
NETINFO_ITEM* GetNetItem( int aNetcode ); |
|||
|
|||
/** |
|||
* Function GetCount |
|||
* @return the number of nets ( always >= 1 ) |
|||
* becuse the first net is the "not connected" net and always exists |
|||
*/ |
|||
unsigned GetCount() { return m_NetBuffer.size(); } |
|||
|
|||
/** |
|||
* Function Append |
|||
* adds \a aNewElement to the end of the list. |
|||
*/ |
|||
void AppendNet( NETINFO_ITEM* aNewElement ); |
|||
|
|||
/** |
|||
* Function DeleteData |
|||
* delete the list of nets (and free memory) |
|||
*/ |
|||
void DeleteData(); |
|||
|
|||
/** |
|||
* Function BuildListOfNets |
|||
* Build or rebuild the list of NETINFO_ITEM m_NetBuffer |
|||
* The list is sorted by names. |
|||
*/ |
|||
void BuildListOfNets(); |
|||
|
|||
/** |
|||
* Function GetPadsCount |
|||
* @return the number of pads in board |
|||
*/ |
|||
unsigned GetPadsCount() |
|||
{ |
|||
return m_PadsFullList.size(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetPad |
|||
* @return the pad idx from m_PadsFullList |
|||
*/ |
|||
D_PAD* GetPad( unsigned aIdx ) |
|||
{ |
|||
if( aIdx < m_PadsFullList.size() ) |
|||
return m_PadsFullList[aIdx]; |
|||
else |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
private: |
|||
|
|||
/** |
|||
* Function Build_Pads_Full_List |
|||
* Create the pad list |
|||
* initialise: |
|||
* m_Pads (list of pads) |
|||
* set m_Status_Pcb = LISTE_PAD_OK; |
|||
* and clear for all pads in list the m_SubRatsnest member; |
|||
* clear m_Pcb->m_FullRatsnest |
|||
*/ |
|||
void Build_Pads_Full_List(); |
|||
}; |
|||
|
|||
|
|||
/** |
|||
* Class NETINFO_ITEM |
|||
* handles the data for a net |
|||
*/ |
|||
class NETINFO_ITEM |
|||
{ |
|||
private: |
|||
int m_NetCode; // this is a number equivalent to the net name |
|||
// Used for fast comparisons in ratsnest and DRC computations. |
|||
|
|||
wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout |
|||
// used by eeschema |
|||
|
|||
wxString m_ShortNetname; // short net name, like vout from |
|||
// /mysheet/mysubsheet/vout |
|||
|
|||
wxString m_NetClassName; // Net Class name. if void this is equivalent |
|||
// to "default" (the first |
|||
// item of the net classes list |
|||
|
|||
NETCLASS* m_NetClass; |
|||
|
|||
|
|||
public: |
|||
int m_NbNodes; // Pads count for this net |
|||
int m_NbLink; // Ratsnets count for this net |
|||
int m_NbNoconn; // Ratsnets remaining to route count |
|||
int m_Flag; // used in some calculations. Had no |
|||
// special meaning |
|||
|
|||
std::vector <D_PAD*> m_ListPad; // List of pads connected to this net |
|||
|
|||
unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this |
|||
* net (included) in a general buffer of |
|||
* ratsnest (a vector<RATSNEST_ITEM*> |
|||
* buffer) */ |
|||
|
|||
unsigned m_RatsnestEndIdx; // Ending point of ratsnests of this net |
|||
// (excluded) in this buffer |
|||
|
|||
NETINFO_ITEM( BOARD_ITEM* aParent ); |
|||
~NETINFO_ITEM(); |
|||
|
|||
/** |
|||
* Function SetClass |
|||
* sets \a aNetclass into this NET |
|||
*/ |
|||
void SetClass( const NETCLASS* aNetClass ) |
|||
{ |
|||
m_NetClass = (NETCLASS*) aNetClass; |
|||
|
|||
if( aNetClass ) |
|||
m_NetClassName = aNetClass->GetName(); |
|||
else |
|||
m_NetClassName = NETCLASS::Default; |
|||
} |
|||
|
|||
|
|||
NETCLASS* GetNetClass() |
|||
{ |
|||
return m_NetClass; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetClassName |
|||
* returns the class name |
|||
*/ |
|||
const wxString& GetClassName() const |
|||
{ |
|||
return m_NetClassName; |
|||
} |
|||
|
|||
|
|||
#if 1 |
|||
|
|||
/** |
|||
* Function GetTrackWidth |
|||
* returns the width of tracks used to route this net. |
|||
*/ |
|||
int GetTrackWidth() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetTrackWidth(); |
|||
} |
|||
|
|||
/** |
|||
* Function GetViaSize |
|||
* returns the size of vias used to route this net |
|||
*/ |
|||
int GetViaSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetViaDiameter(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetMicroViaSize |
|||
* returns the size of vias used to route this net |
|||
*/ |
|||
int GetMicroViaSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetuViaDiameter(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetViaDrillSize |
|||
* returns the size of via drills used to route this net |
|||
*/ |
|||
int GetViaDrillSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetViaDrill(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetViaDrillSize |
|||
* returns the size of via drills used to route this net |
|||
*/ |
|||
int GetMicroViaDrillSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetuViaDrill(); |
|||
} |
|||
|
|||
|
|||
#if 0 |
|||
|
|||
/** |
|||
* Function GetViaMinSize |
|||
* returns the Minimum value for via sizes (used in DRC) |
|||
*/ |
|||
int GetViaMinSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetViaMinSize(); |
|||
} |
|||
|
|||
|
|||
#endif |
|||
|
|||
/** |
|||
* Function GetClearance |
|||
* returns the clearance when routing near aBoardItem |
|||
*/ |
|||
int GetClearance( BOARD_ITEM* aBoardItem ) |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetClearance(); |
|||
} |
|||
|
|||
|
|||
#endif |
|||
|
|||
/* Reading and writing data on files */ |
|||
int ReadDescr( LINE_READER* aReader ); |
|||
|
|||
/** |
|||
* Function Save |
|||
* writes the data structures for this object out to a FILE in "*.brd" |
|||
* format. |
|||
* @param aFile The FILE to write to. |
|||
* @return bool - true if success writing else false. |
|||
*/ |
|||
bool Save( FILE* aFile ) const; |
|||
|
|||
|
|||
/** |
|||
* Function Draw |
|||
* @todo we actually could show a NET, simply show all the tracks and |
|||
* a pads or net name on pad and vias |
|||
*/ |
|||
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const wxPoint& offset ); |
|||
|
|||
|
|||
/** |
|||
* Function GetNet |
|||
* @return int - the netcode |
|||
*/ |
|||
int GetNet() const { return m_NetCode; } |
|||
|
|||
void SetNet( int aNetCode ) { m_NetCode = aNetCode; } |
|||
|
|||
int GetNodesCount() const { return m_ListPad.size(); } |
|||
|
|||
/** |
|||
* Function GetNetname |
|||
* @return const wxString * , a pointer to the full netname |
|||
*/ |
|||
wxString GetNetname() const { return m_Netname; } |
|||
|
|||
/** |
|||
* Function GetShortNetname |
|||
* @return const wxString * , a pointer to the short netname |
|||
*/ |
|||
wxString GetShortNetname() const { return m_ShortNetname; } |
|||
|
|||
/** |
|||
* Function SetNetname |
|||
* @param aNetname : the new netname |
|||
*/ |
|||
void SetNetname( const wxString& aNetname ); |
|||
|
|||
|
|||
/** |
|||
* Function DisplayInfo |
|||
* has knowledge about the frame and how and where to put status information |
|||
* about this object into the frame's message panel. |
|||
* Is virtual from EDA_ITEM. |
|||
* @param frame A EDA_DRAW_FRAME in which to print status information. |
|||
*/ |
|||
void DisplayInfo( EDA_DRAW_FRAME* frame ); |
|||
}; |
|||
|
|||
|
|||
/***********************************************************/ |
|||
/* Description of a trace point for monitoring connections */ |
|||
/***********************************************************/ |
|||
#define START_ON_PAD 0x10 |
|||
#define END_ON_PAD 0x20 |
|||
#define START_ON_TRACK 0x40 |
|||
#define END_ON_TRACK 0x80 |
|||
|
|||
|
|||
/* Status bit (OR'ed bits) for class BOARD member .m_Status_Pcb */ |
|||
enum StatusPcbFlags { |
|||
LISTE_PAD_OK = 1, /* Pad list is Ok */ |
|||
LISTE_RATSNEST_ITEM_OK = 2, /* General Ratsnest is Ok */ |
|||
RATSNEST_ITEM_LOCAL_OK = 4, /* current MODULE ratsnest is Ok */ |
|||
CONNEXION_OK = 8, /* List of connections exists. */ |
|||
NET_CODES_OK = 0x10, /* Bit indicating that Netcode is OK, |
|||
* do not change net name. */ |
|||
DO_NOT_SHOW_GENERAL_RASTNEST = 0x20 /* Do not display the general |
|||
* ratsnest (used in module moves) */ |
|||
}; |
|||
|
|||
|
|||
#endif // __CLASSES_NETINFO__ |
|||
/** |
|||
* @file class_netinfo.h |
|||
*/ |
|||
|
|||
/* |
|||
* Classes to handle info on nets |
|||
*/ |
|||
|
|||
#ifndef __CLASSES_NETINFO__ |
|||
#define __CLASSES_NETINFO__ |
|||
|
|||
#include "class_netclass.h" |
|||
|
|||
|
|||
class LINE_READER; |
|||
class EDA_DRAW_PANEL; |
|||
class EDA_DRAW_FRAME; |
|||
class NETINFO_ITEM; |
|||
class D_PAD; |
|||
class BOARD; |
|||
class BOARD_ITEM; |
|||
|
|||
|
|||
/* Class RATSNEST_ITEM: describes a ratsnest line: a straight line connecting 2 pads */ |
|||
|
|||
/*****************************/ |
|||
/* flags for a RATSNEST_ITEM */ |
|||
/*****************************/ |
|||
#define CH_VISIBLE 1 /* Visible */ |
|||
#define CH_UNROUTABLE 2 /* Don't use autorouter. */ |
|||
#define CH_ROUTE_REQ 4 /* Must be routed by the autorouter. */ |
|||
#define CH_ACTIF 8 /* Not routed. */ |
|||
#define LOCAL_RATSNEST_ITEM 0x8000 /* Line between two pads of a single module. */ |
|||
|
|||
class RATSNEST_ITEM |
|||
{ |
|||
private: |
|||
int m_NetCode; // netcode ( = 1.. n , 0 is the value used for not connected items) |
|||
|
|||
public: |
|||
int m_Status; // State: see previous defines (CH_ ...) |
|||
D_PAD* m_PadStart; // pointer to the starting pad |
|||
D_PAD* m_PadEnd; // pointer to ending pad |
|||
int m_Lenght; // length of the line (used in some calculations) |
|||
|
|||
RATSNEST_ITEM(); |
|||
|
|||
/** |
|||
* Function GetNet |
|||
* @return int - the net code. |
|||
*/ |
|||
int GetNet() const |
|||
{ |
|||
return m_NetCode; |
|||
} |
|||
|
|||
|
|||
void SetNet( int aNetCode ) |
|||
{ |
|||
m_NetCode = aNetCode; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function Draw |
|||
*/ |
|||
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const wxPoint& offset ); |
|||
}; |
|||
|
|||
|
|||
/***************************************************************/ |
|||
/******************* class NETINFO *****************************/ |
|||
/***************************************************************/ |
|||
|
|||
class NETINFO_LIST |
|||
{ |
|||
private: |
|||
BOARD* m_Parent; |
|||
std::vector<NETINFO_ITEM*> m_NetBuffer; // nets buffer list (name, design constraints .. |
|||
|
|||
public: |
|||
std::vector<D_PAD*> m_PadsFullList; // Entry for a sorted pad list (used in ratsnest |
|||
// calculations) |
|||
|
|||
public: NETINFO_LIST( BOARD* aParent ); |
|||
~NETINFO_LIST(); |
|||
|
|||
/** |
|||
* Function GetItem |
|||
* @param aNetcode = netcode to identify a given NETINFO_ITEM |
|||
* @return a NETINFO_ITEM pointer to the selected NETINFO_ITEM by its |
|||
* netcode, or NULL if not found |
|||
*/ |
|||
NETINFO_ITEM* GetNetItem( int aNetcode ); |
|||
|
|||
/** |
|||
* Function GetCount |
|||
* @return the number of nets ( always >= 1 ) |
|||
* becuse the first net is the "not connected" net and always exists |
|||
*/ |
|||
unsigned GetCount() { return m_NetBuffer.size(); } |
|||
|
|||
/** |
|||
* Function Append |
|||
* adds \a aNewElement to the end of the list. |
|||
*/ |
|||
void AppendNet( NETINFO_ITEM* aNewElement ); |
|||
|
|||
/** |
|||
* Function DeleteData |
|||
* delete the list of nets (and free memory) |
|||
*/ |
|||
void DeleteData(); |
|||
|
|||
/** |
|||
* Function BuildListOfNets |
|||
* Build or rebuild the list of NETINFO_ITEM m_NetBuffer |
|||
* The list is sorted by names. |
|||
*/ |
|||
void BuildListOfNets(); |
|||
|
|||
/** |
|||
* Function GetPadsCount |
|||
* @return the number of pads in board |
|||
*/ |
|||
unsigned GetPadsCount() |
|||
{ |
|||
return m_PadsFullList.size(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetPad |
|||
* @return the pad idx from m_PadsFullList |
|||
*/ |
|||
D_PAD* GetPad( unsigned aIdx ) |
|||
{ |
|||
if( aIdx < m_PadsFullList.size() ) |
|||
return m_PadsFullList[aIdx]; |
|||
else |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
private: |
|||
|
|||
/** |
|||
* Function Build_Pads_Full_List |
|||
* Create the pad list |
|||
* initialise: |
|||
* m_Pads (list of pads) |
|||
* set m_Status_Pcb = LISTE_PAD_OK; |
|||
* and clear for all pads in list the m_SubRatsnest member; |
|||
* clear m_Pcb->m_FullRatsnest |
|||
*/ |
|||
void Build_Pads_Full_List(); |
|||
}; |
|||
|
|||
|
|||
/** |
|||
* Class NETINFO_ITEM |
|||
* handles the data for a net |
|||
*/ |
|||
class NETINFO_ITEM |
|||
{ |
|||
private: |
|||
int m_NetCode; // this is a number equivalent to the net name |
|||
// Used for fast comparisons in ratsnest and DRC computations. |
|||
|
|||
wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout |
|||
// used by eeschema |
|||
|
|||
wxString m_ShortNetname; // short net name, like vout from |
|||
// /mysheet/mysubsheet/vout |
|||
|
|||
wxString m_NetClassName; // Net Class name. if void this is equivalent |
|||
// to "default" (the first |
|||
// item of the net classes list |
|||
|
|||
NETCLASS* m_NetClass; |
|||
|
|||
|
|||
public: |
|||
int m_NbNodes; // Pads count for this net |
|||
int m_NbLink; // Ratsnets count for this net |
|||
int m_NbNoconn; // Ratsnets remaining to route count |
|||
int m_Flag; // used in some calculations. Had no |
|||
// special meaning |
|||
|
|||
std::vector <D_PAD*> m_ListPad; // List of pads connected to this net |
|||
|
|||
unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this |
|||
* net (included) in a general buffer of |
|||
* ratsnest (a vector<RATSNEST_ITEM*> |
|||
* buffer) */ |
|||
|
|||
unsigned m_RatsnestEndIdx; // Ending point of ratsnests of this net |
|||
// (excluded) in this buffer |
|||
|
|||
NETINFO_ITEM( BOARD_ITEM* aParent ); |
|||
~NETINFO_ITEM(); |
|||
|
|||
/** |
|||
* Function SetClass |
|||
* sets \a aNetclass into this NET |
|||
*/ |
|||
void SetClass( const NETCLASS* aNetClass ) |
|||
{ |
|||
m_NetClass = (NETCLASS*) aNetClass; |
|||
|
|||
if( aNetClass ) |
|||
m_NetClassName = aNetClass->GetName(); |
|||
else |
|||
m_NetClassName = NETCLASS::Default; |
|||
} |
|||
|
|||
|
|||
NETCLASS* GetNetClass() |
|||
{ |
|||
return m_NetClass; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetClassName |
|||
* returns the class name |
|||
*/ |
|||
const wxString& GetClassName() const |
|||
{ |
|||
return m_NetClassName; |
|||
} |
|||
|
|||
|
|||
#if 1 |
|||
|
|||
/** |
|||
* Function GetTrackWidth |
|||
* returns the width of tracks used to route this net. |
|||
*/ |
|||
int GetTrackWidth() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetTrackWidth(); |
|||
} |
|||
|
|||
/** |
|||
* Function GetViaSize |
|||
* returns the size of vias used to route this net |
|||
*/ |
|||
int GetViaSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetViaDiameter(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetMicroViaSize |
|||
* returns the size of vias used to route this net |
|||
*/ |
|||
int GetMicroViaSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetuViaDiameter(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetViaDrillSize |
|||
* returns the size of via drills used to route this net |
|||
*/ |
|||
int GetViaDrillSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetViaDrill(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Function GetViaDrillSize |
|||
* returns the size of via drills used to route this net |
|||
*/ |
|||
int GetMicroViaDrillSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetuViaDrill(); |
|||
} |
|||
|
|||
|
|||
#if 0 |
|||
|
|||
/** |
|||
* Function GetViaMinSize |
|||
* returns the Minimum value for via sizes (used in DRC) |
|||
*/ |
|||
int GetViaMinSize() |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetViaMinSize(); |
|||
} |
|||
|
|||
|
|||
#endif |
|||
|
|||
/** |
|||
* Function GetClearance |
|||
* returns the clearance when routing near aBoardItem |
|||
*/ |
|||
int GetClearance( BOARD_ITEM* aBoardItem ) |
|||
{ |
|||
wxASSERT( m_NetClass ); |
|||
return m_NetClass->GetClearance(); |
|||
} |
|||
|
|||
|
|||
#endif |
|||
|
|||
/* Reading and writing data on files */ |
|||
int ReadDescr( LINE_READER* aReader ); |
|||
|
|||
/** |
|||
* Function Save |
|||
* writes the data structures for this object out to a FILE in "*.brd" |
|||
* format. |
|||
* @param aFile The FILE to write to. |
|||
* @return bool - true if success writing else false. |
|||
*/ |
|||
bool Save( FILE* aFile ) const; |
|||
|
|||
|
|||
/** |
|||
* Function Draw |
|||
* @todo we actually could show a NET, simply show all the tracks and |
|||
* a pads or net name on pad and vias |
|||
*/ |
|||
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const wxPoint& offset ); |
|||
|
|||
|
|||
/** |
|||
* Function GetNet |
|||
* @return int - the netcode |
|||
*/ |
|||
int GetNet() const { return m_NetCode; } |
|||
|
|||
void SetNet( int aNetCode ) { m_NetCode = aNetCode; } |
|||
|
|||
int GetNodesCount() const { return m_ListPad.size(); } |
|||
|
|||
/** |
|||
* Function GetNetname |
|||
* @return const wxString * , a pointer to the full netname |
|||
*/ |
|||
wxString GetNetname() const { return m_Netname; } |
|||
|
|||
/** |
|||
* Function GetShortNetname |
|||
* @return const wxString * , a pointer to the short netname |
|||
*/ |
|||
wxString GetShortNetname() const { return m_ShortNetname; } |
|||
|
|||
/** |
|||
* Function SetNetname |
|||
* @param aNetname : the new netname |
|||
*/ |
|||
void SetNetname( const wxString& aNetname ); |
|||
|
|||
|
|||
/** |
|||
* Function DisplayInfo |
|||
* has knowledge about the frame and how and where to put status information |
|||
* about this object into the frame's message panel. |
|||
* Is virtual from EDA_ITEM. |
|||
* @param frame A EDA_DRAW_FRAME in which to print status information. |
|||
*/ |
|||
void DisplayInfo( EDA_DRAW_FRAME* frame ); |
|||
}; |
|||
|
|||
|
|||
/***********************************************************/ |
|||
/* Description of a trace point for monitoring connections */ |
|||
/***********************************************************/ |
|||
#define START_ON_PAD 0x10 |
|||
#define END_ON_PAD 0x20 |
|||
#define START_ON_TRACK 0x40 |
|||
#define END_ON_TRACK 0x80 |
|||
|
|||
|
|||
/* Status bit (OR'ed bits) for class BOARD member .m_Status_Pcb */ |
|||
enum StatusPcbFlags { |
|||
LISTE_PAD_OK = 1, /* Pad list is Ok */ |
|||
LISTE_RATSNEST_ITEM_OK = 2, /* General Ratsnest is Ok */ |
|||
RATSNEST_ITEM_LOCAL_OK = 4, /* current MODULE ratsnest is Ok */ |
|||
CONNEXION_OK = 8, /* List of connections exists. */ |
|||
NET_CODES_OK = 0x10, /* Bit indicating that Netcode is OK, |
|||
* do not change net name. */ |
|||
DO_NOT_SHOW_GENERAL_RASTNEST = 0x20 /* Do not display the general |
|||
* ratsnest (used in module moves) */ |
|||
}; |
|||
|
|||
|
|||
#endif // __CLASSES_NETINFO__ |
|||
@ -1,373 +1,373 @@ |
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr |
|||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> |
|||
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
/******************************************************/ |
|||
/* class_pcb_layer_widget.cpp - Pcbnew layers manager */ |
|||
/******************************************************/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "appl_wxstruct.h"
|
|||
#include "class_drawpanel.h"
|
|||
#include "confirm.h"
|
|||
#include "wxPcbStruct.h"
|
|||
#include "pcbstruct.h" // enum PCB_VISIBLE
|
|||
#include "layer_widget.h"
|
|||
#include "macros.h"
|
|||
#include "pcbcommon.h"
|
|||
|
|||
#include "class_board.h"
|
|||
#include "class_pcb_layer_widget.h"
|
|||
|
|||
#include "pcbnew.h"
|
|||
#include "collectors.h"
|
|||
#include "pcbnew_id.h"
|
|||
|
|||
|
|||
/**
|
|||
* Class PCB_LAYER_WIDGET |
|||
* is here to implement the abtract functions of LAYER_WIDGET so they |
|||
* may be tied into the PCB_EDIT_FRAME's data and so we can add a popup |
|||
* menu which is specific to PCBNEW's needs. |
|||
*/ |
|||
|
|||
|
|||
PCB_LAYER_WIDGET::PCB_LAYER_WIDGET( PCB_EDIT_FRAME* aParent, wxWindow* aFocusOwner, int aPointSize ) : |
|||
LAYER_WIDGET( aParent, aFocusOwner, aPointSize ), |
|||
myframe( aParent ) |
|||
{ |
|||
ReFillRender(); |
|||
|
|||
// Update default tabs labels for gerbview
|
|||
SetLayersManagerTabsText( ); |
|||
|
|||
//-----<Popup menu>-------------------------------------------------
|
|||
// handle the popup menu over the layer window.
|
|||
m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN, |
|||
wxMouseEventHandler( PCB_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
|
|||
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
|
|||
// and not m_LayerScrolledWindow->Connect()
|
|||
Connect( ID_SHOW_ALL_COPPERS, ID_SHOW_NO_COPPERS, wxEVT_COMMAND_MENU_SELECTED, |
|||
wxCommandEventHandler( PCB_LAYER_WIDGET::onPopupSelection ), NULL, this ); |
|||
|
|||
// install the right click handler into each control at end of ReFill()
|
|||
// using installRightLayerClickHandler
|
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::installRightLayerClickHandler() |
|||
{ |
|||
int rowCount = GetLayerRowCount(); |
|||
for( int row=0; row<rowCount; ++row ) |
|||
{ |
|||
for( int col=0; col<LYR_COLUMN_COUNT; ++col ) |
|||
{ |
|||
wxWindow* w = getLayerComp( row, col ); |
|||
|
|||
w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( |
|||
PCB_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event ) |
|||
{ |
|||
wxMenu menu; |
|||
|
|||
// menu text is capitalized:
|
|||
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
|
|||
menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_COPPERS, |
|||
_("Show All Copper Layers") ) ); |
|||
|
|||
menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_COPPERS, |
|||
_( "Hide All Copper Layers" ) ) ); |
|||
|
|||
PopupMenu( &menu ); |
|||
|
|||
passOnFocus(); |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event ) |
|||
{ |
|||
int rowCount; |
|||
int menuId = event.GetId(); |
|||
bool visible; |
|||
|
|||
switch( menuId ) |
|||
{ |
|||
case ID_SHOW_ALL_COPPERS: |
|||
visible = true; |
|||
goto L_change_coppers; |
|||
|
|||
case ID_SHOW_NO_COPPERS: |
|||
visible = false; |
|||
L_change_coppers: |
|||
int lastCu = -1; |
|||
rowCount = GetLayerRowCount(); |
|||
for( int row=rowCount-1; row>=0; --row ) |
|||
{ |
|||
wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 ); |
|||
int layer = getDecodedId( cb->GetId() ); |
|||
if( IsValidCopperLayerIndex( layer ) ) |
|||
{ |
|||
lastCu = row; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
for( int row=0; row<rowCount; ++row ) |
|||
{ |
|||
wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 ); |
|||
int layer = getDecodedId( cb->GetId() ); |
|||
|
|||
if( IsValidCopperLayerIndex( layer ) ) |
|||
{ |
|||
cb->SetValue( visible ); |
|||
|
|||
bool isLastCopperLayer = (row==lastCu); |
|||
|
|||
OnLayerVisible( layer, visible, isLastCopperLayer ); |
|||
|
|||
if( isLastCopperLayer ) |
|||
break; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* Function SetLayersManagerTabsText |
|||
* Update the layer manager tabs labels |
|||
* Useful when changing Language or to set labels to a non default value |
|||
*/ |
|||
void PCB_LAYER_WIDGET::SetLayersManagerTabsText( ) |
|||
{ |
|||
m_notebook->SetPageText(0, _("Layer") ); |
|||
m_notebook->SetPageText(1, _("Render") ); |
|||
} |
|||
|
|||
/**
|
|||
* Function ReFillRender |
|||
* Rebuild Render for instance after the config is read |
|||
*/ |
|||
void PCB_LAYER_WIDGET::ReFillRender() |
|||
{ |
|||
BOARD* board = myframe->GetBoard(); |
|||
ClearRenderRows(); |
|||
// Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
|
|||
// is changed before appending to the LAYER_WIDGET. This is an automatic variable
|
|||
// not a static variable, change the color & state after copying from code to renderRows
|
|||
// on the stack.
|
|||
LAYER_WIDGET::ROW renderRows[16] = { |
|||
|
|||
#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
|
|||
|
|||
// text id color tooltip checked
|
|||
RR( _( "Through Via" ), VIA_THROUGH_VISIBLE, WHITE, _( "Show through vias" ) ), |
|||
RR( _( "Bl/Buried Via" ), VIA_BBLIND_VISIBLE, WHITE, _( "Show blind or buried vias" ) ), |
|||
RR( _( "Micro Via" ), VIA_MICROVIA_VISIBLE, WHITE, _( "Show micro vias") ), |
|||
RR( _( "Ratsnest" ), RATSNEST_VISIBLE, WHITE, _( "Show unconnected nets as a ratsnest") ), |
|||
|
|||
RR( _( "Pads Front" ), PAD_FR_VISIBLE, WHITE, _( "Show footprint pads on board's front" ) ), |
|||
RR( _( "Pads Back" ), PAD_BK_VISIBLE, WHITE, _( "Show footprint pads on board's back" ) ), |
|||
|
|||
RR( _( "Text Front" ), MOD_TEXT_FR_VISIBLE, WHITE, _( "Show footprint text on board's back" ) ), |
|||
RR( _( "Text Back" ), MOD_TEXT_BK_VISIBLE, WHITE, _( "Show footprint text on board's back" ) ), |
|||
RR( _( "Hidden Text" ), MOD_TEXT_INVISIBLE, WHITE, _( "Show footprint text marked as invisible" ) ), |
|||
|
|||
RR( _( "Anchors" ), ANCHOR_VISIBLE, WHITE, _( "Show footprint and text origins as a cross" ) ), |
|||
RR( _( "Grid" ), GRID_VISIBLE, WHITE, _( "Show the (x,y) grid dots" ) ), |
|||
RR( _( "No-Connects" ), NO_CONNECTS_VISIBLE, -1, _( "Show a marker on pads which have no net connected" ) ), |
|||
RR( _( "Modules Front" ), MOD_FR_VISIBLE, -1, _( "Show footprints that are on board's front") ), |
|||
RR( _( "Modules Back" ), MOD_BK_VISIBLE, -1, _( "Show footprints that are on board's back") ), |
|||
RR( _( "Values" ), MOD_VALUES_VISIBLE, -1, _( "Show footprint's values") ), |
|||
RR( _( "References" ), MOD_REFERENCES_VISIBLE, -1, _( "Show footprint's references") ), |
|||
}; |
|||
|
|||
for( unsigned row=0; row<DIM(renderRows); ++row ) |
|||
{ |
|||
if( renderRows[row].color != -1 ) // does this row show a color?
|
|||
{ |
|||
// this window frame must have an established BOARD, i.e. after SetBoard()
|
|||
renderRows[row].color = board->GetVisibleElementColor( renderRows[row].id ); |
|||
} |
|||
renderRows[row].state = board->IsElementVisible( renderRows[row].id ); |
|||
} |
|||
|
|||
AppendRenderRows( renderRows, DIM(renderRows) ); |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::ReFill() |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
int layer; |
|||
|
|||
int enabledLayers = brd->GetEnabledLayers(); |
|||
|
|||
// m_Layers->Freeze(); // no screen updates until done modifying
|
|||
|
|||
ClearLayerRows(); |
|||
|
|||
// show all coppers first, with front on top, back on bottom, then technical layers
|
|||
|
|||
layer = LAYER_N_FRONT; |
|||
if( enabledLayers & (1 << layer) ) |
|||
{ |
|||
AppendLayerRow( LAYER_WIDGET::ROW( |
|||
brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ), _("Front copper layer"), true ) ); |
|||
} |
|||
|
|||
for( layer = LAYER_N_FRONT-1; layer >= 1; --layer ) |
|||
{ |
|||
if( enabledLayers & (1 << layer) ) |
|||
{ |
|||
AppendLayerRow( LAYER_WIDGET::ROW( |
|||
brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ), _("An innner copper layer"), true ) ); |
|||
} |
|||
} |
|||
|
|||
layer = LAYER_N_BACK; |
|||
if( enabledLayers & (1 << layer) ) |
|||
{ |
|||
AppendLayerRow( LAYER_WIDGET::ROW( |
|||
brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ), _("Back copper layer"), true ) ); |
|||
} |
|||
|
|||
// technical layers are shown in this order:
|
|||
static const struct { |
|||
int layerId; |
|||
wxString tooltip; |
|||
} techLayerSeq[] = { |
|||
{ ADHESIVE_N_FRONT, _( "Adhesive on board's front" ) }, |
|||
{ ADHESIVE_N_BACK, _( "Adhesive on board's back" ) }, |
|||
{ SOLDERPASTE_N_FRONT, _( "Solder paste on board's front" )}, |
|||
{ SOLDERPASTE_N_BACK, _( "Solder paste on board's back" ) }, |
|||
{ SILKSCREEN_N_FRONT, _( "Silkscreen on board's front" ) }, |
|||
{ SILKSCREEN_N_BACK, _( "Silkscreen on board's back" ) }, |
|||
{ SOLDERMASK_N_FRONT, _( "Solder mask on board's front" ) }, |
|||
{ SOLDERMASK_N_BACK, _( "Solder mask on board's back" ) }, |
|||
{ DRAW_N, _( "Explanatory drawings" ) }, |
|||
{ COMMENT_N, _( "Explanatory comments" ) }, |
|||
{ ECO1_N, _( "TDB" ) }, |
|||
{ ECO2_N, _( "TBD" ) }, |
|||
{ EDGE_N, _( "Board's perimeter definition" ) }, |
|||
}; |
|||
|
|||
for( unsigned i=0; i<DIM(techLayerSeq); ++i ) |
|||
{ |
|||
layer = techLayerSeq[i].layerId; |
|||
|
|||
if( !(enabledLayers & (1 << layer)) ) |
|||
continue; |
|||
|
|||
AppendLayerRow( LAYER_WIDGET::ROW( |
|||
brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ), |
|||
techLayerSeq[i].tooltip, true ) ); |
|||
} |
|||
|
|||
installRightLayerClickHandler(); |
|||
|
|||
// m_Layers->Thaw();
|
|||
} |
|||
|
|||
//-----<LAYER_WIDGET callbacks>-------------------------------------------
|
|||
|
|||
void PCB_LAYER_WIDGET::OnLayerColorChange( int aLayer, int aColor ) |
|||
{ |
|||
myframe->GetBoard()->SetLayerColor( aLayer, aColor ); |
|||
myframe->ReCreateLayerBox( NULL ); |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
bool PCB_LAYER_WIDGET::OnLayerSelect( int aLayer ) |
|||
{ |
|||
// the layer change from the PCB_LAYER_WIDGET can be denied by returning
|
|||
// false from this function.
|
|||
myframe->setActiveLayer( aLayer, false ); |
|||
|
|||
if(DisplayOpt.ContrastModeDisplay) |
|||
myframe->DrawPanel->Refresh(); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
|
|||
int visibleLayers = brd->GetVisibleLayers(); |
|||
|
|||
if( isVisible ) |
|||
visibleLayers |= (1 << aLayer); |
|||
else |
|||
visibleLayers &= ~(1 << aLayer); |
|||
|
|||
brd->SetVisibleLayers( visibleLayers ); |
|||
|
|||
if( isFinal ) |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::OnRenderColorChange( int aId, int aColor ) |
|||
{ |
|||
myframe->GetBoard()->SetVisibleElementColor( aId, aColor ); |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
|
|||
/* @todo:
|
|||
|
|||
move: |
|||
|
|||
GRID_VISIBLE, ? maybe not this one |
|||
into m_VisibleElements and get rid of globals. |
|||
*/ |
|||
|
|||
switch( aId ) |
|||
{ |
|||
// see todo above, don't really want anything except IsElementVisible() here.
|
|||
|
|||
case GRID_VISIBLE: |
|||
// @todo, make read/write accessors for grid control so the write accessor can fire updates to
|
|||
// grid state listeners. I think the grid state should be kept in the BOARD.
|
|||
brd->SetElementVisibility( aId, isEnabled ); // set visibilty flag also in list, and myframe->m_Draw_Grid
|
|||
break; |
|||
|
|||
default: |
|||
brd->SetElementVisibility( aId, isEnabled ); |
|||
} |
|||
|
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
//-----</LAYER_WIDGET callbacks>------------------------------------------
|
|||
|
|||
|
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr |
|||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> |
|||
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
/******************************************************/ |
|||
/* class_pcb_layer_widget.cpp - Pcbnew layers manager */ |
|||
/******************************************************/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "appl_wxstruct.h"
|
|||
#include "class_drawpanel.h"
|
|||
#include "confirm.h"
|
|||
#include "wxPcbStruct.h"
|
|||
#include "pcbstruct.h" // enum PCB_VISIBLE
|
|||
#include "layer_widget.h"
|
|||
#include "macros.h"
|
|||
#include "pcbcommon.h"
|
|||
|
|||
#include "class_board.h"
|
|||
#include "class_pcb_layer_widget.h"
|
|||
|
|||
#include "pcbnew.h"
|
|||
#include "collectors.h"
|
|||
#include "pcbnew_id.h"
|
|||
|
|||
|
|||
/**
|
|||
* Class PCB_LAYER_WIDGET |
|||
* is here to implement the abtract functions of LAYER_WIDGET so they |
|||
* may be tied into the PCB_EDIT_FRAME's data and so we can add a popup |
|||
* menu which is specific to PCBNEW's needs. |
|||
*/ |
|||
|
|||
|
|||
PCB_LAYER_WIDGET::PCB_LAYER_WIDGET( PCB_EDIT_FRAME* aParent, wxWindow* aFocusOwner, int aPointSize ) : |
|||
LAYER_WIDGET( aParent, aFocusOwner, aPointSize ), |
|||
myframe( aParent ) |
|||
{ |
|||
ReFillRender(); |
|||
|
|||
// Update default tabs labels for gerbview
|
|||
SetLayersManagerTabsText( ); |
|||
|
|||
//-----<Popup menu>-------------------------------------------------
|
|||
// handle the popup menu over the layer window.
|
|||
m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN, |
|||
wxMouseEventHandler( PCB_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
|
|||
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
|
|||
// and not m_LayerScrolledWindow->Connect()
|
|||
Connect( ID_SHOW_ALL_COPPERS, ID_SHOW_NO_COPPERS, wxEVT_COMMAND_MENU_SELECTED, |
|||
wxCommandEventHandler( PCB_LAYER_WIDGET::onPopupSelection ), NULL, this ); |
|||
|
|||
// install the right click handler into each control at end of ReFill()
|
|||
// using installRightLayerClickHandler
|
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::installRightLayerClickHandler() |
|||
{ |
|||
int rowCount = GetLayerRowCount(); |
|||
for( int row=0; row<rowCount; ++row ) |
|||
{ |
|||
for( int col=0; col<LYR_COLUMN_COUNT; ++col ) |
|||
{ |
|||
wxWindow* w = getLayerComp( row, col ); |
|||
|
|||
w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( |
|||
PCB_LAYER_WIDGET::onRightDownLayers ), NULL, this ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void PCB_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event ) |
|||
{ |
|||
wxMenu menu; |
|||
|
|||
// menu text is capitalized:
|
|||
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
|
|||
menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_COPPERS, |
|||
_("Show All Copper Layers") ) ); |
|||
|
|||
menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_COPPERS, |
|||
_( "Hide All Copper Layers" ) ) ); |
|||
|
|||
PopupMenu( &menu ); |
|||
|
|||
passOnFocus(); |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event ) |
|||
{ |
|||
int rowCount; |
|||
int menuId = event.GetId(); |
|||
bool visible; |
|||
|
|||
switch( menuId ) |
|||
{ |
|||
case ID_SHOW_ALL_COPPERS: |
|||
visible = true; |
|||
goto L_change_coppers; |
|||
|
|||
case ID_SHOW_NO_COPPERS: |
|||
visible = false; |
|||
L_change_coppers: |
|||
int lastCu = -1; |
|||
rowCount = GetLayerRowCount(); |
|||
for( int row=rowCount-1; row>=0; --row ) |
|||
{ |
|||
wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 ); |
|||
int layer = getDecodedId( cb->GetId() ); |
|||
if( IsValidCopperLayerIndex( layer ) ) |
|||
{ |
|||
lastCu = row; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
for( int row=0; row<rowCount; ++row ) |
|||
{ |
|||
wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 ); |
|||
int layer = getDecodedId( cb->GetId() ); |
|||
|
|||
if( IsValidCopperLayerIndex( layer ) ) |
|||
{ |
|||
cb->SetValue( visible ); |
|||
|
|||
bool isLastCopperLayer = (row==lastCu); |
|||
|
|||
OnLayerVisible( layer, visible, isLastCopperLayer ); |
|||
|
|||
if( isLastCopperLayer ) |
|||
break; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* Function SetLayersManagerTabsText |
|||
* Update the layer manager tabs labels |
|||
* Useful when changing Language or to set labels to a non default value |
|||
*/ |
|||
void PCB_LAYER_WIDGET::SetLayersManagerTabsText( ) |
|||
{ |
|||
m_notebook->SetPageText(0, _("Layer") ); |
|||
m_notebook->SetPageText(1, _("Render") ); |
|||
} |
|||
|
|||
/**
|
|||
* Function ReFillRender |
|||
* Rebuild Render for instance after the config is read |
|||
*/ |
|||
void PCB_LAYER_WIDGET::ReFillRender() |
|||
{ |
|||
BOARD* board = myframe->GetBoard(); |
|||
ClearRenderRows(); |
|||
// Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
|
|||
// is changed before appending to the LAYER_WIDGET. This is an automatic variable
|
|||
// not a static variable, change the color & state after copying from code to renderRows
|
|||
// on the stack.
|
|||
LAYER_WIDGET::ROW renderRows[16] = { |
|||
|
|||
#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
|
|||
|
|||
// text id color tooltip checked
|
|||
RR( _( "Through Via" ), VIA_THROUGH_VISIBLE, WHITE, _( "Show through vias" ) ), |
|||
RR( _( "Bl/Buried Via" ), VIA_BBLIND_VISIBLE, WHITE, _( "Show blind or buried vias" ) ), |
|||
RR( _( "Micro Via" ), VIA_MICROVIA_VISIBLE, WHITE, _( "Show micro vias") ), |
|||
RR( _( "Ratsnest" ), RATSNEST_VISIBLE, WHITE, _( "Show unconnected nets as a ratsnest") ), |
|||
|
|||
RR( _( "Pads Front" ), PAD_FR_VISIBLE, WHITE, _( "Show footprint pads on board's front" ) ), |
|||
RR( _( "Pads Back" ), PAD_BK_VISIBLE, WHITE, _( "Show footprint pads on board's back" ) ), |
|||
|
|||
RR( _( "Text Front" ), MOD_TEXT_FR_VISIBLE, WHITE, _( "Show footprint text on board's back" ) ), |
|||
RR( _( "Text Back" ), MOD_TEXT_BK_VISIBLE, WHITE, _( "Show footprint text on board's back" ) ), |
|||
RR( _( "Hidden Text" ), MOD_TEXT_INVISIBLE, WHITE, _( "Show footprint text marked as invisible" ) ), |
|||
|
|||
RR( _( "Anchors" ), ANCHOR_VISIBLE, WHITE, _( "Show footprint and text origins as a cross" ) ), |
|||
RR( _( "Grid" ), GRID_VISIBLE, WHITE, _( "Show the (x,y) grid dots" ) ), |
|||
RR( _( "No-Connects" ), NO_CONNECTS_VISIBLE, -1, _( "Show a marker on pads which have no net connected" ) ), |
|||
RR( _( "Modules Front" ), MOD_FR_VISIBLE, -1, _( "Show footprints that are on board's front") ), |
|||
RR( _( "Modules Back" ), MOD_BK_VISIBLE, -1, _( "Show footprints that are on board's back") ), |
|||
RR( _( "Values" ), MOD_VALUES_VISIBLE, -1, _( "Show footprint's values") ), |
|||
RR( _( "References" ), MOD_REFERENCES_VISIBLE, -1, _( "Show footprint's references") ), |
|||
}; |
|||
|
|||
for( unsigned row=0; row<DIM(renderRows); ++row ) |
|||
{ |
|||
if( renderRows[row].color != -1 ) // does this row show a color?
|
|||
{ |
|||
// this window frame must have an established BOARD, i.e. after SetBoard()
|
|||
renderRows[row].color = board->GetVisibleElementColor( renderRows[row].id ); |
|||
} |
|||
renderRows[row].state = board->IsElementVisible( renderRows[row].id ); |
|||
} |
|||
|
|||
AppendRenderRows( renderRows, DIM(renderRows) ); |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::ReFill() |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
int layer; |
|||
|
|||
int enabledLayers = brd->GetEnabledLayers(); |
|||
|
|||
// m_Layers->Freeze(); // no screen updates until done modifying
|
|||
|
|||
ClearLayerRows(); |
|||
|
|||
// show all coppers first, with front on top, back on bottom, then technical layers
|
|||
|
|||
layer = LAYER_N_FRONT; |
|||
if( enabledLayers & (1 << layer) ) |
|||
{ |
|||
AppendLayerRow( LAYER_WIDGET::ROW( |
|||
brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ), _("Front copper layer"), true ) ); |
|||
} |
|||
|
|||
for( layer = LAYER_N_FRONT-1; layer >= 1; --layer ) |
|||
{ |
|||
if( enabledLayers & (1 << layer) ) |
|||
{ |
|||
AppendLayerRow( LAYER_WIDGET::ROW( |
|||
brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ), _("An innner copper layer"), true ) ); |
|||
} |
|||
} |
|||
|
|||
layer = LAYER_N_BACK; |
|||
if( enabledLayers & (1 << layer) ) |
|||
{ |
|||
AppendLayerRow( LAYER_WIDGET::ROW( |
|||
brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ), _("Back copper layer"), true ) ); |
|||
} |
|||
|
|||
// technical layers are shown in this order:
|
|||
static const struct { |
|||
int layerId; |
|||
wxString tooltip; |
|||
} techLayerSeq[] = { |
|||
{ ADHESIVE_N_FRONT, _( "Adhesive on board's front" ) }, |
|||
{ ADHESIVE_N_BACK, _( "Adhesive on board's back" ) }, |
|||
{ SOLDERPASTE_N_FRONT, _( "Solder paste on board's front" )}, |
|||
{ SOLDERPASTE_N_BACK, _( "Solder paste on board's back" ) }, |
|||
{ SILKSCREEN_N_FRONT, _( "Silkscreen on board's front" ) }, |
|||
{ SILKSCREEN_N_BACK, _( "Silkscreen on board's back" ) }, |
|||
{ SOLDERMASK_N_FRONT, _( "Solder mask on board's front" ) }, |
|||
{ SOLDERMASK_N_BACK, _( "Solder mask on board's back" ) }, |
|||
{ DRAW_N, _( "Explanatory drawings" ) }, |
|||
{ COMMENT_N, _( "Explanatory comments" ) }, |
|||
{ ECO1_N, _( "TDB" ) }, |
|||
{ ECO2_N, _( "TBD" ) }, |
|||
{ EDGE_N, _( "Board's perimeter definition" ) }, |
|||
}; |
|||
|
|||
for( unsigned i=0; i<DIM(techLayerSeq); ++i ) |
|||
{ |
|||
layer = techLayerSeq[i].layerId; |
|||
|
|||
if( !(enabledLayers & (1 << layer)) ) |
|||
continue; |
|||
|
|||
AppendLayerRow( LAYER_WIDGET::ROW( |
|||
brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ), |
|||
techLayerSeq[i].tooltip, true ) ); |
|||
} |
|||
|
|||
installRightLayerClickHandler(); |
|||
|
|||
// m_Layers->Thaw();
|
|||
} |
|||
|
|||
//-----<LAYER_WIDGET callbacks>-------------------------------------------
|
|||
|
|||
void PCB_LAYER_WIDGET::OnLayerColorChange( int aLayer, int aColor ) |
|||
{ |
|||
myframe->GetBoard()->SetLayerColor( aLayer, aColor ); |
|||
myframe->ReCreateLayerBox( NULL ); |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
bool PCB_LAYER_WIDGET::OnLayerSelect( int aLayer ) |
|||
{ |
|||
// the layer change from the PCB_LAYER_WIDGET can be denied by returning
|
|||
// false from this function.
|
|||
myframe->setActiveLayer( aLayer, false ); |
|||
|
|||
if(DisplayOpt.ContrastModeDisplay) |
|||
myframe->DrawPanel->Refresh(); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
|
|||
int visibleLayers = brd->GetVisibleLayers(); |
|||
|
|||
if( isVisible ) |
|||
visibleLayers |= (1 << aLayer); |
|||
else |
|||
visibleLayers &= ~(1 << aLayer); |
|||
|
|||
brd->SetVisibleLayers( visibleLayers ); |
|||
|
|||
if( isFinal ) |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::OnRenderColorChange( int aId, int aColor ) |
|||
{ |
|||
myframe->GetBoard()->SetVisibleElementColor( aId, aColor ); |
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
void PCB_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled ) |
|||
{ |
|||
BOARD* brd = myframe->GetBoard(); |
|||
|
|||
/* @todo:
|
|||
|
|||
move: |
|||
|
|||
GRID_VISIBLE, ? maybe not this one |
|||
into m_VisibleElements and get rid of globals. |
|||
*/ |
|||
|
|||
switch( aId ) |
|||
{ |
|||
// see todo above, don't really want anything except IsElementVisible() here.
|
|||
|
|||
case GRID_VISIBLE: |
|||
// @todo, make read/write accessors for grid control so the write accessor can fire updates to
|
|||
// grid state listeners. I think the grid state should be kept in the BOARD.
|
|||
brd->SetElementVisibility( aId, isEnabled ); // set visibilty flag also in list, and myframe->m_Draw_Grid
|
|||
break; |
|||
|
|||
default: |
|||
brd->SetElementVisibility( aId, isEnabled ); |
|||
} |
|||
|
|||
myframe->DrawPanel->Refresh(); |
|||
} |
|||
|
|||
//-----</LAYER_WIDGET callbacks>------------------------------------------
|
|||
|
|||
|
|||
@ -1,175 +1,175 @@ |
|||
/*
|
|||
* drc_marker_functions.cpp |
|||
*/ |
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2010 Dick Hollenbeck, dick@softplc.com |
|||
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr |
|||
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
/* Methods of class DRC to initialize drc markers with messages
|
|||
* according to items and error ode |
|||
*/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "common.h"
|
|||
#include "pcbnew.h"
|
|||
#include "class_board_design_settings.h"
|
|||
|
|||
#include "drc_stuff.h"
|
|||
#include "class_pad.h"
|
|||
#include "class_track.h"
|
|||
#include "class_zone.h"
|
|||
#include "class_marker_pcb.h"
|
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe ) |
|||
{ |
|||
wxString textA = aTrack->GetSelectMenuText(); |
|||
wxString textB; |
|||
|
|||
wxPoint position; |
|||
wxPoint posB; |
|||
|
|||
if( aItem ) // aItem might be NULL
|
|||
{ |
|||
textB = aItem->GetSelectMenuText(); |
|||
posB = aItem->GetPosition(); |
|||
|
|||
if( aItem->Type() == TYPE_PAD ) |
|||
position = aItem->GetPosition(); |
|||
|
|||
else if( aItem->Type() == TYPE_VIA ) |
|||
position = aItem->GetPosition(); |
|||
|
|||
else if( aItem->Type() == TYPE_TRACK ) |
|||
{ |
|||
TRACK* track = (TRACK*) aItem; |
|||
wxPoint endPos = track->m_End; |
|||
|
|||
// either of aItem's start or end will be used for the marker position
|
|||
// first assume start, then switch at end if needed. decision made on
|
|||
// distance from end of aTrack.
|
|||
position = track->m_Start; |
|||
|
|||
double dToEnd = hypot( endPos.x - aTrack->m_End.x, |
|||
endPos.y - aTrack->m_End.y ); |
|||
double dToStart = hypot( position.x - aTrack->m_End.x, |
|||
position.y - aTrack->m_End.y ); |
|||
|
|||
if( dToEnd < dToStart ) |
|||
position = endPos; |
|||
} |
|||
} |
|||
else |
|||
position = aTrack->GetPosition(); |
|||
|
|||
if( fillMe ) |
|||
{ |
|||
if( aItem ) |
|||
fillMe->SetData( aErrorCode, position, |
|||
textA, aTrack->GetPosition(), |
|||
textB, posB ); |
|||
else |
|||
fillMe->SetData( aErrorCode, position, |
|||
textA, aTrack->GetPosition() ); |
|||
} |
|||
else |
|||
{ |
|||
if( aItem ) |
|||
fillMe = new MARKER_PCB( aErrorCode, position, |
|||
textA, aTrack->GetPosition(), |
|||
textB, posB ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, position, |
|||
textA, aTrack->GetPosition() ); |
|||
} |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PCB* fillMe ) |
|||
{ |
|||
wxString textA = aPad->GetSelectMenuText(); |
|||
wxString textB = bPad->GetSelectMenuText(); |
|||
|
|||
wxPoint posA = aPad->GetPosition(); |
|||
wxPoint posB = bPad->GetPosition(); |
|||
|
|||
if( fillMe ) |
|||
fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB ); |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* fillMe ) |
|||
{ |
|||
wxString textA = aArea->GetSelectMenuText(); |
|||
|
|||
wxPoint posA = aArea->GetPosition(); |
|||
|
|||
if( fillMe ) |
|||
fillMe->SetData( aErrorCode, posA, textA, posA ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA ); |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( const ZONE_CONTAINER* aArea, |
|||
const wxPoint& aPos, |
|||
int aErrorCode, |
|||
MARKER_PCB* fillMe ) |
|||
{ |
|||
wxString textA = aArea->GetSelectMenuText(); |
|||
|
|||
wxPoint posA = aPos; |
|||
|
|||
if( fillMe ) |
|||
fillMe->SetData( aErrorCode, posA, textA, posA ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA ); |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PCB* fillMe ) |
|||
{ |
|||
wxPoint posA; // not displayed
|
|||
|
|||
if( fillMe ) |
|||
fillMe->SetData( aErrorCode, posA, aMessage, posA ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, posA, aMessage, posA ); |
|||
|
|||
fillMe->SetShowNoCoordinate(); |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
/*
|
|||
* drc_marker_functions.cpp |
|||
*/ |
|||
/*
|
|||
* This program source code file is part of KICAD, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2010 Dick Hollenbeck, dick@softplc.com |
|||
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr |
|||
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
/* Methods of class DRC to initialize drc markers with messages
|
|||
* according to items and error ode |
|||
*/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "common.h"
|
|||
#include "pcbnew.h"
|
|||
#include "class_board_design_settings.h"
|
|||
|
|||
#include "drc_stuff.h"
|
|||
#include "class_pad.h"
|
|||
#include "class_track.h"
|
|||
#include "class_zone.h"
|
|||
#include "class_marker_pcb.h"
|
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe ) |
|||
{ |
|||
wxString textA = aTrack->GetSelectMenuText(); |
|||
wxString textB; |
|||
|
|||
wxPoint position; |
|||
wxPoint posB; |
|||
|
|||
if( aItem ) // aItem might be NULL
|
|||
{ |
|||
textB = aItem->GetSelectMenuText(); |
|||
posB = aItem->GetPosition(); |
|||
|
|||
if( aItem->Type() == TYPE_PAD ) |
|||
position = aItem->GetPosition(); |
|||
|
|||
else if( aItem->Type() == TYPE_VIA ) |
|||
position = aItem->GetPosition(); |
|||
|
|||
else if( aItem->Type() == TYPE_TRACK ) |
|||
{ |
|||
TRACK* track = (TRACK*) aItem; |
|||
wxPoint endPos = track->m_End; |
|||
|
|||
// either of aItem's start or end will be used for the marker position
|
|||
// first assume start, then switch at end if needed. decision made on
|
|||
// distance from end of aTrack.
|
|||
position = track->m_Start; |
|||
|
|||
double dToEnd = hypot( endPos.x - aTrack->m_End.x, |
|||
endPos.y - aTrack->m_End.y ); |
|||
double dToStart = hypot( position.x - aTrack->m_End.x, |
|||
position.y - aTrack->m_End.y ); |
|||
|
|||
if( dToEnd < dToStart ) |
|||
position = endPos; |
|||
} |
|||
} |
|||
else |
|||
position = aTrack->GetPosition(); |
|||
|
|||
if( fillMe ) |
|||
{ |
|||
if( aItem ) |
|||
fillMe->SetData( aErrorCode, position, |
|||
textA, aTrack->GetPosition(), |
|||
textB, posB ); |
|||
else |
|||
fillMe->SetData( aErrorCode, position, |
|||
textA, aTrack->GetPosition() ); |
|||
} |
|||
else |
|||
{ |
|||
if( aItem ) |
|||
fillMe = new MARKER_PCB( aErrorCode, position, |
|||
textA, aTrack->GetPosition(), |
|||
textB, posB ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, position, |
|||
textA, aTrack->GetPosition() ); |
|||
} |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PCB* fillMe ) |
|||
{ |
|||
wxString textA = aPad->GetSelectMenuText(); |
|||
wxString textB = bPad->GetSelectMenuText(); |
|||
|
|||
wxPoint posA = aPad->GetPosition(); |
|||
wxPoint posB = bPad->GetPosition(); |
|||
|
|||
if( fillMe ) |
|||
fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB ); |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* fillMe ) |
|||
{ |
|||
wxString textA = aArea->GetSelectMenuText(); |
|||
|
|||
wxPoint posA = aArea->GetPosition(); |
|||
|
|||
if( fillMe ) |
|||
fillMe->SetData( aErrorCode, posA, textA, posA ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA ); |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( const ZONE_CONTAINER* aArea, |
|||
const wxPoint& aPos, |
|||
int aErrorCode, |
|||
MARKER_PCB* fillMe ) |
|||
{ |
|||
wxString textA = aArea->GetSelectMenuText(); |
|||
|
|||
wxPoint posA = aPos; |
|||
|
|||
if( fillMe ) |
|||
fillMe->SetData( aErrorCode, posA, textA, posA ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA ); |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
|
|||
MARKER_PCB* DRC::fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PCB* fillMe ) |
|||
{ |
|||
wxPoint posA; // not displayed
|
|||
|
|||
if( fillMe ) |
|||
fillMe->SetData( aErrorCode, posA, aMessage, posA ); |
|||
else |
|||
fillMe = new MARKER_PCB( aErrorCode, posA, aMessage, posA ); |
|||
|
|||
fillMe->SetShowNoCoordinate(); |
|||
|
|||
return fillMe; |
|||
} |
|||
|
|||
@ -1,162 +1,162 @@ |
|||
/**
|
|||
* @file zones_convert_to_polygons_aux_functions.cpp |
|||
*/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "polygons_defs.h"
|
|||
#include "PolyLine.h"
|
|||
#include "wxPcbStruct.h"
|
|||
#include "trigo.h"
|
|||
|
|||
#include "class_board.h"
|
|||
#include "class_module.h"
|
|||
#include "class_zone.h"
|
|||
|
|||
#include "pcbnew.h"
|
|||
#include "zones.h"
|
|||
|
|||
|
|||
/**
|
|||
* Function BuildUnconnectedThermalStubsPolygonList |
|||
* Creates a set of polygons corresponding to stubs created by thermal shapes on pads |
|||
* which are not connected to a zone (dangling bridges) |
|||
* @param aCornerBuffer = a std::vector<CPolyPt> where to store polygons |
|||
* @param aPcb = the board. |
|||
* @param aZone = a pointer to the ZONE_CONTAINER to examine. |
|||
* @param aArcCorrection = a pointer to the ZONE_CONTAINER to examine. |
|||
* @param aRoundPadThermalRotation = the rotation in 1.0 degree for thermal stubs in round pads |
|||
*/ |
|||
|
|||
void BuildUnconnectedThermalStubsPolygonList( std::vector<CPolyPt>& aCornerBuffer, |
|||
BOARD* aPcb, |
|||
ZONE_CONTAINER* aZone, |
|||
double aArcCorrection, |
|||
int aRoundPadThermalRotation ) |
|||
{ |
|||
std::vector<wxPoint> corners_buffer; // a local polygon buffer to store one stub
|
|||
corners_buffer.reserve( 4 ); |
|||
wxPoint ptTest[4]; |
|||
|
|||
int zone_clearance = aZone->m_ZoneClearance; |
|||
|
|||
EDA_RECT item_boundingbox; |
|||
EDA_RECT zone_boundingbox = aZone->GetBoundingBox(); |
|||
int biggest_clearance = aPcb->GetBiggestClearanceValue(); |
|||
biggest_clearance = MAX( biggest_clearance, zone_clearance ); |
|||
zone_boundingbox.Inflate( biggest_clearance ); |
|||
|
|||
// half size of the pen used to draw/plot zones outlines
|
|||
int pen_radius = aZone->m_ZoneMinThickness / 2; |
|||
|
|||
// Calculate thermal bridge half width
|
|||
int thermbridgeWidth = aZone->m_ThermalReliefCopperBridgeValue / 2; |
|||
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) |
|||
{ |
|||
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() ) |
|||
{ |
|||
// check
|
|||
if( !pad->IsOnLayer( aZone->GetLayer() ) ) |
|||
continue; |
|||
if( pad->GetNet() != aZone->GetNet() ) |
|||
continue; |
|||
|
|||
item_boundingbox = pad->GetBoundingBox(); |
|||
item_boundingbox.Inflate( aZone->m_ThermalReliefGapValue ); |
|||
if( !( item_boundingbox.Intersects( zone_boundingbox ) ) ) |
|||
continue; |
|||
|
|||
// Thermal bridges are like a segment from a starting point inside the pad
|
|||
// to an ending point outside the pad
|
|||
wxPoint startpoint, endpoint; |
|||
endpoint.x = ( pad->m_Size.x / 2 ) + aZone->m_ThermalReliefGapValue; |
|||
endpoint.y = ( pad->m_Size.y / 2 ) + aZone->m_ThermalReliefGapValue; |
|||
|
|||
int copperThickness = aZone->m_ThermalReliefCopperBridgeValue - aZone->m_ZoneMinThickness; |
|||
if( copperThickness < 0 ) |
|||
copperThickness = 0; |
|||
|
|||
startpoint.x = min( pad->m_Size.x, copperThickness ); |
|||
startpoint.y = min( pad->m_Size.y, copperThickness ); |
|||
startpoint.x /= 2; |
|||
startpoint.y /= 2; |
|||
|
|||
// This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg)
|
|||
int fAngle = pad->m_Orient; |
|||
if( pad->m_PadShape == PAD_CIRCLE ) |
|||
{ |
|||
endpoint.x = (int) ( endpoint.x * aArcCorrection ); |
|||
endpoint.y = endpoint.x; |
|||
fAngle = aRoundPadThermalRotation; |
|||
} |
|||
|
|||
// contour line width has to be taken into calculation to avoid "thermal stub bleed"
|
|||
endpoint.x += pen_radius; |
|||
endpoint.y += pen_radius; |
|||
// compute north, south, west and east points for zone connection.
|
|||
ptTest[0] = wxPoint( 0, endpoint.y ); // lower point
|
|||
ptTest[1] = wxPoint( 0, -endpoint.y ); // upper point
|
|||
ptTest[2] = wxPoint( endpoint.x, 0 ); // right point
|
|||
ptTest[3] = wxPoint( -endpoint.x, 0 ); // left point
|
|||
|
|||
// Test all sides
|
|||
for( int i = 0; i < 4; i++ ) |
|||
{ |
|||
// rotate point
|
|||
RotatePoint( &ptTest[i], fAngle ); |
|||
|
|||
// translate point
|
|||
ptTest[i] += pad->ReturnShapePos(); |
|||
if( aZone->HitTestFilledArea( ptTest[i] ) ) |
|||
continue; |
|||
|
|||
corners_buffer.clear(); |
|||
|
|||
// polygons are rectangles with width of copper bridge value
|
|||
switch( i ) |
|||
{ |
|||
case 0: // lower stub
|
|||
corners_buffer.push_back( wxPoint( -thermbridgeWidth, endpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( +thermbridgeWidth, endpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( +thermbridgeWidth, startpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( -thermbridgeWidth, startpoint.y ) ); |
|||
break; |
|||
|
|||
case 1: // upper stub
|
|||
corners_buffer.push_back( wxPoint( -thermbridgeWidth, -endpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( +thermbridgeWidth, -endpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( +thermbridgeWidth, -startpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( -thermbridgeWidth, -startpoint.y ) ); |
|||
break; |
|||
|
|||
case 2: // right stub
|
|||
corners_buffer.push_back( wxPoint( endpoint.x, -thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( endpoint.x, thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( +startpoint.x, thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( +startpoint.x, -thermbridgeWidth ) ); |
|||
break; |
|||
|
|||
case 3: // left stub
|
|||
corners_buffer.push_back( wxPoint( -endpoint.x, -thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( -endpoint.x, thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( -startpoint.x, thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( -startpoint.x, -thermbridgeWidth ) ); |
|||
break; |
|||
} |
|||
|
|||
|
|||
// add computed polygon to list
|
|||
for( unsigned ic = 0; ic < corners_buffer.size(); ic++ ) |
|||
{ |
|||
wxPoint cpos = corners_buffer[ic]; |
|||
RotatePoint( &cpos, fAngle ); // Rotate according to module orientation
|
|||
cpos += pad->ReturnShapePos(); // Shift origin to position
|
|||
CPolyPt corner; |
|||
corner.x = cpos.x; |
|||
corner.y = cpos.y; |
|||
corner.end_contour = ( ic < (corners_buffer.size() - 1) ) ? 0 : 1; |
|||
aCornerBuffer.push_back( corner ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
/**
|
|||
* @file zones_convert_to_polygons_aux_functions.cpp |
|||
*/ |
|||
|
|||
#include "fctsys.h"
|
|||
#include "polygons_defs.h"
|
|||
#include "PolyLine.h"
|
|||
#include "wxPcbStruct.h"
|
|||
#include "trigo.h"
|
|||
|
|||
#include "class_board.h"
|
|||
#include "class_module.h"
|
|||
#include "class_zone.h"
|
|||
|
|||
#include "pcbnew.h"
|
|||
#include "zones.h"
|
|||
|
|||
|
|||
/**
|
|||
* Function BuildUnconnectedThermalStubsPolygonList |
|||
* Creates a set of polygons corresponding to stubs created by thermal shapes on pads |
|||
* which are not connected to a zone (dangling bridges) |
|||
* @param aCornerBuffer = a std::vector<CPolyPt> where to store polygons |
|||
* @param aPcb = the board. |
|||
* @param aZone = a pointer to the ZONE_CONTAINER to examine. |
|||
* @param aArcCorrection = a pointer to the ZONE_CONTAINER to examine. |
|||
* @param aRoundPadThermalRotation = the rotation in 1.0 degree for thermal stubs in round pads |
|||
*/ |
|||
|
|||
void BuildUnconnectedThermalStubsPolygonList( std::vector<CPolyPt>& aCornerBuffer, |
|||
BOARD* aPcb, |
|||
ZONE_CONTAINER* aZone, |
|||
double aArcCorrection, |
|||
int aRoundPadThermalRotation ) |
|||
{ |
|||
std::vector<wxPoint> corners_buffer; // a local polygon buffer to store one stub
|
|||
corners_buffer.reserve( 4 ); |
|||
wxPoint ptTest[4]; |
|||
|
|||
int zone_clearance = aZone->m_ZoneClearance; |
|||
|
|||
EDA_RECT item_boundingbox; |
|||
EDA_RECT zone_boundingbox = aZone->GetBoundingBox(); |
|||
int biggest_clearance = aPcb->GetBiggestClearanceValue(); |
|||
biggest_clearance = MAX( biggest_clearance, zone_clearance ); |
|||
zone_boundingbox.Inflate( biggest_clearance ); |
|||
|
|||
// half size of the pen used to draw/plot zones outlines
|
|||
int pen_radius = aZone->m_ZoneMinThickness / 2; |
|||
|
|||
// Calculate thermal bridge half width
|
|||
int thermbridgeWidth = aZone->m_ThermalReliefCopperBridgeValue / 2; |
|||
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) |
|||
{ |
|||
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() ) |
|||
{ |
|||
// check
|
|||
if( !pad->IsOnLayer( aZone->GetLayer() ) ) |
|||
continue; |
|||
if( pad->GetNet() != aZone->GetNet() ) |
|||
continue; |
|||
|
|||
item_boundingbox = pad->GetBoundingBox(); |
|||
item_boundingbox.Inflate( aZone->m_ThermalReliefGapValue ); |
|||
if( !( item_boundingbox.Intersects( zone_boundingbox ) ) ) |
|||
continue; |
|||
|
|||
// Thermal bridges are like a segment from a starting point inside the pad
|
|||
// to an ending point outside the pad
|
|||
wxPoint startpoint, endpoint; |
|||
endpoint.x = ( pad->m_Size.x / 2 ) + aZone->m_ThermalReliefGapValue; |
|||
endpoint.y = ( pad->m_Size.y / 2 ) + aZone->m_ThermalReliefGapValue; |
|||
|
|||
int copperThickness = aZone->m_ThermalReliefCopperBridgeValue - aZone->m_ZoneMinThickness; |
|||
if( copperThickness < 0 ) |
|||
copperThickness = 0; |
|||
|
|||
startpoint.x = min( pad->m_Size.x, copperThickness ); |
|||
startpoint.y = min( pad->m_Size.y, copperThickness ); |
|||
startpoint.x /= 2; |
|||
startpoint.y /= 2; |
|||
|
|||
// This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg)
|
|||
int fAngle = pad->m_Orient; |
|||
if( pad->m_PadShape == PAD_CIRCLE ) |
|||
{ |
|||
endpoint.x = (int) ( endpoint.x * aArcCorrection ); |
|||
endpoint.y = endpoint.x; |
|||
fAngle = aRoundPadThermalRotation; |
|||
} |
|||
|
|||
// contour line width has to be taken into calculation to avoid "thermal stub bleed"
|
|||
endpoint.x += pen_radius; |
|||
endpoint.y += pen_radius; |
|||
// compute north, south, west and east points for zone connection.
|
|||
ptTest[0] = wxPoint( 0, endpoint.y ); // lower point
|
|||
ptTest[1] = wxPoint( 0, -endpoint.y ); // upper point
|
|||
ptTest[2] = wxPoint( endpoint.x, 0 ); // right point
|
|||
ptTest[3] = wxPoint( -endpoint.x, 0 ); // left point
|
|||
|
|||
// Test all sides
|
|||
for( int i = 0; i < 4; i++ ) |
|||
{ |
|||
// rotate point
|
|||
RotatePoint( &ptTest[i], fAngle ); |
|||
|
|||
// translate point
|
|||
ptTest[i] += pad->ReturnShapePos(); |
|||
if( aZone->HitTestFilledArea( ptTest[i] ) ) |
|||
continue; |
|||
|
|||
corners_buffer.clear(); |
|||
|
|||
// polygons are rectangles with width of copper bridge value
|
|||
switch( i ) |
|||
{ |
|||
case 0: // lower stub
|
|||
corners_buffer.push_back( wxPoint( -thermbridgeWidth, endpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( +thermbridgeWidth, endpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( +thermbridgeWidth, startpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( -thermbridgeWidth, startpoint.y ) ); |
|||
break; |
|||
|
|||
case 1: // upper stub
|
|||
corners_buffer.push_back( wxPoint( -thermbridgeWidth, -endpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( +thermbridgeWidth, -endpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( +thermbridgeWidth, -startpoint.y ) ); |
|||
corners_buffer.push_back( wxPoint( -thermbridgeWidth, -startpoint.y ) ); |
|||
break; |
|||
|
|||
case 2: // right stub
|
|||
corners_buffer.push_back( wxPoint( endpoint.x, -thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( endpoint.x, thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( +startpoint.x, thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( +startpoint.x, -thermbridgeWidth ) ); |
|||
break; |
|||
|
|||
case 3: // left stub
|
|||
corners_buffer.push_back( wxPoint( -endpoint.x, -thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( -endpoint.x, thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( -startpoint.x, thermbridgeWidth ) ); |
|||
corners_buffer.push_back( wxPoint( -startpoint.x, -thermbridgeWidth ) ); |
|||
break; |
|||
} |
|||
|
|||
|
|||
// add computed polygon to list
|
|||
for( unsigned ic = 0; ic < corners_buffer.size(); ic++ ) |
|||
{ |
|||
wxPoint cpos = corners_buffer[ic]; |
|||
RotatePoint( &cpos, fAngle ); // Rotate according to module orientation
|
|||
cpos += pad->ReturnShapePos(); // Shift origin to position
|
|||
CPolyPt corner; |
|||
corner.x = cpos.x; |
|||
corner.y = cpos.y; |
|||
corner.end_contour = ( ic < (corners_buffer.size() - 1) ) ? 0 : 1; |
|||
aCornerBuffer.push_back( corner ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue