Commit b30b24c5 authored by g_harland's avatar g_harland

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

parent 335fa148
...@@ -4,6 +4,30 @@ Started 2007-June-11 ...@@ -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
......
/*******************************************************/ /*******************************************************/
/* 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 @@ ...@@ -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 { ...@@ -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: ...@@ -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) ...@@ -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;
m_Parent = parent; Button = NULL;
SetFont(*g_DialogFont); text = NULL;
Line = NULL;
// Compute a reasonable number of copper layers StdDialogButtonSizer = NULL;
g_DesignSettings.m_CopperLayerCount = 0;
for( ii = 0; ii < 32; ii++ ) m_Parent = parent;
{ SetFont( *g_DialogFont );
if( g_GERBER_Descr_List[ii] != NULL )
g_DesignSettings.m_CopperLayerCount++; int item_ID, ii, nb_items;
wxString msg;
// Specify the default value for each member of these arrays. wxSize goodSize;
RadioButtonTable[ii] = -1;
LayerLookUpTable[ii] = NB_LAYERS; // Value associated with deselected Gerber layer // 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
int pcb_layer_number = 0; // be set to 26 pixels wide and 26 pixels high in both of those versions, that would
for( nb_items = 0, ii = 0; ii < 32; ii++ ) // result in a dialog box which would be excessively high in the Windows version.)
{ #ifdef __WINDOWS__
if( g_GERBER_Descr_List[ii] == NULL ) int w = 20;
continue; int h = 20;
#else
if( (pcb_layer_number == g_DesignSettings.m_CopperLayerCount - 1) int w = 26;
&& (g_DesignSettings.m_CopperLayerCount > 1) ) int h = 26;
pcb_layer_number = CMP_N; #endif
// As currently implemented, the dimensions of the buttons in the Mac version are
RadioButtonTable[nb_items] = ii; // also 26 pixels wide and 26 pixels high. If appropriate, the above code should be
LayerLookUpTable[ii] = pcb_layer_number; // modified as required in the event that those buttons should be some other size
// in that version.
// Specify initial (temporary) caption for associated radiobutton,
// which will be appropriately updated after dialog box has been sized. // Compute a reasonable number of copper layers
// (If the radiobuttons' captions are not changed in this way, some of g_DesignSettings.m_CopperLayerCount = 0;
// each radiobutton's caption could be truncated if the associated for( ii = 0; ii < 32; ii++ )
// (Gerber) layer is ever subsequently deselected by the user.) {
g_Layer_Name_Pair[nb_items] = _("Gerber layer "); if( g_GERBER_Descr_List[ii] != NULL )
g_Layer_Name_Pair[nb_items] << ii + 1 << wxT(" -> ") << _("Do not export"); g_DesignSettings.m_CopperLayerCount++;
nb_items++; // Specify the default value for each member of these arrays.
pcb_layer_number++; ButtonTable[ii] = -1;
} LayerLookUpTable[ii] = NB_LAYERS; // Value associated with deselected Gerber layer
}
wxBoxSizer* FrameBoxSizer = new wxBoxSizer(wxVERTICAL);
SetSizer(FrameBoxSizer); int pcb_layer_number = 0;
for( nb_items = 0, ii = 0; ii < 32; ii++ )
wxBoxSizer* MainBoxSizer = new wxBoxSizer(wxHORIZONTAL); {
FrameBoxSizer->Add(MainBoxSizer, 0, wxGROW|wxALIGN_LEFT|wxALL, 5);
if( g_GERBER_Descr_List[ii] == NULL )
m_LayerList = new wxRadioBox(this, ID_SWAP_LAYER_SELECT, _("Layers"), continue;
wxDefaultPosition, wxDefaultSize,
nb_items, g_Layer_Name_Pair, if( (pcb_layer_number == g_DesignSettings.m_CopperLayerCount - 1)
nb_items < 16 ? nb_items : 16, && (g_DesignSettings.m_CopperLayerCount > 1) )
wxRA_SPECIFY_ROWS); pcb_layer_number = CMP_N;
// Specify a minimum size for this radiobox (with the objective ButtonTable[nb_items] = ii;
// of attempting to prevent any radiobutton's caption from being LayerLookUpTable[ii] = pcb_layer_number;
// truncated if any of the layers are subsequently deselected) nb_items++;
m_LayerList->SetMinSize( m_LayerList->GetSize() ); pcb_layer_number++;
}
MainBoxSizer->Add(m_LayerList, 0, wxALIGN_TOP|wxALL, 5);
OuterBoxSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* RightBoxSizer = new wxBoxSizer(wxVERTICAL); SetSizer(OuterBoxSizer);
MainBoxSizer->Add(RightBoxSizer, 0, wxALIGN_TOP|wxALL, 0);
MainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
RightBoxSizer->AddSpacer(10); OuterBoxSizer->Add(MainBoxSizer, 1, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
Button = new wxButton(this, ID_SWAP_LAYER_BUTTON_SELECT, _("Select...")); for( ii = 0; ii < nb_items; ii++ )
Button->SetForegroundColour(wxColour(0,100,100)); {
RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5); // If more than 16 Gerber layers are used, provide a vertical line to
// separate the two FlexGrid sizers
Button = new wxButton(this, ID_SWAP_LAYER_DESELECT, _("Deselect")); if( (nb_items > 16) && (ii == 16) )
Button->SetForegroundColour(wxColour(0,100,0)); {
RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5); Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
MainBoxSizer->Add(Line, 0, wxGROW|wxLEFT|wxRIGHT, 5);
wxBoxSizer* BottomBoxSizer = new wxBoxSizer(wxHORIZONTAL); }
FrameBoxSizer->Add(BottomBoxSizer, 0, wxGROW|wxALIGN_RIGHT|wxALL, 5);
// Provide a separate FlexGrid sizer for every sixteen sets of controls
// The following stretch spacer ensures that the "OK" and "Cancel" buttons if( ii % 16 == 0 )
// will be positioned at the lower right corner of the dialog box. {
BottomBoxSizer->AddStretchSpacer(); // 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
Button = new wxButton(this, wxID_OK, _("OK")); // Gerber layer is mapped to), and a second static text string (to depict which
Button->SetForegroundColour(*wxRED); // pcbnew layer that the Gerber layer has been mapped to). Each of those items are
BottomBoxSizer->Add(Button, 0, wxGROW|wxALL, 5); // 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
Button = new wxButton(this, wxID_CANCEL, _("Cancel")); // is set to blue (to indicate that the actual text changes depending upon which
Button->SetForegroundColour(*wxBLUE); // pcbnew layer has been selected by the child dialog box).
BottomBoxSizer->Add(Button, 0, wxGROW|wxALL, 5); // (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.)
// Specify a FlexGrid sizer with an appropriate number of rows and three columns.
// 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).
if( nb_items < 16 )
FlexColumnBoxSizer = new wxFlexGridSizer(nb_items, 3, 0, 0);
else
FlexColumnBoxSizer = new wxFlexGridSizer(16, 3, 0, 0);
// Specify that all of the rows can be expanded.
for( int jj = 0; jj < MIN(nb_items, 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 the Gerber layer
msg = _("Gerber layer ");
msg << ButtonTable[ii] + 1;
label = new wxStaticText( this, wxID_STATIC, msg, 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 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]; ...@@ -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 = event.GetId();
ii = m_LayerList->GetSelection(); if( ii < ID_BUTTON_0 || ii >= ID_BUTTON_0 + 32 )
if( ii < 0 ) return;
return;
ii = event.GetId() - ID_BUTTON_0;
switch ( event.GetId() )
{ jj = LayerLookUpTable[ButtonTable[ii]];
case ID_SWAP_LAYER_DESELECT: if( (jj < 0) || (jj > NB_LAYERS) )
if( LayerLookUpTable[RadioButtonTable[ii]] != NB_LAYERS ) jj = 0; // (Defaults to "Copper" layer.)
{ jj = m_Parent->SelectLayer(jj, -1, -1, true);
LayerLookUpTable[RadioButtonTable[ii]] = NB_LAYERS;
msg = _("Gerber layer "); if( (jj < 0) || (jj > NB_LAYERS) )
msg << RadioButtonTable[ii] + 1 return;
<< wxT(" -> ") << _("Do not export");
m_LayerList->SetString( ii, msg ); if( jj != LayerLookUpTable[ButtonTable[ii]] )
} {
break; LayerLookUpTable[ButtonTable[ii]] = jj;
if( jj == NB_LAYERS )
case ID_SWAP_LAYER_BUTTON_SELECT: layer_list[ii]->SetLabel( _( "Do not export" ) );
case ID_SWAP_LAYER_SELECT: else
jj = LayerLookUpTable[RadioButtonTable[ii]]; layer_list[ii]->SetLabel( ReturnPcbLayerName( jj ) );
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]] )
{
LayerLookUpTable[RadioButtonTable[ii]] = jj;
msg = _("Gerber layer ");
msg << RadioButtonTable[ii] + 1 << wxT(" -> ");
if( jj == NB_LAYERS )
msg << _("Do not export");
else
msg << ReturnPcbLayerName(jj);
m_LayerList->SetString( ii, msg );
}
break;
}
} }
...@@ -256,27 +345,27 @@ void WinEDA_SwapLayerFrame::OnOkClick(wxCommandEvent& event) ...@@ -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 );
} }
...@@ -10,13 +10,16 @@ ...@@ -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 { ...@@ -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: ...@@ -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);
}
pos.x = 5; // Provide a text string to identify this layer (with trailing spaces within that string being purged)
pos.y = START_Y; label = new wxStaticText( this, wxID_STATIC, ReturnPcbLayerName( ii ).Trim(), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
m_LayerList = new wxRadioBox( this, ID_SWAP_LAYER_SELECT, _( "Layers" ), FlexColumnBoxSizer->Add(label, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
pos, wxSize( -1, -1 ),
NB_LAYERS, g_Layer_Name_Pair, 16, wxRA_SPECIFY_ROWS );
winsize.y = m_LayerList->GetRect().GetBottom(); // Provide a button for this layer (which will invoke a child dialog box)
item_ID = ID_BUTTON_0 + ii;
pos.x = m_LayerList->GetRect().GetRight() + 12; Button = new wxButton( this, item_ID, wxT("..."), wxDefaultPosition, wxSize(w, h), 0 );
FlexColumnBoxSizer->Add(Button, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
Button = new wxButton(this, ID_SWAP_LAYER_BUTTON_SELECT, _("Select..."), pos ); // Provide another text string to specify which layer that this layer is
Button->SetForegroundColour(wxColour(0,100,100)); // 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;
pos.y += Button->GetSize().y + 10; // 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);
Button = new wxButton(this, ID_SWAP_LAYER_DESELECT, _("Deselect"), pos ); layer_list[ii] = text;
Button->SetForegroundColour(wxColour(0,100,0)); }
// 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.)
for( int ii = 3 * NB_LAYERS; ii < 96; ii++ )
{
FlexColumnBoxSizer->Add(5, h, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);
}
pos.y = winsize.y - 2 * Button->GetSize().y - 10; // 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);
Button = new wxButton(this, wxID_OK, _("OK"), pos ); // Provide a StdDialogButtonSizer to accommodate the OK and Cancel buttons;
Button->SetForegroundColour(*wxRED); // 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);
pos.y += Button->GetSize().y + 10; Button = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
Button->SetForegroundColour( *wxRED );
StdDialogButtonSizer->AddButton(Button);
Button = new wxButton(this, wxID_CANCEL, _("Cancel"), pos ); Button = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
Button->SetForegroundColour(*wxBLUE); Button->SetForegroundColour( *wxBLUE );
StdDialogButtonSizer->AddButton(Button);
winsize.x = MAX( winsize.x, Button->GetRect().GetRight() ); StdDialogButtonSizer->Realize();
winsize.y = MAX( winsize.y, Button->GetRect().GetBottom() );
winsize.x += 10; // Resize the dialog
winsize.y += 10; if( GetSizer() )
SetClientSize( winsize ); {
GetSizer()->SetSizeHints(this);
}
} }
...@@ -117,56 +239,40 @@ void WinEDA_SwapLayerFrame::Sel_Layer( wxCommandEvent& event ) ...@@ -117,56 +239,40 @@ void WinEDA_SwapLayerFrame::Sel_Layer( wxCommandEvent& event )
{ {
int ii, jj; int ii, jj;
ii = m_LayerList->GetSelection(); ii = event.GetId();
if( ii < ID_BUTTON_0 || ii >= ID_BUTTON_0 + NB_LAYERS )
return;
switch( event.GetId() ) 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:
case ID_SWAP_LAYER_SELECT:
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 )
{
wxString msg;
msg = _( "Deselect this layer to restore its No Change state" );
DisplayInfo( this, msg );
return;
}
if( jj != New_Layer[ii] ) if( jj != New_Layer[ii] )
{ {
New_Layer[ii] = jj; New_Layer[ii] = jj;
if( jj == NB_LAYERS ) if( jj == NB_LAYERS )
m_LayerList->SetString( ii, layer_list[ii]->SetLabel( _( "No Change" ) );
ReturnPcbLayerName( ii ) else
+ wxT( " -> " ) layer_list[ii]->SetLabel( ReturnPcbLayerName( jj ) );
+ _( "No Change" ) );
else
m_LayerList->SetString( ii,
ReturnPcbLayerName( ii )
+ wxT( " -> " )
+ ReturnPcbLayerName( jj ) );
}
break;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment