From 4dda8a39fe3826875550f46644bc39228cfc10f2 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 21 Feb 2018 16:29:24 +0000 Subject: [PATCH] Add inc/dec current layer alpha to menus. Also adds indicators in layers palette for feedback. Also generates sized images for all indicators instead of using scaled bitmaps (which didn't look great). Also fixes a completely unrelated typo in a UI string. --- common/widgets/indicator_icon.cpp | 247 ++++++++++++---------------- eeschema/files-io.cpp | 4 +- include/pcb_base_frame.h | 2 + include/widgets/indicator_icon.h | 19 ++- pcbnew/footprint_edit_frame.cpp | 6 + pcbnew/footprint_edit_frame.h | 3 + pcbnew/layer_widget.cpp | 44 +++-- pcbnew/layer_widget.h | 6 +- pcbnew/menubar_footprint_editor.cpp | 23 ++- pcbnew/menubar_pcb_editor.cpp | 23 ++- pcbnew/pcb_edit_frame.cpp | 6 + pcbnew/pcb_edit_frame.h | 5 + pcbnew/pcb_layer_widget.cpp | 40 +++++ pcbnew/pcb_layer_widget.h | 7 + pcbnew/pcbnew_id.h | 2 + pcbnew/tools/pcb_actions.cpp | 6 + pcbnew/tools/pcbnew_control.cpp | 6 + 17 files changed, 281 insertions(+), 168 deletions(-) diff --git a/common/widgets/indicator_icon.cpp b/common/widgets/indicator_icon.cpp index 4ef2d07462..97ef4fb0ef 100644 --- a/common/widgets/indicator_icon.cpp +++ b/common/widgets/indicator_icon.cpp @@ -24,9 +24,8 @@ #include -INDICATOR_ICON::INDICATOR_ICON( wxWindow* aParent, - ICON_PROVIDER& aIconProvider, - ICON_ID aInitialIcon, int aID ): +INDICATOR_ICON::INDICATOR_ICON( wxWindow* aParent, ICON_PROVIDER& aIconProvider, + ICON_ID aInitialIcon, int aID ): wxPanel( aParent, aID ), m_iconProvider( aIconProvider ), m_currentId( aInitialIcon ) @@ -34,12 +33,9 @@ INDICATOR_ICON::INDICATOR_ICON( wxWindow* aParent, auto sizer = new wxBoxSizer( wxHORIZONTAL ); SetSizer( sizer ); - const wxBitmap& initBitmap = m_iconProvider.GetIndicatorIcon( m_currentId ); - wxBitmap scaled = ScaledIcon( initBitmap ); + const wxBitmap& icon = m_iconProvider.GetIndicatorIcon( m_currentId ); - m_bitmap = new wxStaticBitmap( this, aID, - scaled, wxDefaultPosition, - scaled.GetSize() ); + m_bitmap = new wxStaticBitmap( this, aID, icon, wxDefaultPosition, icon.GetSize() ); sizer->Add( m_bitmap, 0, 0 ); @@ -58,7 +54,9 @@ void INDICATOR_ICON::SetIndicatorState( ICON_ID aIconId ) m_currentId = aIconId; - m_bitmap->SetBitmap( ScaledIcon( m_iconProvider.GetIndicatorIcon( m_currentId ) ) ); + const wxBitmap& icon = m_iconProvider.GetIndicatorIcon( m_currentId ); + m_bitmap->SetBitmap( icon ); + m_bitmap->SetSize( icon.GetSize() ); } @@ -68,145 +66,116 @@ INDICATOR_ICON::ICON_ID INDICATOR_ICON::GetIndicatorState() const } -// Uses wxImage::Rescale to provide a bitmap scaled to a fixed size relative to -// the system font. This doesn't work particularly well in the general case -// and so is not an answer to DPI-independent scaling of e.g. toolbar icons, -// but it gives perfectly acceptable results for the simple icons embedded in -// this file. -wxBitmap INDICATOR_ICON::ScaledIcon( wxBitmap const& aSource ) const +wxImage createBlankImage( int size ) { - int dest_height = ConvertDialogToPixels( wxSize( 0, 4 ) ).y; - wxSize source_size = aSource.GetSize(); - double scale = (double) dest_height / (double) source_size.y; + wxImage image( size, size ); - wxImage source = aSource.ConvertToImage(); - source.Rescale( scale * source_size.x, scale * source_size.y, wxIMAGE_QUALITY_HIGH ); + image.InitAlpha(); + for( int y = 0; y < size; ++y ) + for( int x = 0; x < size; ++x ) + image.SetAlpha( x, y, wxIMAGE_ALPHA_TRANSPARENT ); - wxBitmap dest( source ); +#ifdef __WXWINDOWS__ + // wxWidgets on Windows chokes on an empty fully transparent bitmap and draws it + // as a black box + image.SetRGB( size / 2, size / 2, 128, 128, 128 ); + image.SetAlpha( size / 2, size / 2, 10 ); +#endif - return dest; + return image; } -// ==================================================================== -// 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 "}; - - -ROW_ICON_PROVIDER::ROW_ICON_PROVIDER( bool aAlt ): - m_alt( aAlt ) -{} - - -const wxBitmap& ROW_ICON_PROVIDER::GetIndicatorIcon( - INDICATOR_ICON::ICON_ID aIconId ) const +// Create an arrow icon of a particular size, colour and direction. 0 points up, 1 points +// right, and so forth. +wxBitmap createArrow( int size, int aDirection, wxColour aColour ) { - // need to wait until UI is ready before construction - // so can't go in the global scope - static const wxBitmap rightArrowBitmap( rightarrow_xpm ); - static const wxBitmap rightArrowAlternateBitmap( rightarrow_alternate_xpm ); - static const wxBitmap blankBitmap( clear_xpm ); - static const wxBitmap blankAlternateBitmap( clear_alternate_xpm ); + wxImage image = createBlankImage( size ); - const bool on = ( aIconId == STATE::ON ); + int startX = size / 2 - 1; + int len = 1; - if( m_alt ) - return ( on ? rightArrowAlternateBitmap : blankAlternateBitmap ); + int startY = aDirection % 2; - return ( on ? rightArrowBitmap : blankBitmap ); + for( int y = startY; y < startY + ( size / 2 ); ++y ) + { + for( int x = startX; x < startX + len; ++x ) + { + image.SetRGB( x, y, aColour.Red(), aColour.Green(), aColour.Blue() ); + image.SetAlpha( x, y, wxIMAGE_ALPHA_OPAQUE ); + } + + // Next row will start one pixel back and be two pixels longer + startX -= 1; + len += 2; + } + + for( int i = 0; i < aDirection; ++i ) + image = image.Rotate90(); + + return wxBitmap( image ); +} + + +// Create a diamond icon of a particular size and colour. +wxBitmap createDiamond( int size, wxColour aColour ) +{ + wxImage image = createBlankImage( size ); + + int startX = size / 2 - 1; + int len = 1; + + int startY = 2; + + for( int y = startY; y < size && len > 0; ++y ) + { + for( int x = startX; x < startX + len; ++x ) + { + image.SetRGB( x, y, aColour.Red(), aColour.Green(), aColour.Blue() ); + image.SetAlpha( x, y, wxIMAGE_ALPHA_OPAQUE ); + } + + // Next row will start one pixel back and be two pixels longer + if( y < ( size / 2) - 1 ) + { + startX -= 1; + len += 2; + } + else + { + startX += 1; + len -= 2; + } + } + + return wxBitmap( image ); +} + + +ROW_ICON_PROVIDER::ROW_ICON_PROVIDER( int aSize ) +{ + m_blankBitmap = wxBitmap( createBlankImage( aSize ) ); + m_rightArrowBitmap = createArrow( aSize, 1, wxColour( 64, 72, 255 ) ); + m_upArrowBitmap = createArrow( aSize - 2, 0, wxSystemSettings().GetColour( wxSYS_COLOUR_3DDKSHADOW ) ); + m_downArrowBitmap = createArrow( aSize - 2, 2, wxSystemSettings().GetColour( wxSYS_COLOUR_3DDKSHADOW ) ); + m_dotBitmap = createDiamond( aSize, wxColour( 128, 144, 255 ) ); +} + + +const wxBitmap& ROW_ICON_PROVIDER::GetIndicatorIcon( INDICATOR_ICON::ICON_ID aId ) const +{ + switch( aId ) + { + case STATE::UP: + return m_upArrowBitmap; + case STATE::DOWN: + return m_downArrowBitmap; + case STATE::ON: + return m_rightArrowBitmap; + case STATE::DIMMED: + return m_dotBitmap; + case STATE::OFF: + default: + return m_blankBitmap; + } } diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index ecbff0861f..7c6c81be93 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -297,8 +297,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in if( !pi->GetError().IsEmpty() ) { DisplayErrorMessage( this, - _( "The entire schematic could not be load. Errors " - "occurred attempting to load hierarchical sheet " + _( "The entire schematic could not be loaded. Errors " + "occurred attempting to load \nhierarchical sheet " "schematics." ), pi->GetError() ); } diff --git a/include/pcb_base_frame.h b/include/pcb_base_frame.h index 71ed229914..cf091b05a9 100644 --- a/include/pcb_base_frame.h +++ b/include/pcb_base_frame.h @@ -660,6 +660,8 @@ public: void OnUpdateSelectGrid( wxUpdateUIEvent& aEvent ); void OnUpdateSelectZoom( wxUpdateUIEvent& aEvent ); + virtual void OnUpdateLayerAlpha( wxUpdateUIEvent& aEvent ) {} + /** * Function SetFastGrid1() * diff --git a/include/widgets/indicator_icon.h b/include/widgets/indicator_icon.h index 39fcea7166..39c610d8ed 100644 --- a/include/widgets/indicator_icon.h +++ b/include/widgets/indicator_icon.h @@ -78,8 +78,7 @@ public: * @param aID the ID to use for the widgets - events will have * this ID. */ - INDICATOR_ICON( wxWindow* aParent, - ICON_PROVIDER& aIconProvider, + INDICATOR_ICON( wxWindow* aParent, ICON_PROVIDER& aIconProvider, ICON_ID aInitialIcon, int aID ); /** @@ -97,11 +96,6 @@ public: private: - /** - * Scale an icon to one character width. - */ - wxBitmap ScaledIcon( wxBitmap const& aSource ) const; - ///> An class that delivers icons for the indictor (currently just ///> uses a default implementation). ICON_PROVIDER& m_iconProvider; @@ -126,20 +120,27 @@ public: enum STATE { OFF, ///> Row "off" or "deselected" + DIMMED, ///> Row "dimmed" ON, ///> Row "on" or "selected" + UP, ///> Row above design alpha + DOWN, ///> Row below design alpha }; /** * @param aAlt false: normal icons (blue arrow/blank), true: * alternative icons (blue arrow/green diamond) */ - ROW_ICON_PROVIDER( bool aAlt ); + ROW_ICON_PROVIDER( int aSize ); ///> @copydoc INDICATOR_ICON::ICON_PROVIDER::GetIndicatorIcon() const wxBitmap& GetIndicatorIcon( INDICATOR_ICON::ICON_ID aIconId ) const override; private: - bool m_alt; + wxBitmap m_blankBitmap; + wxBitmap m_rightArrowBitmap; + wxBitmap m_upArrowBitmap; + wxBitmap m_downArrowBitmap; + wxBitmap m_dotBitmap; }; diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index bff1994b00..a8020e6f1a 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -873,6 +873,12 @@ void FOOTPRINT_EDIT_FRAME::SetElementVisibility( GAL_LAYER_ID aElement, bool aNe } +void FOOTPRINT_EDIT_FRAME::OnUpdateLayerAlpha( wxUpdateUIEvent & ) +{ + m_Layers->SyncLayerAlphaIndicators(); +} + + void FOOTPRINT_EDIT_FRAME::ProcessPreferences( wxCommandEvent& event ) { int id = event.GetId(); diff --git a/pcbnew/footprint_edit_frame.h b/pcbnew/footprint_edit_frame.h index 11e549d4b7..50872104d9 100644 --- a/pcbnew/footprint_edit_frame.h +++ b/pcbnew/footprint_edit_frame.h @@ -463,6 +463,9 @@ public: ///> @copydoc PCB_BASE_FRAME::SetActiveLayer() void SetActiveLayer( PCB_LAYER_ID aLayer ) override; + ///> @copydoc PCB_BASE_FRAME::OnUpdateLayerAlpha() + void OnUpdateLayerAlpha( wxUpdateUIEvent& aEvent ) override; + ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas() virtual void UseGalCanvas( bool aEnable ) override; diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp index 87acce504e..917c283a3f 100644 --- a/pcbnew/layer_widget.cpp +++ b/pcbnew/layer_widget.cpp @@ -47,11 +47,6 @@ const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType(); -/* - * Icon providers for the row icons - */ -static ROW_ICON_PROVIDER defaultRowIcons( false ); -static ROW_ICON_PROVIDER alternativeRowIcons( true ); /** * Function shrinkFont @@ -322,13 +317,10 @@ 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 = COLUMN_ICON_ACTIVE; - auto sbm = new INDICATOR_ICON( m_LayerScrolledWindow, iconProvider, - ROW_ICON_PROVIDER::STATE::OFF, - encodeId( col, aSpec.id ) ); + auto sbm = new INDICATOR_ICON( m_LayerScrolledWindow, *m_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 ); @@ -358,6 +350,12 @@ void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec ) st->SetToolTip( aSpec.tooltip ); m_LayersFlexGridSizer->wxSizer::Insert( index+col, st, 0, flags ); + // column 4 (COLUMN_ALPHA_INDICATOR) + col = COLUMN_ALPHA_INDICATOR; + sbm = new INDICATOR_ICON( m_LayerScrolledWindow, *m_IconProvider, + ROW_ICON_PROVIDER::STATE::OFF, wxID_ANY ); + m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags ); + // Bind right click eventhandler to all columns wxString layerName( aSpec.rowName ); @@ -462,6 +460,9 @@ LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPoint m_notebook->SetMeasuringFont( font ); } + int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x; + m_IconProvider = new ROW_ICON_PROVIDER( indicatorSize ); + m_LayerPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer3; @@ -469,7 +470,7 @@ LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPoint m_LayerScrolledWindow = new wxScrolledWindow( m_LayerPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER ); m_LayerScrolledWindow->SetScrollRate( 5, 5 ); - m_LayersFlexGridSizer = new wxFlexGridSizer( 0, 4, 0, 1 ); + m_LayersFlexGridSizer = new wxFlexGridSizer( 0, LYR_COLUMN_COUNT, 0, 1 ); m_LayersFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL ); m_LayersFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE ); @@ -489,7 +490,7 @@ LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPoint m_RenderScrolledWindow = new wxScrolledWindow( m_RenderingPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER ); m_RenderScrolledWindow->SetScrollRate( 5, 5 ); - m_RenderFlexGridSizer = new wxFlexGridSizer( 0, 2, 0, 1 ); + m_RenderFlexGridSizer = new wxFlexGridSizer( 0, RND_COLUMN_COUNT, 0, 1 ); m_RenderFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL ); m_RenderFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE ); @@ -520,6 +521,7 @@ LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPoint LAYER_WIDGET::~LAYER_WIDGET() { + delete m_IconProvider; } @@ -627,7 +629,12 @@ void LAYER_WIDGET::SelectLayerRow( int aRow ) INDICATOR_ICON* oldIndicator = (INDICATOR_ICON*) getLayerComp( m_CurrentRow, 0 ); if( oldIndicator ) - oldIndicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF ); + { + if( useAlternateBitmap( m_CurrentRow ) ) + oldIndicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::DIMMED ); + else + oldIndicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF ); + } INDICATOR_ICON* newIndicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 ); if( newIndicator ) @@ -771,8 +778,15 @@ void LAYER_WIDGET::UpdateLayerIcons() if( indicator ) { - auto state = ( row == m_CurrentRow ) ? ROW_ICON_PROVIDER::STATE::ON - : ROW_ICON_PROVIDER::STATE::OFF; + ROW_ICON_PROVIDER::STATE state; + + if( row == m_CurrentRow ) + state = ROW_ICON_PROVIDER::STATE::ON; + else if( useAlternateBitmap( row ) ) + state = ROW_ICON_PROVIDER::STATE::DIMMED; + else + state = ROW_ICON_PROVIDER::STATE::OFF; + indicator->SetIndicatorState( state ); } } diff --git a/pcbnew/layer_widget.h b/pcbnew/layer_widget.h index d1fe0e76be..902988b4ba 100644 --- a/pcbnew/layer_widget.h +++ b/pcbnew/layer_widget.h @@ -44,14 +44,16 @@ #include #include #include +#include -#define LYR_COLUMN_COUNT 4 ///< Layer tab column count +#define LYR_COLUMN_COUNT 5 ///< Layer tab column count #define RND_COLUMN_COUNT 2 ///< Rendering tab column count #define COLUMN_ICON_ACTIVE 0 #define COLUMN_COLORBM 1 #define COLUMN_COLOR_LYR_CB 2 #define COLUMN_COLOR_LYRNAME 3 +#define COLUMN_ALPHA_INDICATOR 4 using KIGFX::COLOR4D; @@ -119,6 +121,8 @@ protected: int m_CurrentRow; ///< selected row of layer list int m_PointSize; + ROW_ICON_PROVIDER* m_IconProvider; + /** * Virtual Function useAlternateBitmap * @return true if bitmaps shown in Render layer list diff --git a/pcbnew/menubar_footprint_editor.cpp b/pcbnew/menubar_footprint_editor.cpp index 9b461ec093..471cfda625 100644 --- a/pcbnew/menubar_footprint_editor.cpp +++ b/pcbnew/menubar_footprint_editor.cpp @@ -302,13 +302,34 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() _( "Select how items are displayed" ), KiBitmap( add_zone_xpm ) ); + // Contrast Mode Submenu + wxMenu* contrastModeSubMenu = new wxMenu; text = AddHotkeyName( _( "&High Contrast Mode" ), m_hotkeysDescrList, HK_SWITCH_HIGHCONTRAST_MODE ); - AddMenuItem( viewMenu, ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, text, + AddMenuItem( contrastModeSubMenu, ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, text, _( "Use high contrast display mode" ), KiBitmap( contrast_mode_xpm ), wxITEM_CHECK ); + contrastModeSubMenu->AppendSeparator(); + + text = AddHotkeyName( _( "&Dim Current Layer" ), g_Pcbnew_Editor_Hotkeys_Descr, + HK_DEC_LAYER_ALHPA ); + AddMenuItem( contrastModeSubMenu, ID_DEC_LAYER_ALPHA, + text, _( "Dim the current layer" ), + KiBitmap( contrast_mode_xpm ) ); + + text = AddHotkeyName( _( "&Brighten Current Layer" ), g_Pcbnew_Editor_Hotkeys_Descr, + HK_INC_LAYER_ALHPA ); + AddMenuItem( contrastModeSubMenu, ID_INC_LAYER_ALPHA, + text, _( "Brighten the current layer" ), + KiBitmap( contrast_mode_xpm ) ); + + AddMenuItem( viewMenu, contrastModeSubMenu, + -1, _( "&Contrast Mode" ), + _( "Select how items are displayed" ), + KiBitmap( contrast_mode_xpm ) ); + #ifdef __APPLE__ viewMenu->AppendSeparator(); #endif diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp index 4ae435ae38..75ef20cfa0 100644 --- a/pcbnew/menubar_pcb_editor.cpp +++ b/pcbnew/menubar_pcb_editor.cpp @@ -744,13 +744,34 @@ void prepareViewMenu( wxMenu* aParentMenu, bool aUseGal ) _( "Select how items are displayed" ), KiBitmap( add_zone_xpm ) ); + // Contrast Mode Submenu + wxMenu* contrastModeSubMenu = new wxMenu; text = AddHotkeyName( _( "&High Contrast Mode" ), g_Pcbnew_Editor_Hotkeys_Descr, HK_SWITCH_HIGHCONTRAST_MODE ); - AddMenuItem( aParentMenu, ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, + AddMenuItem( contrastModeSubMenu, ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, text, _( "Use high contrast display mode" ), KiBitmap( contrast_mode_xpm ), wxITEM_CHECK ); + contrastModeSubMenu->AppendSeparator(); + + text = AddHotkeyName( _( "&Dim Current Layer" ), g_Pcbnew_Editor_Hotkeys_Descr, + HK_DEC_LAYER_ALHPA ); + AddMenuItem( contrastModeSubMenu, ID_DEC_LAYER_ALPHA, + text, _( "Dim the current layer" ), + KiBitmap( contrast_mode_xpm ) ); + + text = AddHotkeyName( _( "&Brighten Current Layer" ), g_Pcbnew_Editor_Hotkeys_Descr, + HK_INC_LAYER_ALHPA ); + AddMenuItem( contrastModeSubMenu, ID_INC_LAYER_ALPHA, + text, _( "Brighten the current layer" ), + KiBitmap( contrast_mode_xpm ) ); + + AddMenuItem( aParentMenu, contrastModeSubMenu, + -1, _( "&Contrast Mode" ), + _( "Select how items are displayed" ), + KiBitmap( contrast_mode_xpm ) ); + AddMenuItem( aParentMenu, ID_MENU_PCB_FLIP_VIEW, _( "Flip &Board View" ), _( "Flip (mirror) the board view" ), diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 2a397040fb..682d6da8fa 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -962,6 +962,12 @@ void PCB_EDIT_FRAME::syncLayerVisibilities() } +void PCB_EDIT_FRAME::OnUpdateLayerAlpha( wxUpdateUIEvent & ) +{ + m_Layers->SyncLayerAlphaIndicators(); +} + + void PCB_EDIT_FRAME::unitsChangeRefresh() { PCB_BASE_FRAME::unitsChangeRefresh(); // Update the grid size select box. diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index 1fef5e26a8..9c299614d2 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -604,6 +604,11 @@ public: */ virtual void SetActiveLayer( PCB_LAYER_ID aLayer ) override; + /** + * Update the UI to reflect changes to the current layer's transparency. + */ + void OnUpdateLayerAlpha( wxUpdateUIEvent& aEvent ) override; + /** * Function IsElementVisible * tests whether a given element category is visible. Keep this as an diff --git a/pcbnew/pcb_layer_widget.cpp b/pcbnew/pcb_layer_widget.cpp index a2a184b657..2bc622d154 100644 --- a/pcbnew/pcb_layer_widget.cpp +++ b/pcbnew/pcb_layer_widget.cpp @@ -39,9 +39,13 @@ #include #include #include +#include #include +#include #include #include +#include +#include #include #include @@ -451,6 +455,42 @@ void PCB_LAYER_WIDGET::SyncLayerVisibilities() } +#define ALPHA_EPSILON 0.04 + +void PCB_LAYER_WIDGET::SyncLayerAlphaIndicators() +{ + int count = GetLayerRowCount(); + TOOL_MANAGER* mgr = myframe->GetToolManager(); + KIGFX::PCB_PAINTER* painter = static_cast( mgr->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = painter->GetSettings(); + + for( int row = 0; row < count; ++row ) + { + // this utilizes more implementation knowledge than ideal, eventually + // add member ROW getRow() or similar to base LAYER_WIDGET. + + wxWindow* w = getLayerComp( row, COLUMN_ICON_ACTIVE ); + PCB_LAYER_ID layerId = ToLAYER_ID( getDecodedId( w->GetId() ) ); + KIGFX::COLOR4D screenColor = settings->GetLayerColor( layerId ); + + COLOR_SWATCH* swatch = static_cast( getLayerComp( row, COLUMN_COLORBM ) ); + KIGFX::COLOR4D layerColor = swatch->GetSwatchColor(); + + INDICATOR_ICON* indicator = static_cast( getLayerComp( row, COLUMN_ALPHA_INDICATOR ) ); + + if( std::abs( screenColor.a - layerColor.a ) > ALPHA_EPSILON ) + { + if( screenColor.a < layerColor.a ) + indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::DOWN ); + else + indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::UP ); + } + else + indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF ); + } +} + + void PCB_LAYER_WIDGET::ReFill() { BOARD* brd = myframe->GetBoard(); diff --git a/pcbnew/pcb_layer_widget.h b/pcbnew/pcb_layer_widget.h index b73468aa5c..04751872b1 100644 --- a/pcbnew/pcb_layer_widget.h +++ b/pcbnew/pcb_layer_widget.h @@ -80,6 +80,13 @@ public: */ void SyncLayerVisibilities(); + /** + * Function SyncLayerAlphaIndicators + * updates each "Layer"s alpha indicator to show if the board is currently being + * rendered with more transparency or less. + */ + void SyncLayerAlphaIndicators(); + /** * Function SetLayersManagerTabsText * Update the layer manager tabs labels diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h index e7d56a21d2..ac3aa433e8 100644 --- a/pcbnew/pcbnew_id.h +++ b/pcbnew/pcbnew_id.h @@ -319,6 +319,8 @@ enum pcbnew_ids ID_TB_OPTIONS_SHOW_VIAS_SKETCH, ID_TB_OPTIONS_SHOW_TRACKS_SKETCH, ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, + ID_DEC_LAYER_ALPHA, + ID_INC_LAYER_ALPHA, ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE, ID_PCB_MUWAVE_START_CMD, diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index 83ff15e819..2569bc3426 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -145,6 +145,12 @@ OPT PCB_ACTIONS::TranslateLegacyId( int aId ) case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE: return PCB_ACTIONS::highContrastMode.MakeEvent(); + case ID_DEC_LAYER_ALPHA: + return PCB_ACTIONS::layerAlphaDec.MakeEvent(); + + case ID_INC_LAYER_ALPHA: + return PCB_ACTIONS::layerAlphaInc.MakeEvent(); + case ID_FIND_ITEMS: return PCB_ACTIONS::find.MakeEvent(); diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 39a85a20ce..7a6ea11452 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -528,6 +528,9 @@ int PCBNEW_CONTROL::LayerAlphaInc( const TOOL_EVENT& aEvent ) currentColor.a += 0.05; settings->SetLayerColor( currentLayer, currentColor ); m_frame->GetGalCanvas()->GetView()->UpdateLayerColor( currentLayer ); + + wxUpdateUIEvent dummy; + static_cast( m_frame )->OnUpdateLayerAlpha( dummy ); } return 0; @@ -547,6 +550,9 @@ int PCBNEW_CONTROL::LayerAlphaDec( const TOOL_EVENT& aEvent ) currentColor.a -= 0.05; settings->SetLayerColor( currentLayer, currentColor ); m_frame->GetGalCanvas()->GetView()->UpdateLayerColor( currentLayer ); + + wxUpdateUIEvent dummy; + static_cast( m_frame )->OnUpdateLayerAlpha( dummy ); } return 0;