From 52bc2511cd8357f6fca9d91eb15879f3782eb3db Mon Sep 17 00:00:00 2001
From: Jeff Young <jeff@rokeby.ie>
Date: Sun, 12 Jun 2022 20:09:21 +0100
Subject: [PATCH] Add a radioButton mode to IMAGE_BUTTON.

Fixes https://gitlab.com/kicad/code/kicad/issues/11797
---
 common/widgets/bitmap_button.cpp                 | 11 ++++++++++-
 eeschema/dialogs/dialog_field_properties.cpp     | 16 ++++++++--------
 eeschema/dialogs/dialog_label_properties.cpp     |  8 ++++----
 eeschema/dialogs/dialog_lib_text_properties.cpp  | 16 ++++++++--------
 .../dialogs/dialog_lib_textbox_properties.cpp    | 12 ++++++------
 eeschema/dialogs/dialog_text_properties.cpp      | 12 ++++++------
 include/widgets/bitmap_button.h                  |  3 +++
 pagelayout_editor/dialogs/properties_frame.cpp   | 12 ++++++------
 pcbnew/dialogs/dialog_dimension_properties.cpp   |  6 +++---
 pcbnew/dialogs/dialog_text_properties.cpp        |  6 +++---
 pcbnew/dialogs/dialog_textbox_properties.cpp     |  6 +++---
 11 files changed, 60 insertions(+), 48 deletions(-)

diff --git a/common/widgets/bitmap_button.cpp b/common/widgets/bitmap_button.cpp
index c58d9df420..26f14c814c 100644
--- a/common/widgets/bitmap_button.cpp
+++ b/common/widgets/bitmap_button.cpp
@@ -35,6 +35,7 @@
 BITMAP_BUTTON::BITMAP_BUTTON( wxWindow* aParent, wxWindowID aId, const wxPoint& aPos,
                               const wxSize& aSize, int aStyles ) :
         wxPanel( aParent, aId, aPos, aSize, aStyles ),
+        m_isRadioButton( false ),
         m_buttonState( 0 ),
         m_padding( 0 ),
         m_acceptDraggedInClicks( false )
