Commit b30b24c5 authored by g_harland's avatar g_harland
Browse files

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

parent 335fa148
Loading
Loading
Loading
Loading
+24 −0
Original line number Original line Diff line number Diff line
@@ -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
+284 −195
Original line number Original line Diff line number Diff line
@@ -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
};
};




@@ -30,7 +32,14 @@ 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:


@@ -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_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + NB_LAYERS - 1,
                       wxEVT_COMMAND_BUTTON_CLICKED,
                       WinEDA_SwapLayerFrame::Sel_Layer )
    EVT_BUTTON( wxID_OK, WinEDA_SwapLayerFrame::OnOkClick )
    EVT_BUTTON( wxID_OK, WinEDA_SwapLayerFrame::OnOkClick )
    EVT_BUTTON( wxID_CANCEL, WinEDA_SwapLayerFrame::OnCancelClick )
    EVT_BUTTON( wxID_CANCEL, WinEDA_SwapLayerFrame::OnCancelClick )
    EVT_BUTTON(ID_SWAP_LAYER_DESELECT, WinEDA_SwapLayerFrame::Sel_Layer)
    EVT_BUTTON(ID_SWAP_LAYER_BUTTON_SELECT, WinEDA_SwapLayerFrame::Sel_Layer)
    EVT_RADIOBOX(ID_SWAP_LAYER_SELECT, WinEDA_SwapLayerFrame::Sel_Layer)
END_EVENT_TABLE()
END_EVENT_TABLE()




@@ -78,16 +86,42 @@ int * InstallDialogLayerPairChoice(WinEDA_GerberFrame * parent)
/*************************************************************************/
/*************************************************************************/
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 );


    int item_ID, ii, nb_items;
    wxString msg;
    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.

    // Compute a reasonable number of copper layers
    // Compute a reasonable number of copper layers
    g_DesignSettings.m_CopperLayerCount = 0;
    g_DesignSettings.m_CopperLayerCount = 0;
    for( ii = 0; ii < 32; ii++ )
    for( ii = 0; ii < 32; ii++ )
