From 6720473db944c46f4a7c21b07ba18384b56f037d Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Wed, 19 Aug 2020 21:11:22 -0400 Subject: [PATCH] Move net visibility/color controls to a wxGrid Fixes https://gitlab.com/kicad/code/kicad/-/issues/5235 Might improve https://gitlab.com/kicad/code/kicad/-/issues/5210 --- common/CMakeLists.txt | 1 + common/dialogs/dialog_color_picker.cpp | 2 +- common/dialogs/dialog_color_picker.h | 2 +- common/dialogs/dialog_color_picker_base.cpp | 4 +- common/dialogs/dialog_color_picker_base.fbp | 2 +- common/dialogs/panel_setup_netclasses.cpp | 2 +- common/widgets/color_swatch.cpp | 3 + common/widgets/grid_bitmap_toggle.cpp | 62 ++ common/widgets/grid_color_swatch_helpers.cpp | 66 +- common/widgets/grid_color_swatch_helpers.h | 22 +- include/widgets/color_swatch.h | 3 +- include/widgets/grid_bitmap_toggle.h | 53 ++ pcbnew/files.cpp | 2 - pcbnew/widgets/appearance_controls.cpp | 659 +++++++++++++------ pcbnew/widgets/appearance_controls.h | 119 +++- pcbnew/widgets/appearance_controls_base.cpp | 44 +- pcbnew/widgets/appearance_controls_base.fbp | 66 +- pcbnew/widgets/appearance_controls_base.h | 10 +- 18 files changed, 846 insertions(+), 276 deletions(-) create mode 100644 common/widgets/grid_bitmap_toggle.cpp create mode 100644 include/widgets/grid_bitmap_toggle.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index b917e7a6cc..ac7d818d55 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -208,6 +208,7 @@ set( COMMON_WIDGET_SRCS widgets/footprint_preview_widget.cpp widgets/footprint_select_widget.cpp widgets/gal_options_panel.cpp + widgets/grid_bitmap_toggle.cpp widgets/grid_color_swatch_helpers.cpp widgets/grid_combobox.cpp widgets/grid_icon_text_helpers.cpp diff --git a/common/dialogs/dialog_color_picker.cpp b/common/dialogs/dialog_color_picker.cpp index df4a5d76a1..1fdfec193d 100644 --- a/common/dialogs/dialog_color_picker.cpp +++ b/common/dialogs/dialog_color_picker.cpp @@ -40,7 +40,7 @@ void configureSpinCtrl( wxSpinCtrl* aCtrl ) } -DIALOG_COLOR_PICKER::DIALOG_COLOR_PICKER( wxWindow* aParent, COLOR4D& aCurrentColor, +DIALOG_COLOR_PICKER::DIALOG_COLOR_PICKER( wxWindow* aParent, const COLOR4D& aCurrentColor, bool aAllowOpacityControl, CUSTOM_COLORS_LIST* aUserColors, const COLOR4D& aDefaultColor ) : diff --git a/common/dialogs/dialog_color_picker.h b/common/dialogs/dialog_color_picker.h index 7d375bb690..2c973b31dc 100644 --- a/common/dialogs/dialog_color_picker.h +++ b/common/dialogs/dialog_color_picker.h @@ -79,7 +79,7 @@ public: * false to not show this setting (opacity = 1.0 always) * @param aUserColors: if not null is a list of defined colors replacing the dialog predefined colors */ - DIALOG_COLOR_PICKER( wxWindow* aParent, KIGFX::COLOR4D& aCurrentColor, + DIALOG_COLOR_PICKER( wxWindow* aParent, const KIGFX::COLOR4D& aCurrentColor, bool aAllowOpacityControl, CUSTOM_COLORS_LIST* aUserColors = nullptr, const KIGFX::COLOR4D& aDefaultColor = KIGFX::COLOR4D::UNSPECIFIED ); ~DIALOG_COLOR_PICKER(); diff --git a/common/dialogs/dialog_color_picker_base.cpp b/common/dialogs/dialog_color_picker_base.cpp index c4d3cba3f2..016cfaa681 100644 --- a/common/dialogs/dialog_color_picker_base.cpp +++ b/common/dialogs/dialog_color_picker_base.cpp @@ -143,9 +143,9 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID m_fgridColor->AddGrowableCol( 9 ); m_fgridColor->SetFlexibleDirection( wxBOTH ); m_fgridColor->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + - - m_SizerDefinedColors->Add( m_fgridColor, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 10 ); + m_SizerDefinedColors->Add( m_fgridColor, 1, wxALL|wxEXPAND, 10 ); m_panelDefinedColors->SetSizer( m_SizerDefinedColors ); diff --git a/common/dialogs/dialog_color_picker_base.fbp b/common/dialogs/dialog_color_picker_base.fbp index 4d1ca75767..89d354f381 100644 --- a/common/dialogs/dialog_color_picker_base.fbp +++ b/common/dialogs/dialog_color_picker_base.fbp @@ -1213,7 +1213,7 @@ protected 10 - wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND + wxALL|wxEXPAND 1 10 diff --git a/common/dialogs/panel_setup_netclasses.cpp b/common/dialogs/panel_setup_netclasses.cpp index a8e4e64400..ed4f84d57e 100644 --- a/common/dialogs/panel_setup_netclasses.cpp +++ b/common/dialogs/panel_setup_netclasses.cpp @@ -131,7 +131,7 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSE } wxGridCellAttr* attr = new wxGridCellAttr; - attr->SetRenderer( new GRID_CELL_COLOR_RENDERER() ); + attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( aParent ) ); attr->SetEditor( new GRID_CELL_COLOR_SELECTOR( aParent, m_netclassGrid ) ); m_netclassGrid->SetColAttr( GRID_SCHEMATIC_COLOR, attr ); diff --git a/common/widgets/color_swatch.cpp b/common/widgets/color_swatch.cpp index 79c85d4cd2..5b1f1d5ac1 100644 --- a/common/widgets/color_swatch.cpp +++ b/common/widgets/color_swatch.cpp @@ -120,11 +120,14 @@ COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, COLOR4D aColor, int aID, COLOR4D m_background( aBackground ), m_default( aDefault ) { + wxASSERT_MSG( aSwatchSize != SWATCH_EXPAND, "SWATCH_EXPAND not supported in COLOR_SWATCH" ); + switch( aSwatchSize ) { case SWATCH_MEDIUM: m_size = ConvertDialogToPixels( SWATCH_SIZE_MEDIUM_DU ); break; case SWATCH_SMALL: m_size = ConvertDialogToPixels( SWATCH_SIZE_SMALL_DU ); break; case SWATCH_LARGE: m_size = ConvertDialogToPixels( SWATCH_SIZE_LARGE_DU ); break; + case SWATCH_EXPAND: m_size = ConvertDialogToPixels( SWATCH_SIZE_LARGE_DU ); break; } m_checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU ); diff --git a/common/widgets/grid_bitmap_toggle.cpp b/common/widgets/grid_bitmap_toggle.cpp new file mode 100644 index 0000000000..ee8071cd0c --- /dev/null +++ b/common/widgets/grid_bitmap_toggle.cpp @@ -0,0 +1,62 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * @author Jon Evans + * + * 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 3 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, see . + */ + +#include +#include + + +GRID_BITMAP_TOGGLE_RENDERER::GRID_BITMAP_TOGGLE_RENDERER( const wxBitmap& aCheckedBitmap, + const wxBitmap& aUncheckedBitmap ) : + wxGridCellRenderer(), + m_bitmapChecked( aCheckedBitmap ), + m_bitmapUnchecked( aUncheckedBitmap ) +{ +} + + +GRID_BITMAP_TOGGLE_RENDERER* GRID_BITMAP_TOGGLE_RENDERER::Clone() const +{ + GRID_BITMAP_TOGGLE_RENDERER* clone = new GRID_BITMAP_TOGGLE_RENDERER( m_bitmapChecked, + m_bitmapUnchecked ); + return clone; +} + + +void GRID_BITMAP_TOGGLE_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDc, + const wxRect& aRect, int aRow, int aCol, bool aIsSelected ) +{ + // erase background + wxGridCellRenderer::Draw( aGrid, aAttr, aDc, aRect, aRow, aCol, aIsSelected ); + + bool checked = aGrid.GetCellValue( aRow, aCol ) == "1"; + const wxBitmap& bitmap = checked ? m_bitmapChecked : m_bitmapUnchecked; + + int x = std::max( 0, ( aRect.GetWidth() - m_bitmapChecked.GetWidth() ) / 2 ); + int y = std::max( 0, ( aRect.GetHeight() - m_bitmapChecked.GetHeight() ) / 2 ); + + aDc.DrawBitmap( bitmap, aRect.GetTopLeft() + wxPoint( x, y ) ); +} + + +wxSize GRID_BITMAP_TOGGLE_RENDERER::GetBestSize( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDc, + int aRow, int aCol) +{ + return m_bitmapChecked.GetSize(); +} diff --git a/common/widgets/grid_color_swatch_helpers.cpp b/common/widgets/grid_color_swatch_helpers.cpp index b47d3551de..bee87f4763 100644 --- a/common/widgets/grid_color_swatch_helpers.cpp +++ b/common/widgets/grid_color_swatch_helpers.cpp @@ -25,14 +25,37 @@ #include #include -#include //-------- Custom wxGridCellRenderers -------------------------------------------------- -GRID_CELL_COLOR_RENDERER::GRID_CELL_COLOR_RENDERER() +GRID_CELL_COLOR_RENDERER::GRID_CELL_COLOR_RENDERER( wxWindow* aParent, SWATCH_SIZE aSize, + const KIGFX::COLOR4D& aBackground ) : + wxGridCellRenderer(), + m_parent( aParent ), + m_background( aBackground ) { + switch( aSize ) + { + case SWATCH_MEDIUM: m_size = m_parent->ConvertDialogToPixels( SWATCH_SIZE_MEDIUM_DU ); break; + case SWATCH_SMALL: m_size = m_parent->ConvertDialogToPixels( SWATCH_SIZE_SMALL_DU ); break; + case SWATCH_LARGE: m_size = m_parent->ConvertDialogToPixels( SWATCH_SIZE_LARGE_DU ); break; + case SWATCH_EXPAND: m_size = wxDefaultSize; break; + } + + m_checkerboardSize = m_parent->ConvertDialogToPixels( CHECKERBOARD_SIZE_DU ); + m_checkerboardBg = m_parent->GetBackgroundColour(); +} + + +GRID_CELL_COLOR_RENDERER::GRID_CELL_COLOR_RENDERER( const GRID_CELL_COLOR_RENDERER& aOther ) +{ + m_parent = aOther.m_parent; + m_background = aOther.m_background; + m_size = aOther.m_size; + m_checkerboardSize = aOther.m_checkerboardSize; + m_checkerboardBg = aOther.m_checkerboardBg; } @@ -43,16 +66,19 @@ GRID_CELL_COLOR_RENDERER::~GRID_CELL_COLOR_RENDERER() wxGridCellRenderer* GRID_CELL_COLOR_RENDERER::Clone() const { - return new GRID_CELL_COLOR_RENDERER; + return new GRID_CELL_COLOR_RENDERER( *this ); } wxSize GRID_CELL_COLOR_RENDERER::GetBestSize( wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, int row, int col ) { + if( m_size != wxDefaultSize ) + return m_size; + wxSize bestSize; - dc.SetFont(attr.GetFont()); + dc.SetFont( attr.GetFont() ); dc.GetTextExtent( "WWW", &bestSize.x, &bestSize.y ); return bestSize; @@ -68,21 +94,21 @@ void GRID_CELL_COLOR_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& wxGridCellRenderer::Draw( aGrid, aAttr, aDC, aRect, aRow, aCol, isSelected ); // draw the swatch - wxBitmap bitmap( aRect.GetWidth() + 1, aRect.GetHeight() + 1 ); - wxMemoryDC bmpDC; - wxBrush brush; - wxColour color; + COLOR4D color( aGrid.GetTable()->GetValue( aRow, aCol ) ); + wxSize size = ( m_size == wxDefaultSize ) ? aRect.GetSize() : m_size; + wxBitmap bitmap = COLOR_SWATCH::MakeBitmap( color, m_background, size, m_checkerboardSize, + m_checkerboardBg ); - // Prepare Bitmap - bmpDC.SelectObject( bitmap ); + wxPoint origin = rect.GetTopLeft(); - color.Set( aGrid.GetTable()->GetValue( aRow, aCol ) ); - brush.SetStyle( wxBRUSHSTYLE_SOLID ); - brush.SetColour( color ); - bmpDC.SetBrush( brush ); - bmpDC.DrawRectangle( -1, -1, bitmap.GetWidth()+1, bitmap.GetHeight()+1 ); + if( m_size != wxDefaultSize ) + { + int x = std::max( 0, ( aRect.GetWidth() - m_size.x ) / 2 ); + int y = std::max( 0, ( aRect.GetHeight() - m_size.y ) / 2 ); + origin += wxPoint( x, y ); + } - aDC.DrawBitmap( bitmap, rect.GetTopLeft(), true ); + aDC.DrawBitmap( bitmap, origin, true ); } @@ -92,8 +118,8 @@ void GRID_CELL_COLOR_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& // Note: this implementation is an adaptation of wxGridCellBoolEditor -GRID_CELL_COLOR_SELECTOR::GRID_CELL_COLOR_SELECTOR( DIALOG_SHIM* aDialog, wxGrid* aGrid ) : - m_dialog( aDialog ), +GRID_CELL_COLOR_SELECTOR::GRID_CELL_COLOR_SELECTOR( wxWindow* aParent, wxGrid* aGrid ) : + m_parent( aParent ), m_grid( aGrid ), m_value( COLOR4D::UNSPECIFIED ) { @@ -102,7 +128,7 @@ GRID_CELL_COLOR_SELECTOR::GRID_CELL_COLOR_SELECTOR( DIALOG_SHIM* aDialog, wxGrid wxGridCellEditor* GRID_CELL_COLOR_SELECTOR::Clone() const { - return new GRID_CELL_COLOR_SELECTOR( m_dialog, m_grid ); + return new GRID_CELL_COLOR_SELECTOR( m_parent, m_grid ); } @@ -126,7 +152,7 @@ void GRID_CELL_COLOR_SELECTOR::BeginEdit( int row, int col, wxGrid* grid ) { m_value.SetFromWxString( grid->GetTable()->GetValue( row, col ) ); - DIALOG_COLOR_PICKER dialog( m_dialog, m_value, false ); + DIALOG_COLOR_PICKER dialog( m_parent, m_value, false ); if( dialog.ShowModal() == wxID_OK ) m_value = dialog.GetColor(); diff --git a/common/widgets/grid_color_swatch_helpers.h b/common/widgets/grid_color_swatch_helpers.h index 81c8e0c90a..1381ac4529 100644 --- a/common/widgets/grid_color_swatch_helpers.h +++ b/common/widgets/grid_color_swatch_helpers.h @@ -27,18 +27,19 @@ #include #include #include +#include class wxGrid; -class DIALOG_SHIM; - //-------- Custom wxGridCellRenderers -------------------------------------------------- class GRID_CELL_COLOR_RENDERER : public wxGridCellRenderer { public: - GRID_CELL_COLOR_RENDERER(); + GRID_CELL_COLOR_RENDERER( wxWindow* aParent = nullptr, SWATCH_SIZE aSize = SWATCH_EXPAND, + const KIGFX::COLOR4D& aBackground = KIGFX::COLOR4D::UNSPECIFIED ); + GRID_CELL_COLOR_RENDERER( const GRID_CELL_COLOR_RENDERER& aOther ); ~GRID_CELL_COLOR_RENDERER() override; wxGridCellRenderer* Clone() const override; @@ -46,6 +47,17 @@ public: void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC, const wxRect& aRect, int aRow, int aCol, bool isSelected ) override; + +private: + wxWindow* m_parent; + + KIGFX::COLOR4D m_background; + + wxSize m_size; + + wxSize m_checkerboardSize; + + KIGFX::COLOR4D m_checkerboardBg; }; @@ -56,7 +68,7 @@ public: class GRID_CELL_COLOR_SELECTOR : public wxGridCellEditor { public: - GRID_CELL_COLOR_SELECTOR( DIALOG_SHIM* aDialog, wxGrid* aGrid ); + GRID_CELL_COLOR_SELECTOR( wxWindow* aParent, wxGrid* aGrid ); wxGridCellEditor* Clone() const override; void Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler ) override; @@ -69,7 +81,7 @@ public: void Reset() override; protected: - DIALOG_SHIM* m_dialog; + wxWindow* m_parent; wxGrid* m_grid; KIGFX::COLOR4D m_value; diff --git a/include/widgets/color_swatch.h b/include/widgets/color_swatch.h index ba720048c8..4060db7633 100644 --- a/include/widgets/color_swatch.h +++ b/include/widgets/color_swatch.h @@ -35,7 +35,8 @@ enum SWATCH_SIZE { SWATCH_SMALL, SWATCH_MEDIUM, - SWATCH_LARGE + SWATCH_LARGE, + SWATCH_EXPAND }; diff --git a/include/widgets/grid_bitmap_toggle.h b/include/widgets/grid_bitmap_toggle.h new file mode 100644 index 0000000000..f57a40e170 --- /dev/null +++ b/include/widgets/grid_bitmap_toggle.h @@ -0,0 +1,53 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * @author Jon Evans + * + * 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 3 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, see . + */ + +#ifndef KICAD_GRID_BITMAP_TOGGLE_H +#define KICAD_GRID_BITMAP_TOGGLE_H + +#include +#include + + +/** + * A toggle button renderer for a wxGrid, similar to BITMAP_TOGGLE + */ +class GRID_BITMAP_TOGGLE_RENDERER : public wxGridCellRenderer +{ +public: + GRID_BITMAP_TOGGLE_RENDERER( const wxBitmap& aCheckedBitmap, + const wxBitmap& aUncheckedBitmap ); + + ~GRID_BITMAP_TOGGLE_RENDERER() {} + + GRID_BITMAP_TOGGLE_RENDERER* Clone() const override; + + void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDc, const wxRect& aRect, + int aRow, int aCol, bool aIsSelected ) override; + + wxSize GetBestSize( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDc, + int aRow, int aCol) override; + +private: + wxBitmap m_bitmapChecked; + + wxBitmap m_bitmapUnchecked; +}; + +#endif // KICAD_GRID_BITMAP_TOGGLE_H diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index d84328c6e6..56139358c5 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -643,8 +643,6 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in GetBoard()->BuildConnectivity(); Compile_Ratsnest( true ); - m_appearancePanel->OnBoardChanged(); - // Load project settings after setting up board; some of them depend on the nets list LoadProjectSettings(); diff --git a/pcbnew/widgets/appearance_controls.cpp b/pcbnew/widgets/appearance_controls.cpp index f70d40ee9e..852dc60004 100644 --- a/pcbnew/widgets/appearance_controls.cpp +++ b/pcbnew/widgets/appearance_controls.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -32,8 +33,244 @@ #include #include #include +#include +#include #include -#include + + +wxString NET_GRID_TABLE::GetValue( int aRow, int aCol ) +{ + wxASSERT( static_cast( aRow ) < m_nets.size() ); + + switch( aCol ) + { + case COL_COLOR: + return m_nets[aRow].color.ToWxString( wxC2S_CSS_SYNTAX ); + + case COL_VISIBILITY: + return m_nets[aRow].visible ? "1" : "0"; + + case COL_LABEL: + return m_nets[aRow].name; + + default: + return wxEmptyString; + } +} + + +void NET_GRID_TABLE::SetValue( int aRow, int aCol, const wxString& aValue ) +{ + wxASSERT( static_cast( aRow ) < m_nets.size() ); + + NET_GRID_ENTRY& net = m_nets[aRow]; + + switch( aCol ) + { + case COL_COLOR: + net.color.SetFromWxString( aValue ); + updateNetColor( net ); + break; + + case COL_VISIBILITY: + net.visible = ( aValue != "0" ); + updateNetVisibility( net ); + break; + + case COL_LABEL: + net.name = aValue; + break; + + default: + break; + } +} + + +wxString NET_GRID_TABLE::GetTypeName( int aRow, int aCol ) +{ + switch( aCol ) + { + case COL_COLOR: + return wxT( "COLOR4D" ); + + case COL_VISIBILITY: + return wxGRID_VALUE_BOOL; + + case COL_LABEL: + default: + return wxGRID_VALUE_STRING; + } +} + + +bool NET_GRID_TABLE::GetValueAsBool( int aRow, int aCol ) +{ + wxASSERT( static_cast( aRow ) < m_nets.size() ); + wxASSERT( aCol == COL_VISIBILITY ); + + return m_nets[aRow].visible; +} + + +void NET_GRID_TABLE::SetValueAsBool( int aRow, int aCol, bool aValue ) +{ + wxASSERT( static_cast( aRow ) < m_nets.size() ); + wxASSERT( aCol == COL_VISIBILITY ); + + m_nets[aRow].visible = aValue; + updateNetVisibility( m_nets[aRow] ); +} + + +void* NET_GRID_TABLE::GetValueAsCustom( int aRow, int aCol, const wxString& aTypeName ) +{ + wxASSERT( aCol == COL_COLOR ); + wxASSERT( aTypeName == wxT( "COLOR4D" ) ); + wxASSERT( static_cast( aRow ) < m_nets.size() ); + + return ColorToVoid( m_nets[aRow].color ); +} + + +void NET_GRID_TABLE::SetValueAsCustom( int aRow, int aCol, const wxString& aTypeName, void* aValue ) +{ + wxASSERT( aCol == COL_COLOR ); + wxASSERT( aTypeName == wxT( "COLOR4D" ) ); + wxASSERT( static_cast( aRow ) < m_nets.size() ); + + m_nets[aRow].color = VoidToColor( aValue ); + updateNetColor( m_nets[aRow] ); + + if( GetView() ) + { + wxGridTableMessage msg( this, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES ); + GetView()->ProcessTableMessage( msg ); + } +} + + +NET_GRID_ENTRY& NET_GRID_TABLE::GetEntry( int aRow ) +{ + wxASSERT( static_cast( aRow ) < m_nets.size() ); + return m_nets[aRow]; +} + + +int NET_GRID_TABLE::GetRowByNetcode( int aCode ) +{ + auto it = std::find_if( m_nets.begin(), m_nets.end(), + [aCode]( const NET_GRID_ENTRY& aEntry ) + { + return aEntry.code == aCode; + } ); + + if( it == m_nets.end() ) + return -1; + + return std::distance( m_nets.begin(), it ); +} + + +void NET_GRID_TABLE::Rebuild() +{ + BOARD* board = m_frame->GetBoard(); + const NETNAMES_MAP& nets = board->GetNetInfo().NetsByName(); + + KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( + m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings() ); + + std::set& hiddenNets = rs->GetHiddenNets(); + std::map& netColors = rs->GetNetColorMap(); + + int deleted = m_nets.size(); + m_nets.clear(); + + if( GetView() ) + { + wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, deleted ); + GetView()->ProcessTableMessage( msg ); + } + + for( const std::pair& pair : nets ) + { + int netCode = pair.second->GetNet(); + + if( netCode > 0 ) + { + COLOR4D color = netColors.count( netCode ) ? netColors.at( netCode ) : + COLOR4D::UNSPECIFIED; + + bool visible = hiddenNets.count( netCode ) == 0; + + m_nets.emplace_back( NET_GRID_ENTRY( netCode, pair.first, color, visible ) ); + } + } + + // TODO(JE) move to ::Compare so we can re-sort easily + std::sort( m_nets.begin(), m_nets.end(), + []( const NET_GRID_ENTRY& a, const NET_GRID_ENTRY& b ) + { + return a.name < b.name; + } ); + + if( GetView() ) + { + wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_nets.size() ); + GetView()->ProcessTableMessage( msg ); + + GetView()->AutoSizeColumn( NET_GRID_TABLE::COL_LABEL ); + } +} + + +void NET_GRID_TABLE::ShowAllNets() +{ + for( NET_GRID_ENTRY& net : m_nets ) + { + net.visible = true; + updateNetVisibility( net ); + } + + if( GetView() ) + GetView()->ForceRefresh(); +} + + +void NET_GRID_TABLE::HideOtherNets( const NET_GRID_ENTRY& aNet ) +{ + for( NET_GRID_ENTRY& net : m_nets ) + { + net.visible = ( net.code == aNet.code ); + updateNetVisibility( net ); + } + + if( GetView() ) + GetView()->ForceRefresh(); +} + + +void NET_GRID_TABLE::updateNetVisibility( const NET_GRID_ENTRY& aNet ) +{ + const TOOL_ACTION& action = aNet.visible ? PCB_ACTIONS::showNet : PCB_ACTIONS::hideNet; + m_frame->GetToolManager()->RunAction( action, true, aNet.code ); +} + + +void NET_GRID_TABLE::updateNetColor( const NET_GRID_ENTRY& aNet ) +{ + KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( + m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings() ); + + std::map& netColors = rs->GetNetColorMap(); + + netColors[aNet.code] = aNet.color; + + m_frame->GetCanvas()->GetView()->UpdateAllLayersColor(); + m_frame->GetCanvas()->RedrawRatsnest(); + m_frame->GetCanvas()->Refresh(); +} + /// Template for object appearance settings const APPEARANCE_CONTROLS::APPEARANCE_SETTING APPEARANCE_CONTROLS::s_objectSettings[] = { @@ -94,8 +331,7 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo m_focusOwner( aFocusOwner ), m_board( nullptr ), m_currentPreset( nullptr ), - m_layerContextMenu( nullptr ), - m_contextMenuNetCode( 0 ) + m_layerContextMenu( nullptr ) { int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x; m_iconProvider = new ROW_ICON_PROVIDER( indicatorSize ); @@ -121,9 +357,9 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo pointSize = pointSize * 8 / 10; m_pointSize = pointSize; + wxFont font = m_notebook->GetFont(); #ifdef __WXMAC__ - wxFont font = m_notebook->GetFont(); font.SetPointSize( m_pointSize ); m_notebook->SetFont( font ); #endif @@ -183,6 +419,41 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo m_paneLayerDisplay->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_toggleGridRenderer = new GRID_BITMAP_TOGGLE_RENDERER( KiBitmap( visibility_xpm ), + KiBitmap( visibility_off_xpm ) ); + + m_netsGrid->RegisterDataType( wxT( "bool" ), m_toggleGridRenderer, new wxGridCellBoolEditor ); + + // TODO(JE) Update background color of swatch renderer when theme changes + m_netsGrid->RegisterDataType( wxT( "COLOR4D" ), + new GRID_CELL_COLOR_RENDERER( m_frame, SWATCH_SMALL ), + new GRID_CELL_COLOR_SELECTOR( m_frame, m_netsGrid ) ); + + m_netsTable = new NET_GRID_TABLE( m_frame ); + m_netsGrid->SetTable( m_netsTable, true, wxGrid::wxGridSelectRows ); + + m_netsGrid->SetSelectionForeground( m_netsGrid->GetDefaultCellTextColour() ); + m_netsGrid->SetSelectionBackground( m_netsGrid->GetBackgroundColour() ); + + const int cellPadding = 6; + const int rowHeightPadding = 4; + + wxSize size = ConvertDialogToPixels( SWATCH_SIZE_SMALL_DU ); + m_netsGrid->SetColSize( NET_GRID_TABLE::COL_COLOR, size.x + cellPadding ); + + size = KiBitmap( visibility_xpm ).GetSize(); + m_netsGrid->SetColSize( NET_GRID_TABLE::COL_VISIBILITY, size.x + cellPadding ); + + m_netsGrid->SetDefaultCellFont( font ); + m_netsGrid->SetDefaultRowSize( font.GetPixelSize().y + rowHeightPadding ); + + m_netsGrid->GetGridWindow()->Bind( wxEVT_MOTION, + &APPEARANCE_CONTROLS::OnNetGridMouseEvent, this ); + + // To handle middle click on color swatches + m_netsGrid->GetGridWindow()->Bind( wxEVT_MIDDLE_UP, + &APPEARANCE_CONTROLS::OnNetGridMouseEvent, this ); + m_currentLayer = F_Cu; loadDefaultLayerPresets(); @@ -271,6 +542,143 @@ void APPEARANCE_CONTROLS::OnSetFocus( wxFocusEvent& aEvent ) } +void APPEARANCE_CONTROLS::OnSize( wxSizeEvent& aEvent ) +{ + aEvent.Skip(); +} + + +void APPEARANCE_CONTROLS::OnNetGridClick( wxGridEvent& event ) +{ + int row = event.GetRow(); + int col = event.GetCol(); + + switch( col ) + { + case NET_GRID_TABLE::COL_VISIBILITY: + m_netsTable->SetValueAsBool( row, col, !m_netsTable->GetValueAsBool( row, col ) ); + m_netsGrid->RefreshRect( m_netsGrid->CellToRect( row, col ) ); + break; + + default: + break; + } +} + + +void APPEARANCE_CONTROLS::OnNetGridDoubleClick( wxGridEvent& event ) +{ + int row = event.GetRow(); + int col = event.GetCol(); + + switch( col ) + { + case NET_GRID_TABLE::COL_COLOR: + m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid ); + break; + + default: + break; + } +} + + +void APPEARANCE_CONTROLS::OnNetGridRightClick( wxGridEvent& event ) +{ + m_netsGrid->SelectRow( event.GetRow() ); + + wxString netName = m_netsGrid->GetCellValue( event.GetRow(), NET_GRID_TABLE::COL_LABEL ); + wxMenu menu; + + menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR, + _( "Set net color" ), wxEmptyString, wxITEM_NORMAL ) ); + menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET, + wxString::Format( _( "Highlight %s" ), netName ), + wxEmptyString, wxITEM_NORMAL ) ); + menu.Append( new wxMenuItem( &menu, ID_SELECT_NET, + wxString::Format( _( "Select tracks and vias in %s" ), netName ), + wxEmptyString, wxITEM_NORMAL ) ); + + menu.AppendSeparator(); + + menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS, + _( "Show all nets" ), wxEmptyString, wxITEM_NORMAL ) ); + menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS, + _( "Hide all other nets" ), wxEmptyString, + wxITEM_NORMAL ) ); + + menu.Bind( wxEVT_COMMAND_MENU_SELECTED, + &APPEARANCE_CONTROLS::onNetContextMenu, this ); + + PopupMenu( &menu ); +} + + +void APPEARANCE_CONTROLS::OnNetGridMouseEvent( wxMouseEvent& aEvent ) +{ + wxPoint pos = m_netsGrid->CalcUnscrolledPosition( aEvent.GetPosition() ); + wxGridCellCoords cell = m_netsGrid->XYToCell( pos ); + + if( aEvent.Moving() || aEvent.Entering() ) + { + aEvent.Skip(); + + if( !cell ) + { + m_netsGrid->GetGridWindow()->UnsetToolTip(); + return; + } + + if( cell == m_hoveredCell ) + return; + + m_hoveredCell = cell; + + NET_GRID_ENTRY& net = m_netsTable->GetEntry( cell.GetRow() ); + + wxString name = net.name; + wxString showOrHide = net.visible ? _( "Click to hide ratsnest for %s" ) + : _( "Click to show ratsnest for %s" ); + wxString tip; + + if( cell.GetCol() == NET_GRID_TABLE::COL_VISIBILITY ) + tip.Printf( showOrHide, name ); + else if( cell.GetCol() == NET_GRID_TABLE::COL_COLOR ) + tip = _( "Left double click or middle click for color change, " + "right click for menu" ); + + m_netsGrid->GetGridWindow()->SetToolTip( tip ); + } + else if( aEvent.Leaving() ) + { + m_netsGrid->UnsetToolTip(); + aEvent.Skip(); + } + else if( aEvent.Dragging() ) + { + // not allowed + CallAfter( [&]() + { + m_netsGrid->ClearSelection(); + } ); + } + else if( aEvent.ButtonUp( wxMOUSE_BTN_MIDDLE ) && !!cell ) + { + int row = cell.GetRow(); + int col = cell.GetCol(); + + if(col == NET_GRID_TABLE::COL_COLOR ) + m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid ); + + aEvent.Skip(); + } + else + { + aEvent.Skip(); + } +} + + void APPEARANCE_CONTROLS::OnBoardChanged() { Freeze(); @@ -1223,128 +1631,10 @@ void APPEARANCE_CONTROLS::rebuildNets() KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings() ); - std::set& hiddenNets = rs->GetHiddenNets(); - std::map& netColors = rs->GetNetColorMap(); std::map& netclassColors = rs->GetNetclassColorMap(); - m_netsOuterSizer->Clear( true ); m_netclassOuterSizer->Clear( true ); - auto appendNet = - [&]( NETINFO_ITEM* aNet ) - { - int netCode = aNet->GetNet(); - int id = netCode + wxID_HIGHEST; - - if( netCode == 0 ) - return; - - m_netSettings.emplace_back( std::make_unique() ); - APPEARANCE_SETTING* setting = m_netSettings.back().get(); - m_netSettingsMap[netCode] = setting; - - setting->ctl_panel = new wxPanel( m_netsScrolledWindow, id ); - wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL ); - setting->ctl_panel->SetSizer( sizer ); - - COLOR4D color = netColors.count( netCode ) ? netColors.at( netCode ) : - COLOR4D::UNSPECIFIED; - - setting->ctl_color = new COLOR_SWATCH( setting->ctl_panel, color, id, bgColor, - COLOR4D::UNSPECIFIED, SWATCH_SMALL ); - setting->ctl_color->SetToolTip( _( "Left double click or middle click for color " - "change, right click for menu" ) ); - - setting->ctl_color->Bind( COLOR_SWATCH_CHANGED, - [&]( wxCommandEvent& aEvent ) - { - COLOR_SWATCH* s = static_cast( aEvent.GetEventObject() ); - int net = s->GetId(); - net -= wxID_HIGHEST; - - netColors[net] = s->GetSwatchColor(); - - m_frame->GetCanvas()->GetView()->UpdateAllLayersColor(); - - m_frame->GetCanvas()->RedrawRatsnest(); - m_frame->GetCanvas()->Refresh(); - passOnFocus(); - } ); - - bool visible = hiddenNets.count( netCode ) == 0; - - setting->ctl_visibility = - new BITMAP_TOGGLE( setting->ctl_panel, id, KiBitmap( visibility_xpm ), - KiBitmap( visibility_off_xpm ), visible ); - - wxString tip; - tip.Printf( _( "Show or hide ratsnest for %s" ), aNet->GetShortNetname() ); - setting->ctl_visibility->SetToolTip( tip ); - - setting->ctl_text = new wxStaticText( setting->ctl_panel, id, - aNet->GetShortNetname() ); - setting->ctl_text->Wrap( -1 ); - - sizer->Add( setting->ctl_color, 0, wxALIGN_CENTER_VERTICAL, 5 ); - sizer->AddSpacer( 7 ); - sizer->Add( setting->ctl_visibility, 0, wxALIGN_CENTER_VERTICAL, 5 ); - sizer->AddSpacer( 3 ); - sizer->Add( setting->ctl_text, 1, wxALIGN_CENTER_VERTICAL, 5 ); - - m_netsOuterSizer->Add( setting->ctl_panel, 0, wxEXPAND, 5 ); - m_netsOuterSizer->AddSpacer( 1 ); - - setting->ctl_visibility->Bind( TOGGLE_CHANGED, - [&]( wxCommandEvent& aEvent ) - { - int net = static_cast( aEvent.GetEventObject() )->GetId(); - net -= wxID_HIGHEST; - const TOOL_ACTION& action = aEvent.GetInt() ? PCB_ACTIONS::showNet : - PCB_ACTIONS::hideNet; - - m_frame->GetToolManager()->RunAction( action, true, net ); - passOnFocus(); - } ); - - const wxString& netName = aNet->GetShortNetname(); - - auto menuHandler = - [&, netCode, netName]( wxMouseEvent& aEvent ) - { - m_contextMenuNetCode = netCode; - - wxMenu menu; - - menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR, - _( "Set net color" ), wxEmptyString, wxITEM_NORMAL ) ); - menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET, - wxString::Format( _( "Highlight %s" ), netName ), - wxEmptyString, wxITEM_NORMAL ) ); - menu.Append( new wxMenuItem( &menu, ID_SELECT_NET, - wxString::Format( _( "Select tracks and vias in %s" ), - netName ), - wxEmptyString, wxITEM_NORMAL ) ); - - menu.AppendSeparator(); - - menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS, - _( "Show all nets" ), wxEmptyString, wxITEM_NORMAL ) ); - menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS, - _( "Hide all other nets" ), wxEmptyString, - wxITEM_NORMAL ) ); - - menu.Bind( wxEVT_COMMAND_MENU_SELECTED, - &APPEARANCE_CONTROLS::onNetContextMenu, this ); - - PopupMenu( &menu ); - }; - - setting->ctl_panel->Bind( wxEVT_RIGHT_DOWN, menuHandler ); - setting->ctl_visibility->Bind( wxEVT_RIGHT_DOWN, menuHandler ); - setting->ctl_color->Bind( wxEVT_RIGHT_DOWN, menuHandler ); - setting->ctl_text->Bind( wxEVT_RIGHT_DOWN, menuHandler ); - }; - auto appendNetclass = [&]( int aId, const NETCLASSPTR& aClass, bool isDefaultClass = false ) { @@ -1441,24 +1731,9 @@ void APPEARANCE_CONTROLS::rebuildNets() setting->ctl_text->Bind( wxEVT_RIGHT_DOWN, menuHandler ); }; - const NETNAMES_MAP& nets = board->GetNetInfo().NetsByName(); - - std::vector names; - - for( const auto& pair : nets ) - names.emplace_back( pair.first ); - - std::sort( names.begin(), names.end() ); - - m_netSettings.clear(); - m_netSettingsMap.clear(); - - for( const wxString& name : names ) - appendNet( nets.at( name ) ); - const NETCLASS_MAP& classes = board->GetDesignSettings().GetNetClasses().NetClasses(); - names.clear(); + std::vector names; for( const auto& pair : classes ) names.emplace_back( pair.first ); @@ -1467,7 +1742,7 @@ void APPEARANCE_CONTROLS::rebuildNets() m_netclassIdMap.clear(); - int idx = wxID_HIGHEST + nets.size(); + int idx = wxID_HIGHEST; NETCLASSPTR defaultClass = board->GetDesignSettings().GetNetClasses().GetDefault(); @@ -1480,7 +1755,9 @@ void APPEARANCE_CONTROLS::rebuildNets() appendNetclass( idx++, classes.at( name ) ); } - m_netsOuterSizer->Layout(); + m_netsTable->Rebuild(); + + //m_netsOuterSizer->Layout(); m_netclassOuterSizer->Layout(); //m_netsTabSplitter->Layout(); } @@ -1727,79 +2004,48 @@ void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity ) void APPEARANCE_CONTROLS::onNetContextMenu( wxCommandEvent& aEvent ) { + wxASSERT( m_netsGrid->GetSelectedRows().size() == 1 ); + + int row = m_netsGrid->GetSelectedRows()[0]; + NET_GRID_ENTRY& net = m_netsTable->GetEntry( row ); + + m_netsGrid->ClearSelection(); + switch( aEvent.GetId() ) { case ID_SET_NET_COLOR: { - if( m_netSettingsMap.count( m_contextMenuNetCode ) ) - { - APPEARANCE_SETTING* setting = m_netSettingsMap.at( m_contextMenuNetCode ); - setting->ctl_color->GetNewSwatchColor(); - - COLOR4D color = setting->ctl_color->GetSwatchColor(); - - setting->ctl_color->Show( color != COLOR4D::UNSPECIFIED ); - - KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( - m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings() ); - std::map& netColors = rs->GetNetColorMap(); - - if( color != COLOR4D::UNSPECIFIED ) - netColors[m_contextMenuNetCode] = color; - else - netColors.erase( m_contextMenuNetCode ); - - m_frame->GetCanvas()->GetView()->UpdateAllLayersColor(); - m_frame->GetCanvas()->Refresh(); - } - + wxGridCellEditor* editor = m_netsGrid->GetCellEditor( row, NET_GRID_TABLE::COL_COLOR ); + editor->BeginEdit( row, NET_GRID_TABLE::COL_COLOR, m_netsGrid ); break; } case ID_HIGHLIGHT_NET: - m_frame->GetToolManager()->RunAction( PCB_ACTIONS::highlightNet, true, - m_contextMenuNetCode ); + { + m_frame->GetToolManager()->RunAction( PCB_ACTIONS::highlightNet, true, net.code ); + m_frame->GetCanvas()->Refresh(); break; + } case ID_SELECT_NET: - m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectNet, true, - m_contextMenuNetCode ); + { + m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectNet, true, net.code ); + m_frame->GetCanvas()->Refresh(); break; + } case ID_SHOW_ALL_NETS: - { - for( const std::pair& pair : m_netSettingsMap ) - { - pair.second->ctl_visibility->SetValue( true ); - m_frame->GetToolManager()->RunAction( PCB_ACTIONS::showNet, true, pair.first ); - } - + m_netsTable->ShowAllNets(); break; - } case ID_HIDE_OTHER_NETS: - { - TOOL_MANAGER* manager = m_frame->GetToolManager(); - - for( const std::pair& pair : m_netSettingsMap ) - { - bool show = pair.first == m_contextMenuNetCode; - pair.second->ctl_visibility->SetValue( show ); - manager->RunAction( show ? PCB_ACTIONS::showNet : PCB_ACTIONS::hideNet, - true, pair.first ); - } - + m_netsTable->HideOtherNets( net ); break; - } default: break; } - m_frame->GetCanvas()->RedrawRatsnest(); - m_frame->GetCanvas()->Refresh(); - - m_contextMenuNetCode = 0; passOnFocus(); } @@ -1826,16 +2072,6 @@ void APPEARANCE_CONTROLS::showNetclass( const wxString& aClassName, bool aShow ) NETCLASS* defaultClass = classes.GetDefaultPtr(); - auto updateWidget = - [&]( int aCode ) - { - if( m_netSettingsMap.count( aCode ) ) - { - APPEARANCE_SETTING* setting = m_netSettingsMap.at( aCode ); - setting->ctl_visibility->SetValue( aShow ); - } - }; - if( netclass == classes.GetDefault() ) { const TOOL_ACTION& action = aShow ? PCB_ACTIONS::showNet : PCB_ACTIONS::hideNet; @@ -1845,7 +2081,15 @@ void APPEARANCE_CONTROLS::showNetclass( const wxString& aClassName, bool aShow ) if( net->GetNetClass() == defaultClass ) { manager->RunAction( action, true, net->GetNet() ); - updateWidget( net->GetNet() ); + + int row = m_netsTable->GetRowByNetcode( net->GetNet() ); + + if( row >= 0 ) + { + m_netsTable->SetValueAsBool( row, NET_GRID_TABLE::COL_VISIBILITY, aShow ); + m_netsGrid->RefreshRect( + m_netsGrid->CellToRect( row, NET_GRID_TABLE::COL_VISIBILITY ) ); + } } } } @@ -1857,8 +2101,17 @@ void APPEARANCE_CONTROLS::showNetclass( const wxString& aClassName, bool aShow ) { if( NETINFO_ITEM* net = nets.GetNetItem( member ) ) { - manager->RunAction( action, true, net->GetNet() ); - updateWidget( net->GetNet() ); + int code = net->GetNet(); + manager->RunAction( action, true, code ); + + int row = m_netsTable->GetRowByNetcode( code ); + + if( row >= 0 ) + { + m_netsTable->SetValueAsBool( row, NET_GRID_TABLE::COL_VISIBILITY, aShow ); + m_netsGrid->RefreshRect( + m_netsGrid->CellToRect( row, NET_GRID_TABLE::COL_VISIBILITY ) ); + } } } } diff --git a/pcbnew/widgets/appearance_controls.h b/pcbnew/widgets/appearance_controls.h index 2cbb02fe25..018acd744d 100644 --- a/pcbnew/widgets/appearance_controls.h +++ b/pcbnew/widgets/appearance_controls.h @@ -35,10 +35,102 @@ class COLOR_SWATCH; class INDICATOR_ICON; class PCB_BASE_FRAME; class ROW_ICON_PROVIDER; +class GRID_BITMAP_TOGGLE_RENDERER; using KIGFX::COLOR4D; +struct NET_GRID_ENTRY +{ + NET_GRID_ENTRY( int aCode, const wxString& aName, const COLOR4D& aColor, bool aVisible ) + { + code = aCode; + name = aName; + color = aColor; + visible = aVisible; + } + + int code; + wxString name; + COLOR4D color; + bool visible; +}; + + +class NET_GRID_TABLE : public wxGridTableBase +{ +public: + enum COLUMNS + { + COL_COLOR, + COL_VISIBILITY, + COL_LABEL, + COL_SIZE + }; + + static void* ColorToVoid( COLOR4D& aColor ) + { + return static_cast( &aColor ); + } + + static COLOR4D VoidToColor( void* aColor ) + { + return *static_cast( aColor ); + } + +public: + NET_GRID_TABLE( PCB_BASE_FRAME* aFrame ) : + wxGridTableBase(), + m_frame( aFrame ) + {} + + int GetNumberRows() override + { + return m_nets.size(); + } + + int GetNumberCols() override + { + return COL_SIZE; + } + + wxString GetValue( int aRow, int aCol ) override; + + void SetValue( int aRow, int aCol, const wxString& aValue ) override; + + wxString GetTypeName( int aRow, int aCol ) override; + + bool GetValueAsBool( int aRow, int aCol ) override; + + void SetValueAsBool( int aRow, int aCol, bool aValue ) override; + + void* GetValueAsCustom( int aRow, int aCol, const wxString& aTypeName ) override; + + void SetValueAsCustom( int aRow, int aCol, const wxString& aTypeName, void* aValue ) override; + + NET_GRID_ENTRY& GetEntry( int aRow ); + + int GetRowByNetcode( int aCode ); + + void Rebuild(); + + void ShowAllNets(); + + void HideOtherNets( const NET_GRID_ENTRY& aNet ); + +private: + void updateNetVisibility( const NET_GRID_ENTRY& aNet ); + + void updateNetColor( const NET_GRID_ENTRY& aNet ); + +private: + PCB_BASE_FRAME* m_frame; + + std::vector m_nets; +}; + + + class APPEARANCE_CONTROLS : public APPEARANCE_CONTROLS_BASE, public BOARD_LISTENER { public: @@ -164,6 +256,16 @@ protected: void OnSetFocus( wxFocusEvent& aEvent ) override; + void OnSize( wxSizeEvent& aEvent ) override; + + void OnNetGridClick( wxGridEvent& event ) override; + + void OnNetGridDoubleClick( wxGridEvent& event ) override; + + void OnNetGridRightClick( wxGridEvent& event ) override; + + void OnNetGridMouseEvent( wxMouseEvent& aEvent ); + private: PCB_BASE_FRAME* m_frame; @@ -175,6 +277,14 @@ private: BOARD* m_board; + // Nets grid view + NET_GRID_TABLE* m_netsTable; + + GRID_BITMAP_TOGGLE_RENDERER* m_toggleGridRenderer; + + /// Grid cell that is being hovered over, for tooltips + wxGridCellCoords m_hoveredCell; + PCB_LAYER_ID m_currentLayer; std::vector> m_layerSettings; @@ -185,10 +295,6 @@ private: std::map m_objectSettingsMap; - std::vector> m_netSettings; - - std::map m_netSettingsMap; - std::vector> m_netclassSettings; std::map m_netclassSettingsMap; @@ -207,9 +313,6 @@ private: /// Stores wxIDs for each netclass for control event mapping std::map m_netclassIdMap; - /// The net code of the net that was right-clicked - int m_contextMenuNetCode; - /// The name of the netclass that was right-clicked wxString m_contextMenuNetclass; @@ -304,6 +407,8 @@ private: void passOnFocus(); void idleFocusHandler( wxIdleEvent& aEvent ); + + void updateNetsDataViewToolTip( wxMouseEvent& aEvent ); }; #endif diff --git a/pcbnew/widgets/appearance_controls_base.cpp b/pcbnew/widgets/appearance_controls_base.cpp index 04a1d38cf1..fc8d54683d 100644 --- a/pcbnew/widgets/appearance_controls_base.cpp +++ b/pcbnew/widgets/appearance_controls_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jul 10 2019) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -120,15 +120,31 @@ APPEARANCE_CONTROLS_BASE::APPEARANCE_CONTROLS_BASE( wxWindow* parent, wxWindowID bSizer192->Add( bSizer17, 0, wxEXPAND, 5 ); - m_netsScrolledWindow = new wxScrolledWindow( m_panelNets, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL ); - m_netsScrolledWindow->SetScrollRate( 5, 5 ); - m_netsOuterSizer = new wxBoxSizer( wxVERTICAL ); + m_netsGrid = new wxGrid( m_panelNets, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + // Grid + m_netsGrid->CreateGrid( 5, 3 ); + m_netsGrid->EnableEditing( false ); + m_netsGrid->EnableGridLines( false ); + m_netsGrid->EnableDragGridSize( false ); + m_netsGrid->SetMargins( 0, 0 ); - m_netsScrolledWindow->SetSizer( m_netsOuterSizer ); - m_netsScrolledWindow->Layout(); - m_netsOuterSizer->Fit( m_netsScrolledWindow ); - bSizer192->Add( m_netsScrolledWindow, 1, wxEXPAND | wxALL, 5 ); + // Columns + m_netsGrid->EnableDragColMove( false ); + m_netsGrid->EnableDragColSize( false ); + m_netsGrid->SetColLabelSize( 0 ); + m_netsGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + + // Rows + m_netsGrid->EnableDragRowSize( false ); + m_netsGrid->SetRowLabelSize( 0 ); + m_netsGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + + // Label Appearance + + // Cell Defaults + m_netsGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + bSizer192->Add( m_netsGrid, 1, wxALL|wxEXPAND, 5 ); m_panelNets->SetSizer( bSizer192 ); @@ -173,7 +189,7 @@ APPEARANCE_CONTROLS_BASE::APPEARANCE_CONTROLS_BASE( wxWindow* parent, wxWindowID bSizer16->Add( m_netsTabSplitter, 1, wxEXPAND, 5 ); m_paneNetDisplay = new wxCollapsiblePane( m_panelNetsAndClasses, wxID_ANY, wxT("Net Display Options"), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE|wxCP_NO_TLW_RESIZE ); - m_paneNetDisplay->Collapse( false ); + m_paneNetDisplay->Collapse( true ); wxBoxSizer* bSizerNetDisplay; bSizerNetDisplay = new wxBoxSizer( wxVERTICAL ); @@ -260,6 +276,7 @@ APPEARANCE_CONTROLS_BASE::APPEARANCE_CONTROLS_BASE( wxWindow* parent, wxWindowID // Connect Events this->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ) ); + this->Connect( wxEVT_SIZE, wxSizeEventHandler( APPEARANCE_CONTROLS_BASE::OnSize ) ); m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( APPEARANCE_CONTROLS_BASE::OnNotebookPageChanged ), NULL, this ); m_notebook->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_panelLayers->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); @@ -270,6 +287,10 @@ APPEARANCE_CONTROLS_BASE::APPEARANCE_CONTROLS_BASE( wxWindow* parent, wxWindowID m_panelNetsAndClasses->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_panelNets->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_btnNetInspector->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); + m_netsGrid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( APPEARANCE_CONTROLS_BASE::OnNetGridClick ), NULL, this ); + m_netsGrid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( APPEARANCE_CONTROLS_BASE::OnNetGridDoubleClick ), NULL, this ); + m_netsGrid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( APPEARANCE_CONTROLS_BASE::OnNetGridRightClick ), NULL, this ); + m_netsGrid->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_panelNetclasses->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_btnConfigureNetClasses->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_paneNetDisplay->Connect( wxEVT_COLLAPSIBLEPANE_CHANGED, wxCollapsiblePaneEventHandler( APPEARANCE_CONTROLS_BASE::OnNetDisplayPaneChanged ), NULL, this ); @@ -281,6 +302,7 @@ APPEARANCE_CONTROLS_BASE::~APPEARANCE_CONTROLS_BASE() { // Disconnect Events this->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ) ); + this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( APPEARANCE_CONTROLS_BASE::OnSize ) ); m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( APPEARANCE_CONTROLS_BASE::OnNotebookPageChanged ), NULL, this ); m_notebook->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_panelLayers->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); @@ -291,6 +313,10 @@ APPEARANCE_CONTROLS_BASE::~APPEARANCE_CONTROLS_BASE() m_panelNetsAndClasses->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_panelNets->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_btnNetInspector->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); + m_netsGrid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( APPEARANCE_CONTROLS_BASE::OnNetGridClick ), NULL, this ); + m_netsGrid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( APPEARANCE_CONTROLS_BASE::OnNetGridDoubleClick ), NULL, this ); + m_netsGrid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( APPEARANCE_CONTROLS_BASE::OnNetGridRightClick ), NULL, this ); + m_netsGrid->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_panelNetclasses->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_btnConfigureNetClasses->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( APPEARANCE_CONTROLS_BASE::OnSetFocus ), NULL, this ); m_paneNetDisplay->Disconnect( wxEVT_COLLAPSIBLEPANE_CHANGED, wxCollapsiblePaneEventHandler( APPEARANCE_CONTROLS_BASE::OnNetDisplayPaneChanged ), NULL, this ); diff --git a/pcbnew/widgets/appearance_controls_base.fbp b/pcbnew/widgets/appearance_controls_base.fbp index 4b5b2a107f..2cfc146d5b 100644 --- a/pcbnew/widgets/appearance_controls_base.fbp +++ b/pcbnew/widgets/appearance_controls_base.fbp @@ -14,7 +14,6 @@ appearance_controls_base 1000 none - 0 Appearance Panel @@ -26,7 +25,6 @@ 1 1 UI - 0 0 0 @@ -52,6 +50,7 @@ wxTAB_TRAVERSAL OnSetFocus + OnSize m_sizerOuter @@ -892,7 +891,7 @@ 5 wxEXPAND 1 - + 1 1 1 @@ -949,8 +948,8 @@ - - + + 1 1 1 @@ -1002,7 +1001,7 @@ wxTAB_TRAVERSAL OnSetFocus - + bSizer192 wxVERTICAL @@ -1216,11 +1215,11 @@ - + 5 - wxEXPAND | wxALL + wxALL|wxEXPAND 1 - + 1 1 1 @@ -1229,25 +1228,50 @@ + 0 + 0 1 + + + wxALIGN_LEFT + + wxALIGN_TOP 0 1 + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + 3 + 1 0 Dock 0 Left + 0 + 0 + 0 + 0 + 0 1 1 + + 0 0 0 wxID_ANY + + + + 0 + 0 0 @@ -1255,7 +1279,7 @@ 0 1 - m_netsScrolledWindow + m_netsGrid 1 @@ -1263,8 +1287,12 @@ 1 Resizable - 5 - 5 + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 5 1 ; ; forward_declare @@ -1272,13 +1300,11 @@ - wxHSCROLL|wxVSCROLL - - - m_netsOuterSizer - wxVERTICAL - protected - + + OnNetGridClick + OnNetGridDoubleClick + OnNetGridRightClick + OnSetFocus @@ -1576,7 +1602,7 @@ 1 0 1 - 0 + 1 1 0 diff --git a/pcbnew/widgets/appearance_controls_base.h b/pcbnew/widgets/appearance_controls_base.h index 3fe16d5219..51822b6ff0 100644 --- a/pcbnew/widgets/appearance_controls_base.h +++ b/pcbnew/widgets/appearance_controls_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jul 10 2019) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -64,8 +65,7 @@ class APPEARANCE_CONTROLS_BASE : public wxPanel wxStaticText* m_staticTextNets; wxTextCtrl* m_txtNetFilter; wxBitmapButton* m_btnNetInspector; - wxScrolledWindow* m_netsScrolledWindow; - wxBoxSizer* m_netsOuterSizer; + wxGrid* m_netsGrid; wxPanel* m_panelNetclasses; wxStaticText* m_staticText14; wxBitmapButton* m_btnConfigureNetClasses; @@ -82,9 +82,13 @@ class APPEARANCE_CONTROLS_BASE : public wxPanel // Virtual event handlers, overide them in your derived class virtual void OnSetFocus( wxFocusEvent& event ) { event.Skip(); } + virtual void OnSize( wxSizeEvent& event ) { event.Skip(); } virtual void OnNotebookPageChanged( wxNotebookEvent& event ) { event.Skip(); } virtual void OnLayerDisplayPaneChanged( wxCollapsiblePaneEvent& event ) { event.Skip(); } virtual void OnFlipBoardChecked( wxCommandEvent& event ) { event.Skip(); } + virtual void OnNetGridClick( wxGridEvent& event ) { event.Skip(); } + virtual void OnNetGridDoubleClick( wxGridEvent& event ) { event.Skip(); } + virtual void OnNetGridRightClick( wxGridEvent& event ) { event.Skip(); } virtual void OnNetDisplayPaneChanged( wxCollapsiblePaneEvent& event ) { event.Skip(); } virtual void onLayerPresetChanged( wxCommandEvent& event ) { event.Skip(); }