diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 3edab082b4..275c416e68 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -826,13 +826,42 @@ void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent ) void PCB_EDIT_FRAME::OnSelectAutoPlaceMode( wxCommandEvent& aEvent ) { - if( aEvent.IsChecked() ) + // Automatic placement of modules and tracks is a mutually exclusive operation so + // clear the other tool if one of the two is selected. + // Be careful: this event function is called both by the + // ID_TOOLBARH_PCB_MODE_MODULE and the ID_TOOLBARH_PCB_MODE_TRACKS tool + // Therefore we should avoid a race condition when deselecting one of these tools + // inside this function (seems happen on some Linux/wxWidgets versions) + // when the other tool is selected + + int previous_state = m_autoPlaceModeId; + switch( aEvent.GetId() ) { - m_autoPlaceModeId = aEvent.GetId(); - } - else - { - m_autoPlaceModeId = 0; - } + case ID_TOOLBARH_PCB_MODE_MODULE: + if( aEvent.IsChecked() ) + { + m_autoPlaceModeId = ID_TOOLBARH_PCB_MODE_MODULE; + + if( previous_state == ID_TOOLBARH_PCB_MODE_TRACKS ) + m_mainToolBar->ToggleTool( ID_TOOLBARH_PCB_MODE_TRACKS, false ); + } + else if( m_autoPlaceModeId == ID_TOOLBARH_PCB_MODE_MODULE ) + // Deselect m_autoPlaceModeId only if it was selected by this tool + m_autoPlaceModeId = 0; + break; + + case ID_TOOLBARH_PCB_MODE_TRACKS: + if( aEvent.IsChecked() ) + { + m_autoPlaceModeId = ID_TOOLBARH_PCB_MODE_TRACKS; + + if( previous_state == ID_TOOLBARH_PCB_MODE_MODULE ) + m_mainToolBar->ToggleTool( ID_TOOLBARH_PCB_MODE_MODULE, false ); + } + else if( m_autoPlaceModeId == ID_TOOLBARH_PCB_MODE_TRACKS ) + // Deselect m_autoPlaceModeId only if it was selected by this tool + m_autoPlaceModeId = 0; + break; + } } diff --git a/pcbnew/tool_pcb.cpp b/pcbnew/tool_pcb.cpp index 27714cf1de..cfc9aa8916 100644 --- a/pcbnew/tool_pcb.cpp +++ b/pcbnew/tool_pcb.cpp @@ -59,7 +59,9 @@ /* Data to build the layer pair indicator button */ static wxBitmap* LayerPairBitmap = NULL; -static const char s_BitmapLayerIcon[24][24] = { +#define BM_LAYERICON_SIZE 24 +static const char s_BitmapLayerIcon[BM_LAYERICON_SIZE][BM_LAYERICON_SIZE] = +{ // 0 = draw pixel with active layer color // 1 = draw pixel with top layer color (top/bottom layer used inautoroute and place via) // 2 = draw pixel with bottom layer color @@ -155,9 +157,9 @@ void PCB_EDIT_FRAME::PrepareLayerIndicator() wxPen pen; int buttonColor = -1; - for( ii = 0; ii < 24; ii++ ) + for( ii = 0; ii < BM_LAYERICON_SIZE; ii++ ) { - for( jj = 0; jj < 24; jj++ ) + for( jj = 0; jj < BM_LAYERICON_SIZE; jj++ ) { if( s_BitmapLayerIcon[ii][jj] != buttonColor ) { @@ -305,7 +307,7 @@ void PCB_EDIT_FRAME::ReCreateHToolbar() m_mainToolBar->AddTool( ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, wxEmptyString, KiBitmap( book_xpm ), _( "Show/Hide the Scripting console" ) ); - + m_mainToolBar->AddSeparator(); #endif // after adding the buttons to the toolbar, must call Realize() to reflect the changes diff --git a/pcbnew/toolbars_update_user_interface.cpp b/pcbnew/toolbars_update_user_interface.cpp index 48589f9da2..6b37dfd5aa 100644 --- a/pcbnew/toolbars_update_user_interface.cpp +++ b/pcbnew/toolbars_update_user_interface.cpp @@ -206,15 +206,25 @@ void PCB_EDIT_FRAME::OnUpdateVerticalToolbar( wxUpdateUIEvent& aEvent ) void PCB_EDIT_FRAME::OnUpdateAutoPlaceTracksMode( wxUpdateUIEvent& aEvent ) { - // Automatic placement of modules and tracks is a mutually exclusive operation so - // clear the other tool if one of the two is selected. - aEvent.Check( m_autoPlaceModeId == ID_TOOLBARH_PCB_MODE_TRACKS ); + // Automatic placement of modules and tracks is a mutually exclusive operation + // So this tool is activated only if + // m_autoPlaceModeId == ID_TOOLBARH_PCB_MODE_TRACKS. + // To avoid creating erroneous events (seems happen on some Linux/wxWidgets versions) + // the tool state is changed only when it is incorrect + bool state = m_autoPlaceModeId == ID_TOOLBARH_PCB_MODE_TRACKS; + if( aEvent.IsChecked() != state ) + aEvent.Check( state ); } void PCB_EDIT_FRAME::OnUpdateAutoPlaceModulesMode( wxUpdateUIEvent& aEvent ) { - // Automatic placement of modules and tracks is a mutually exclusive operation so - // clear the other tool if one of the two is selected. - aEvent.Check( m_autoPlaceModeId == ID_TOOLBARH_PCB_MODE_MODULE ); + // Automatic placement of modules and tracks is a mutually exclusive operation, + // So this tool is activated only if + // m_autoPlaceModeId == ID_TOOLBARH_PCB_MODE_MODULE. + // To avoid creating erroneous events (seems happen on some Linux/wxWidgets versions) + // the tool state is changed only when it is incorrect + bool state = m_autoPlaceModeId == ID_TOOLBARH_PCB_MODE_MODULE; + if( aEvent.IsChecked() != state ) + aEvent.Check( state ); }