Update (Pcbnew) "Swap Layers:" and (GerbView) "Layer selection" dialog boxes

This commit is contained in:
g_harland 2007-11-02 05:33:31 +00:00
parent 335fa14849
commit b30b24c50a
3 changed files with 482 additions and 263 deletions

View File

@ -4,6 +4,30 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2007-Nov-02 UPDATE Geoff Harland <gharlandau@yahoo.com.au>
================================================================================
+ pcbnew
* Sizers have now been provided for the "Swap Layers:" dialog box, and the
previously provided radiobuttons have been replaced with buttons and static
text strings. (In the previous version of this dialog, radiobuttons were being
used in an inappropriate manner. The most "orthodox" way of implementing the
functionality within this dialog would be to provide a combobox for each layer,
but as up to 30 strings would be needed within the dropdown list associated with
each of those controls (one string for each of the layers, and another string to
deselect the layer), such controls would be less than user-friendly. Hence a
button is now provided for each layer instead (and which, like the previously
provided radiobutton, invokes the "Select Layer:" dialog box after being clicked
on). Two static text strings are also provided for each layer, with one of them
being used to identify that layer, and the other being used to identify which
layer that each layer is currently being swapped to.) The previously provided
"Select" and "Deselect" buttons are no longer required, and are thus no longer
provided.
+ gerbview
* The "Layer selection" dialog box (invoked during the "Export to Pcbnew" command)
has similarly been updated. (This dialog did use spacers before, but once again,
the previously provided radiobuttons were being used in an inappropriate manner.)
2007-Nov-01 UPDATE Geoff Harland <gharlandau@yahoo.com.au> 2007-Nov-01 UPDATE Geoff Harland <gharlandau@yahoo.com.au>
================================================================================ ================================================================================
+ pcbnew + pcbnew

View File

