Fix layer color swatches in Linux

This commit is contained in:
John Beard 2017-03-01 09:51:35 +01:00 committed by Maciej Suminski
commit 96b32861cd
9 changed files with 701 additions and 316 deletions

View File

@ -165,10 +165,12 @@ 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
widgets/footprint_preview_panel.cpp
widgets/indicator_icon.cpp
)
set( COMMON_PAGE_LAYOUT_SRCS

View File

@ -0,0 +1,174 @@
/*
* 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>
#include <wx/colour.h>
#include <wx/colordlg.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,
bool aArbitraryColors ):
wxPanel( aParent, aID ),
m_arbitraryColors( aArbitraryColors ),
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 = COLOR4D::UNSPECIFIED;
if( m_arbitraryColors )
{
wxColourData colourData;
colourData.SetColour( m_color.ToColour() );
wxColourDialog* dialog = new wxColourDialog( this, &colourData );
if( dialog->ShowModal() == wxID_OK )
{
newColor = COLOR4D( dialog->GetColourData().GetColour() );
}
}
else
{
newColor = DisplayColorFrame( this, m_color );
}
if( newColor != COLOR4D::UNSPECIFIED )
{
m_color = newColor;
wxBitmap bm = makeBitmap( newColor );
m_swatch->SetBitmap( bm );
sendSwatchChangeEvent( *this );
}
}

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,92 @@
/*
* 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,
bool aArbitraryColors );
/**
* 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 );
///> Can the swatch have any color, or only preset ones?
bool m_arbitraryColors;
///> 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_

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

@ -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.
*/
@ -37,129 +37,20 @@
#include <macros.h>
#include <common.h>
#include <wx/colour.h>
#include <wx/colordlg.h>
#include <widgets/color_swatch.h>
#include <widgets/indicator_icon.h>
#include <algorithm>
#define BUTT_SIZE_X 20
#define BUTT_SIZE_Y 18
#define BUTT_VOID 2
// See selcolor.cpp:
extern COLOR4D DisplayColorFrame( wxWindow* aParent, COLOR4D aOldColor );
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 "};
/**
* 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 ROW_ICON_PROVIDER defaultRowIcons( false );
static ROW_ICON_PROVIDER alternativeRowIcons( true );
/**
* Function shrinkFont
@ -187,46 +78,6 @@ LAYER_NUM LAYER_WIDGET::getDecodedId( int aControlId )
}
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 );
wxBrush brush;
wxMemoryDC iconDC;
iconDC.SelectObject( bitmap );
brush.SetColour( aColor.ToColour() );
brush.SetStyle( wxBRUSHSTYLE_SOLID );
iconDC.SetBrush( brush );
iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X - 2 * BUTT_VOID, BUTT_SIZE_Y - 2 * BUTT_VOID );
return bitmap;
}
wxBitmapButton* LAYER_WIDGET::makeColorButton( 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.
ret->SetName( makeColorTxt( aColor ) );
return ret;
}
void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
{
int row;
@ -275,48 +126,20 @@ void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
}
void LAYER_WIDGET::OnMiddleDownLayerColor( wxMouseEvent& aEvent )
void LAYER_WIDGET::OnLayerSwatchChanged( wxCommandEvent& aEvent )
{
wxBitmapButton* eventSource = (wxBitmapButton*) aEvent.GetEventObject();
auto eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
wxString colorTxt = eventSource->GetName();
COLOR4D newColor = eventSource->GetSwatchColor();
COLOR4D oldColor;
wxASSERT( oldColor.SetFromWxString( colorTxt ) );
COLOR4D newColor = COLOR4D::UNSPECIFIED;
LAYER_NUM layer = getDecodedId( eventSource->GetId() );
if( AreArbitraryColorsAllowed() )
{
wxColourData colourData;
colourData.SetColour( oldColor.ToColour() );
wxColourDialog* dialog = new wxColourDialog( m_LayerScrolledWindow, &colourData );
// tell the client code.
OnLayerColorChange( layer, newColor );
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.ToColour() );
eventSource->SetBitmapLabel( bm );
LAYER_NUM layer = getDecodedId( eventSource->GetId() );
// 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();
}
@ -331,44 +154,17 @@ void LAYER_WIDGET::OnLayerCheckBox( wxCommandEvent& event )
}
void LAYER_WIDGET::OnMiddleDownRenderColor( wxMouseEvent& event )
void LAYER_WIDGET::OnRenderSwatchChanged( wxCommandEvent& aEvent )
{
wxBitmapButton* eventSource = (wxBitmapButton*) event.GetEventObject();
auto eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
wxString colorTxt = eventSource->GetName();
COLOR4D newColor = eventSource->GetSwatchColor();
COLOR4D oldColor;
wxASSERT( oldColor.SetFromWxString( colorTxt ) );
COLOR4D newColor = COLOR4D::UNSPECIFIED;
LAYER_NUM id = getDecodedId( eventSource->GetId() );
if( AreArbitraryColorsAllowed() )
{
wxColourData colourData;
colourData.SetColour( oldColor.ToColour() );
wxColourDialog *dialog = new wxColourDialog( m_LayerScrolledWindow, &colourData );
// tell the client code.
OnRenderColorChange( id, newColor );
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->SetBitmapLabel( bm );
LAYER_NUM id = getDecodedId( eventSource->GetId() );
// tell the client code.
OnRenderColorChange( id, newColor );
}
passOnFocus();
}
@ -394,8 +190,10 @@ void LAYER_WIDGET::OnTabChange( wxNotebookEvent& event )
wxWindow* LAYER_WIDGET::getLayerComp( int aRow, int aColumn ) const
{
unsigned ndx = aRow * LYR_COLUMN_COUNT + aColumn;
if( ndx < m_LayersFlexGridSizer->GetChildren().GetCount() )
return m_LayersFlexGridSizer->GetChildren()[ndx]->GetWindow();
return NULL;
}
@ -403,7 +201,8 @@ wxWindow* LAYER_WIDGET::getLayerComp( int aRow, int aColumn ) const
int LAYER_WIDGET::findLayerRow( LAYER_NUM aLayer ) const
{
int count = GetLayerRowCount();
for( int row=0; row<count; ++row )
for( int row = 0; row < count; ++row )
{
// column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
wxWindow* w = getLayerComp( row, 0 );
@ -412,6 +211,7 @@ int LAYER_WIDGET::findLayerRow( LAYER_NUM aLayer ) const
if( aLayer == getDecodedId( w->GetId() ))
return row;
}
return -1;
}
@ -419,8 +219,10 @@ int LAYER_WIDGET::findLayerRow( LAYER_NUM aLayer ) const
wxWindow* LAYER_WIDGET::getRenderComp( int aRow, int aColumn ) const
{
int ndx = aRow * RND_COLUMN_COUNT + aColumn;
if( (unsigned) ndx < m_RenderFlexGridSizer->GetChildren().GetCount() )
return m_RenderFlexGridSizer->GetChildren()[ndx]->GetWindow();
return NULL;
}
@ -428,7 +230,8 @@ wxWindow* LAYER_WIDGET::getRenderComp( int aRow, int aColumn ) const
int LAYER_WIDGET::findRenderRow( int aId ) const
{
int count = GetRenderRowCount();
for( int row=0; row<count; ++row )
for( int row = 0; row < count; ++row )
{
// column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
wxWindow* w = getRenderComp( row, 0 );
@ -437,6 +240,7 @@ int LAYER_WIDGET::findRenderRow( int aId ) const
if( aId == getDecodedId( w->GetId() ))
return row;
}
return -1;
}
@ -449,21 +253,23 @@ 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 );
sbm->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
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 );
// column 1 (COLUMN_COLORBM)
col = COLUMN_COLORBM;
wxBitmapButton* bmb = makeColorButton( 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 ),
AreArbitraryColorsAllowed() );
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, 0, flags );
@ -471,7 +277,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 );
@ -479,7 +285,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 );
}
@ -497,9 +303,9 @@ 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 ) );
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 ),
AreArbitraryColorsAllowed() );
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, 0, flags );
@ -518,8 +324,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 );
}
@ -608,16 +413,8 @@ 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->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();
}
@ -625,10 +422,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;
}
@ -637,14 +430,16 @@ wxSize LAYER_WIDGET::GetBestSize() const
// size of m_LayerScrolledWindow --------------
wxArrayInt widths = m_LayersFlexGridSizer->GetColWidths();
int totWidth = 0;
if( widths.GetCount() )
{
for( int i=0; i<LYR_COLUMN_COUNT; ++i )
for( int i = 0; i < LYR_COLUMN_COUNT; ++i )
{
totWidth += widths[i] + m_LayersFlexGridSizer->GetHGap();
// printf("widths[%d]:%d\n", i, widths[i] );
}
}
// Account for the parent's frame:
totWidth += 10;
@ -662,9 +457,10 @@ wxSize LAYER_WIDGET::GetBestSize() const
// size of m_RenderScrolledWindow --------------
widths = m_RenderFlexGridSizer->GetColWidths();
totWidth = 0;
if( widths.GetCount() )
{
for( int i=0; i<RND_COLUMN_COUNT; ++i )
for( int i = 0; i < RND_COLUMN_COUNT; ++i )
{
totWidth += widths[i] + m_RenderFlexGridSizer->GetHGap();
// printf("widths[%d]:%d\n", i, widths[i] );
@ -731,14 +527,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.
@ -803,13 +599,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 );
}
}
@ -834,6 +627,7 @@ COLOR4D LAYER_WIDGET::GetLayerColor( LAYER_NUM aLayer ) const
void LAYER_WIDGET::SetRenderState( int aId, bool isSet )
{
int row = findRenderRow( aId );
if( row >= 0 )
{
int col = 1; // checkbox is column 1
@ -847,6 +641,7 @@ void LAYER_WIDGET::SetRenderState( int aId, bool isSet )
bool LAYER_WIDGET::GetRenderState( int aId )
{
int row = findRenderRow( aId );
if( row >= 0 )
{
int col = 1; // checkbox is column 1
@ -854,6 +649,7 @@ bool LAYER_WIDGET::GetRenderState( int aId )
wxASSERT( cb );
return cb->GetValue();
}
return false; // the value of a non-existent row
}
@ -867,6 +663,25 @@ 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,16 +113,9 @@ 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;
static wxBitmap makeBitmap( COLOR4D aColor );
/**
* Virtual Function useAlternateBitmap
* @return true if bitmaps shown in Render layer list
@ -156,19 +149,13 @@ 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 );
/**
* 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
@ -177,7 +164,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 );
@ -367,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()
{