@@ -96,13 +130,14 @@ wxString g_Layer_Name_Pair[32];
            g_DesignSettings.m_CopperLayerCount++;
            g_DesignSettings.m_CopperLayerCount++;


        // Specify the default value for each member of these arrays.
        // Specify the default value for each member of these arrays.
		RadioButtonTable[ii] = -1;
        ButtonTable[ii] = -1;
        LayerLookUpTable[ii] = NB_LAYERS; // Value associated with deselected Gerber layer
        LayerLookUpTable[ii] = NB_LAYERS; // Value associated with deselected Gerber layer
    }
    }


    int pcb_layer_number = 0;
    int pcb_layer_number = 0;
    for( nb_items = 0, ii = 0; ii < 32; ii++ )
    for( nb_items = 0, ii = 0; ii < 32; ii++ )
    {
    {

        if( g_GERBER_Descr_List[ii] == NULL )
        if( g_GERBER_Descr_List[ii] == NULL )
            continue;
            continue;


@@ -110,84 +145,156 @@ wxString g_Layer_Name_Pair[32];
         && (g_DesignSettings.m_CopperLayerCount > 1) )
         && (g_DesignSettings.m_CopperLayerCount > 1) )
            pcb_layer_number = CMP_N;
            pcb_layer_number = CMP_N;


		RadioButtonTable[nb_items] = ii;
        ButtonTable[nb_items] = ii;
        LayerLookUpTable[ii] = pcb_layer_number;
        LayerLookUpTable[ii] = pcb_layer_number;

		// Specify initial (temporary) caption for associated radiobutton,
		// which will be appropriately updated after dialog box has been sized.
		// (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++;
        nb_items++;
        pcb_layer_number++;
        pcb_layer_number++;
    }
    }


    wxBoxSizer* FrameBoxSizer = new wxBoxSizer(wxVERTICAL);
    OuterBoxSizer = new wxBoxSizer(wxVERTICAL);
    SetSizer(FrameBoxSizer);
    SetSizer(OuterBoxSizer);

    MainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
    OuterBoxSizer->Add(MainBoxSizer, 1, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);


    wxBoxSizer* MainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
    for( ii = 0; ii < nb_items; ii++ )
    FrameBoxSizer->Add(MainBoxSizer, 0, wxGROW|wxALIGN_LEFT|wxALL, 5);
    {
        // If more than 16 Gerber layers are used, provide a vertical line to
        // 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);
        }


	m_LayerList = new wxRadioBox(this, ID_SWAP_LAYER_SELECT, _("Layers"),
        // Provide a separate FlexGrid sizer for every sixteen sets of controls
			wxDefaultPosition, wxDefaultSize,
        if( ii % 16 == 0 )
			nb_items, g_Layer_Name_Pair,
        {
			nb_items < 16 ? nb_items : 16,
            // Each Gerber layer has an associated static text string (to identify that layer),
			wxRA_SPECIFY_ROWS);
            // 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.)

            // 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 a minimum size for this radiobox (with the objective
            // Specify that all of the rows can be expanded.
    // of attempting to prevent any radiobutton's caption from being
            for( int jj = 0; jj < MIN(nb_items, 16); jj++ )
    // truncated if any of the layers are subsequently deselected)
            {
    m_LayerList->SetMinSize( m_LayerList->GetSize() );
                FlexColumnBoxSizer->AddGrowableRow(jj);
            }


    MainBoxSizer->Add(m_LayerList, 0, wxALIGN_TOP|wxALL, 5);
            // Specify that (just) the right-hand column can be expanded.
            FlexColumnBoxSizer->AddGrowableCol(2);


    wxBoxSizer* RightBoxSizer = new wxBoxSizer(wxVERTICAL);
            MainBoxSizer->Add(FlexColumnBoxSizer, 1, wxGROW|wxTOP, 5);
    MainBoxSizer->Add(RightBoxSizer, 0, wxALIGN_TOP|wxALL, 0);
        }


	RightBoxSizer->AddSpacer(10);
        // Provide a text string to identify the Gerber layer
        msg = _("Gerber layer ");
        msg << ButtonTable[ii] + 1;


	Button = new wxButton(this, ID_SWAP_LAYER_BUTTON_SELECT, _("Select..."));
        label = new wxStaticText( this, wxID_STATIC, msg, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
	Button->SetForegroundColour(wxColour(0,100,100));
        FlexColumnBoxSizer->Add(label, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
    RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);


	Button = new wxButton(this, ID_SWAP_LAYER_DESELECT, _("Deselect"));
        // Provide a button for this layer (which will invoke a child dialog box)
	Button->SetForegroundColour(wxColour(0,100,0));
        item_ID = ID_BUTTON_0 + ii;
    RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);


    wxBoxSizer* BottomBoxSizer = new wxBoxSizer(wxHORIZONTAL);
        Button = new wxButton( this, item_ID, wxT("..."), wxDefaultPosition, wxSize(w, h), 0 );
    FrameBoxSizer->Add(BottomBoxSizer, 0, wxGROW|wxALIGN_RIGHT|wxALL, 5);
        FlexColumnBoxSizer->Add(Button, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);


	// The following stretch spacer ensures that the "OK" and "Cancel" buttons
        // Provide another text string to specify which pcbnew layer that this
    // will be positioned at the lower right corner of the dialog box.
        // Gerber layer is initially mapped to, and set the initial text to
	BottomBoxSizer->AddStretchSpacer();
        // 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;


	Button = new wxButton(this, wxID_OK, _("OK"));
        // 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 );
    Button->SetForegroundColour( *wxRED );
    BottomBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);
    StdDialogButtonSizer->AddButton(Button);


	Button = new wxButton(this, wxID_CANCEL, _("Cancel"));
    Button = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
    Button->SetForegroundColour( *wxBLUE );
    Button->SetForegroundColour( *wxBLUE );
    BottomBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);
    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] );
	}
}
}




@@ -196,47 +303,29 @@ 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 )

    if( ii < ID_BUTTON_0 || ii >= ID_BUTTON_0 + 32 )
        return;
        return;


	switch ( event.GetId() )
    ii = event.GetId() - ID_BUTTON_0;
	{
	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:
    jj = LayerLookUpTable[ButtonTable[ii]];
	case ID_SWAP_LAYER_SELECT:
		jj = LayerLookUpTable[RadioButtonTable[ii]];
    if( (jj < 0) || (jj > NB_LAYERS) )
    if( (jj < 0) || (jj > NB_LAYERS) )
        jj = 0; // (Defaults to "Copper" layer.)
        jj = 0; // (Defaults to "Copper" layer.)
    jj = m_Parent->SelectLayer(jj, -1, -1, true);
    jj = m_Parent->SelectLayer(jj, -1, -1, true);

    if( (jj < 0) || (jj > NB_LAYERS) )
    if( (jj < 0) || (jj > NB_LAYERS) )
        return;
        return;


		if( jj != LayerLookUpTable[RadioButtonTable[ii]] )
    if( jj != LayerLookUpTable[ButtonTable[ii]] )
    {
    {
			LayerLookUpTable[RadioButtonTable[ii]] = jj;
        LayerLookUpTable[ButtonTable[ii]] = jj;
			msg = _("Gerber layer ");
			msg << RadioButtonTable[ii] + 1 << wxT(" -> ");
        if( jj == NB_LAYERS )
        if( jj == NB_LAYERS )
                msg << _("Do not export");
            layer_list[ii]->SetLabel( _( "Do not export" ) );
        else
        else
                msg << ReturnPcbLayerName(jj);
            layer_list[ii]->SetLabel( ReturnPcbLayerName( jj ) );
			m_LayerList->SetString( ii, msg );
		}
		break;
    }
    }
}
}