@ -1,8 +1,8 @@
/*******************************************************/ /*******************************************************/
/* Dialog frame to choose gerber layers and pcb layers */ /* Dialog frame to choose gerber layers and pcb layers */
/*******************************************************/ /*******************************************************/
/* select_layers_to_pcb.cpp*/ /* select_layers_to_pcb.cpp */
#include "fctsys.h" #include "fctsys.h"
#include "common.h" #include "common.h"
@ -10,15 +10,17 @@
#include "protos.h" #include "protos.h"
#include "wx/statline.h"
/* Variables locales */ /* Variables locales */
static int RadioButtonTable[32]; // Indexes radiobuttons to Gerber layers static int ButtonTable[32]; // Indexes buttons to Gerber layers
static int LayerLookUpTable[32]; // Indexes Gerber layers to PCB file layers static int LayerLookUpTable[32]; // Indexes Gerber layers to PCB file layers
wxStaticText* layer_list[32]; // Indexes text strings to buttons
enum swap_layer_id { enum swap_layer_id {
ID_SWAP_LAYER_BUTTON_SELECT = 1800, ID_WINEDA_SWAPLAYERFRAME = 1800,
ID_SWAP_LAYER_DESELECT, ID_BUTTON_0,
ID_SWAP_LAYER_SELECT ID_TEXT_0 = ID_BUTTON_0 + 32
}; };
@ -29,14 +31,21 @@ enum swap_layer_id {
class WinEDA_SwapLayerFrame: public wxDialog class WinEDA_SwapLayerFrame: public wxDialog
{ {
private: private:
WinEDA_GerberFrame *m_Parent; WinEDA_GerberFrame* m_Parent;
wxRadioBox * m_LayerList; wxBoxSizer* OuterBoxSizer;
wxBoxSizer* MainBoxSizer;
wxFlexGridSizer* FlexColumnBoxSizer;
wxStaticText* label;
wxButton* Button;
wxStaticText* text;
wxStaticLine* Line;
wxStdDialogButtonSizer* StdDialogButtonSizer;
public: public:
// Constructor and destructor // Constructor and destructor
WinEDA_SwapLayerFrame(WinEDA_GerberFrame *parent); WinEDA_SwapLayerFrame(WinEDA_GerberFrame *parent);
~WinEDA_SwapLayerFrame() {}; ~WinEDA_SwapLayerFrame() {};
private: private:
void Sel_Layer(wxCommandEvent& event); void Sel_Layer(wxCommandEvent& event);
@ -44,16 +53,15 @@ private:
void OnCancelClick(wxCommandEvent& event); void OnCancelClick(wxCommandEvent& event);
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
/* Table des evenements pour WinEDA_SwapLayerFrame */ /* Table des evenements pour WinEDA_SwapLayerFrame */
BEGIN_EVENT_TABLE(WinEDA_SwapLayerFrame, wxDialog) BEGIN_EVENT_TABLE(WinEDA_SwapLayerFrame, wxDialog)
EVT_BUTTON(wxID_OK, WinEDA_SwapLayerFrame::OnOkClick) EVT_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + NB_LAYERS - 1,
EVT_BUTTON(wxID_CANCEL, WinEDA_SwapLayerFrame::OnCancelClick) wxEVT_COMMAND_BUTTON_CLICKED,
EVT_BUTTON(ID_SWAP_LAYER_DESELECT, WinEDA_SwapLayerFrame::Sel_Layer) WinEDA_SwapLayerFrame::Sel_Layer )
EVT_BUTTON(ID_SWAP_LAYER_BUTTON_SELECT, WinEDA_SwapLayerFrame::Sel_Layer) EVT_BUTTON( wxID_OK, WinEDA_SwapLayerFrame::OnOkClick )
EVT_RADIOBOX(ID_SWAP_LAYER_SELECT, WinEDA_SwapLayerFrame::Sel_Layer) EVT_BUTTON( wxID_CANCEL, WinEDA_SwapLayerFrame::OnCancelClick )
END_EVENT_TABLE() END_EVENT_TABLE()
@ -65,129 +73,228 @@ int * InstallDialogLayerPairChoice(WinEDA_GerberFrame * parent)
* return the "lookup table" if ok, or NULL * return the "lookup table" if ok, or NULL
*/ */
{ {
WinEDA_SwapLayerFrame * frame = new WinEDA_SwapLayerFrame(parent); WinEDA_SwapLayerFrame * frame = new WinEDA_SwapLayerFrame(parent);
int ii = frame->ShowModal(); int ii = frame->ShowModal();
frame->Destroy(); frame->Destroy();
if( ii >= 0 ) if( ii >= 0 )
return LayerLookUpTable; return LayerLookUpTable;
else else
return NULL; return NULL;
} }
/*************************************************************************/ /*************************************************************************/
WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame(WinEDA_GerberFrame *parent): WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame(WinEDA_GerberFrame *parent) :
wxDialog( parent, -1, _("Layer selection:"), wxPoint(-1, -1), wxDialog( parent, -1, _("Layer selection:"), wxPoint(-1, -1),
wxDefaultSize, DIALOG_STYLE ) wxDefaultSize, wxDEFAULT_DIALOG_STYLE|MAYBE_RESIZE_BORDER )
/*************************************************************************/ /*************************************************************************/
{ {
wxButton * Button; OuterBoxSizer = NULL;
int ii, nb_items; MainBoxSizer = NULL;
wxString g_Layer_Name_Pair[32]; FlexColumnBoxSizer = NULL;
label = NULL;
Button = NULL;
text = NULL;
Line = NULL;
StdDialogButtonSizer = NULL;
m_Parent = parent; m_Parent = parent;
SetFont(*g_DialogFont); SetFont( *g_DialogFont );
// Compute a reasonable number of copper layers int item_ID, ii, nb_items;
g_DesignSettings.m_CopperLayerCount = 0; wxString msg;
for( ii = 0; ii < 32; ii++ ) wxSize goodSize;
{
if( g_GERBER_Descr_List[ii] != NULL )
g_DesignSettings.m_CopperLayerCount++;
// Specify the default value for each member of these arrays. // Experimentation has shown that buttons in the Windows version can be 20 pixels
RadioButtonTable[ii] = -1; // wide and 20 pixels high, but that they need to be 26 pixels wide and 26 pixels
LayerLookUpTable[ii] = NB_LAYERS; // Value associated with deselected Gerber layer // high in the Linux version. (And although the dimensions of those buttons could
} // be set to 26 pixels wide and 26 pixels high in both of those versions, that would
// result in a dialog box which would be excessively high in the Windows version.)
#ifdef __WINDOWS__
int w = 20;
int h = 20;
#else
int w = 26;
int h = 26;
#endif
// As currently implemented, the dimensions of the buttons in the Mac version are
// also 26 pixels wide and 26 pixels high. If appropriate, the above code should be
// modified as required in the event that those buttons should be some other size
// in that version.
int pcb_layer_number = 0; // Compute a reasonable number of copper layers
for( nb_items = 0, ii = 0; ii < 32; ii++ ) g_DesignSettings.m_CopperLayerCount = 0;
{ for( ii = 0; ii < 32; ii++ )
if( g_GERBER_Descr_List[ii] == NULL ) {
continue; if( g_GERBER_Descr_List[ii] != NULL )
g_DesignSettings.m_CopperLayerCount++;
if( (pcb_layer_number == g_DesignSettings.m_CopperLayerCount - 1) // Specify the default value for each member of these arrays.
&& (g_DesignSettings.m_CopperLayerCount > 1) ) ButtonTable[ii] = -1;
pcb_layer_number = CMP_N; LayerLookUpTable[ii] = NB_LAYERS; // Value associated with deselected Gerber layer
}
RadioButtonTable[nb_items] = ii; int pcb_layer_number = 0;
LayerLookUpTable[ii] = pcb_layer_number; for( nb_items = 0, ii = 0; ii < 32; ii++ )
{
// Specify initial (temporary) caption for associated radiobutton, if( g_GERBER_Descr_List[ii] == NULL )
// which will be appropriately updated after dialog box has been sized. continue;
// (If the radiobuttons' captions are not changed in this way, some of
// each radiobutton's caption could be truncated if the associated
// (Gerber) layer is ever subsequently deselected by the user.)
g_Layer_Name_Pair[nb_items] = _("Gerber layer ");
g_Layer_Name_Pair[nb_items] << ii + 1 << wxT(" -> ") << _("Do not export");
nb_items++; if( (pcb_layer_number == g_DesignSettings.m_CopperLayerCount - 1)
pcb_layer_number++; && (g_DesignSettings.m_CopperLayerCount > 1) )
} pcb_layer_number = CMP_N;
wxBoxSizer* FrameBoxSizer = new wxBoxSizer(wxVERTICAL); ButtonTable[nb_items] = ii;
SetSizer(FrameBoxSizer); LayerLookUpTable[ii] = pcb_layer_number;
nb_items++;
pcb_layer_number++;
}
wxBoxSizer* MainBoxSizer = new wxBoxSizer(wxHORIZONTAL); OuterBoxSizer = new wxBoxSizer(wxVERTICAL);
FrameBoxSizer->Add(MainBoxSizer, 0, wxGROW|wxALIGN_LEFT|wxALL, 5); SetSizer(OuterBoxSizer);
m_LayerList = new wxRadioBox(this, ID_SWAP_LAYER_SELECT, _("Layers"), MainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
wxDefaultPosition, wxDefaultSize, OuterBoxSizer->Add(MainBoxSizer, 1, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
nb_items, g_Layer_Name_Pair,
nb_items < 16 ? nb_items : 16,
wxRA_SPECIFY_ROWS);
// Specify a minimum size for this radiobox (with the objective for( ii = 0; ii < nb_items; ii++ )
// of attempting to prevent any radiobutton's caption from being {
// truncated if any of the layers are subsequently deselected) // If more than 16 Gerber layers are used, provide a vertical line to
m_LayerList->SetMinSize( m_LayerList->GetSize() ); // separate the two FlexGrid sizers
if( (nb_items > 16) && (ii == 16) )
{
Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
MainBoxSizer->Add(Line, 0, wxGROW|wxLEFT|wxRIGHT, 5);
}
MainBoxSizer->Add(m_LayerList, 0, wxALIGN_TOP|wxALL, 5); // Provide a separate FlexGrid sizer for every sixteen sets of controls
if( ii % 16 == 0 )
{
// Each Gerber layer has an associated static text string (to identify that layer),
// a button (for invoking a child dialog box to change which pcbnew layer that the
// Gerber layer is mapped to), and a second static text string (to depict which
// pcbnew layer that the Gerber layer has been mapped to). Each of those items are
// placed into the left hand column, middle column, and right hand column
// (respectively) of the Flexgrid sizer, and the color of the second text string
// is set to blue (to indicate that the actual text changes depending upon which
// pcbnew layer has been selected by the child dialog box).
// (Experimentation has shown that if a text control is used to depict which
// pcbnew layer that each Gerber layer is mapped to (instead of a static text
// string), then those controls do not behave in a fully satisfactory manner in
// the Linux version. Even when the read-only attribute is specified for all of
// those controls, they can still be selected when the arrow keys or Tab key is
// used to step through all of the controls within the dialog box, and
// directives to set the foreground color of the text of each such control to
// blue (to indicate that the text is of a read-only nature) are disregarded.)
wxBoxSizer* RightBoxSizer = new wxBoxSizer(wxVERTICAL); // Specify a FlexGrid sizer with an appropriate number of rows and three columns.
MainBoxSizer->Add(RightBoxSizer, 0, wxALIGN_TOP|wxALL, 0); // If nb_items < 16, then the number of rows is nb_items; otherwise, the number of
// rows is 16 (with two separate columns of controls being used if nb_items > 16).
RightBoxSizer->AddSpacer(10); if( nb_items < 16 )
FlexColumnBoxSizer = new wxFlexGridSizer(nb_items, 3, 0, 0);
else
FlexColumnBoxSizer = new wxFlexGridSizer(16, 3, 0, 0);
Button = new wxButton(this, ID_SWAP_LAYER_BUTTON_SELECT, _("Select...")); // Specify that all of the rows can be expanded.
Button->SetForegroundColour(wxColour(0,100,100)); for( int jj = 0; jj < MIN(nb_items, 16); jj++ )
RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5); {
FlexColumnBoxSizer->AddGrowableRow(jj);
}
Button = new wxButton(this, ID_SWAP_LAYER_DESELECT, _("Deselect")); // Specify that (just) the right-hand column can be expanded.
Button->SetForegroundColour(wxColour(0,100,0)); FlexColumnBoxSizer->AddGrowableCol(2);
RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);
wxBoxSizer* BottomBoxSizer = new wxBoxSizer(wxHORIZONTAL); MainBoxSizer->Add(FlexColumnBoxSizer, 1, wxGROW|wxTOP, 5);
FrameBoxSizer->Add(BottomBoxSizer, 0, wxGROW|wxALIGN_RIGHT|wxALL, 5); }
// The following stretch spacer ensures that the "OK" and "Cancel" buttons // Provide a text string to identify the Gerber layer
// will be positioned at the lower right corner of the dialog box. msg = _("Gerber layer ");
BottomBoxSizer->AddStretchSpacer(); msg << ButtonTable[ii] + 1;
Button = new wxButton(this, wxID_OK, _("OK")); label = new wxStaticText( this, wxID_STATIC, msg, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
Button->SetForegroundColour(*wxRED); FlexColumnBoxSizer->Add(label, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
BottomBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);
Button = new wxButton(this, wxID_CANCEL, _("Cancel"));
Button->SetForegroundColour(*wxBLUE);
BottomBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);
// Provide a button for this layer (which will invoke a child dialog box)
item_ID = ID_BUTTON_0 + ii;
Button = new wxButton( this, item_ID, wxT("..."), wxDefaultPosition, wxSize(w, h), 0 );
FlexColumnBoxSizer->Add(Button, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
// Provide another text string to specify which pcbnew layer that this
// Gerber layer is initially mapped to, and set the initial text to
// specify the appropriate pcbnew layer, and set the foreground color
// of the text to blue (to indicate that the text can be changed).
item_ID = ID_TEXT_0 + ii;
// When the first of these text strings is being added, determine what size is necessary to
// to be able to display any possible string without it being truncated. Then specify that
// size as the minimum size for all of these text strings. (If this minimum size is not
// determined in this fashion, then it is possible for the display of one or more of these
// strings to be truncated after different pcbnew layers are selected.)
if( ii == 0 )
{
msg = _( "Do not export" );
text = new wxStaticText( this, item_ID, msg, wxDefaultPosition, wxDefaultSize, 0 );
goodSize = text->GetSize();
for( int jj = 0; jj < NB_LAYERS; jj++ )
{
text->SetLabel( ReturnPcbLayerName( jj ) );
if( goodSize.x < text->GetSize().x )
goodSize.x = text->GetSize().x;
}
msg = ReturnPcbLayerName(LayerLookUpTable[ButtonTable[ii]]);
text->SetLabel( msg );
}
else
{
msg = ReturnPcbLayerName(LayerLookUpTable[ButtonTable[ii]]);
text = new wxStaticText( this, item_ID, msg, wxDefaultPosition, wxDefaultSize, 0 );
}
text->SetMinSize( goodSize );
text->SetForegroundColour( *wxBLUE );
FlexColumnBoxSizer->Add(text, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);
layer_list[ii] = text;
}
// If required, provide spacers to occupy otherwise blank cells within the
// second FlexGrid sizer. (As it incorporates three columns, three spacers
// are thus required for each otherwise unused row.)
if( 16 < nb_items && nb_items < 32 )
{
for( ii = 3 * nb_items; ii < 96; ii++ )
{
FlexColumnBoxSizer->Add(5, h, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);
}
}
// Provide a line to separate the controls which have been provided so far
// from the OK and Cancel buttons (which will be provided after this line)
Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
OuterBoxSizer->Add(Line, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
// Provide a StdDialogButtonSizer to accommodate the OK and Cancel buttons;
// using that type of sizer results in those buttons being automatically
// located in positions appropriate for each (OS) version of KiCad.
StdDialogButtonSizer = new wxStdDialogButtonSizer;
OuterBoxSizer->Add(StdDialogButtonSizer, 0, wxALIGN_RIGHT|wxALL, 10);
Button = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
Button->SetForegroundColour( *wxRED );
StdDialogButtonSizer->AddButton(Button);
Button = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
Button->SetForegroundColour( *wxBLUE );
StdDialogButtonSizer->AddButton(Button);
StdDialogButtonSizer->Realize();
// Resize the dialog
if( GetSizer() ) if( GetSizer() )
{ {
GetSizer()->SetSizeHints(this); GetSizer()->SetSizeHints(this);
} }
// Now specify the correct caption for each radiobutton.
// (Regrettably though there are still problems with the Windows
// version; captions for each radiobutton can still be truncated.) :-(
for( ii = 0; ii < nb_items; ii++ )
{
g_Layer_Name_Pair[ii] = _("Gerber layer ");
g_Layer_Name_Pair[ii] << RadioButtonTable[ii] + 1 << wxT(" -> ")
<< ReturnPcbLayerName(LayerLookUpTable[RadioButtonTable[ii]]);
m_LayerList->SetString( ii, g_Layer_Name_Pair[ii] );
}
} }
@ -195,49 +302,31 @@ wxString g_Layer_Name_Pair[32];
void WinEDA_SwapLayerFrame::Sel_Layer(wxCommandEvent& event) void WinEDA_SwapLayerFrame::Sel_Layer(wxCommandEvent& event)
/***************************************************************/ /***************************************************************/
{ {
int ii, jj; int ii, jj;
// int gerber_layer_number;
wxString msg;
ii = m_LayerList->GetSelection(); ii = event.GetId();
if( ii < 0 )
return;
switch ( event.GetId() ) if( ii < ID_BUTTON_0 || ii >= ID_BUTTON_0 + 32 )
{ return;
case ID_SWAP_LAYER_DESELECT:
if( LayerLookUpTable[RadioButtonTable[ii]] != NB_LAYERS )
{
LayerLookUpTable[RadioButtonTable[ii]] = NB_LAYERS;
msg = _("Gerber layer ");
msg << RadioButtonTable[ii] + 1
<< wxT(" -> ") << _("Do not export");
m_LayerList->SetString( ii, msg );
}
break;
case ID_SWAP_LAYER_BUTTON_SELECT: ii = event.GetId() - ID_BUTTON_0;
case ID_SWAP_LAYER_SELECT:
jj = LayerLookUpTable[RadioButtonTable[ii]];
if( (jj < 0) || (jj > NB_LAYERS) )
jj = 0; // (Defaults to "Copper" layer.)
jj = m_Parent->SelectLayer(jj, -1, -1, true);
if( (jj < 0) || (jj > NB_LAYERS) )
return;
if( jj != LayerLookUpTable[RadioButtonTable[ii]] ) jj = LayerLookUpTable[ButtonTable[ii]];
{ if( (jj < 0) || (jj > NB_LAYERS) )
LayerLookUpTable[RadioButtonTable[ii]] = jj; jj = 0; // (Defaults to "Copper" layer.)
msg = _("Gerber layer "); jj = m_Parent->SelectLayer(jj, -1, -1, true);
msg << RadioButtonTable[ii] + 1 << wxT(" -> ");
if( jj == NB_LAYERS ) if( (jj < 0) || (jj > NB_LAYERS) )
msg << _("Do not export"); return;
else
msg << ReturnPcbLayerName(jj); if( jj != LayerLookUpTable[ButtonTable[ii]] )
m_LayerList->SetString( ii, msg ); {
} LayerLookUpTable[ButtonTable[ii]] = jj;
break; if( jj == NB_LAYERS )
} layer_list[ii]->SetLabel( _( "Do not export" ) );
else
layer_list[ii]->SetLabel( ReturnPcbLayerName( jj ) );
}
} }
@ -256,27 +345,27 @@ void WinEDA_SwapLayerFrame::OnOkClick(wxCommandEvent& event)
int ii; int ii;
bool AsCmpLayer = false; bool AsCmpLayer = false;
/* Compute the number of copper layers /* Compute the number of copper layers
* this is the max layer number + 1 (if some internal layers exist) * this is the max layer number + 1 (if some internal layers exist)
*/ */
g_DesignSettings.m_CopperLayerCount = 1; g_DesignSettings.m_CopperLayerCount = 1;
for( ii = 0; ii < 32; ii++ ) for( ii = 0; ii < 32; ii++ )
{ {
if( LayerLookUpTable[ii] == CMP_N ) if( LayerLookUpTable[ii] == CMP_N )
AsCmpLayer = true; AsCmpLayer = true;
else else
{ {
if( LayerLookUpTable[ii] >= LAST_COPPER_LAYER ) if( LayerLookUpTable[ii] >= LAST_COPPER_LAYER )
continue; // not a copper layer continue; // not a copper layer
if( LayerLookUpTable[ii] >= g_DesignSettings.m_CopperLayerCount ) if( LayerLookUpTable[ii] >= g_DesignSettings.m_CopperLayerCount )
g_DesignSettings.m_CopperLayerCount++; g_DesignSettings.m_CopperLayerCount++;
} }
} }
if( AsCmpLayer ) if( AsCmpLayer )
g_DesignSettings.m_CopperLayerCount++; g_DesignSettings.m_CopperLayerCount++;
if( g_DesignSettings.m_CopperLayerCount > NB_COPPER_LAYERS ) // should not occur. if( g_DesignSettings.m_CopperLayerCount > NB_COPPER_LAYERS ) // should not occur.
g_DesignSettings.m_CopperLayerCount = NB_COPPER_LAYERS; g_DesignSettings.m_CopperLayerCount = NB_COPPER_LAYERS;
EndModal( 1 ); EndModal( 1 );
} }

View File

@ -10,13 +10,16 @@
#include "protos.h" #include "protos.h"
#include "wx/statline.h"
/* Variables locales */ /* Variables locales */
static int New_Layer[NB_LAYERS]; static int New_Layer[NB_LAYERS];
wxStaticText* layer_list[NB_LAYERS];
enum swap_layer_id { enum swap_layer_id {
ID_SWAP_LAYER_BUTTON_SELECT = 1800, ID_WINEDA_SWAPLAYERFRAME = 1800,
ID_SWAP_LAYER_DESELECT, ID_BUTTON_0,
ID_SWAP_LAYER_SELECT ID_TEXT_0 = ID_BUTTON_0 + NB_LAYERS
}; };
@ -27,8 +30,15 @@ enum swap_layer_id {
class WinEDA_SwapLayerFrame : public wxDialog class WinEDA_SwapLayerFrame : public wxDialog
{ {
private: private:
WinEDA_BasePcbFrame* m_Parent; WinEDA_BasePcbFrame* m_Parent;
wxRadioBox* m_LayerList; wxBoxSizer* OuterBoxSizer;
wxBoxSizer* MainBoxSizer;
wxFlexGridSizer* FlexColumnBoxSizer;
wxStaticText* label;
wxButton* Button;
wxStaticText* text;
wxStaticLine* Line;
wxStdDialogButtonSizer* StdDialogButtonSizer;
public: public:
@ -46,68 +56,180 @@ private:
/* Table des evenements pour WinEDA_SwapLayerFrame */ /* Table des evenements pour WinEDA_SwapLayerFrame */
BEGIN_EVENT_TABLE( WinEDA_SwapLayerFrame, wxDialog ) BEGIN_EVENT_TABLE( WinEDA_SwapLayerFrame, wxDialog )
EVT_BUTTON( wxID_OK, WinEDA_SwapLayerFrame::OnOkClick ) EVT_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + NB_LAYERS - 1,
EVT_BUTTON( wxID_CANCEL, WinEDA_SwapLayerFrame::OnCancelClick ) wxEVT_COMMAND_BUTTON_CLICKED,
EVT_BUTTON( ID_SWAP_LAYER_DESELECT, WinEDA_SwapLayerFrame::Sel_Layer ) WinEDA_SwapLayerFrame::Sel_Layer )
EVT_BUTTON( ID_SWAP_LAYER_BUTTON_SELECT, WinEDA_SwapLayerFrame::Sel_Layer ) EVT_BUTTON( wxID_OK, WinEDA_SwapLayerFrame::OnOkClick )
EVT_RADIOBOX( ID_SWAP_LAYER_SELECT, WinEDA_SwapLayerFrame::Sel_Layer ) EVT_BUTTON( wxID_CANCEL, WinEDA_SwapLayerFrame::OnCancelClick )
END_EVENT_TABLE() END_EVENT_TABLE()
/*************************************************************************/ /*************************************************************************/
WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame( WinEDA_BasePcbFrame* parent ) : WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame( WinEDA_BasePcbFrame* parent ) :
wxDialog( parent, -1, _( "Swap Layers:" ), wxPoint( -1, -1 ), wxDialog( parent, -1, _( "Swap Layers:" ), wxPoint( -1, -1 ),
wxSize( 470, 450 ), DIALOG_STYLE ) wxDefaultSize, wxDEFAULT_DIALOG_STYLE|MAYBE_RESIZE_BORDER )
/*************************************************************************/ /*************************************************************************/
{ {
#define START_Y 15 OuterBoxSizer = NULL;
wxButton* Button; MainBoxSizer = NULL;
int ii; FlexColumnBoxSizer = NULL;
wxPoint pos; label = NULL;
wxString g_Layer_Name_Pair[NB_LAYERS]; Button = NULL;
wxSize winsize; text = NULL;
Line = NULL;
StdDialogButtonSizer = NULL;
m_Parent = parent; m_Parent = parent;
SetFont( *g_DialogFont ); SetFont( *g_DialogFont );
for( ii = 0; ii < NB_LAYERS; ii++ ) int item_ID;
wxSize goodSize;
// Experimentation has shown that buttons in the Windows version can be 20 pixels
// wide and 20 pixels high, but that they need to be 26 pixels wide and 26 pixels
// high in the Linux version. (And although the dimensions of those buttons could
// be set to 26 pixels wide and 26 pixels high in both of those versions, that would
// result in a dialog box which would be excessively high in the Windows version.)
#ifdef __WINDOWS__
int w = 20;
int h = 20;
#else
int w = 26;
int h = 26;
#endif
// As currently implemented, the dimensions of the buttons in the Mac version are
// also 26 pixels wide and 26 pixels high. If appropriate, the above code should be
// modified as required in the event that those buttons should be some other size
// in that version.
OuterBoxSizer = new wxBoxSizer(wxVERTICAL);
SetSizer(OuterBoxSizer);
MainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
OuterBoxSizer->Add(MainBoxSizer, 1, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
for( int ii = 0; ii < NB_LAYERS; ii++ )
{ {
g_Layer_Name_Pair[ii] = ReturnPcbLayerName( ii ) + wxT( " -> " ) + _( "No Change" ); // Provide a vertical line to separate the two FlexGrid sizers
if( ii == 16 )
{
Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
MainBoxSizer->Add(Line, 0, wxGROW|wxLEFT|wxRIGHT, 5);
}
// Provide a separate FlexGrid sizer for every sixteen sets of controls
if( ii % 16 == 0 )
{
// Each layer has an associated static text string (to identify that layer),
// a button (for invoking a child dialog box to change which layer that the
// layer is mapped to), and a second static text string (to depict which layer
// that the layer has been mapped to). Each of those items are placed into
// the left hand column, middle column, and right hand column (respectively)
// of the Flexgrid sizer, and the color of the second text string is set to blue
// (to indicate that the actual text changes depending upon which layer has been
// selected by the child dialog box).
// (Experimentation has shown that if a text control is used to depict which
// layer that each layer is mapped to (instead of a static text string), then
// those controls do not behave in a fully satisfactory manner in the Linux
// version. Even when the read-only attribute is specified for all of those
// controls, they can still be selected when the arrow keys or Tab key is used
// to step through all of the controls within the dialog box, and directives
// to set the foreground color of the text of each such control to blue (to
// indicate that the text is of a read-only nature) are disregarded.)
// Specify a FlexGrid sizer with sixteen rows and three columns.
FlexColumnBoxSizer = new wxFlexGridSizer(16, 3, 0, 0);
// Specify that all of the rows can be expanded.
for( int jj = 0; jj < 16; jj++ )
{
FlexColumnBoxSizer->AddGrowableRow(jj);
}
// Specify that (just) the right-hand column can be expanded.
FlexColumnBoxSizer->AddGrowableCol(2);
MainBoxSizer->Add(FlexColumnBoxSizer, 1, wxGROW|wxTOP, 5);
}
// Provide a text string to identify this layer (with trailing spaces within that string being purged)
label = new wxStaticText( this, wxID_STATIC, ReturnPcbLayerName( ii ).Trim(), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
FlexColumnBoxSizer->Add(label, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
// Provide a button for this layer (which will invoke a child dialog box)
item_ID = ID_BUTTON_0 + ii;
Button = new wxButton( this, item_ID, wxT("..."), wxDefaultPosition, wxSize(w, h), 0 );
FlexColumnBoxSizer->Add(Button, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
// Provide another text string to specify which layer that this layer is
// mapped to, set the initial text to "No Change" (to indicate that this
// layer is currently unmapped to any other layer), and set the foreground
// color of the text to blue (to indicate that the text can be changed).
item_ID = ID_TEXT_0 + ii;
// When the first of these text strings is being added, determine what size is necessary to
// to be able to display any possible string without it being truncated. Then specify that
// size as the minimum size for all of these text strings. (If this minimum size is not
// determined in this fashion, then it is possible for the display of one or more of these
// strings to be truncated after different layers are selected.)
if( ii == 0 )
{
text = new wxStaticText( this, item_ID, ReturnPcbLayerName( 0 ), wxDefaultPosition, wxDefaultSize, 0 );
goodSize = text->GetSize();
for( int jj = 1; jj < NB_LAYERS; jj++ )
{
text->SetLabel( ReturnPcbLayerName( jj ) );
if( goodSize.x < text->GetSize().x )
goodSize.x = text->GetSize().x;
}
text->SetLabel( _("No Change") );
if( goodSize.x < text->GetSize().x )
goodSize.x = text->GetSize().x;
}
else
text = new wxStaticText( this, item_ID, _("No Change"), wxDefaultPosition, wxDefaultSize, 0 );
text->SetMinSize( goodSize );
text->SetForegroundColour( *wxBLUE );
FlexColumnBoxSizer->Add(text, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);
layer_list[ii] = text;
} }
pos.x = 5; // Provide spacers to occupy otherwise blank cells within the second FlexGrid sizer. (As it
pos.y = START_Y; // incorporates three columns, three spacers are thus required for each otherwise unused row.)
m_LayerList = new wxRadioBox( this, ID_SWAP_LAYER_SELECT, _( "Layers" ), for( int ii = 3 * NB_LAYERS; ii < 96; ii++ )
pos, wxSize( -1, -1 ), {
NB_LAYERS, g_Layer_Name_Pair, 16, wxRA_SPECIFY_ROWS ); FlexColumnBoxSizer->Add(5, h, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);
}
winsize.y = m_LayerList->GetRect().GetBottom(); // Provide a line to separate the controls which have been provided so far
// from the OK and Cancel buttons (which will be provided after this line)
Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
OuterBoxSizer->Add(Line, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
pos.x = m_LayerList->GetRect().GetRight() + 12; // Provide a StdDialogButtonSizer to accommodate the OK and Cancel buttons;
// using that type of sizer results in those buttons being automatically
// located in positions appropriate for each (OS) version of KiCad.
StdDialogButtonSizer = new wxStdDialogButtonSizer;
OuterBoxSizer->Add(StdDialogButtonSizer, 0, wxALIGN_RIGHT|wxALL, 10);
Button = new wxButton(this, ID_SWAP_LAYER_BUTTON_SELECT, _("Select..."), pos ); Button = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
Button->SetForegroundColour(wxColour(0,100,100)); Button->SetForegroundColour( *wxRED );
StdDialogButtonSizer->AddButton(Button);
pos.y += Button->GetSize().y + 10; Button = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
Button->SetForegroundColour( *wxBLUE );
StdDialogButtonSizer->AddButton(Button);
Button = new wxButton(this, ID_SWAP_LAYER_DESELECT, _("Deselect"), pos ); StdDialogButtonSizer->Realize();
Button->SetForegroundColour(wxColour(0,100,0));
pos.y = winsize.y - 2 * Button->GetSize().y - 10; // Resize the dialog
if( GetSizer() )
Button = new wxButton(this, wxID_OK, _("OK"), pos ); {
Button->SetForegroundColour(*wxRED); GetSizer()->SetSizeHints(this);
}
pos.y += Button->GetSize().y + 10;
Button = new wxButton(this, wxID_CANCEL, _("Cancel"), pos );
Button->SetForegroundColour(*wxBLUE);
winsize.x = MAX( winsize.x, Button->GetRect().GetRight() );
winsize.y = MAX( winsize.y, Button->GetRect().GetBottom() );
winsize.x += 10;
winsize.y += 10;
SetClientSize( winsize );
} }
@ -117,56 +239,40 @@ void WinEDA_SwapLayerFrame::Sel_Layer( wxCommandEvent& event )
{ {
int ii, jj; int ii, jj;
ii = m_LayerList->GetSelection(); ii = event.GetId();
switch( event.GetId() ) if( ii < ID_BUTTON_0 || ii >= ID_BUTTON_0 + NB_LAYERS )
return;
ii = event.GetId() - ID_BUTTON_0;
jj = New_Layer[ii];
if( (jj < 0) || (jj > NB_LAYERS) )
jj = NB_LAYERS; // (Defaults to "No Change".)
jj = m_Parent->SelectLayer( jj, -1, -1, true );
if( (jj < 0) || (jj > NB_LAYERS) )
return;
// No change if the selected layer matches the layer being edited.
// (Hence the only way to restore a layer to the "No Change"
// state is by specifically deselecting it; any attempt
// to select the same layer (instead) will be ignored.)
if( jj == ii )
{ {
case ID_SWAP_LAYER_DESELECT: wxString msg;
if( New_Layer[ii] != NB_LAYERS ) msg = _( "Deselect this layer to select the No Change state" );
{ DisplayInfo( this, msg );
New_Layer[ii] = NB_LAYERS; return;
m_LayerList->SetString( ii, ReturnPcbLayerName( ii ) }
+ wxT( " -> " ) + _( "No Change" ) );
}
break;
case ID_SWAP_LAYER_BUTTON_SELECT: if( jj != New_Layer[ii] )
case ID_SWAP_LAYER_SELECT: {
jj = New_Layer[ii]; New_Layer[ii] = jj;
if( (jj < 0) || (jj > NB_LAYERS) ) if( jj == NB_LAYERS )
jj = NB_LAYERS; // (Defaults to "No Change".) layer_list[ii]->SetLabel( _( "No Change" ) );
jj = m_Parent->SelectLayer( jj, -1, -1, true ); else
layer_list[ii]->SetLabel( ReturnPcbLayerName( jj ) );
if( (jj < 0) || (jj > NB_LAYERS) )
return;
// No change if the selected layer matches the layer being edited.
// (Hence the only way to restore a layer to the "No Change"
// state is by specifically deselecting it; any attempt
// to select the same layer (instead) will be ignored.)
if( jj == ii )
{
wxString msg;
msg = _( "Deselect this layer to restore its No Change state" );
DisplayInfo( this, msg );
return;
}
if( jj != New_Layer[ii] )
{
New_Layer[ii] = jj;
if( jj == NB_LAYERS )
m_LayerList->SetString( ii,
ReturnPcbLayerName( ii )
+ wxT( " -> " )
+ _( "No Change" ) );
else
m_LayerList->SetString( ii,
ReturnPcbLayerName( ii )
+ wxT( " -> " )
+ ReturnPcbLayerName( jj ) );
}
break;
} }
} }