Add a new BITMAP_BUTTON widget and use it in the appearances panel

This button behaves like an AUI button, so it is more suited
to being on panels without a border.
This commit is contained in:
Ian McInerney 2020-09-20 00:41:26 +01:00
parent c5feccca53
commit 65bd1ee9a4
7 changed files with 352 additions and 46 deletions

View File

@ -202,6 +202,7 @@ set( COMMON_DLG_SRCS
set( COMMON_WIDGET_SRCS
widgets/app_progress_dialog.cpp
widgets/bitmap_button.cpp
widgets/bitmap_toggle.cpp
widgets/button_row_panel.cpp
widgets/collapsible_pane.cpp

View File

@ -0,0 +1,200 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <ian.s.mcinerney at ieee dot org>
* Copyright (C) 2020 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 <kiplatform/ui.h>
#include <widgets/bitmap_button.h>
#include <wx/button.h>
#include <wx/dcclient.h>
#include <wx/renderer.h>
#include <wx/settings.h>
BITMAP_BUTTON::BITMAP_BUTTON( wxWindow* aParent, wxWindowID aId, const wxPoint& aPos,
const wxSize& aSize, int aStyles ) :
wxPanel( aParent, aId, aPos, aSize, aStyles ),
m_buttonState( 0 ),
m_padding( 0 )
{
if( aSize == wxDefaultSize )
SetMinSize( wxButton::GetDefaultSize() );
Bind( wxEVT_PAINT, &BITMAP_BUTTON::OnPaint, this );
Bind( wxEVT_LEFT_UP, &BITMAP_BUTTON::OnLeftButtonUp, this );
Bind( wxEVT_LEFT_DOWN, &BITMAP_BUTTON::OnLeftButtonDown, this );
Bind( wxEVT_LEAVE_WINDOW, &BITMAP_BUTTON::OnMouseLeave, this );
Bind( wxEVT_ENTER_WINDOW, &BITMAP_BUTTON::OnMouseEnter, this );
}
BITMAP_BUTTON::~BITMAP_BUTTON()
{
}
void BITMAP_BUTTON::SetPadding( int aPadding )
{
m_padding = aPadding;
SetMinSize( m_unadjustedMinSize + wxSize( aPadding * 2, aPadding * 2) );
}
void BITMAP_BUTTON::SetBitmap( const wxBitmap& aBmp )
{
m_normalBitmap = aBmp;
m_unadjustedMinSize = aBmp.GetSize();
SetMinSize( wxSize( aBmp.GetWidth() + ( m_padding * 2 ), aBmp.GetHeight() + ( m_padding * 2 ) ) );
}
void BITMAP_BUTTON::SetDisabledBitmap( const wxBitmap& aBmp )
{
m_disabledBitmap = aBmp;
}
void BITMAP_BUTTON::OnMouseLeave( wxMouseEvent& aEvent )
{
clearFlag( wxCONTROL_CURRENT );
Refresh();
aEvent.Skip();
}
void BITMAP_BUTTON::OnMouseEnter( wxMouseEvent& aEvent )
{
setFlag( wxCONTROL_CURRENT );
Refresh();
aEvent.Skip();
}
void BITMAP_BUTTON::OnLeftButtonUp( wxMouseEvent& aEvent )
{
// Only create a button event when the control is enabled
if( !hasFlag( wxCONTROL_DISABLED ) )
{
wxEvtHandler* pEventHandler = GetEventHandler();
wxASSERT( pEventHandler );
pEventHandler->CallAfter(
[=]()
{
wxCommandEvent evt( wxEVT_BUTTON, this->GetId() );
evt.SetEventObject( this );
GetEventHandler()->ProcessEvent( evt );
} );
}
clearFlag( wxCONTROL_PRESSED );
Refresh();
aEvent.Skip();
}
void BITMAP_BUTTON::OnLeftButtonDown( wxMouseEvent& aEvent )
{
setFlag( wxCONTROL_PRESSED );
Refresh();
aEvent.Skip();
}
void BITMAP_BUTTON::OnPaint( wxPaintEvent& aEvent )
{
bool darkMode = KIPLATFORM::UI::IsDarkTheme();
wxColor highlightColor = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
// The drawing rectangle
wxRect rect( wxPoint( 0, 0 ), GetSize() );
wxPaintDC dc( this );
// This drawing is done so the button looks the same as an AUI toolbar button
if( !hasFlag( wxCONTROL_DISABLED ) )
{
if( hasFlag( wxCONTROL_PRESSED ) )
{
dc.SetPen( wxPen( highlightColor ) );
dc.SetBrush( wxBrush( highlightColor.ChangeLightness( darkMode ? 20 : 150 ) ) );
dc.DrawRectangle( rect );
}
else if( hasFlag( wxCONTROL_CURRENT ) )
{
dc.SetPen( wxPen( highlightColor ) );
dc.SetBrush( wxBrush( highlightColor.ChangeLightness( darkMode ? 40 : 170 ) ) );
// Checked items need a lighter hover rectangle
if( hasFlag( wxCONTROL_CHECKED ) )
dc.SetBrush( wxBrush( highlightColor.ChangeLightness( darkMode ? 50 : 180 ) ) );
dc.DrawRectangle( rect );
}
else if( hasFlag( wxCONTROL_CHECKED ) )
{
dc.SetPen( wxPen( highlightColor ) );
dc.SetBrush( wxBrush( highlightColor.ChangeLightness( darkMode ? 40 : 170 ) ) );
dc.DrawRectangle( rect );
}
}
const wxBitmap& bmp = hasFlag( wxCONTROL_DISABLED ) ? m_disabledBitmap : m_normalBitmap;
// Draw the bitmap with the upper-left corner offset by the padding
if( bmp.IsOk() )
dc.DrawBitmap( bmp, m_padding, m_padding, true );
}
bool BITMAP_BUTTON::Enable( bool aEnable )
{
// If the requested state is already the current state, don't do anything
if( aEnable != hasFlag( wxCONTROL_DISABLED ) )
return false;
wxPanel::Enable( aEnable );
if( aEnable )
clearFlag( wxCONTROL_DISABLED );
else
setFlag( wxCONTROL_DISABLED );
Refresh();
return true;
}
void BITMAP_BUTTON::Check( bool aCheck )
{
if( aCheck )
clearFlag( wxCONTROL_CHECKED );
else
setFlag( wxCONTROL_CHECKED );
Refresh();
}

View File

@ -0,0 +1,121 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <ian.s.mcinerney at ieee dot org>
* Copyright (C) 2020 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 BITMAP_BUTTON_H_
#define BITMAP_BUTTON_H_
#include <wx/bitmap.h>
#include <wx/panel.h>
/**
* A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
* Specifically:
* * It has no border
* * It has a rectangle highlight when the mouse is hovering/pressed
* * It has the ability to be checked/toggled
*/
class BITMAP_BUTTON : public wxPanel
{
public:
BITMAP_BUTTON( wxWindow* aParent, wxWindowID aId, const wxPoint& aPos = wxDefaultPosition,
const wxSize& aSize = wxDefaultSize, int aStyles = wxBORDER_NONE | wxTAB_TRAVERSAL );
~BITMAP_BUTTON();
/**
* Set the amount of padding present on each side of the bitmap.
*
* @param aPadding is the amount in px of padding for each side
*/
void SetPadding( int aPadding );
/**
* Set the bitmap shown when the button is enabled.
*
* @param aBmp is the enabled bitmap
*/
void SetBitmap( const wxBitmap& aBmp );
/**
* Set the bitmap shown when the button is disabled.
*
* @param aBmp is the disabled bitmap
*/
void SetDisabledBitmap( const wxBitmap& aBmp );
/**
* Enable the button.
*
* @param aEnable is true to enable, false to disable
*/
bool Enable( bool aEnable = true ) override;
/**
* Check the control. This is the equivalent to toggling a toolbar button.
*
* @param aCheck is true to check, false to uncheck
*/
void Check( bool aCheck = true );
protected:
void OnMouseLeave( wxMouseEvent& aEvent );
void OnMouseEnter( wxMouseEvent& aEvent );
void OnLeftButtonUp( wxMouseEvent& aEvent );
void OnLeftButtonDown( wxMouseEvent& aEvent );
void OnPaint( wxPaintEvent& aEvent );
void setFlag( int aFlag)
{
m_buttonState |= aFlag;
}
void clearFlag( int aFlag )
{
m_buttonState &= ~aFlag;
}
bool hasFlag( int aFlag )
{
return m_buttonState & aFlag;
}
private:
///> Bitmap shown when button is enabled
wxBitmap m_normalBitmap;
///> Bitmap shown when button is disabled
wxBitmap m_disabledBitmap;
///> Current state of the button
int m_buttonState;
///> Padding on each side of the bitmap
int m_padding;
///> Size without the padding
wxSize m_unadjustedMinSize;
};
#endif /*BITMAP_BUTTON_H_*/

View File

@ -31,6 +31,7 @@
#include <settings/color_settings.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <widgets/bitmap_button.h>
#include <widgets/bitmap_toggle.h>
#include <widgets/collapsible_pane.h>
#include <widgets/color_swatch.h>
@ -404,8 +405,11 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
createControls();
m_btnNetInspector->SetBitmapLabel( KiBitmap( list_nets_xpm ) );
m_btnConfigureNetClasses->SetBitmapLabel( KiBitmap( options_generic_xpm ) );
m_btnNetInspector->SetBitmap( KiBitmap( list_nets_xpm ) );
m_btnNetInspector->SetPadding( 2 );
m_btnConfigureNetClasses->SetBitmap( KiBitmap( options_generic_xpm ) );
m_btnConfigureNetClasses->SetPadding( 2 );
m_txtNetFilter->SetHint( _( "Filter nets" ) );

View File

@ -5,6 +5,7 @@
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/bitmap_button.h"
#include "widgets/wx_grid.h"
#include "appearance_controls_base.h"
@ -69,7 +70,7 @@ APPEARANCE_CONTROLS_BASE::APPEARANCE_CONTROLS_BASE( wxWindow* parent, wxWindowID
bSizer17->Add( m_txtNetFilter, 1, wxLEFT|wxTOP, 5 );
m_btnNetInspector = new wxBitmapButton( m_panelNets, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBORDER_NONE );
m_btnNetInspector = new BITMAP_BUTTON( m_panelNets, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_btnNetInspector->SetToolTip( wxT("Show the Net Inspector") );
bSizer17->Add( m_btnNetInspector, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
@ -123,10 +124,10 @@ APPEARANCE_CONTROLS_BASE::APPEARANCE_CONTROLS_BASE( wxWindow* parent, wxWindowID
bSizer20->Add( m_staticText14, 1, wxALL, 5 );
m_btnConfigureNetClasses = new wxBitmapButton( m_panelNetclasses, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBORDER_NONE );
m_btnConfigureNetClasses = new BITMAP_BUTTON( m_panelNetclasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_btnConfigureNetClasses->SetToolTip( wxT("Configure net classes") );
bSizer20->Add( m_btnConfigureNetClasses, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
bSizer20->Add( m_btnConfigureNetClasses, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 );
bSizerNetClasses->Add( bSizer20, 0, wxEXPAND, 5 );

View File

@ -685,7 +685,7 @@
<property name="border">5</property>
<property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="0">
<object class="CustomControl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -696,31 +696,27 @@
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="class">BITMAP_BUTTON</property>
<property name="close_button">1</property>
<property name="construction"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="context_menu">0</property>
<property name="declaration"></property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Net Inspector</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="include"></property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -735,19 +731,13 @@
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="settings"></property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxBORDER_NONE</property>
<property name="subclass">; ; forward_declare</property>
<property name="subclass">BITMAP_BUTTON; widgets/bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Show the Net Inspector</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
@ -980,9 +970,9 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="0">
<object class="CustomControl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -993,31 +983,27 @@
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="class">BITMAP_BUTTON</property>
<property name="close_button">1</property>
<property name="construction"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="declaration"></property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Configure Net Classes</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="include"></property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -1032,19 +1018,13 @@
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="settings"></property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxBORDER_NONE</property>
<property name="subclass">; ; forward_declare</property>
<property name="subclass">BITMAP_BUTTON; widgets/bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Configure net classes</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>

View File

@ -9,6 +9,7 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
class BITMAP_BUTTON;
class WX_GRID;
#include <wx/scrolwin.h>
@ -24,8 +25,6 @@ class WX_GRID;
#include <wx/icon.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/bmpbuttn.h>
#include <wx/button.h>
#include <wx/grid.h>
#include <wx/splitter.h>
#include <wx/notebook.h>
@ -56,11 +55,11 @@ class APPEARANCE_CONTROLS_BASE : public wxPanel
wxPanel* m_panelNets;
wxStaticText* m_staticTextNets;
wxTextCtrl* m_txtNetFilter;
wxBitmapButton* m_btnNetInspector;
BITMAP_BUTTON* m_btnNetInspector;
WX_GRID* m_netsGrid;
wxPanel* m_panelNetclasses;
wxStaticText* m_staticText14;
wxBitmapButton* m_btnConfigureNetClasses;
BITMAP_BUTTON* m_btnConfigureNetClasses;
wxScrolledWindow* m_netclassScrolledWindow;
wxBoxSizer* m_netclassOuterSizer;
wxStaticText* presetsLabel;