kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #28078
Re: [PATCH] Fix layer color swatches in Linux
Hi Wayne,
I rebased the patches onto the COLOR4D work.
I've also added a further refactor than generalises the row indicator
icons, which removes a bit more logic from the layer widgets, and can
be reused as a generic switchable icon for other purposes if needed (I
had an Inkscape-style "eye" for the visibility checkbox in mind, but
it's not limited to two states, or to just the layer widget).
I've put both the COLOR_SWATCH and INDICATOR_ICONS in common/widgets.
There's a lot more scope for tidying this widget, and other UI ideas
abound. This should help a little to tidying up, and at least makes it
usable and consistent across platforms for v5.
Cheers,
John
On Tue, Feb 21, 2017 at 11:05 PM, John Beard <john.j.beard@xxxxxxxxx> wrote:
> On Tue, Feb 21, 2017 at 10:41 PM, Wayne Stambaugh <stambaughw@xxxxxxxxx> wrote:
>> I forgot to mention that this will likely clash with the COLOR4D work
>> that is already in progress so we will have to coordinate the changes.
>
> Happy to rebase as needed.
>
>> On 2/21/2017 9:35 AM, Wayne Stambaugh wrote:
>>> My only issue with this change is that the tooltip letting the user know
>>> that a left button double click or a middle button click would allow
>>> them to change the color is gone.
>
> The tooltip is still there for me (Linux). I specifically checked it,
> as I think it's a useful thing, since there's no other affordance on
> the swatches to tell you what to do. I hope it's not platform specfic
> as to whether the swatch wxStaticBitmap or the COLOR_SWATCH panel
> provide the tooltip.
>
> Cheers,
>
> John
From 8dc00c8c102b644768c8fda411daa41b6af075e5 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Wed, 22 Feb 2017 20:34:23 +0800
Subject: [PATCH 4/4] Break row indicators out to own class
The introduces INDICATOR_ICON, which is a very simple class holding a
bitmap that can toggle on or off.
The ICON_PROVIDER class then provides icons to INDICATOR_ICONS, which
means the class can be used for more than just row indicators.
A default row icon provider is also provided for use in the standard row
selector.
---
common/CMakeLists.txt | 1 +
common/widgets/indicator_icon.cpp | 191 +++++++++++++++++++++++++++++++
gerbview/class_gerbview_layer_widget.cpp | 21 ----
gerbview/class_gerbview_layer_widget.h | 7 --
include/widgets/indicator_icon.h | 140 ++++++++++++++++++++++
pcbnew/layer_widget.cpp | 152 ++++++------------------
pcbnew/layer_widget.h | 13 ++-
7 files changed, 375 insertions(+), 150 deletions(-)
create mode 100644 common/widgets/indicator_icon.cpp
create mode 100644 include/widgets/indicator_icon.h
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index f2c6f04b3..349f6bc01 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -166,6 +166,7 @@ set( COMMON_WIDGET_SRCS
widgets/widget_hotkey_list.cpp
widgets/two_column_tree_list.cpp
widgets/footprint_preview_panel.cpp
+ widgets/indicator_icon.cpp
)
set( COMMON_PAGE_LAYOUT_SRCS
diff --git a/common/widgets/indicator_icon.cpp b/common/widgets/indicator_icon.cpp
new file mode 100644
index 000000000..c365c390c
--- /dev/null
+++ b/common/widgets/indicator_icon.cpp
@@ -0,0 +1,191 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+
+ * Copyright (C) 2017 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <widgets/indicator_icon.h>
+
+
+INDICATOR_ICON::INDICATOR_ICON( wxWindow* aParent,
+ ICON_PROVIDER& aIconProvider,
+ ICON_ID aInitialIcon, int aID ):
+ wxPanel( aParent, aID ),
+ m_iconProvider( aIconProvider ),
+ m_currentId( aInitialIcon )
+{
+ auto sizer = new wxBoxSizer( wxHORIZONTAL );
+ SetSizer( sizer );
+
+ const wxBitmap& initBitmap = m_iconProvider.GetIndicatorIcon( m_currentId );
+
+ m_bitmap = new wxStaticBitmap( this, aID,
+ initBitmap, wxDefaultPosition,
+ initBitmap.GetSize() );
+
+ sizer->Add( m_bitmap, 0, 0 );
+
+ auto evtSkipper = [this] ( wxEvent& aEvent ) {
+ wxPostEvent( this, aEvent );
+ };
+
+ m_bitmap->Bind( wxEVT_LEFT_DOWN, evtSkipper );
+}
+
+
+void INDICATOR_ICON::SetIndicatorState( ICON_ID aIconId )
+{
+ if( aIconId == m_currentId )
+ return;
+
+ m_currentId = aIconId;
+
+ m_bitmap->SetBitmap( m_iconProvider.GetIndicatorIcon( m_currentId ) );
+}
+
+
+INDICATOR_ICON::ICON_ID INDICATOR_ICON::GetIndicatorState() const
+{
+ return m_currentId;
+}
+
+// ====================================================================
+// Common icon providers
+
+/* XPM
+ * This bitmap is used for not selected layers
+ */
+static const char * clear_xpm[] = {
+"10 14 1 1",
+" c None",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
+
+/* XPM
+ * This bitmap can be used to show a not selected layer
+ * with special property (mainly not selected layers not in use in GerbView)
+ */
+static const char * clear_alternate_xpm[] = {
+"10 14 4 1",
+" c None",
+"X c #008080",
+"o c GREEN",
+"O c #00B080",
+" ",
+" ",
+" ",
+" ",
+" X ",
+" XXX ",
+" XXXXX ",
+" OOOOOOO ",
+" ooooo ",
+" ooo ",
+" o ",
+" ",
+" ",
+" "};
+
+
+/* XPM
+ * This bitmap is used for a normale selected layer
+ */
+static const char * rightarrow_xpm[] = {
+"10 14 4 1",
+" c None",
+"X c #8080ff",
+"o c BLUE",
+"O c gray56",
+" X ",
+" XX ",
+" XXX ",
+" XXXX ",
+" XXXXX ",
+" XXXXXX ",
+" XXXXXXX ",
+" oooooooO",
+" ooooooO ",
+" oooooO ",
+" ooooO ",
+" oooO ",
+" ooO ",
+" oO "};
+
+/* XPM
+ * This bitmap can be used to show the selected layer
+ * with special property (mainly a layer in use in GerbView)
+ */
+static const char * rightarrow_alternate_xpm[] = {
+"10 14 5 1",
+" c None",
+". c #00B000",
+"X c #8080ff",
+"o c BLUE",
+"O c gray56",
+"..X ",
+"..XX ",
+"..XXX ",
+"..XXXX ",
+"..XXXXX ",
+"..XXXXXX ",
+"..XXXXXXX ",
+"..oooooooO",
+"..ooooooO ",
+"..oooooO ",
+"..ooooO ",
+"..oooO ",
+"..ooO ",
+"..oO "};
+
+
+
+static wxBitmap rightArrowBitmap( rightarrow_xpm );
+static wxBitmap rightArrowAlternateBitmap( rightarrow_alternate_xpm );
+static wxBitmap blankBitmap( clear_xpm );
+static wxBitmap blankAlternateBitmap( clear_alternate_xpm );
+
+
+ROW_ICON_PROVIDER::ROW_ICON_PROVIDER( bool aAlt ):
+ m_alt( aAlt )
+{}
+
+
+const wxBitmap& ROW_ICON_PROVIDER::GetIndicatorIcon(
+ INDICATOR_ICON::ICON_ID aIconId ) const
+{
+ const bool on = ( aIconId == STATE::ON );
+
+ if( m_alt )
+ return ( on ? rightArrowAlternateBitmap : blankAlternateBitmap );
+
+ return ( on ? rightArrowBitmap : blankBitmap );
+}
diff --git a/gerbview/class_gerbview_layer_widget.cpp b/gerbview/class_gerbview_layer_widget.cpp
index f6c6ca9bb..1470417d4 100644
--- a/gerbview/class_gerbview_layer_widget.cpp
+++ b/gerbview/class_gerbview_layer_widget.cpp
@@ -314,24 +314,3 @@ bool GERBER_LAYER_WIDGET::useAlternateBitmap(int aRow)
{
return GetImagesList()->GetGbrImage( aRow ) != NULL;
}
-
-/*
- * Update the layer manager icons (layers only)
- * Useful when loading a file or clearing a layer because they change
- */
-void GERBER_LAYER_WIDGET::UpdateLayerIcons()
-{
- int row_count = GetLayerRowCount();
- for( int row = 0; row < row_count ; row++ )
- {
- wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row, COLUMN_ICON_ACTIVE );
- if( bm == NULL)
- continue;
-
- if( row == m_CurrentRow )
- bm->SetBitmap( useAlternateBitmap(row) ? *m_RightArrowAlternateBitmap :
- *m_RightArrowBitmap );
- else
- bm->SetBitmap( useAlternateBitmap(row) ? *m_BlankAlternateBitmap : *m_BlankBitmap );
- }
-}
diff --git a/gerbview/class_gerbview_layer_widget.h b/gerbview/class_gerbview_layer_widget.h
index 8e5c6ef18..ad40533af 100644
--- a/gerbview/class_gerbview_layer_widget.h
+++ b/gerbview/class_gerbview_layer_widget.h
@@ -125,13 +125,6 @@ public:
bool OnLayerSelected(); // postprocess after an active layer selection
// ensure active layer visible if
// m_alwaysShowActiveCopperLayer is true;
-
- /**
- * Function UpdateLayerIcons
- * Update the layer manager icons (layers only)
- * Useful when loading a file or clearing a layer because they change
- */
- void UpdateLayerIcons();
};
#endif // _CLASS_GERBER_LAYER_WIDGET_H_
diff --git a/include/widgets/indicator_icon.h b/include/widgets/indicator_icon.h
new file mode 100644
index 000000000..fc3436ab9
--- /dev/null
+++ b/include/widgets/indicator_icon.h
@@ -0,0 +1,140 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef ROW_INDICATOR__H_
+#define ROW_INDICATOR__H_
+
+#include <wx/wx.h>
+
+/**
+ * Class representing a row indicator icon for use in
+ * places like the layer widget
+ */
+class INDICATOR_ICON: public wxPanel
+{
+public:
+
+ /**
+ * An id that refers to a certain icon state.
+ *
+ * Exactly what that state might mean in terms of icons is up
+ * to the icon provider.
+ */
+ using ICON_ID = int;
+
+ /**
+ * A simple object that can provide fixed bitmaps for use as row
+ * indicators
+ */
+ class ICON_PROVIDER
+ {
+ public:
+
+ virtual ~ICON_PROVIDER() {};
+
+ /**
+ * Gets a reference to the row icon in the given mode
+ *
+ * @param aIconId the id of the icon to get (depends on the
+ * provider).
+ */
+ virtual const wxBitmap& GetIndicatorIcon( ICON_ID aIconId ) const = 0;
+ };
+
+ /**
+ * Accessor for the default icon providers, which take
+ * true and false for IDs, meaining on/off.
+ *
+ * @param aAlternative false for blue arrow/blank, true for the
+ * green diamond
+ */
+ static ICON_PROVIDER& GetDefaultRowIconProvider( bool aAlternative );
+
+ /**
+ * @param aParent the owning window
+ * @param aIconProvider the icon provider to get icons from
+ * @param aID the ID to use for the widgets - events will have
+ * this ID.
+ */
+ INDICATOR_ICON( wxWindow* aParent,
+ ICON_PROVIDER& aIconProvider,
+ ICON_ID aInitialIcon, int aID );
+
+ /**
+ * Sets the row indiciator to the given state
+ *
+ * @param aIconId the icon ID to pass to the provider.
+ */
+ void SetIndicatorState( ICON_ID aIconId );
+
+
+ /**
+ * @return the current state of the indicator
+ */
+ ICON_ID GetIndicatorState() const;
+
+private:
+
+ ///> An class that delivers icons for the indictor (currently just
+ ///> uses a default implementation).
+ ICON_PROVIDER& m_iconProvider;
+
+ ///> Handle on the bitmap widget
+ wxStaticBitmap* m_bitmap;
+
+ ///> Is the icon currently "on"
+ ICON_ID m_currentId;
+};
+
+
+/**
+ * Icon provider for the "standard" row indicators, for example in
+ * layer selection lists
+ */
+class ROW_ICON_PROVIDER: public INDICATOR_ICON::ICON_PROVIDER
+{
+public:
+
+ ///> State constants to select the right icons
+ enum STATE
+ {
+ OFF, ///> Row "off" or "deselected"
+ ON, ///> Row "on" or "selected"
+ };
+
+ /**
+ * @param aAlt false: normal icons (blue arrow/blank), true:
+ * alternative icons (blue arrow/green diamond)
+ */
+ ROW_ICON_PROVIDER( bool aAlt );
+
+ ///> @copydoc INDICATOR_ICON::ICON_PROVIDER::GetIndicatorIcon()
+ const wxBitmap& GetIndicatorIcon( INDICATOR_ICON::ICON_ID aIconId ) const override;
+
+private:
+ bool m_alt;
+};
+
+
+
+#endif // ROW_INDICATOR__H_
diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp
index 2f03f8356..7ceb0ab0d 100644
--- a/pcbnew/layer_widget.cpp
+++ b/pcbnew/layer_widget.cpp
@@ -38,6 +38,7 @@
#include <macros.h>
#include <common.h>
#include <widgets/color_swatch.h>
+#include <widgets/indicator_icon.h>
#include <wx/colour.h>
#include <wx/colordlg.h>
@@ -46,103 +47,11 @@
const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType();
-/* XPM
- * This bitmap is used for not selected layers
- */
-static const char * clear_xpm[] = {
-"10 14 1 1",
-" c None",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
-
-/* XPM
- * This bitmap can be used to show a not selected layer
- * with special property (mainly not selected layers not in use in GerbView)
- */
-static const char * clear_alternate_xpm[] = {
-"10 14 4 1",
-" c None",
-"X c #008080",
-"o c GREEN",
-"O c #00B080",
-" ",
-" ",
-" ",
-" ",
-" X ",
-" XXX ",
-" XXXXX ",
-" OOOOOOO ",
-" ooooo ",
-" ooo ",
-" o ",
-" ",
-" ",
-" "};
-
-
-/* XPM
- * This bitmap is used for a normale selected layer
- */
-static const char * rightarrow_xpm[] = {
-"10 14 4 1",
-" c None",
-"X c #8080ff",
-"o c BLUE",
-"O c gray56",
-" X ",
-" XX ",
-" XXX ",
-" XXXX ",
-" XXXXX ",
-" XXXXXX ",
-" XXXXXXX ",
-" oooooooO",
-" ooooooO ",
-" oooooO ",
-" ooooO ",
-" oooO ",
-" ooO ",
-" oO "};
-
-/* XPM
- * This bitmap can be used to show the selected layer
- * with special property (mainly a layer in use in GerbView)
+/*
+ * Icon providers for the row icons
*/
-static const char * rightarrow_alternate_xpm[] = {
-"10 14 5 1",
-" c None",
-". c #00B000",
-"X c #8080ff",
-"o c BLUE",
-"O c gray56",
-"..X ",
-"..XX ",
-"..XXX ",
-"..XXXX ",
-"..XXXXX ",
-"..XXXXXX ",
-"..XXXXXXX ",
-"..oooooooO",
-"..ooooooO ",
-"..oooooO ",
-"..ooooO ",
-"..oooO ",
-"..ooO ",
-"..oO "};
-
+static ROW_ICON_PROVIDER defaultRowIcons( false );
+static ROW_ICON_PROVIDER alternativeRowIcons( true );
/**
* Function shrinkFont
@@ -337,11 +246,13 @@ void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
int index = aRow * LYR_COLUMN_COUNT;
const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
+ auto& iconProvider = useAlternateBitmap(aRow) ? alternativeRowIcons : defaultRowIcons;
+
// column 0
- col = 0;
- wxStaticBitmap* sbm = new wxStaticBitmap( m_LayerScrolledWindow, encodeId( col, aSpec.id ),
- useAlternateBitmap(aRow) ? *m_BlankAlternateBitmap : *m_BlankBitmap,
- wxDefaultPosition, m_BitmapSize );
+ col = COLUMN_ICON_ACTIVE;
+ auto sbm = new INDICATOR_ICON( m_LayerScrolledWindow, iconProvider,
+ ROW_ICON_PROVIDER::STATE::OFF,
+ encodeId( col, aSpec.id ) );
sbm->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags );
@@ -493,13 +404,6 @@ LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPoint
m_CurrentRow = -1; // hide the arrow initially
- m_RightArrowBitmap = new wxBitmap( rightarrow_xpm );
- m_RightArrowAlternateBitmap = new wxBitmap( rightarrow_alternate_xpm );
-
- m_BlankBitmap = new wxBitmap( clear_xpm ); // translucent
- m_BlankAlternateBitmap = new wxBitmap( clear_alternate_xpm );
- m_BitmapSize = wxSize(m_BlankBitmap->GetWidth(), m_BlankBitmap->GetHeight());
-
// trap the tab changes so that we can call passOnFocus().
m_notebook->Bind( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &LAYER_WIDGET::OnTabChange, this );
@@ -509,10 +413,6 @@ LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPoint
LAYER_WIDGET::~LAYER_WIDGET()
{
- delete m_BlankBitmap;
- delete m_BlankAlternateBitmap;
- delete m_RightArrowBitmap;
- delete m_RightArrowAlternateBitmap;
}
@@ -615,14 +515,14 @@ void LAYER_WIDGET::SelectLayerRow( int aRow )
// enable the layer tab at index 0
m_notebook->SetSelection( 0 );
- wxStaticBitmap* oldbm = (wxStaticBitmap*) getLayerComp( m_CurrentRow, 0 );
- if( oldbm )
- oldbm->SetBitmap( useAlternateBitmap(m_CurrentRow) ? *m_BlankAlternateBitmap : *m_BlankBitmap );
+ INDICATOR_ICON* oldIndicator = (INDICATOR_ICON*) getLayerComp( m_CurrentRow, 0 );
+ if( oldIndicator )
+ oldIndicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF );
- wxStaticBitmap* newbm = (wxStaticBitmap*) getLayerComp( aRow, 0 );
- if( newbm )
+ INDICATOR_ICON* newIndicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
+ if( newIndicator )
{
- newbm->SetBitmap( useAlternateBitmap(aRow) ? *m_RightArrowAlternateBitmap : *m_RightArrowBitmap );
+ newIndicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::ON );
// Make sure the desired layer row is visible.
// It seems that as of 2.8.2, setting the focus does this.
@@ -748,6 +648,24 @@ void LAYER_WIDGET::UpdateLayouts()
FitInside();
}
+
+void LAYER_WIDGET::UpdateLayerIcons()
+{
+ int rowCount = GetLayerRowCount();
+ for( int row = 0; row < rowCount ; row++ )
+ {
+ INDICATOR_ICON* indicator = (INDICATOR_ICON*) getLayerComp( row, COLUMN_ICON_ACTIVE );
+
+ if( indicator )
+ {
+ auto state = ( row == m_CurrentRow ) ? ROW_ICON_PROVIDER::STATE::ON
+ : ROW_ICON_PROVIDER::STATE::OFF;
+ indicator->SetIndicatorState( state );
+ }
+ }
+}
+
+
#if defined(STAND_ALONE)
#include <wx/aui/aui.h>
diff --git a/pcbnew/layer_widget.h b/pcbnew/layer_widget.h
index 635ee18a2..99949b59d 100644
--- a/pcbnew/layer_widget.h
+++ b/pcbnew/layer_widget.h
@@ -113,11 +113,6 @@ protected:
wxFlexGridSizer* m_RenderFlexGridSizer;
wxWindow* m_FocusOwner;
- wxBitmap* m_BlankBitmap;
- wxBitmap* m_BlankAlternateBitmap;
- wxBitmap* m_RightArrowBitmap;
- wxBitmap* m_RightArrowAlternateBitmap;
- wxSize m_BitmapSize;
int m_CurrentRow; ///< selected row of layer list
int m_PointSize;
@@ -363,6 +358,14 @@ public:
void UpdateLayouts();
+ /**
+ * Function UpdateLayerIcons
+ * Update all layer manager icons (layers only)
+ * Useful when loading a file or clearing a layer because they change,
+ * and the indicator arrow icon needs to be updated
+ */
+ void UpdateLayerIcons();
+
/* did not help:
void Freeze()
{
--
2.11.0
From 990653e3b97a6db5baba5ddab9f77d9c84f39596 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Tue, 21 Feb 2017 20:43:02 +0800
Subject: [PATCH 3/4] Use Bind rather than Connect in LAYER_WIDGET
Bind is safer than Connect. Bind is more flexible and has a more concise
signature.
---
pcbnew/layer_widget.cpp | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp
index 5d3a53d52..2f03f8356 100644
--- a/pcbnew/layer_widget.cpp
+++ b/pcbnew/layer_widget.cpp
@@ -342,7 +342,7 @@ void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
wxStaticBitmap* sbm = new wxStaticBitmap( m_LayerScrolledWindow, encodeId( col, aSpec.id ),
useAlternateBitmap(aRow) ? *m_BlankAlternateBitmap : *m_BlankBitmap,
wxDefaultPosition, m_BitmapSize );
- sbm->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
+ sbm->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags );
// column 1 (COLUMN_COLORBM)
@@ -358,7 +358,7 @@ void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
col = COLUMN_COLOR_LYR_CB;
wxCheckBox* cb = new wxCheckBox( m_LayerScrolledWindow, encodeId( col, aSpec.id ), wxEmptyString );
cb->SetValue( aSpec.state );
- cb->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( LAYER_WIDGET::OnLayerCheckBox ), NULL, this );
+ cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnLayerCheckBox, this );
cb->SetToolTip( _( "Enable this for visibility" ) );
m_LayersFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
@@ -366,7 +366,7 @@ void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
col = COLUMN_COLOR_LYRNAME;
wxStaticText* st = new wxStaticText( m_LayerScrolledWindow, encodeId( col, aSpec.id ), aSpec.rowName );
shrinkFont( st, m_PointSize );
- st->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
+ st->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
st->SetToolTip( aSpec.tooltip );
m_LayersFlexGridSizer->wxSizer::Insert( index+col, st, 0, flags );
}
@@ -404,8 +404,7 @@ void LAYER_WIDGET::insertRenderRow( int aRow, const ROW& aSpec )
aSpec.rowName, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
shrinkFont( cb, m_PointSize );
cb->SetValue( aSpec.state );
- cb->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED,
- wxCommandEventHandler( LAYER_WIDGET::OnRenderCheckBox ), NULL, this );
+ cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnRenderCheckBox, this );
cb->SetToolTip( aSpec.tooltip );
m_RenderFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
}
@@ -502,8 +501,7 @@ LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPoint
m_BitmapSize = wxSize(m_BlankBitmap->GetWidth(), m_BlankBitmap->GetHeight());
// trap the tab changes so that we can call passOnFocus().
- m_notebook->Connect( -1, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
- wxNotebookEventHandler( LAYER_WIDGET::OnTabChange ), NULL, this );
+ m_notebook->Bind( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &LAYER_WIDGET::OnTabChange, this );
Layout();
}
--
2.11.0
From 003d5f08804a747dcff5f32c97c5ffe05cc56c8b Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Tue, 21 Feb 2017 20:31:19 +0800
Subject: [PATCH 2/4] Move layer/render swatches to own class
This introduces COLOR_SWATCH, which is a reusable
widget that shows a color swatch and can invoke the colour picker
when duble/middle clicked.
It uses it's own wxCommandEvent to signal the change.
This makes the layer widget simpler internally, and also allows other
code to show identical swatches if needed.
---
common/CMakeLists.txt | 1 +
common/widgets/color_swatch.cpp | 153 ++++++++++++++++++++++++++++++++++++
include/widgets/color_swatch.h | 88 +++++++++++++++++++++
pcbnew/layer_widget.cpp | 167 ++++++----------------------------------
pcbnew/layer_widget.h | 12 ++-
5 files changed, 275 insertions(+), 146 deletions(-)
create mode 100644 common/widgets/color_swatch.cpp
create mode 100644 include/widgets/color_swatch.h
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index dba4e7f61..f2c6f04b3 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -161,6 +161,7 @@ set( COMMON_DLG_SRCS
)
set( COMMON_WIDGET_SRCS
+ widgets/color_swatch.cpp
widgets/mathplot.cpp
widgets/widget_hotkey_list.cpp
widgets/two_column_tree_list.cpp
diff --git a/common/widgets/color_swatch.cpp b/common/widgets/color_swatch.cpp
new file mode 100644
index 000000000..85a5c990b
--- /dev/null
+++ b/common/widgets/color_swatch.cpp
@@ -0,0 +1,153 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+
+ * Copyright (C) 2017 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <widgets/color_swatch.h>
+
+wxDEFINE_EVENT(COLOR_SWATCH_CHANGED, wxCommandEvent);
+
+using KIGFX::COLOR4D;
+
+
+const static int SWATCH_SIZE_X = 14;
+const static int SWATCH_SIZE_Y = 12;
+
+// See selcolor.cpp:
+extern COLOR4D DisplayColorFrame( wxWindow* aParent, COLOR4D aOldColor );
+
+
+/**
+ * Make a simple color swatch bitmap
+ */
+static wxBitmap makeBitmap( COLOR4D aColor )
+{
+ wxBitmap bitmap( SWATCH_SIZE_X, SWATCH_SIZE_Y );
+ wxBrush brush;
+ wxMemoryDC iconDC;
+
+ iconDC.SelectObject( bitmap );
+
+ brush.SetColour( aColor.ToColour() );
+ brush.SetStyle( wxBRUSHSTYLE_SOLID );
+
+ iconDC.SetBrush( brush );
+
+ iconDC.DrawRectangle( 0, 0, SWATCH_SIZE_X, SWATCH_SIZE_Y );
+
+ return bitmap;
+}
+
+
+/**
+ * Function makeColorButton
+ * creates a wxStaticBitmap and assigns it a solid color and a control ID
+ */
+static std::unique_ptr<wxStaticBitmap> makeColorSwatch(
+ wxWindow* aParent, COLOR4D aColor, int aID )
+{
+ // construct a bitmap of the right color and make the swatch from it
+ wxBitmap bitmap = makeBitmap( aColor );
+ auto ret = std::make_unique<wxStaticBitmap>( aParent, aID, bitmap );
+
+ return ret;
+}
+
+
+COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, COLOR4D aColor, int aID ):
+ wxPanel( aParent, aID ),
+ m_color( aColor )
+{
+ auto sizer = new wxBoxSizer( wxHORIZONTAL );
+ SetSizer( sizer );
+
+ auto swatch = makeColorSwatch( this, m_color, aID );
+ m_swatch = swatch.get(); // hold a handle
+
+ sizer->Add( swatch.release(), 0, 0 );
+
+ // forward click to any other listeners, since we don't want them
+ m_swatch->Bind( wxEVT_LEFT_DOWN, &COLOR_SWATCH::rePostEvent, this );
+ m_swatch->Bind( wxEVT_RIGHT_DOWN, &COLOR_SWATCH::rePostEvent, this );
+
+ // bind the events that trigger the dialog
+ m_swatch->Bind( wxEVT_LEFT_DCLICK, [this] ( wxMouseEvent& aEvt ) {
+ GetNewSwatchColor();
+ } );
+
+ m_swatch->Bind( wxEVT_MIDDLE_DOWN, [this] ( wxMouseEvent& aEvt ) {
+ GetNewSwatchColor();
+ } );
+}
+
+
+void COLOR_SWATCH::rePostEvent( wxEvent& aEvt )
+{
+ wxPostEvent( this, aEvt );
+}
+
+
+static void sendSwatchChangeEvent( COLOR_SWATCH& aSender )
+{
+ wxCommandEvent changeEvt( COLOR_SWATCH_CHANGED );
+
+ // use this class as the object (alternative might be to
+ // set a custom event class but that's more work)
+ changeEvt.SetEventObject( &aSender );
+
+ wxPostEvent( &aSender, changeEvt );
+}
+
+
+void COLOR_SWATCH::SetSwatchColor( COLOR4D aColor, bool sendEvent )
+{
+ m_color = aColor;
+
+ wxBitmap bm = makeBitmap( aColor );
+ m_swatch->SetBitmap( bm );
+
+ if( sendEvent )
+ {
+ sendSwatchChangeEvent( *this );
+ }
+}
+
+
+COLOR4D COLOR_SWATCH::GetSwatchColor() const
+{
+ return m_color;
+}
+
+
+void COLOR_SWATCH::GetNewSwatchColor()
+{
+ COLOR4D newColor = DisplayColorFrame( this, m_color );
+
+ if( newColor != COLOR4D::UNSPECIFIED )
+ {
+ m_color = newColor;
+
+ wxBitmap bm = makeBitmap( newColor );
+ m_swatch->SetBitmap( bm );
+
+ sendSwatchChangeEvent( *this );
+ }
+}
diff --git a/include/widgets/color_swatch.h b/include/widgets/color_swatch.h
new file mode 100644
index 000000000..d634ef3bf
--- /dev/null
+++ b/include/widgets/color_swatch.h
@@ -0,0 +1,88 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef COLOR_SWATCH__H_
+#define COLOR_SWATCH__H_
+
+#include <wx/wx.h>
+
+#include <common.h>
+
+#include <gal/color4d.h>
+
+
+/**
+ * Class representing a simple color swatch, of the kind used to
+ * set layer colors
+ */
+class COLOR_SWATCH: public wxPanel
+{
+public:
+
+ /**
+ * Construct a COLOR_SWATCH
+ *
+ * @param aParent parent window
+ * @param aColor initial swatch color
+ * @param aID id to use when sending swatch events
+ */
+ COLOR_SWATCH( wxWindow* aParent, KIGFX::COLOR4D aColor, int aID );
+
+ /**
+ * Set the current swatch color directly.
+ */
+ void SetSwatchColor( KIGFX::COLOR4D aColor, bool sendEvent );
+
+ /**
+ * @return the current swatch color
+ */
+ KIGFX::COLOR4D GetSwatchColor() const;
+
+ /**
+ * Prompt for a new colour, using the colour picker dialog.
+ *
+ * A colour change event will be sent if it's set.
+ */
+ void GetNewSwatchColor();
+
+private:
+
+ /**
+ * Pass unwanted events on to listeners of this object
+ */
+ void rePostEvent( wxEvent& aEvt );
+
+ ///> The current colour of the swatch
+ KIGFX::COLOR4D m_color;
+
+ ///> Handle of the actual swatch shown
+ wxStaticBitmap* m_swatch;
+};
+
+
+/**
+ * Event signalling a swatch has changed color
+ */
+wxDECLARE_EVENT(COLOR_SWATCH_CHANGED, wxCommandEvent);
+
+#endif // COLOR_SWATCH__H_
diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp
index d63c3f914..5d3a53d52 100644
--- a/pcbnew/layer_widget.cpp
+++ b/pcbnew/layer_widget.cpp
@@ -37,18 +37,13 @@
#include <macros.h>
#include <common.h>
+#include <widgets/color_swatch.h>
#include <wx/colour.h>
#include <wx/colordlg.h>
#include <algorithm>
-const static int SWATCH_SIZE_X = 14;
-const static int SWATCH_SIZE_Y = 12;
-
-// See selcolor.cpp:
-extern COLOR4D DisplayColorFrame( wxWindow* aParent, COLOR4D aOldColor );
-
const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType();
/* XPM
@@ -150,56 +145,6 @@ static const char * rightarrow_alternate_xpm[] = {
/**
- * Function makeColorTxt
- * returns a string representing the color in CSS format
- * For example: "rgba(255, 0, 0, 255)"
- */
-static wxString makeColorTxt( COLOR4D aColor )
-{
- return aColor.ToWxString( wxC2S_CSS_SYNTAX );
-}
-
-
-static wxBitmap makeBitmap( COLOR4D aColor )
-{
- wxBitmap bitmap( SWATCH_SIZE_X, SWATCH_SIZE_Y );
- wxBrush brush;
- wxMemoryDC iconDC;
-
- iconDC.SelectObject( bitmap );
-
- brush.SetColour( aColor.ToColour() );
- brush.SetStyle( wxBRUSHSTYLE_SOLID );
-
- iconDC.SetBrush( brush );
-
- iconDC.DrawRectangle( 0, 0, SWATCH_SIZE_X, SWATCH_SIZE_Y );
-
- return bitmap;
-}
-
-
-/**
- * Function makeColorButton
- * creates a wxStaticBitmap and assigns it a solid color and a control ID
- */
-static std::unique_ptr<wxStaticBitmap> makeColorSwatch( wxWindow* aParent,
- COLOR4D aColor, int aID )
-{
- // dynamically make a wxBitMap and brush it with the appropriate color,
- // then create a wxBitmapButton from it.
- wxBitmap bitmap = makeBitmap( aColor );
-
- // save the color value in the name, no where else to put it.
- auto ret = std::make_unique<wxStaticBitmap>( aParent, aID, bitmap );
-
- ret->SetName( makeColorTxt( aColor ) );
-
- return ret;
-}
-
-
-/**
* Function shrinkFont
* reduces the size of the wxFont associated with \a aControl
*/
@@ -273,48 +218,20 @@ void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
}
-void LAYER_WIDGET::OnMiddleDownLayerColor( wxMouseEvent& aEvent )
+void LAYER_WIDGET::OnLayerSwatchChanged( wxCommandEvent& aEvent )
{
- auto eventSource = static_cast<wxStaticBitmap*>( aEvent.GetEventObject() );
-
- wxString colorTxt = eventSource->GetName();
-
- COLOR4D oldColor;
- wxASSERT( oldColor.SetFromWxString( colorTxt ) );
- COLOR4D newColor = COLOR4D::UNSPECIFIED;
-
- if( AreArbitraryColorsAllowed() )
- {
- wxColourData colourData;
- colourData.SetColour( oldColor.ToColour() );
- wxColourDialog* dialog = new wxColourDialog( m_LayerScrolledWindow, &colourData );
+ auto eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
- if( dialog->ShowModal() == wxID_OK )
- {
- newColor = COLOR4D( dialog->GetColourData().GetColour() );
- }
- }
- else
- {
- newColor = DisplayColorFrame( this, oldColor );
- }
+ COLOR4D newColor = eventSource->GetSwatchColor();
- if( newColor != COLOR4D::UNSPECIFIED )
- {
- eventSource->SetName( makeColorTxt( newColor ) );
-
- wxBitmap bm = makeBitmap( newColor.ToColour() );
- eventSource->SetBitmap( bm );
-
- LAYER_NUM layer = getDecodedId( eventSource->GetId() );
+ LAYER_NUM layer = getDecodedId( eventSource->GetId() );
- // tell the client code.
- OnLayerColorChange( layer, newColor );
+ // tell the client code.
+ OnLayerColorChange( layer, newColor );
- // notify others
- wxCommandEvent event( EVT_LAYER_COLOR_CHANGE );
- wxPostEvent( this, event );
- }
+ // notify others
+ wxCommandEvent event( EVT_LAYER_COLOR_CHANGE );
+ wxPostEvent( this, event );
passOnFocus();
}
@@ -329,44 +246,17 @@ void LAYER_WIDGET::OnLayerCheckBox( wxCommandEvent& event )
}
-void LAYER_WIDGET::OnMiddleDownRenderColor( wxMouseEvent& aEvent )
+void LAYER_WIDGET::OnRenderSwatchChanged( wxCommandEvent& aEvent )
{
- auto eventSource = static_cast<wxStaticBitmap*>( aEvent.GetEventObject() );
+ auto eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
- wxString colorTxt = eventSource->GetName();
-
- COLOR4D oldColor;
- wxASSERT( oldColor.SetFromWxString( colorTxt ) );
- COLOR4D newColor = COLOR4D::UNSPECIFIED;
-
- if( AreArbitraryColorsAllowed() )
- {
- wxColourData colourData;
- colourData.SetColour( oldColor.ToColour() );
- wxColourDialog *dialog = new wxColourDialog( m_LayerScrolledWindow, &colourData );
+ COLOR4D newColor = eventSource->GetSwatchColor();
- if( dialog->ShowModal() == wxID_OK )
- {
- newColor = COLOR4D( dialog->GetColourData().GetColour() );
- }
- }
- else
- {
- newColor = DisplayColorFrame( this, oldColor );
- }
-
- if( newColor != COLOR4D::UNSPECIFIED )
- {
- eventSource->SetName( makeColorTxt( newColor ) );
-
- wxBitmap bm = makeBitmap( newColor );
- eventSource->SetBitmap( bm );
+ LAYER_NUM id = getDecodedId( eventSource->GetId() );
- LAYER_NUM id = getDecodedId( eventSource->GetId() );
+ // tell the client code.
+ OnRenderColorChange( id, newColor );
- // tell the client code.
- OnRenderColorChange( id, newColor );
- }
passOnFocus();
}
@@ -458,12 +348,11 @@ void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
// column 1 (COLUMN_COLORBM)
col = COLUMN_COLORBM;
- auto bmb = makeColorSwatch( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
- bmb->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
- bmb->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownLayerColor ), NULL, this );
- bmb->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownLayerColor ), NULL, this );
+ auto bmb = new COLOR_SWATCH( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
+ bmb->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
+ bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnLayerSwatchChanged, this );
bmb->SetToolTip( _("Left double click or middle click for color change, right click for menu" ) );
- m_LayersFlexGridSizer->wxSizer::Insert( index+col, bmb.release(), 0, flags );
+ m_LayersFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
// column 2 (COLUMN_COLOR_LYR_CB)
col = COLUMN_COLOR_LYR_CB;
@@ -495,13 +384,10 @@ void LAYER_WIDGET::insertRenderRow( int aRow, const ROW& aSpec )
col = 0;
if( aSpec.color != COLOR4D::UNSPECIFIED )
{
- auto bmb = makeColorSwatch(m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
-
- //makeColorSwatch( m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
- bmb->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownRenderColor ), NULL, this );
- bmb->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownRenderColor ), NULL, this );
+ auto bmb = new COLOR_SWATCH(m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
+ bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnRenderSwatchChanged, this );
bmb->SetToolTip( _( "Left double click or middle click for color change" ) );
- m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb.release(), 0, flags );
+ m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
// could add a left click handler on the color button that toggles checkbox.
}
@@ -803,13 +689,10 @@ void LAYER_WIDGET::SetLayerColor( LAYER_NUM aLayer, COLOR4D aColor )
if( row >= 0 )
{
int col = 1; // bitmap button is column 1
- wxBitmapButton* bmb = (wxBitmapButton*) getLayerComp( row, col );
+ auto bmb = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
wxASSERT( bmb );
- wxBitmap bm = makeBitmap( aColor );
-
- bmb->SetBitmapLabel( bm );
- bmb->SetName( makeColorTxt( aColor ) ); // save color value in name as string
+ bmb->SetSwatchColor( aColor, false );
}
}
diff --git a/pcbnew/layer_widget.h b/pcbnew/layer_widget.h
index 892de638d..635ee18a2 100644
--- a/pcbnew/layer_widget.h
+++ b/pcbnew/layer_widget.h
@@ -157,10 +157,10 @@ protected:
void OnLeftDownLayers( wxMouseEvent& event );
/**
- * Function OnMiddleDownLayerColor
- * is called only from a color button when user right clicks.
+ * Function OnSwatchChanged()
+ * is called when a user changes a swatch color
*/
- void OnMiddleDownLayerColor( wxMouseEvent& event );
+ void OnLayerSwatchChanged( wxCommandEvent& aEvent );
/**
* Function OnLayerCheckBox
@@ -169,7 +169,11 @@ protected:
*/
void OnLayerCheckBox( wxCommandEvent& event );
- void OnMiddleDownRenderColor( wxMouseEvent& event );
+ /**
+ * Function OnRenderSwatchChanged
+ * Called when user has changed the swatch color of a render entry
+ */
+ void OnRenderSwatchChanged( wxCommandEvent& aEvent );
void OnRenderCheckBox( wxCommandEvent& event );
--
2.11.0
From 1d7553d5f4ed56b753f62d5b4d32368960fcd092 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Tue, 21 Feb 2017 19:09:10 +0800
Subject: [PATCH 1/4] Use wxStaticBitmaps for layer/render swatches
On Linux with recent GTK+ toolkits, these swatches had very wide
borders, resulting in colour swatches of only a few pixels. On OSX, all
borders were disabled, leaving only the swatch.
This commit changes the wxBitmapButton to wxStaticBitmap, which fixes
the issue on Linux GTK+ and also removes the platform-specific element,
as it will now be the same on all systems.
These widgets aren't used as buttons anyway, a single click is handled
across the whole row, not just the swatch. So using a button was not the
most intuitive affordance.
Fixes: lp:1605411
* https://bugs.launchpad.net/kicad/+bug/1605411
---
pcbnew/layer_widget.cpp | 104 ++++++++++++++++++++++++------------------------
pcbnew/layer_widget.h | 8 ----
2 files changed, 52 insertions(+), 60 deletions(-)
diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp
index 5eb11b047..d63c3f914 100644
--- a/pcbnew/layer_widget.cpp
+++ b/pcbnew/layer_widget.cpp
@@ -26,7 +26,7 @@
/* This source module implements the layer visibility and selection widget
- @todo make the bitmapbutton a staticbitmap, and make dependent on the point size.
+ @todo make bitmap size dependent on the point size.
*/
@@ -43,9 +43,8 @@
#include <algorithm>
-#define BUTT_SIZE_X 20
-#define BUTT_SIZE_Y 18
-#define BUTT_VOID 2
+const static int SWATCH_SIZE_X = 14;
+const static int SWATCH_SIZE_Y = 12;
// See selcolor.cpp:
extern COLOR4D DisplayColorFrame( wxWindow* aParent, COLOR4D aOldColor );
@@ -161,37 +160,9 @@ static wxString makeColorTxt( COLOR4D aColor )
}
-/**
- * Function shrinkFont
- * reduces the size of the wxFont associated with \a aControl
- */
-static void shrinkFont( wxWindow* aControl, int aPointSize )
+static wxBitmap makeBitmap( COLOR4D aColor )
{
- wxFont font = aControl->GetFont();
- font.SetPointSize( aPointSize );
- aControl->SetFont( font ); // need this?
-}
-
-
-int LAYER_WIDGET::encodeId( int aColumn, int aId )
-{
- int id = aId * LYR_COLUMN_COUNT + aColumn;
- return id;
-}
-
-
-LAYER_NUM LAYER_WIDGET::getDecodedId( int aControlId )
-{
- int id = aControlId / LYR_COLUMN_COUNT; // rounding is OK.
- return id;
-}
-
-
-wxBitmap LAYER_WIDGET::makeBitmap( COLOR4D aColor )
-{
- // the bitmap will be BUTT_VOID*2 pixels smaller than the button, leaving a
- // border of BUTT_VOID pixels on each side.
- wxBitmap bitmap( BUTT_SIZE_X - 2 * BUTT_VOID, BUTT_SIZE_Y - 2 * BUTT_VOID );
+ wxBitmap bitmap( SWATCH_SIZE_X, SWATCH_SIZE_Y );
wxBrush brush;
wxMemoryDC iconDC;
@@ -202,31 +173,58 @@ wxBitmap LAYER_WIDGET::makeBitmap( COLOR4D aColor )
iconDC.SetBrush( brush );
- iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X - 2 * BUTT_VOID, BUTT_SIZE_Y - 2 * BUTT_VOID );
+ iconDC.DrawRectangle( 0, 0, SWATCH_SIZE_X, SWATCH_SIZE_Y );
return bitmap;
}
-wxBitmapButton* LAYER_WIDGET::makeColorButton( wxWindow* aParent, COLOR4D aColor, int aID )
+/**
+ * Function makeColorButton
+ * creates a wxStaticBitmap and assigns it a solid color and a control ID
+ */
+static std::unique_ptr<wxStaticBitmap> makeColorSwatch( wxWindow* aParent,
+ COLOR4D aColor, int aID )
{
// dynamically make a wxBitMap and brush it with the appropriate color,
// then create a wxBitmapButton from it.
wxBitmap bitmap = makeBitmap( aColor );
-#ifdef __WXMAC__
- wxBitmapButton* ret = new wxBitmapButton( aParent, aID, bitmap,
- wxDefaultPosition, wxSize(BUTT_SIZE_X, BUTT_SIZE_Y), wxBORDER_NONE );
-#else
- wxBitmapButton* ret = new wxBitmapButton( aParent, aID, bitmap,
- wxDefaultPosition, wxSize(BUTT_SIZE_X, BUTT_SIZE_Y), wxBORDER_RAISED );
-#endif
// save the color value in the name, no where else to put it.
+ auto ret = std::make_unique<wxStaticBitmap>( aParent, aID, bitmap );
+
ret->SetName( makeColorTxt( aColor ) );
+
return ret;
}
+/**
+ * Function shrinkFont
+ * reduces the size of the wxFont associated with \a aControl
+ */
+static void shrinkFont( wxWindow* aControl, int aPointSize )
+{
+ wxFont font = aControl->GetFont();
+ font.SetPointSize( aPointSize );
+ aControl->SetFont( font ); // need this?
+}
+
+
+int LAYER_WIDGET::encodeId( int aColumn, int aId )
+{
+ int id = aId * LYR_COLUMN_COUNT + aColumn;
+ return id;
+}
+
+
+LAYER_NUM LAYER_WIDGET::getDecodedId( int aControlId )
+{
+ int id = aControlId / LYR_COLUMN_COUNT; // rounding is OK.
+ return id;
+}
+
+
void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
{
int row;
@@ -277,7 +275,7 @@ void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
void LAYER_WIDGET::OnMiddleDownLayerColor( wxMouseEvent& aEvent )
{
- wxBitmapButton* eventSource = (wxBitmapButton*) aEvent.GetEventObject();
+ auto eventSource = static_cast<wxStaticBitmap*>( aEvent.GetEventObject() );
wxString colorTxt = eventSource->GetName();
@@ -306,7 +304,7 @@ void LAYER_WIDGET::OnMiddleDownLayerColor( wxMouseEvent& aEvent )
eventSource->SetName( makeColorTxt( newColor ) );
wxBitmap bm = makeBitmap( newColor.ToColour() );
- eventSource->SetBitmapLabel( bm );
+ eventSource->SetBitmap( bm );
LAYER_NUM layer = getDecodedId( eventSource->GetId() );
@@ -331,9 +329,9 @@ void LAYER_WIDGET::OnLayerCheckBox( wxCommandEvent& event )
}
-void LAYER_WIDGET::OnMiddleDownRenderColor( wxMouseEvent& event )
+void LAYER_WIDGET::OnMiddleDownRenderColor( wxMouseEvent& aEvent )
{
- wxBitmapButton* eventSource = (wxBitmapButton*) event.GetEventObject();
+ auto eventSource = static_cast<wxStaticBitmap*>( aEvent.GetEventObject() );
wxString colorTxt = eventSource->GetName();
@@ -362,7 +360,7 @@ void LAYER_WIDGET::OnMiddleDownRenderColor( wxMouseEvent& event )
eventSource->SetName( makeColorTxt( newColor ) );
wxBitmap bm = makeBitmap( newColor );
- eventSource->SetBitmapLabel( bm );
+ eventSource->SetBitmap( bm );
LAYER_NUM id = getDecodedId( eventSource->GetId() );
@@ -460,12 +458,12 @@ void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
// column 1 (COLUMN_COLORBM)
col = COLUMN_COLORBM;
- wxBitmapButton* bmb = makeColorButton( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
+ auto bmb = makeColorSwatch( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
bmb->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
bmb->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownLayerColor ), NULL, this );
bmb->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownLayerColor ), NULL, this );
bmb->SetToolTip( _("Left double click or middle click for color change, right click for menu" ) );
- m_LayersFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
+ m_LayersFlexGridSizer->wxSizer::Insert( index+col, bmb.release(), 0, flags );
// column 2 (COLUMN_COLOR_LYR_CB)
col = COLUMN_COLOR_LYR_CB;
@@ -497,11 +495,13 @@ void LAYER_WIDGET::insertRenderRow( int aRow, const ROW& aSpec )
col = 0;
if( aSpec.color != COLOR4D::UNSPECIFIED )
{
- wxBitmapButton* bmb = makeColorButton( m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
+ auto bmb = makeColorSwatch(m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
+
+ //makeColorSwatch( m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
bmb->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownRenderColor ), NULL, this );
bmb->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownRenderColor ), NULL, this );
bmb->SetToolTip( _( "Left double click or middle click for color change" ) );
- m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
+ m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb.release(), 0, flags );
// could add a left click handler on the color button that toggles checkbox.
}
diff --git a/pcbnew/layer_widget.h b/pcbnew/layer_widget.h
index 23624e340..892de638d 100644
--- a/pcbnew/layer_widget.h
+++ b/pcbnew/layer_widget.h
@@ -121,8 +121,6 @@ protected:
int m_CurrentRow; ///< selected row of layer list
int m_PointSize;
- static wxBitmap makeBitmap( COLOR4D aColor );
-
/**
* Virtual Function useAlternateBitmap
* @return true if bitmaps shown in Render layer list
@@ -156,12 +154,6 @@ protected:
*/
static LAYER_NUM getDecodedId( int aControlId );
- /**
- * Function makeColorButton
- * creates a wxBitmapButton and assigns it a solid color and a control ID
- */
- wxBitmapButton* makeColorButton( wxWindow* aParent, COLOR4D aColor, int aID );
-
void OnLeftDownLayers( wxMouseEvent& event );
/**
--
2.11.0
Follow ups
References