@@ -49,6 +50,7 @@ BITMAP_BUTTON::BITMAP_BUTTON( wxWindow* aParent, wxWindowID aId, const wxPoint&
 BITMAP_BUTTON::BITMAP_BUTTON( wxWindow* aParent, wxWindowID aId, const wxBitmap& aDummyBitmap,
                               const wxPoint& aPos, const wxSize& aSize, int aStyles ) :
         wxPanel( aParent, aId, aPos, aSize, aStyles ),
+        m_isRadioButton( false ),
         m_buttonState( 0 ),
         m_padding( 5 ),
         m_acceptDraggedInClicks( false )
@@ -165,7 +167,7 @@ void BITMAP_BUTTON::OnLeftButtonDown( wxMouseEvent& aEvent )
 {
     if( hasFlag( wxCONTROL_CHECKABLE ) )
     {
-        if( hasFlag( wxCONTROL_CHECKED ) )
+        if( hasFlag( wxCONTROL_CHECKED ) && !m_isRadioButton )
         {
             clearFlag( wxCONTROL_CHECKED );
 
@@ -280,6 +282,13 @@ void BITMAP_BUTTON::SetIsCheckButton()
 }
 
 
+void BITMAP_BUTTON::SetIsRadioButton()
+{
+    setFlag( wxCONTROL_CHECKABLE );
+    m_isRadioButton = true;
+}
+
+
 void BITMAP_BUTTON::SetIsSeparator()
 {
     setFlag( wxCONTROL_SEPARATOR | wxCONTROL_DISABLED );
diff --git a/eeschema/dialogs/dialog_field_properties.cpp b/eeschema/dialogs/dialog_field_properties.cpp
index f3b0c02072..8ffd584350 100644
--- a/eeschema/dialogs/dialog_field_properties.cpp
+++ b/eeschema/dialogs/dialog_field_properties.cpp
@@ -80,9 +80,9 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
 
     m_separator1->SetIsSeparator();
 
-    m_horizontal->SetIsCheckButton();
+    m_horizontal->SetIsRadioButton();
     m_horizontal->SetBitmap( KiBitmap( BITMAPS::text_horizontal ) );
-    m_vertical->SetIsCheckButton();
+    m_vertical->SetIsRadioButton();
     m_vertical->SetBitmap( KiBitmap( BITMAPS::text_vertical ) );
 
     m_separator2->SetIsSeparator();
@@ -94,20 +94,20 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
 
     m_separator3->SetIsSeparator();
 
-    m_hAlignLeft->SetIsCheckButton();
+    m_hAlignLeft->SetIsRadioButton();
     m_hAlignLeft->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
-    m_hAlignCenter->SetIsCheckButton();
+    m_hAlignCenter->SetIsRadioButton();
     m_hAlignCenter->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
-    m_hAlignRight->SetIsCheckButton();
+    m_hAlignRight->SetIsRadioButton();
     m_hAlignRight->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
 
     m_separator4->SetIsSeparator();
 
-    m_vAlignTop->SetIsCheckButton();
+    m_vAlignTop->SetIsRadioButton();
     m_vAlignTop->SetBitmap( KiBitmap( BITMAPS::text_valign_top ) );
-    m_vAlignCenter->SetIsCheckButton();
+    m_vAlignCenter->SetIsRadioButton();
     m_vAlignCenter->SetBitmap( KiBitmap( BITMAPS::text_valign_center ) );
-    m_vAlignBottom->SetIsCheckButton();
+    m_vAlignBottom->SetIsRadioButton();
     m_vAlignBottom->SetBitmap( KiBitmap( BITMAPS::text_valign_bottom ) );
 
     m_separator5->SetIsSeparator();
diff --git a/eeschema/dialogs/dialog_label_properties.cpp b/eeschema/dialogs/dialog_label_properties.cpp
index 8d07f06f83..3ff6010ab8 100644
--- a/eeschema/dialogs/dialog_label_properties.cpp
+++ b/eeschema/dialogs/dialog_label_properties.cpp
@@ -139,10 +139,10 @@ DIALOG_LABEL_PROPERTIES::DIALOG_LABEL_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_L
 
     m_separator2->SetIsSeparator();
 
-    m_spin0->SetIsCheckButton();
-    m_spin1->SetIsCheckButton();
-    m_spin2->SetIsCheckButton();
-    m_spin3->SetIsCheckButton();
+    m_spin0->SetIsRadioButton();
+    m_spin1->SetIsRadioButton();
+    m_spin2->SetIsRadioButton();
+    m_spin3->SetIsRadioButton();
 
     m_separator3->SetIsSeparator();
 
diff --git a/eeschema/dialogs/dialog_lib_text_properties.cpp b/eeschema/dialogs/dialog_lib_text_properties.cpp
index 1f7e5f52c4..264f06327c 100644
--- a/eeschema/dialogs/dialog_lib_text_properties.cpp
+++ b/eeschema/dialogs/dialog_lib_text_properties.cpp
@@ -54,9 +54,9 @@ DIALOG_LIB_TEXT_PROPERTIES::DIALOG_LIB_TEXT_PROPERTIES( SYMBOL_EDIT_FRAME* aPare
 
     m_separator1->SetIsSeparator();
 
-    m_horizontal->SetIsCheckButton();
+    m_horizontal->SetIsRadioButton();
     m_horizontal->SetBitmap( KiBitmap( BITMAPS::text_horizontal ) );
-    m_vertical->SetIsCheckButton();
+    m_vertical->SetIsRadioButton();
     m_vertical->SetBitmap( KiBitmap( BITMAPS::text_vertical ) );
 
     m_separator2->SetIsSeparator();
@@ -68,20 +68,20 @@ DIALOG_LIB_TEXT_PROPERTIES::DIALOG_LIB_TEXT_PROPERTIES( SYMBOL_EDIT_FRAME* aPare
 
     m_separator3->SetIsSeparator();
 
-    m_hAlignLeft->SetIsCheckButton();
+    m_hAlignLeft->SetIsRadioButton();
     m_hAlignLeft->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
-    m_hAlignCenter->SetIsCheckButton();
+    m_hAlignCenter->SetIsRadioButton();
     m_hAlignCenter->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
-    m_hAlignRight->SetIsCheckButton();
+    m_hAlignRight->SetIsRadioButton();
     m_hAlignRight->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
 
     m_separator4->SetIsSeparator();
 
-    m_vAlignTop->SetIsCheckButton();
+    m_vAlignTop->SetIsRadioButton();
     m_vAlignTop->SetBitmap( KiBitmap( BITMAPS::text_valign_top ) );
-    m_vAlignCenter->SetIsCheckButton();
+    m_vAlignCenter->SetIsRadioButton();
     m_vAlignCenter->SetBitmap( KiBitmap( BITMAPS::text_valign_center ) );
-    m_vAlignBottom->SetIsCheckButton();
+    m_vAlignBottom->SetIsRadioButton();
     m_vAlignBottom->SetBitmap( KiBitmap( BITMAPS::text_valign_bottom ) );
 
     m_separator5->SetIsSeparator();
diff --git a/eeschema/dialogs/dialog_lib_textbox_properties.cpp b/eeschema/dialogs/dialog_lib_textbox_properties.cpp
index 9f61e7ba4f..114b9230df 100644
--- a/eeschema/dialogs/dialog_lib_textbox_properties.cpp
+++ b/eeschema/dialogs/dialog_lib_textbox_properties.cpp
@@ -85,17 +85,17 @@ DIALOG_LIB_TEXTBOX_PROPERTIES::DIALOG_LIB_TEXTBOX_PROPERTIES( SYMBOL_EDIT_FRAME*
 
     m_separator2->SetIsSeparator();
 
-    m_spin0->SetIsCheckButton();
+    m_spin0->SetIsRadioButton();
     m_spin0->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
-    m_spin1->SetIsCheckButton();
+    m_spin1->SetIsRadioButton();
     m_spin1->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
-    m_spin2->SetIsCheckButton();
+    m_spin2->SetIsRadioButton();
     m_spin2->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
-    m_spin3->SetIsCheckButton();
+    m_spin3->SetIsRadioButton();
     m_spin3->SetBitmap( KiBitmap( BITMAPS::text_align_bottom ) );
-    m_spin4->SetIsCheckButton();
+    m_spin4->SetIsRadioButton();
     m_spin4->SetBitmap( KiBitmap( BITMAPS::text_align_middle ) );
-    m_spin5->SetIsCheckButton();
+    m_spin5->SetIsRadioButton();
     m_spin5->SetBitmap( KiBitmap( BITMAPS::text_align_top ) );
 
     m_separator3->SetIsSeparator();
diff --git a/eeschema/dialogs/dialog_text_properties.cpp b/eeschema/dialogs/dialog_text_properties.cpp
index 16332ba792..1372c8b167 100644
--- a/eeschema/dialogs/dialog_text_properties.cpp
+++ b/eeschema/dialogs/dialog_text_properties.cpp
@@ -111,17 +111,17 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_ITE
 
     m_separator2->SetIsSeparator();
 
-    m_spin0->SetIsCheckButton();
+    m_spin0->SetIsRadioButton();
     m_spin0->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
-    m_spin1->SetIsCheckButton();
+    m_spin1->SetIsRadioButton();
     m_spin1->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
-    m_spin2->SetIsCheckButton();
+    m_spin2->SetIsRadioButton();
     m_spin2->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
-    m_spin3->SetIsCheckButton();
+    m_spin3->SetIsRadioButton();
     m_spin3->SetBitmap( KiBitmap( BITMAPS::text_align_bottom ) );
-    m_spin4->SetIsCheckButton();
+    m_spin4->SetIsRadioButton();
     m_spin4->SetBitmap( KiBitmap( BITMAPS::text_align_middle ) );
-    m_spin5->SetIsCheckButton();
+    m_spin5->SetIsRadioButton();
     m_spin5->SetBitmap( KiBitmap( BITMAPS::text_align_top ) );
 
     m_separator3->SetIsSeparator();
diff --git a/include/widgets/bitmap_button.h b/include/widgets/bitmap_button.h
index 85a6d39349..e1e824eaf0 100644
--- a/include/widgets/bitmap_button.h
+++ b/include/widgets/bitmap_button.h
@@ -81,6 +81,8 @@ public:
      */
     void SetIsCheckButton();
 
+    void SetIsRadioButton();
+
     /**
      * Check the control. This is the equivalent to toggling a toolbar button.
      */
@@ -132,6 +134,7 @@ private:
     wxBitmap  m_normalBitmap;
     wxBitmap  m_disabledBitmap;
 
+    bool      m_isRadioButton;
     int       m_buttonState;
     int       m_padding;
     wxSize    m_unadjustedMinSize;
diff --git a/pagelayout_editor/dialogs/properties_frame.cpp b/pagelayout_editor/dialogs/properties_frame.cpp
index 0865956aaa..7f899093ce 100644
--- a/pagelayout_editor/dialogs/properties_frame.cpp
+++ b/pagelayout_editor/dialogs/properties_frame.cpp
@@ -81,20 +81,20 @@ PROPERTIES_FRAME::PROPERTIES_FRAME( PL_EDITOR_FRAME* aParent ) :
 
     m_separator2->SetIsSeparator();
 
-    m_alignLeft->SetIsCheckButton();
+    m_alignLeft->SetIsRadioButton();
     m_alignLeft->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
-    m_alignCenter->SetIsCheckButton();
+    m_alignCenter->SetIsRadioButton();
     m_alignCenter->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
-    m_alignRight->SetIsCheckButton();
+    m_alignRight->SetIsRadioButton();
     m_alignRight->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
 
     m_separator3->SetIsSeparator();
 
-    m_vAlignTop->SetIsCheckButton();
+    m_vAlignTop->SetIsRadioButton();
     m_vAlignTop->SetBitmap( KiBitmap( BITMAPS::text_valign_top ) );
-    m_vAlignMiddle->SetIsCheckButton();
+    m_vAlignMiddle->SetIsRadioButton();
     m_vAlignMiddle->SetBitmap( KiBitmap( BITMAPS::text_valign_center ) );
-    m_vAlignBottom->SetIsCheckButton();
+    m_vAlignBottom->SetIsRadioButton();
     m_vAlignBottom->SetBitmap( KiBitmap( BITMAPS::text_valign_bottom ) );
 
     m_separator4->SetIsSeparator();
diff --git a/pcbnew/dialogs/dialog_dimension_properties.cpp b/pcbnew/dialogs/dialog_dimension_properties.cpp
index f0972b9fe9..c37f84c843 100644
--- a/pcbnew/dialogs/dialog_dimension_properties.cpp
+++ b/pcbnew/dialogs/dialog_dimension_properties.cpp
@@ -101,11 +101,11 @@ DIALOG_DIMENSION_PROPERTIES::DIALOG_DIMENSION_PROPERTIES( PCB_BASE_EDIT_FRAME* a
 
     m_separator1->SetIsSeparator();
 
-    m_alignLeft->SetIsCheckButton();
+    m_alignLeft->SetIsRadioButton();
     m_alignLeft->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
-    m_alignCenter->SetIsCheckButton();
+    m_alignCenter->SetIsRadioButton();
     m_alignCenter->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
-    m_alignRight->SetIsCheckButton();
+    m_alignRight->SetIsRadioButton();
     m_alignRight->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
 
     m_separator2->SetIsSeparator();
diff --git a/pcbnew/dialogs/dialog_text_properties.cpp b/pcbnew/dialogs/dialog_text_properties.cpp
index cdd9eb6da7..ec85e1361b 100644
--- a/pcbnew/dialogs/dialog_text_properties.cpp
+++ b/pcbnew/dialogs/dialog_text_properties.cpp
@@ -126,11 +126,11 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BO
 
     m_separator1->SetIsSeparator();
 
-    m_alignLeft->SetIsCheckButton();
+    m_alignLeft->SetIsRadioButton();
     m_alignLeft->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
-    m_alignCenter->SetIsCheckButton();
+    m_alignCenter->SetIsRadioButton();
     m_alignCenter->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
-    m_alignRight->SetIsCheckButton();
+    m_alignRight->SetIsRadioButton();
     m_alignRight->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
 
     m_separator2->SetIsSeparator();
diff --git a/pcbnew/dialogs/dialog_textbox_properties.cpp b/pcbnew/dialogs/dialog_textbox_properties.cpp
index a66b68e634..13b4230b41 100644
--- a/pcbnew/dialogs/dialog_textbox_properties.cpp
+++ b/pcbnew/dialogs/dialog_textbox_properties.cpp
@@ -96,11 +96,11 @@ DIALOG_TEXTBOX_PROPERTIES::DIALOG_TEXTBOX_PROPERTIES( PCB_BASE_EDIT_FRAME* aPare
 
     m_separator1->SetIsSeparator();
 
-    m_alignLeft->SetIsCheckButton();
+    m_alignLeft->SetIsRadioButton();
     m_alignLeft->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
-    m_alignCenter->SetIsCheckButton();
+    m_alignCenter->SetIsRadioButton();
     m_alignCenter->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
-    m_alignRight->SetIsCheckButton();
+    m_alignRight->SetIsRadioButton();
     m_alignRight->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
 
     m_separator2->SetIsSeparator();