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;