diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 6920d554b9..f305e7778a 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -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 @@ -400,7 +401,7 @@ set( COMMON_SRCS ${COMMON_SRCS} origin_viewitem.cpp - + view/view.cpp view/view_item.cpp view/view_group.cpp diff --git a/common/widgets/bitmap_button.cpp b/common/widgets/bitmap_button.cpp new file mode 100644 index 0000000000..bddeb196c2 --- /dev/null +++ b/common/widgets/bitmap_button.cpp @@ -0,0 +1,200 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2020 Ian McInerney + * 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 +#include +#include +#include +#include +#include + + +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(); +} diff --git a/include/widgets/bitmap_button.h b/include/widgets/bitmap_button.h new file mode 100644 index 0000000000..c578b5da8b --- /dev/null +++ b/include/widgets/bitmap_button.h @@ -0,0 +1,121 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2020 Ian McInerney + * 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 +#include + + +/** + * 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_*/ diff --git a/pcbnew/widgets/appearance_controls.cpp b/pcbnew/widgets/appearance_controls.cpp index 504ce1bbcf..27b2c87115 100644 --- a/pcbnew/widgets/appearance_controls.cpp +++ b/pcbnew/widgets/appearance_controls.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -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" ) ); diff --git a/pcbnew/widgets/appearance_controls_base.cpp b/pcbnew/widgets/appearance_controls_base.cpp index dfcb9edd55..fce6e9f058 100644 --- a/pcbnew/widgets/appearance_controls_base.cpp +++ b/pcbnew/widgets/appearance_controls_base.cpp @@ -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 ); diff --git a/pcbnew/widgets/appearance_controls_base.fbp b/pcbnew/widgets/appearance_controls_base.fbp index cf083dfc2b..e62c9db139 100644 --- a/pcbnew/widgets/appearance_controls_base.fbp +++ b/pcbnew/widgets/appearance_controls_base.fbp @@ -685,7 +685,7 @@ 5 wxLEFT|wxRIGHT|wxTOP 0 - + 1 1 1 @@ -696,31 +696,27 @@ - 1 0 + BITMAP_BUTTON 1 + - 1 - - 0 + 0 + 0 - Dock 0 Left 1 1 - 0 0 wxID_ANY - Net Inspector - - 0 + 0 @@ -735,19 +731,13 @@ protected 1 - - Resizable + 1 - wxBORDER_NONE - ; ; forward_declare + BITMAP_BUTTON; widgets/bitmap_button.h; forward_declare 0 Show the Net Inspector - - wxFILTER_NONE - wxDefaultValidator - @@ -980,9 +970,9 @@ 5 - wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP 0 - + 1 1 1 @@ -993,31 +983,27 @@ - 1 0 + BITMAP_BUTTON 1 + 1 - - 0 + 0 - Dock 0 Left 1 1 - 0 0 wxID_ANY - Configure Net Classes - - 0 + 0 @@ -1032,19 +1018,13 @@ protected 1 - - Resizable + 1 - wxBORDER_NONE - ; ; forward_declare + BITMAP_BUTTON; widgets/bitmap_button.h; forward_declare 0 Configure net classes - - wxFILTER_NONE - wxDefaultValidator - diff --git a/pcbnew/widgets/appearance_controls_base.h b/pcbnew/widgets/appearance_controls_base.h index a304dadeb5..6da9be1054 100644 --- a/pcbnew/widgets/appearance_controls_base.h +++ b/pcbnew/widgets/appearance_controls_base.h @@ -9,6 +9,7 @@ #include #include +class BITMAP_BUTTON; class WX_GRID; #include @@ -24,8 +25,6 @@ class WX_GRID; #include #include #include -#include -#include #include #include #include @@ -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;