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.
This commit is contained in:
John Beard 2017-02-22 20:34:23 +08:00 committed by Maciej Suminski
parent 72354c5a81
commit 1d039cb4c1
7 changed files with 375 additions and 150 deletions

View File

@ -170,6 +170,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

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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_

View File

@ -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_

View File

@ -39,109 +39,18 @@
#include <common.h>
#include <widgets/color_swatch.h>
#include <widgets/indicator_icon.h>
#include <algorithm>
const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType();
/* XPM
* This bitmap is used for not selected layers
/*
* Icon providers for the row icons
*/
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 ROW_ICON_PROVIDER defaultRowIcons( false );
static ROW_ICON_PROVIDER alternativeRowIcons( true );
/**
* Function shrinkFont
@ -336,11 +245,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 );
@ -494,13 +405,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 );
@ -510,10 +414,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;
}
@ -616,14 +516,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.
@ -749,6 +649,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>

View File

@ -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()
{