From bd14f8a82a3b006b4f0f9948a70637b08dfa7980 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sat, 11 Jul 2020 13:42:00 -0400 Subject: [PATCH] ADDED: New appearance control widget for PcbNew Featuring: - Layer view presets - Per-type opacity for tracks, vias, pads, zones - Net and netclass color and visibility controls CHANGED: Simplified object visibilty controls Fixes https://gitlab.com/kicad/code/kicad/-/issues/1951 Fixes https://gitlab.com/kicad/code/kicad/-/issues/1981 Fixes https://gitlab.com/kicad/code/kicad/-/issues/2003 Fixes https://gitlab.com/kicad/code/kicad/-/issues/2173 Fixes https://gitlab.com/kicad/code/kicad/-/issues/2254 Fixes https://gitlab.com/kicad/code/kicad/-/issues/4325 --- bitmaps_png/CMakeLists.txt | 2 + bitmaps_png/cpp_16/visibility.cpp | 31 + bitmaps_png/cpp_16/visibility_off.cpp | 28 + .../include/bitmaps_png/bitmaps_list.h | 2 + bitmaps_png/sources/visibility.svg | 196 ++ bitmaps_png/sources/visibility_off.svg | 166 ++ common/CMakeLists.txt | 1 + common/lset.cpp | 67 + common/page_layout/ws_painter.cpp | 2 +- common/project/project_local_settings.cpp | 21 +- common/settings/color_settings.cpp | 1 - common/widgets/bitmap_toggle.cpp | 72 + common/widgets/color_swatch.cpp | 14 +- eeschema/sch_painter.cpp | 2 +- eeschema/sch_painter.h | 2 +- gerbview/gerbview_painter.cpp | 2 +- gerbview/gerbview_painter.h | 2 +- include/layers_id_colors_and_visibility.h | 61 +- include/pcb_display_options.h | 16 +- include/project/board_project_settings.h | 41 +- include/project/project_local_settings.h | 11 + include/render_settings.h | 3 +- include/widgets/bitmap_toggle.h | 69 + include/ws_painter.h | 2 +- pcbnew/CMakeLists.txt | 3 + pcbnew/class_pad.cpp | 4 + pcbnew/class_track.cpp | 8 +- pcbnew/class_zone.cpp | 10 +- pcbnew/class_zone.h | 2 + pcbnew/connectivity/connectivity_data.cpp | 7 + pcbnew/connectivity/connectivity_data.h | 8 + pcbnew/dialogs/dialog_drc.cpp | 4 +- .../dialogs/panel_pcbnew_color_settings.cpp | 4 +- pcbnew/files.cpp | 2 - pcbnew/initpcb.cpp | 3 +- pcbnew/menubar_pcb_editor.cpp | 6 +- pcbnew/pcb_base_edit_frame.cpp | 6 +- pcbnew/pcb_base_edit_frame.h | 4 + pcbnew/pcb_display_options.cpp | 10 +- pcbnew/pcb_draw_panel_gal.cpp | 98 +- pcbnew/pcb_edit_frame.cpp | 138 +- pcbnew/pcb_edit_frame.h | 44 +- pcbnew/pcb_painter.cpp | 181 +- pcbnew/pcb_painter.h | 35 +- pcbnew/pcbnew_config.cpp | 74 +- pcbnew/pcbnew_settings.cpp | 5 +- pcbnew/ratsnest/ratsnest_viewitem.cpp | 23 +- pcbnew/router/router_tool.cpp | 3 - pcbnew/swig/layers_id_colors_and_visibility.i | 4 + pcbnew/toolbars_pcb_editor.cpp | 15 +- pcbnew/tools/pcb_inspection_tool.cpp | 9 +- pcbnew/tools/pcbnew_control.cpp | 11 +- pcbnew/tools/pcbnew_control.h | 3 - pcbnew/tools/selection_tool.cpp | 22 +- pcbnew/widgets/appearance_controls.cpp | 1907 +++++++++++++++ pcbnew/widgets/appearance_controls.h | 286 +++ pcbnew/widgets/appearance_controls_base.cpp | 283 +++ pcbnew/widgets/appearance_controls_base.fbp | 2055 +++++++++++++++++ pcbnew/widgets/appearance_controls_base.h | 107 + 59 files changed, 5799 insertions(+), 399 deletions(-) create mode 100644 bitmaps_png/cpp_16/visibility.cpp create mode 100644 bitmaps_png/cpp_16/visibility_off.cpp create mode 100644 bitmaps_png/sources/visibility.svg create mode 100644 bitmaps_png/sources/visibility_off.svg create mode 100644 common/widgets/bitmap_toggle.cpp create mode 100644 include/widgets/bitmap_toggle.h create mode 100644 pcbnew/widgets/appearance_controls.cpp create mode 100644 pcbnew/widgets/appearance_controls.h create mode 100644 pcbnew/widgets/appearance_controls_base.cpp create mode 100644 pcbnew/widgets/appearance_controls_base.fbp create mode 100644 pcbnew/widgets/appearance_controls_base.h diff --git a/bitmaps_png/CMakeLists.txt b/bitmaps_png/CMakeLists.txt index 7cb83b1b8b..0ddfd20a1a 100644 --- a/bitmaps_png/CMakeLists.txt +++ b/bitmaps_png/CMakeLists.txt @@ -100,6 +100,8 @@ set( BMAPS_SMALL trash tree_nosel tree_sel + visibility + visibility_off www ) diff --git a/bitmaps_png/cpp_16/visibility.cpp b/bitmaps_png/cpp_16/visibility.cpp new file mode 100644 index 0000000000..2203c899d5 --- /dev/null +++ b/bitmaps_png/cpp_16/visibility.cpp @@ -0,0 +1,31 @@ + +/* Do not modify this file, it was automatically generated by the + * PNG2cpp CMake script, using a *.png file as input. + */ + +#include + +static const unsigned char png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0xb5, 0xfa, 0x37, + 0xea, 0x00, 0x00, 0x00, 0xe5, 0x49, 0x44, 0x41, 0x54, 0x28, 0x15, 0x05, 0xc1, 0xb1, 0x2b, 0x84, + 0x01, 0x00, 0x07, 0xd0, 0xf7, 0x5d, 0xb1, 0x89, 0x2c, 0x06, 0x92, 0x52, 0xea, 0x92, 0x8b, 0x44, + 0x8e, 0xae, 0xce, 0x22, 0x3b, 0x83, 0xba, 0xe5, 0x16, 0xfb, 0x2d, 0x8c, 0x36, 0x7f, 0x87, 0xdd, + 0x62, 0x30, 0x18, 0x24, 0xb1, 0xe8, 0x0c, 0x4e, 0x19, 0x2c, 0x26, 0x74, 0xc9, 0x6a, 0x40, 0x9d, + 0xef, 0xe7, 0x3d, 0x00, 0x86, 0x14, 0xa8, 0xa9, 0x83, 0x61, 0x80, 0x0a, 0x80, 0x47, 0x55, 0x6c, + 0xd9, 0xc5, 0x9c, 0x27, 0x80, 0x8a, 0xc2, 0x0a, 0xb8, 0xd7, 0x04, 0xb0, 0xa9, 0x0b, 0x56, 0x14, + 0x85, 0x69, 0xf7, 0x5a, 0xae, 0x2c, 0x9a, 0x35, 0x61, 0x4a, 0xbc, 0xe9, 0x7b, 0xd3, 0xb3, 0xed, + 0xc4, 0x32, 0x34, 0x9d, 0xda, 0xd2, 0x13, 0x51, 0x8a, 0x88, 0x3b, 0x0d, 0x67, 0x36, 0x00, 0x8e, + 0x95, 0xe2, 0xd5, 0x8e, 0x11, 0xa3, 0x5a, 0x3e, 0xc4, 0x9f, 0x43, 0x80, 0x03, 0x11, 0xdf, 0xe6, + 0xad, 0xbb, 0x74, 0x61, 0xc9, 0xaa, 0x81, 0x88, 0x7d, 0x98, 0xf1, 0x2b, 0xe2, 0x5a, 0xa1, 0x2f, + 0xe2, 0x19, 0x0f, 0x22, 0xbe, 0x4c, 0x54, 0x44, 0x40, 0x21, 0x4a, 0x50, 0xa2, 0x00, 0x51, 0x42, + 0x47, 0xc4, 0x8f, 0x05, 0xab, 0x2e, 0x9c, 0xab, 0xa9, 0x1b, 0x88, 0x68, 0x03, 0x1c, 0x29, 0xc5, + 0xbb, 0x3d, 0x63, 0xc6, 0xb5, 0x7d, 0x8a, 0x81, 0x0e, 0x00, 0x6c, 0xea, 0x8a, 0x88, 0x88, 0xb8, + 0xb1, 0x06, 0x14, 0x00, 0xa8, 0x6a, 0x98, 0x14, 0xaf, 0x6e, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x5e, 0x5d, 0x56, 0xf6, 0x32, 0x70, + 0x52, 0x40, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +const BITMAP_OPAQUE visibility_xpm[1] = {{ png, sizeof( png ), "visibility_xpm" }}; + +//EOF diff --git a/bitmaps_png/cpp_16/visibility_off.cpp b/bitmaps_png/cpp_16/visibility_off.cpp new file mode 100644 index 0000000000..fa2b900665 --- /dev/null +++ b/bitmaps_png/cpp_16/visibility_off.cpp @@ -0,0 +1,28 @@ + +/* Do not modify this file, it was automatically generated by the + * PNG2cpp CMake script, using a *.png file as input. + */ + +#include + +static const unsigned char png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0xb5, 0xfa, 0x37, + 0xea, 0x00, 0x00, 0x00, 0xb6, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0xa0, 0x27, 0x48, + 0xd7, 0x4f, 0xcd, 0x4a, 0x6f, 0x4b, 0x6b, 0x4d, 0xcf, 0x48, 0xd7, 0xc2, 0x90, 0x4c, 0x73, 0x4b, + 0x3b, 0x9f, 0xf6, 0x1f, 0x08, 0xff, 0x81, 0xc9, 0xff, 0xe9, 0xc7, 0x53, 0x6c, 0x91, 0xa5, 0x5b, + 0xc1, 0x12, 0x8f, 0x52, 0x83, 0x93, 0x78, 0xd3, 0xf8, 0x53, 0xa3, 0xd3, 0x5e, 0x00, 0x79, 0x7f, + 0xd3, 0xca, 0x60, 0xd2, 0xa5, 0x60, 0x5d, 0xdf, 0x53, 0xb5, 0x61, 0x1a, 0x32, 0xcc, 0xd2, 0xfe, + 0x80, 0xc4, 0x52, 0x53, 0x81, 0x9c, 0x64, 0xf9, 0xb4, 0x1f, 0x60, 0x05, 0xfb, 0x80, 0x4a, 0x37, + 0xa6, 0x9f, 0x01, 0xc2, 0x75, 0x40, 0xd6, 0x39, 0xb0, 0xd8, 0x97, 0x2c, 0x09, 0x84, 0x82, 0x03, + 0x28, 0x0a, 0x20, 0x2e, 0xfa, 0x94, 0x28, 0x0a, 0xb2, 0xa2, 0x00, 0xcc, 0xf9, 0x91, 0xa6, 0x0b, + 0xf7, 0x8f, 0x25, 0xd4, 0x8a, 0x04, 0xa8, 0x40, 0x6a, 0x1d, 0xd8, 0x91, 0x4f, 0x52, 0x23, 0x12, + 0x04, 0x92, 0x85, 0x52, 0x13, 0xd2, 0x5e, 0x01, 0x79, 0x7f, 0xd2, 0x0a, 0x90, 0xfd, 0xe1, 0x98, + 0x7a, 0x12, 0xe2, 0x41, 0x28, 0x3c, 0x98, 0x62, 0x81, 0x11, 0x16, 0x29, 0x9a, 0xe9, 0x69, 0xe9, + 0x8d, 0x69, 0x0d, 0xa9, 0x49, 0xc9, 0x2a, 0x74, 0x8d, 0x21, 0x00, 0xfd, 0xf4, 0x70, 0x5c, 0x67, + 0xba, 0xa2, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +const BITMAP_OPAQUE visibility_off_xpm[1] = {{ png, sizeof( png ), "visibility_off_xpm" }}; + +//EOF diff --git a/bitmaps_png/include/bitmaps_png/bitmaps_list.h b/bitmaps_png/include/bitmaps_png/bitmaps_list.h index 4b8af49d1e..0adc5aa35e 100644 --- a/bitmaps_png/include/bitmaps_png/bitmaps_list.h +++ b/bitmaps_png/include/bitmaps_png/bitmaps_list.h @@ -496,6 +496,8 @@ EXTERN_BITMAP( via_annulus_xpm ) EXTERN_BITMAP( via_diameter_xpm ) EXTERN_BITMAP( via_hole_diameter_xpm ) EXTERN_BITMAP( viewlibs_icon_xpm ) +EXTERN_BITMAP( visibility_xpm ) +EXTERN_BITMAP( visibility_off_xpm ) EXTERN_BITMAP( warning_xpm ) EXTERN_BITMAP( width_track_via_xpm ) EXTERN_BITMAP( width_track_xpm ) diff --git a/bitmaps_png/sources/visibility.svg b/bitmaps_png/sources/visibility.svg new file mode 100644 index 0000000000..3b1a25dc69 --- /dev/null +++ b/bitmaps_png/sources/visibility.svg @@ -0,0 +1,196 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bitmaps_png/sources/visibility_off.svg b/bitmaps_png/sources/visibility_off.svg new file mode 100644 index 0000000000..5759f110e4 --- /dev/null +++ b/bitmaps_png/sources/visibility_off.svg @@ -0,0 +1,166 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index b7ac4769f7..7b156683a3 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -198,6 +198,7 @@ set( COMMON_DLG_SRCS set( COMMON_WIDGET_SRCS widgets/app_progress_dialog.cpp + widgets/bitmap_toggle.cpp widgets/button_row_panel.cpp widgets/color_swatch.cpp widgets/footprint_choice.cpp diff --git a/common/lset.cpp b/common/lset.cpp index 5084aa9ad2..8101222af6 100644 --- a/common/lset.cpp +++ b/common/lset.cpp @@ -651,6 +651,7 @@ LSET LSET::FrontAssembly() F_SilkS, F_Mask, F_Fab, + F_CrtYd }; static const LSET saved( front_assembly, arrayDim( front_assembly ) ); @@ -664,6 +665,7 @@ LSET LSET::BackAssembly() B_SilkS, B_Mask, B_Fab, + B_CrtYd }; static const LSET saved( back_assembly, arrayDim( back_assembly ) ); @@ -854,3 +856,68 @@ PCB_LAYER_ID ToLAYER_ID( int aLayer ) return PCB_LAYER_ID( aLayer ); } + +GAL_SET::GAL_SET( const GAL_LAYER_ID* aArray, unsigned aCount ) : GAL_SET() +{ + for( unsigned i = 0; i < aCount; ++i ) + set( aArray[i] ); +} + + +std::vector GAL_SET::Seq() const +{ + std::vector ret; + + for( size_t i = 0; i < size(); ++i ) + { + if( test( i ) ) + ret.push_back( static_cast( i ) ); + } + + return ret; +} + + +GAL_SET GAL_SET::DefaultVisible() +{ + static const GAL_LAYER_ID visible[] = { + LAYER_VIAS, + LAYER_VIA_MICROVIA, + LAYER_VIA_BBLIND, + LAYER_VIA_THROUGH, + LAYER_NON_PLATEDHOLES, + LAYER_MOD_TEXT_FR, + LAYER_MOD_TEXT_BK, + // LAYER_MOD_TEXT_INVISIBLE, // Invisible text hidden by default + LAYER_ANCHOR, + LAYER_PAD_FR, + LAYER_PAD_BK, + LAYER_RATSNEST, + LAYER_GRID, + LAYER_GRID_AXES, + LAYER_NO_CONNECTS, + LAYER_MOD_FR, + LAYER_MOD_BK, + LAYER_MOD_VALUES, + LAYER_MOD_REFERENCES, + LAYER_TRACKS, + LAYER_PADS_TH, + LAYER_PADS_PLATEDHOLES, + LAYER_VIAS_HOLES, + LAYER_DRC_ERROR, + LAYER_DRC_WARNING, + // LAYER_DRC_EXCLUSION, // DRC exclusions hidden by default + LAYER_WORKSHEET, + LAYER_GP_OVERLAY, + LAYER_SELECT_OVERLAY, + LAYER_PCB_BACKGROUND, + LAYER_CURSOR, + LAYER_AUX_ITEMS, + LAYER_DRAW_BITMAPS, + LAYER_PADS, + LAYER_ZONES, + }; + + static const GAL_SET saved( visible, arrayDim( visible ) ); + return saved; +} diff --git a/common/page_layout/ws_painter.cpp b/common/page_layout/ws_painter.cpp index bd41205894..fc4bb9e4f1 100644 --- a/common/page_layout/ws_painter.cpp +++ b/common/page_layout/ws_painter.cpp @@ -68,7 +68,7 @@ void WS_RENDER_SETTINGS::LoadColors( const COLOR_SETTINGS* aSettings ) } -const COLOR4D& WS_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const +COLOR4D WS_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const { const EDA_ITEM* item = dynamic_cast( aItem ); diff --git a/common/project/project_local_settings.cpp b/common/project/project_local_settings.cpp index 9f28f237fd..7ad056f29b 100644 --- a/common/project/project_local_settings.cpp +++ b/common/project/project_local_settings.cpp @@ -43,9 +43,6 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( const wxString& aFilename ) : }, LSET::AllLayersMask().FmtHex() ) ); - static GAL_SET defaultVisible; - defaultVisible.set().reset( GAL_LAYER_INDEX( LAYER_MOD_TEXT_INVISIBLE ) ); - m_params.emplace_back( new PARAM_LAMBDA( "board.visible_items", [&]() -> nlohmann::json { @@ -61,7 +58,7 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( const wxString& aFilename ) : { if( !aVal.is_array() || aVal.empty() ) { - m_VisibleItems = defaultVisible; + m_VisibleItems = GAL_SET::DefaultVisible(); return; } @@ -149,7 +146,23 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( const wxString& aFilename ) : &m_ContrastModeDisplay, HIGH_CONTRAST_MODE::NORMAL, HIGH_CONTRAST_MODE::NORMAL, HIGH_CONTRAST_MODE::HIDDEN ) ); + m_params.emplace_back( new PARAM( "board.opacity.tracks", &m_TrackOpacity, 1.0 ) ); + m_params.emplace_back( new PARAM( "board.opacity.vias", &m_ViaOpacity, 1.0 ) ); + m_params.emplace_back( new PARAM( "board.opacity.pads", &m_PadOpacity, 1.0 ) ); + m_params.emplace_back( new PARAM( "board.opacity.zones", &m_ZoneOpacity, 1.0 ) ); + m_params.emplace_back( new PARAM_LIST( "board.hidden_nets", &m_HiddenNets, {} ) ); + + m_params.emplace_back( new PARAM_ENUM( "board.net_color_mode", + &m_NetColorMode, NET_COLOR_MODE::RATSNEST, NET_COLOR_MODE::OFF, + NET_COLOR_MODE::ALL ) ); + + // TODO: move the rest of PCB_DISPLAY_OPTIONS that are project-specific in here +#if 0 + m_params.emplace_back( new PARAM_ENUM( "board.zone_display_mode", + &m_ZoneDisplayMode, ZONE_DISPLAY_MODE::SHOW_FILLED, ZONE_DISPLAY_MODE::SHOW_OUTLINED, + ZONE_DISPLAY_MODE::SHOW_FILLED ) ); +#endif } diff --git a/common/settings/color_settings.cpp b/common/settings/color_settings.cpp index 29cf6b1ad9..b214324248 100644 --- a/common/settings/color_settings.cpp +++ b/common/settings/color_settings.cpp @@ -142,7 +142,6 @@ COLOR_SETTINGS::COLOR_SETTINGS( wxString aFilename ) : CLR( "board.ratsnest", LAYER_RATSNEST, COLOR4D( WHITE ) ); CLR( "board.select_overlay", LAYER_SELECT_OVERLAY, COLOR4D( DARKRED ) ); CLR( "board.through_via", LAYER_VIA_THROUGH, COLOR4D( LIGHTGRAY ) ); - CLR( "board.via", LAYER_VIAS, COLOR4D( BLACK ) ); CLR( "board.via_blind_buried", LAYER_VIA_BBLIND, COLOR4D( BROWN ) ); CLR( "board.via_hole", LAYER_VIAS_HOLES, COLOR4D( WHITE ) ); CLR( "board.via_micro", LAYER_VIA_MICROVIA, COLOR4D( CYAN ) ); diff --git a/common/widgets/bitmap_toggle.cpp b/common/widgets/bitmap_toggle.cpp new file mode 100644 index 0000000000..4e5ea05968 --- /dev/null +++ b/common/widgets/bitmap_toggle.cpp @@ -0,0 +1,72 @@ +/* + * 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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + + +wxDEFINE_EVENT( TOGGLE_CHANGED, wxCommandEvent ); + + +BITMAP_TOGGLE::BITMAP_TOGGLE( wxWindow *aParent, wxWindowID aId, const wxBitmap& aCheckedBitmap, + const wxBitmap& aUncheckedBitmap, bool aChecked ) : + wxPanel( aParent, aId ), + m_checked( aChecked ), + m_unchecked_bitmap( aUncheckedBitmap ), + m_checked_bitmap( aCheckedBitmap ) +{ + wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL ); + SetSizer( sizer ); + + const wxBitmap& bitmap = aChecked ? m_checked_bitmap : m_unchecked_bitmap; + + m_bitmap = new wxStaticBitmap( this, aId, bitmap, wxDefaultPosition, bitmap.GetSize() ); + + sizer->Add( m_bitmap, 0, 0 ); + + m_bitmap->Bind( wxEVT_LEFT_UP, + [&]( wxMouseEvent& ) + { + SetValue( !GetValue() ); + wxCommandEvent event( TOGGLE_CHANGED ); + event.SetInt( m_checked ); + event.SetEventObject( this ); + wxPostEvent( this, event ); + } ); + + auto passOnEvent = + [&]( wxEvent& aEvent ) + { + wxPostEvent( this, aEvent ); + }; + + m_bitmap->Bind( wxEVT_RIGHT_DOWN, passOnEvent ); + m_bitmap->Bind( wxEVT_RIGHT_UP, passOnEvent ); +} + + +void BITMAP_TOGGLE::SetValue( bool aValue ) +{ + m_checked = aValue; + m_bitmap->SetBitmap( aValue ? m_checked_bitmap : m_unchecked_bitmap ); +} diff --git a/common/widgets/color_swatch.cpp b/common/widgets/color_swatch.cpp index 26192790c1..6e7ed9e3f1 100644 --- a/common/widgets/color_swatch.cpp +++ b/common/widgets/color_swatch.cpp @@ -214,15 +214,17 @@ void COLOR_SWATCH::GetNewSwatchColor() DIALOG_COLOR_PICKER dialog( ::wxGetTopLevelParent( this ), m_color, true, nullptr, m_default ); if( dialog.ShowModal() == wxID_OK ) + { newColor = dialog.GetColor(); - if( newColor != COLOR4D::UNSPECIFIED || m_default == COLOR4D::UNSPECIFIED ) - { - m_color = newColor; + if( newColor != COLOR4D::UNSPECIFIED || m_default == COLOR4D::UNSPECIFIED ) + { + m_color = newColor; - wxBitmap bm = MakeBitmap( newColor, m_background, m_size ); - m_swatch->SetBitmap( bm ); + wxBitmap bm = MakeBitmap( newColor, m_background, m_size ); + m_swatch->SetBitmap( bm ); - sendSwatchChangeEvent( *this ); + sendSwatchChangeEvent( *this ); + } } } diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index 12473ceca8..350274136c 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -102,7 +102,7 @@ void SCH_RENDER_SETTINGS::LoadColors( const COLOR_SETTINGS* aSettings ) } -const COLOR4D& SCH_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const +COLOR4D SCH_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const { return m_layerColors[ aLayer ]; } diff --git a/eeschema/sch_painter.h b/eeschema/sch_painter.h index fbaa92bc72..864eb0b3eb 100644 --- a/eeschema/sch_painter.h +++ b/eeschema/sch_painter.h @@ -77,7 +77,7 @@ public: void LoadColors( const COLOR_SETTINGS* aSettings ) override; /// @copydoc RENDER_SETTINGS::GetColor() - virtual const COLOR4D& GetColor( const VIEW_ITEM* aItem, int aLayer ) const override; + virtual COLOR4D GetColor( const VIEW_ITEM* aItem, int aLayer ) const override; bool IsBackgroundDark() const override { diff --git a/gerbview/gerbview_painter.cpp b/gerbview/gerbview_painter.cpp index b8ee35bb25..5f2cb4afb9 100644 --- a/gerbview/gerbview_painter.cpp +++ b/gerbview/gerbview_painter.cpp @@ -102,7 +102,7 @@ void GERBVIEW_RENDER_SETTINGS::LoadDisplayOptions( const GBR_DISPLAY_OPTIONS& aO } -const COLOR4D& GERBVIEW_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const +COLOR4D GERBVIEW_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const { const EDA_ITEM* item = static_cast( aItem ); static const COLOR4D transparent = COLOR4D( 0, 0, 0, 0 ); diff --git a/gerbview/gerbview_painter.h b/gerbview/gerbview_painter.h index 0596c93a79..fc86aff0fa 100644 --- a/gerbview/gerbview_painter.h +++ b/gerbview/gerbview_painter.h @@ -61,7 +61,7 @@ public: void LoadDisplayOptions( const GBR_DISPLAY_OPTIONS& aOptions ); /// @copydoc RENDER_SETTINGS::GetColor() - virtual const COLOR4D& GetColor( const VIEW_ITEM* aItem, int aLayer ) const override; + virtual COLOR4D GetColor( const VIEW_ITEM* aItem, int aLayer ) const override; /** * Function GetLayerColor diff --git a/include/layers_id_colors_and_visibility.h b/include/layers_id_colors_and_visibility.h index f0e6f0bd00..4c9e4cbd30 100644 --- a/include/layers_id_colors_and_visibility.h +++ b/include/layers_id_colors_and_visibility.h @@ -170,7 +170,7 @@ enum GAL_LAYER_ID: int { GAL_LAYER_ID_START = NETNAMES_LAYER_ID_END, - LAYER_VIAS = GAL_LAYER_ID_START, + LAYER_VIAS = GAL_LAYER_ID_START, ///< Meta control for all vias opacity/visibility LAYER_VIA_MICROVIA, ///< to draw micro vias LAYER_VIA_BBLIND, ///< to draw blind/buried vias LAYER_VIA_THROUGH, ///< to draw usual through hole vias @@ -211,6 +211,13 @@ enum GAL_LAYER_ID: int LAYER_WORKSHEET_PAGE1, ///< for pageLayout editor previewing LAYER_WORKSHEET_PAGEn, ///< for pageLayout editor previewing + LAYER_PADS, ///< Meta control for all pads opacity/visibility (color ignored) + LAYER_ZONES, ///< Control for copper zone opacity/visibility (color ignored) + + /// Virtual layers for stacking zones and tracks on a given copper layer + LAYER_ZONE_START, + LAYER_ZONE_END = LAYER_ZONE_START + PCB_LAYER_ID_COUNT, + /// Add new GAL layers here GAL_LAYER_ID_END @@ -219,6 +226,9 @@ enum GAL_LAYER_ID: int /// Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS #define GAL_LAYER_INDEX( x ) ( x - GAL_LAYER_ID_START ) +/// Macro for getting the zone layer for a given copper layer +#define ZONE_LAYER_FOR( copperLayer ) ( LAYER_ZONE_START + copperLayer ) + constexpr int GAL_LAYER_ID_COUNT = GAL_LAYER_ID_END - GAL_LAYER_ID_START; inline GAL_LAYER_ID operator++( GAL_LAYER_ID& a ) @@ -227,6 +237,12 @@ inline GAL_LAYER_ID operator++( GAL_LAYER_ID& a ) return a; } +inline GAL_LAYER_ID ToGalLayer( int aInteger ) +{ + wxASSERT( aInteger >= GAL_LAYER_ID_START && aInteger <= GAL_LAYER_ID_END ); + return static_cast( aInteger ); +} + /// Used for via types inline GAL_LAYER_ID operator+( const GAL_LAYER_ID& a, int b ) { @@ -235,9 +251,14 @@ inline GAL_LAYER_ID operator+( const GAL_LAYER_ID& a, int b ) return t; } +typedef std::bitset GAL_BASE_SET; + /// Helper for storing and iterating over GAL_LAYER_IDs -class GAL_SET : public std::bitset +class GAL_SET : public GAL_BASE_SET { +private: + static constexpr int start = static_cast( GAL_LAYER_ID_START ); + public: GAL_SET() : std::bitset() { @@ -247,30 +268,34 @@ public: { } + GAL_SET( const GAL_LAYER_ID* aArray, unsigned aCount ); + GAL_SET& set() { - std::bitset::set(); + GAL_BASE_SET::set(); return *this; } - GAL_SET& set( size_t aPos, bool aVal = true ) + GAL_SET& set( int aPos, bool aVal = true ) { - std::bitset::set( aPos, aVal ); + GAL_BASE_SET::set( aPos, aVal ); return *this; } - std::vector Seq() const + GAL_SET& set( GAL_LAYER_ID aPos, bool aVal = true ) { - std::vector ret; - - for( size_t i = 0; i < size(); ++i ) - { - if( test( i ) ) - ret.push_back( static_cast( i ) ); - } - - return ret; + GAL_BASE_SET::set( static_cast( aPos ) - start, aVal ); + return *this; } + + bool Contains( GAL_LAYER_ID aPos ) + { + return test( static_cast( aPos ) - start ); + } + + std::vector Seq() const; + + static GAL_SET DefaultVisible(); }; /// Eeschema drawing layers @@ -905,6 +930,12 @@ inline bool IsNetnameLayer( LAYER_NUM aLayer ) } +inline bool IsZoneLayer( LAYER_NUM aLayer ) +{ + return aLayer >= LAYER_ZONE_START && aLayer <= LAYER_ZONE_END; +} + + inline bool IsDCodeLayer( int aLayer ) { return aLayer >= (GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT) && diff --git a/include/pcb_display_options.h b/include/pcb_display_options.h index 74e8e738f2..7a077d524e 100644 --- a/include/pcb_display_options.h +++ b/include/pcb_display_options.h @@ -74,22 +74,34 @@ public: /// How trace clearances are displayed. @see TRACE_CLEARANCE_DISPLAY_MODE_T. TRACE_CLEARANCE_DISPLAY_MODE_T m_ShowTrackClearanceMode; - int m_DisplayZonesMode; + /// @see ZONE_DISPLAY_MODE - stored in the project + ZONE_DISPLAY_MODE m_ZoneDisplayMode; + int m_DisplayNetNamesMode; /* 0 do not show netnames, * 1 show netnames on pads * 2 show netnames on tracks * 3 show netnames on tracks and pads */ - /// How inactive layers are displayed. @see HIGH_CONTRAST_MODE + /// How inactive layers are displayed. @see HIGH_CONTRAST_MODE - stored in the project HIGH_CONTRAST_MODE m_ContrastModeDisplay; + /// How to use color overrides on specific nets and netclasses + NET_COLOR_MODE m_NetColorMode; + int m_MaxLinksShowed; // in track creation: number of hairwires shown bool m_ShowModuleRatsnest; // When moving a footprint: allows displaying a ratsnest bool m_ShowGlobalRatsnest; // If true, show all bool m_DisplayRatsnestLinesCurved; // Airwires can be drawn as straight lines (false) // or curved lines (true) + // These opacity overrides multiply with any opacity in the base layer color + + double m_TrackOpacity; ///< Opacity override for all tracks + double m_ViaOpacity; ///< Opacity override for all types of via + double m_PadOpacity; ///< Opacity override for SMD pads and PTHs + double m_ZoneOpacity; ///< Opacity override for filled zone areas + public: PCB_DISPLAY_OPTIONS(); diff --git a/include/project/board_project_settings.h b/include/project/board_project_settings.h index 7661442a66..8fb08ed927 100644 --- a/include/project/board_project_settings.h +++ b/include/project/board_project_settings.h @@ -76,8 +76,8 @@ struct SELECTION_FILTER_OPTIONS }; /** - * Determines how inactive layers should be displayed - */ + * Determines how inactive layers should be displayed + */ enum class HIGH_CONTRAST_MODE { NORMAL = 0, ///> Non-active layers are shown normally (no high-contrast mode) @@ -85,6 +85,22 @@ enum class HIGH_CONTRAST_MODE HIDDEN ///> Non-active layers are hidden }; +///> Determines how zones should be displayed +enum class ZONE_DISPLAY_MODE +{ + SHOW_FILLED, ///< Filled polygons are shown + HIDE_FILLED, ///< Only the zone outline is shown + SHOW_OUTLINED ///< Outlines of filled polygons are shown +}; + +///> Determines how net color overrides should be applied +enum class NET_COLOR_MODE +{ + OFF, ///< Net (and netclass) colors are not shown + RATSNEST, ///< Net/netclass colors are shown on ratsnest lines only + ALL ///< Net/netclass colors are shown on all net copper +}; + /** * A saved set of layers that are visible */ @@ -94,25 +110,34 @@ struct LAYER_PRESET LSET layers; ///< Board layers that are visible GAL_SET renderLayers; ///< Render layers (e.g. object types) that are visible PCB_LAYER_ID activeLayer; ///< Optional layer to set active when this preset is loaded + bool readOnly; ///< True if this is a read-only (built-in) preset - LAYER_PRESET( const wxString& aName ) : + LAYER_PRESET( const wxString& aName = wxEmptyString ) : name( aName ), activeLayer( UNSELECTED_LAYER ) { + layers = LSET::AllLayersMask(); + renderLayers = GAL_SET::DefaultVisible(); + readOnly = false; } - LAYER_PRESET( const wxString& aName, const LSET& aSet ) : + LAYER_PRESET( const wxString& aName, const LSET& aVisibleLayers ) : name( aName ), - layers( aSet ), + layers( aVisibleLayers ), activeLayer( UNSELECTED_LAYER ) { + renderLayers = GAL_SET::DefaultVisible(); + readOnly = false; } - LAYER_PRESET( const wxString& aName, const LSET& aSet, PCB_LAYER_ID aActive ) : + LAYER_PRESET( const wxString& aName, const LSET& aVisibleLayers, const GAL_SET& aVisibleObjects, + PCB_LAYER_ID aActiveLayer ) : name( aName ), - layers( aSet ), - activeLayer( aActive ) + layers( aVisibleLayers ), + renderLayers( aVisibleObjects ), + activeLayer( aActiveLayer ) { + readOnly = false; } bool LayersMatch( const LAYER_PRESET& aOther ) diff --git a/include/project/project_local_settings.h b/include/project/project_local_settings.h index 50b1158a04..aa15e05f04 100644 --- a/include/project/project_local_settings.h +++ b/include/project/project_local_settings.h @@ -94,6 +94,17 @@ public: /// The current contrast mode HIGH_CONTRAST_MODE m_ContrastModeDisplay; + /// The current net color mode + NET_COLOR_MODE m_NetColorMode; + + /// How zones are drawn (TODO: not yet used) + ZONE_DISPLAY_MODE m_ZoneDisplayMode; + + double m_TrackOpacity; ///< Opacity override for all tracks + double m_ViaOpacity; ///< Opacity override for all types of via + double m_PadOpacity; ///< Opacity override for SMD pads and PTH + double m_ZoneOpacity; ///< Opacity override for filled zones + /** * A list of netnames that have been manually hidden in the board editor. * Currently, hiding nets means hiding the ratsnest for those nets. diff --git a/include/render_settings.h b/include/render_settings.h index f3965c4a3b..7e6e8c5dcd 100644 --- a/include/render_settings.h +++ b/include/render_settings.h @@ -151,14 +151,13 @@ public: bool GetHighContrast() const { return m_hiContrastEnabled; } /** - * Function GetColor * Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer * using currently used render settings. * @param aItem is the VIEW_ITEM. * @param aLayer is the layer. * @return The color. */ - virtual const COLOR4D& GetColor( const VIEW_ITEM* aItem, int aLayer ) const = 0; + virtual COLOR4D GetColor( const VIEW_ITEM* aItem, int aLayer ) const = 0; float GetWorksheetLineWidth() const { return m_worksheetLineWidth; } diff --git a/include/widgets/bitmap_toggle.h b/include/widgets/bitmap_toggle.h new file mode 100644 index 0000000000..9adb70a975 --- /dev/null +++ b/include/widgets/bitmap_toggle.h @@ -0,0 +1,69 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019 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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _BITMAP_TOGGLE_H +#define _BITMAP_TOGGLE_H + +#include + +//#include + +#include + + +wxDECLARE_EVENT( TOGGLE_CHANGED, wxCommandEvent ); + +/** + * A checkbox control except with custom bitmaps for the checked and unchecked states + * + * This is useful in space-constrained situations where native toggle button controls are too big + */ + +class BITMAP_TOGGLE : public wxPanel +{ +public: + BITMAP_TOGGLE() {} + + BITMAP_TOGGLE( wxWindow *aParent, wxWindowID aId, const wxBitmap& aCheckedBitmap, + const wxBitmap& aUncheckedBitmap, bool aChecked = false ); + + ///> Set the checkbox state + void SetValue( bool aValue ); + + ///> Read the checkbox state + bool GetValue() { return m_checked; } + +private: + bool m_checked; + + wxStaticBitmap* m_bitmap; + + ///> Bitmap to display in unchecked state + wxBitmap m_unchecked_bitmap; + + ///> Bitmap to display in checked state + wxBitmap m_checked_bitmap; +}; + +#endif diff --git a/include/ws_painter.h b/include/ws_painter.h index 24889bc2a6..f9d45ff015 100644 --- a/include/ws_painter.h +++ b/include/ws_painter.h @@ -54,7 +54,7 @@ public: void LoadColors( const COLOR_SETTINGS* aSettings ) override; /// @copydoc RENDER_SETTINGS::GetColor() - virtual const COLOR4D& GetColor( const VIEW_ITEM* aItem, int aLayer ) const override; + virtual COLOR4D GetColor( const VIEW_ITEM* aItem, int aLayer ) const override; inline bool IsBackgroundDark() const override { diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 1fdbad0231..1df708be91 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -339,8 +339,11 @@ set( PCBNEW_CLASS_SRCS footprint_preview_panel.cpp footprint_tree_pane.cpp + widgets/appearance_controls.cpp + widgets/appearance_controls_base.cpp widgets/panel_selection_filter.cpp widgets/panel_selection_filter_base.cpp + ) set( PCBNEW_SRCS diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 6680a9efc6..0a41706d2d 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -1164,6 +1164,10 @@ unsigned int D_PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const const int HIDE = std::numeric_limits::max(); BOARD* board = GetBoard(); + // Meta control for hiding all pads + if( !aView->IsLayerVisible( LAYER_PADS ) ) + return HIDE; + // Handle Render tab switches if( ( GetAttribute() == PAD_ATTRIB_STANDARD || GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ) && !aView->IsLayerVisible( LAYER_PADS_TH ) ) diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index dbbc774590..cb7f640630 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -622,9 +622,13 @@ unsigned int VIA::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const } } - // Only draw the via if at least one of the layers it crosses is being displayed - if( onVisibleLayer && aView->IsLayerVisible( LAYER_VIAS ) ) + // Draw through vias unconditionally if the vias control is turned on. + // Draw blind/buried/microvias only if at least one of the layers crossed is enabeld. + if( aView->IsLayerVisible( LAYER_VIAS ) ) { + if( !onVisibleLayer && m_ViaType != VIATYPE::THROUGH ) + return HIDE; + switch( m_ViaType ) { case VIATYPE::THROUGH: return aView->IsLayerVisible( LAYER_VIA_THROUGH ) ? 0 : HIDE; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index a9feebf3b2..6c5e92454a 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -296,12 +296,20 @@ void ZONE_CONTAINER::ViewGetLayers( int aLayers[], int& aCount ) const LSEQ layers = m_layerSet.Seq(); for( unsigned int idx = 0; idx < layers.size(); idx++ ) - aLayers[idx] = layers[idx]; + aLayers[idx] = LAYER_ZONE_START + layers[idx]; aCount = layers.size(); } +unsigned int ZONE_CONTAINER::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const +{ + constexpr unsigned int HIDE = std::numeric_limits::max(); + + return aView->IsLayerVisible( LAYER_ZONES ) ? 0 : HIDE; +} + + bool ZONE_CONTAINER::IsOnLayer( PCB_LAYER_ID aLayer ) const { return m_layerSet.test( aLayer ); diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index e67ab58545..d003d657a2 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -148,6 +148,8 @@ public: virtual void ViewGetLayers( int aLayers[], int& aCount ) const override; + unsigned int ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override; + void SetFillMode( ZONE_FILL_MODE aFillMode ) { m_FillMode = aFillMode; } ZONE_FILL_MODE GetFillMode() const { return m_FillMode; } diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index 12d6a97ae5..5c45c597dd 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -82,6 +82,13 @@ void CONNECTIVITY_DATA::Build( BOARD* aBoard ) { m_connAlgo.reset( new CN_CONNECTIVITY_ALGO ); m_connAlgo->Build( aBoard ); + + m_netclassMap.clear(); + + for( NETINFO_ITEM* net : aBoard->GetNetInfo() ) + if( net->GetNetClass()->GetName() != NETCLASS::Default ) + m_netclassMap[net->GetNet()] = net->GetNetClass()->GetName(); + RecalculateRatsnest(); } diff --git a/pcbnew/connectivity/connectivity_data.h b/pcbnew/connectivity/connectivity_data.h index bd51480f98..faa0f3bab5 100644 --- a/pcbnew/connectivity/connectivity_data.h +++ b/pcbnew/connectivity/connectivity_data.h @@ -258,6 +258,11 @@ public: void MarkItemNetAsDirty( BOARD_ITEM* aItem ); void SetProgressReporter( PROGRESS_REPORTER* aReporter ); + const std::map& GetNetclassMap() const + { + return m_netclassMap; + } + #ifndef SWIG const std::vector GetRatsnestForItems( const std::vector aItems ); @@ -286,6 +291,9 @@ private: bool m_skipRatsnest = false; std::mutex m_lock; + + /// Map of netcode -> netclass the net is a member of; used for ratsnest painting + std::map m_netclassMap; }; #endif diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 8ffe0a52c8..cc7e427d9f 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -38,8 +38,8 @@ #include #include #include +#include #include -#include DIALOG_DRC::DIALOG_DRC( DRC* aTester, PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) : @@ -273,7 +273,7 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent ) if( ( violationLayers & board->GetVisibleLayers() ) == 0 ) { - m_brdEditor->GetLayerManager()->SetLayerVisible( item->GetLayer(), true ); + m_brdEditor->GetAppearancePanel()->SetLayerVisible( item->GetLayer(), true ); m_brdEditor->GetCanvas()->Refresh(); } diff --git a/pcbnew/dialogs/panel_pcbnew_color_settings.cpp b/pcbnew/dialogs/panel_pcbnew_color_settings.cpp index cae3e63d4b..5aeb5c1097 100644 --- a/pcbnew/dialogs/panel_pcbnew_color_settings.cpp +++ b/pcbnew/dialogs/panel_pcbnew_color_settings.cpp @@ -26,10 +26,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -439,7 +439,7 @@ bool PANEL_PCBNEW_COLOR_SETTINGS::TransferDataFromWindow() PCBNEW_SETTINGS* app_settings = settingsMgr.GetAppSettings(); app_settings->m_ColorTheme = m_currentSettings->GetFilename(); - m_frame->GetLayerManager()->SyncLayerColors(); + m_frame->GetAppearancePanel()->OnColorThemeChanged(); return true; } diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 3514e789ac..a4ad14d085 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -506,8 +506,6 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in return false; } - wxWindowUpdateLocker no_update( m_Layers ); // Avoid flicker when rebuilding m_Layers - // Unlink the old project if needed GetBoard()->ClearProject(); diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index 25fb31f032..094b81701a 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -37,6 +37,7 @@ #include #include +#include bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery, bool aFinal ) @@ -81,7 +82,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery, bool aFinal ) GetBoard()->SetVisibleLayers( LSET().set() ); ReCreateLayerBox(); ReCreateAuxiliaryToolbar(); - ReFillLayerWidget(); + m_appearancePanel->OnBoardChanged(); UpdateTitle(); Zoom_Automatique( false ); diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp index eceb584017..a5ddde87a0 100644 --- a/pcbnew/menubar_pcb_editor.cpp +++ b/pcbnew/menubar_pcb_editor.cpp @@ -294,15 +294,15 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() }; auto zonesFilledCondition = [ &disp_opt ]( const SELECTION &aSel ) { - return disp_opt.m_DisplayZonesMode == 0; + return disp_opt.m_ZoneDisplayMode == ZONE_DISPLAY_MODE::SHOW_FILLED; }; auto zonesWireframedCondition = [ &disp_opt ]( const SELECTION &aSel ) { - return disp_opt.m_DisplayZonesMode == 1; + return disp_opt.m_ZoneDisplayMode == ZONE_DISPLAY_MODE::HIDE_FILLED; }; auto zonesOutlinedCondition = [ &disp_opt ]( const SELECTION &aSel ) { - return disp_opt.m_DisplayZonesMode == 2; + return disp_opt.m_ZoneDisplayMode == ZONE_DISPLAY_MODE::SHOW_OUTLINED; }; auto sketchTracksCondition = [ &disp_opt ]( const SELECTION &aSel ) { diff --git a/pcbnew/pcb_base_edit_frame.cpp b/pcbnew/pcb_base_edit_frame.cpp index 5314ecb59b..fc8d081f75 100644 --- a/pcbnew/pcb_base_edit_frame.cpp +++ b/pcbnew/pcb_base_edit_frame.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include PCB_BASE_EDIT_FRAME::PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, @@ -136,8 +136,8 @@ void PCB_BASE_EDIT_FRAME::SetGridVisibility( bool aVisible ) PCB_BASE_FRAME::SetGridVisibility( aVisible ); // Update the grid checkbox in the layer widget - if( m_Layers ) - m_Layers->SetRenderState( LAYER_GRID, aVisible ); + if( m_appearancePanel ) + m_appearancePanel->SetObjectVisible( LAYER_GRID, aVisible ); // TODO (ISM): Remove this by changing toolbars to use the EVT_UPDATE_UI to get the state SyncToolbars(); diff --git a/pcbnew/pcb_base_edit_frame.h b/pcbnew/pcb_base_edit_frame.h index 23231033df..153fc0c676 100644 --- a/pcbnew/pcb_base_edit_frame.h +++ b/pcbnew/pcb_base_edit_frame.h @@ -27,6 +27,7 @@ #include +class APPEARANCE_CONTROLS; class BOARD_ITEM_CONTAINER; class PCB_LAYER_WIDGET; class PANEL_SELECTION_FILTER; @@ -222,6 +223,9 @@ protected: /// AUI panel for changing the selection tool filter controls PANEL_SELECTION_FILTER* m_selectionFilterPanel; + + /// AUI panel for controlling layer and object visibility and appearance + APPEARANCE_CONTROLS* m_appearancePanel; }; #endif diff --git a/pcbnew/pcb_display_options.cpp b/pcbnew/pcb_display_options.cpp index 799fe3bb87..2861ac2510 100644 --- a/pcbnew/pcb_display_options.cpp +++ b/pcbnew/pcb_display_options.cpp @@ -43,16 +43,20 @@ PCB_DISPLAY_OPTIONS::PCB_DISPLAY_OPTIONS() m_DisplayPcbTrackFill = FILLED; // false = sketch , true = filled m_ShowTrackClearanceMode = SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS; - m_DisplayZonesMode = 0; /* 0 = Show filled areas outlines in zones, - * 1 = do not show filled areas outlines - * 2 = show outlines of filled areas */ + m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FILLED; m_DisplayNetNamesMode = 3; /* 0 do not show netnames, * 1 show netnames on pads * 2 show netnames on tracks * 3 show netnames on tracks and pads */ m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL; + m_NetColorMode = NET_COLOR_MODE::RATSNEST; m_MaxLinksShowed = 3; // in track creation: number of hairwires shown m_ShowModuleRatsnest = true; // When moving a footprint: allows displaying a ratsnest m_DisplayRatsnestLinesCurved = false; m_ShowGlobalRatsnest = true; + + m_TrackOpacity = 1.0; + m_ViaOpacity = 1.0; + m_PadOpacity = 1.0; + m_ZoneOpacity = 1.0; } diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 38efddf56a..113b7e1f3f 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -66,41 +66,43 @@ const LAYER_NUM GAL_LAYER_ORDER[] = LAYER_VIA_MICROVIA, LAYER_PADS_TH, LAYER_PAD_FR_NETNAMES, LAYER_PAD_FR, - NETNAMES_LAYER_INDEX( F_Cu ), F_Cu, F_Mask, F_SilkS, F_Paste, F_Adhes, F_CrtYd, F_Fab, + NETNAMES_LAYER_INDEX( F_Cu ), F_Cu, ZONE_LAYER_FOR( F_Cu ), + F_Mask, F_SilkS, F_Paste, F_Adhes, F_CrtYd, F_Fab, - NETNAMES_LAYER_INDEX( In1_Cu ), In1_Cu, - NETNAMES_LAYER_INDEX( In2_Cu ), In2_Cu, - NETNAMES_LAYER_INDEX( In3_Cu ), In3_Cu, - NETNAMES_LAYER_INDEX( In4_Cu ), In4_Cu, - NETNAMES_LAYER_INDEX( In5_Cu ), In5_Cu, - NETNAMES_LAYER_INDEX( In6_Cu ), In6_Cu, - NETNAMES_LAYER_INDEX( In7_Cu ), In7_Cu, - NETNAMES_LAYER_INDEX( In8_Cu ), In8_Cu, - NETNAMES_LAYER_INDEX( In9_Cu ), In9_Cu, - NETNAMES_LAYER_INDEX( In10_Cu ), In10_Cu, - NETNAMES_LAYER_INDEX( In11_Cu ), In11_Cu, - NETNAMES_LAYER_INDEX( In12_Cu ), In12_Cu, - NETNAMES_LAYER_INDEX( In13_Cu ), In13_Cu, - NETNAMES_LAYER_INDEX( In14_Cu ), In14_Cu, - NETNAMES_LAYER_INDEX( In15_Cu ), In15_Cu, - NETNAMES_LAYER_INDEX( In16_Cu ), In16_Cu, - NETNAMES_LAYER_INDEX( In17_Cu ), In17_Cu, - NETNAMES_LAYER_INDEX( In18_Cu ), In18_Cu, - NETNAMES_LAYER_INDEX( In19_Cu ), In19_Cu, - NETNAMES_LAYER_INDEX( In20_Cu ), In20_Cu, - NETNAMES_LAYER_INDEX( In21_Cu ), In21_Cu, - NETNAMES_LAYER_INDEX( In22_Cu ), In22_Cu, - NETNAMES_LAYER_INDEX( In23_Cu ), In23_Cu, - NETNAMES_LAYER_INDEX( In24_Cu ), In24_Cu, - NETNAMES_LAYER_INDEX( In25_Cu ), In25_Cu, - NETNAMES_LAYER_INDEX( In26_Cu ), In26_Cu, - NETNAMES_LAYER_INDEX( In27_Cu ), In27_Cu, - NETNAMES_LAYER_INDEX( In28_Cu ), In28_Cu, - NETNAMES_LAYER_INDEX( In29_Cu ), In29_Cu, - NETNAMES_LAYER_INDEX( In30_Cu ), In30_Cu, + NETNAMES_LAYER_INDEX( In1_Cu ), In1_Cu, ZONE_LAYER_FOR( In1_Cu ), + NETNAMES_LAYER_INDEX( In2_Cu ), In2_Cu, ZONE_LAYER_FOR( In2_Cu ), + NETNAMES_LAYER_INDEX( In3_Cu ), In3_Cu, ZONE_LAYER_FOR( In3_Cu ), + NETNAMES_LAYER_INDEX( In4_Cu ), In4_Cu, ZONE_LAYER_FOR( In4_Cu ), + NETNAMES_LAYER_INDEX( In5_Cu ), In5_Cu, ZONE_LAYER_FOR( In5_Cu ), + NETNAMES_LAYER_INDEX( In6_Cu ), In6_Cu, ZONE_LAYER_FOR( In6_Cu ), + NETNAMES_LAYER_INDEX( In7_Cu ), In7_Cu, ZONE_LAYER_FOR( In7_Cu ), + NETNAMES_LAYER_INDEX( In8_Cu ), In8_Cu, ZONE_LAYER_FOR( In8_Cu ), + NETNAMES_LAYER_INDEX( In9_Cu ), In9_Cu, ZONE_LAYER_FOR( In9_Cu ), + NETNAMES_LAYER_INDEX( In10_Cu ), In10_Cu, ZONE_LAYER_FOR( In10_Cu ), + NETNAMES_LAYER_INDEX( In11_Cu ), In11_Cu, ZONE_LAYER_FOR( In11_Cu ), + NETNAMES_LAYER_INDEX( In12_Cu ), In12_Cu, ZONE_LAYER_FOR( In12_Cu ), + NETNAMES_LAYER_INDEX( In13_Cu ), In13_Cu, ZONE_LAYER_FOR( In13_Cu ), + NETNAMES_LAYER_INDEX( In14_Cu ), In14_Cu, ZONE_LAYER_FOR( In14_Cu ), + NETNAMES_LAYER_INDEX( In15_Cu ), In15_Cu, ZONE_LAYER_FOR( In15_Cu ), + NETNAMES_LAYER_INDEX( In16_Cu ), In16_Cu, ZONE_LAYER_FOR( In16_Cu ), + NETNAMES_LAYER_INDEX( In17_Cu ), In17_Cu, ZONE_LAYER_FOR( In17_Cu ), + NETNAMES_LAYER_INDEX( In18_Cu ), In18_Cu, ZONE_LAYER_FOR( In18_Cu ), + NETNAMES_LAYER_INDEX( In19_Cu ), In19_Cu, ZONE_LAYER_FOR( In19_Cu ), + NETNAMES_LAYER_INDEX( In20_Cu ), In20_Cu, ZONE_LAYER_FOR( In20_Cu ), + NETNAMES_LAYER_INDEX( In21_Cu ), In21_Cu, ZONE_LAYER_FOR( In21_Cu ), + NETNAMES_LAYER_INDEX( In22_Cu ), In22_Cu, ZONE_LAYER_FOR( In22_Cu ), + NETNAMES_LAYER_INDEX( In23_Cu ), In23_Cu, ZONE_LAYER_FOR( In23_Cu ), + NETNAMES_LAYER_INDEX( In24_Cu ), In24_Cu, ZONE_LAYER_FOR( In24_Cu ), + NETNAMES_LAYER_INDEX( In25_Cu ), In25_Cu, ZONE_LAYER_FOR( In25_Cu ), + NETNAMES_LAYER_INDEX( In26_Cu ), In26_Cu, ZONE_LAYER_FOR( In26_Cu ), + NETNAMES_LAYER_INDEX( In27_Cu ), In27_Cu, ZONE_LAYER_FOR( In27_Cu ), + NETNAMES_LAYER_INDEX( In28_Cu ), In28_Cu, ZONE_LAYER_FOR( In28_Cu ), + NETNAMES_LAYER_INDEX( In29_Cu ), In29_Cu, ZONE_LAYER_FOR( In29_Cu ), + NETNAMES_LAYER_INDEX( In30_Cu ), In30_Cu, ZONE_LAYER_FOR( In30_Cu ), LAYER_PAD_BK_NETNAMES, LAYER_PAD_BK, - NETNAMES_LAYER_INDEX( B_Cu ), B_Cu, B_Mask, B_Adhes, B_Paste, B_SilkS, B_CrtYd, B_Fab, + NETNAMES_LAYER_INDEX( B_Cu ), B_Cu, ZONE_LAYER_FOR( B_Cu ), + B_Mask, B_Adhes, B_Paste, B_SilkS, B_CrtYd, B_Fab, LAYER_MOD_TEXT_BK, LAYER_WORKSHEET @@ -253,6 +255,7 @@ void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( PCB_LAYER_ID aLayer ) // should be done in some other way I guess.. LAYER_NUM layers[] = { GetNetnameLayer( aLayer ), + ZONE_LAYER_FOR( aLayer ), LAYER_VIA_THROUGH, LAYER_VIAS_HOLES, LAYER_VIAS_NETNAMES, LAYER_PADS_TH, LAYER_PADS_PLATEDHOLES, LAYER_PADS_NETNAMES, LAYER_NON_PLATEDHOLES, LAYER_SELECT_OVERLAY, LAYER_GP_OVERLAY, @@ -301,12 +304,12 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer ) // Extra layers that are brought to the top if a F.* or B.* is selected const std::vector frontLayers = { F_Cu, F_Adhes, F_Paste, F_SilkS, F_Mask, F_Fab, F_CrtYd, LAYER_PAD_FR, - LAYER_PAD_FR_NETNAMES, NETNAMES_LAYER_INDEX( F_Cu ) + LAYER_PAD_FR_NETNAMES, NETNAMES_LAYER_INDEX( F_Cu ), ZONE_LAYER_FOR( F_Cu ) }; const std::vector backLayers = { B_Cu, B_Adhes, B_Paste, B_SilkS, B_Mask, B_Fab, B_CrtYd, LAYER_PAD_BK, - LAYER_PAD_BK_NETNAMES, NETNAMES_LAYER_INDEX( B_Cu ) + LAYER_PAD_BK_NETNAMES, NETNAMES_LAYER_INDEX( B_Cu ), ZONE_LAYER_FOR( B_Cu ) }; const std::vector* extraLayers = NULL; @@ -330,6 +333,7 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer ) { // Display labels for copper layers on the top m_view->SetTopLayer( GetNetnameLayer( aLayer ) ); + m_view->SetTopLayer( ZONE_LAYER_FOR( aLayer ) ); } m_view->EnableTopLayer( true ); @@ -346,10 +350,23 @@ void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard ) for( GAL_LAYER_ID i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; ++i ) m_view->SetLayerVisible( i, aBoard->IsElementVisible( i ) ); + // Via layers controlled by dependencies + m_view->SetLayerVisible( LAYER_VIA_MICROVIA, true ); + m_view->SetLayerVisible( LAYER_VIA_BBLIND, true ); + m_view->SetLayerVisible( LAYER_VIA_THROUGH, true ); + + // Pad layers controlled by dependencies + m_view->SetLayerVisible( LAYER_PADS_TH, true ); + m_view->SetLayerVisible( LAYER_PAD_FR, true ); + m_view->SetLayerVisible( LAYER_PAD_BK, true ); + // Always enable netname layers, as their visibility is controlled by layer dependencies for( LAYER_NUM i = NETNAMES_LAYER_ID_START; i < NETNAMES_LAYER_ID_END; ++i ) m_view->SetLayerVisible( i, true ); + for( LAYER_NUM i = LAYER_ZONE_START; i < LAYER_ZONE_END; i++ ) + m_view->SetLayerVisible( i, true ); + // Enable some layers that are GAL specific m_view->SetLayerVisible( LAYER_PADS_PLATEDHOLES, true ); m_view->SetLayerVisible( LAYER_VIAS_HOLES, true ); @@ -476,7 +493,10 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps() // Set layer display dependencies & targets if( IsCopperLayer( layer ) ) + { + m_view->SetRequired( ZONE_LAYER_FOR( layer ), layer ); m_view->SetRequired( GetNetnameLayer( layer ), layer ); + } else if( IsNetnameLayer( layer ) ) m_view->SetLayerDisplayOnly( layer ); } @@ -491,6 +511,16 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps() m_view->SetRequired( LAYER_NON_PLATEDHOLES, LAYER_PADS_TH ); m_view->SetRequired( LAYER_PADS_NETNAMES, LAYER_PADS_TH ); + // Via visibility + m_view->SetRequired( LAYER_VIA_MICROVIA, LAYER_VIAS ); + m_view->SetRequired( LAYER_VIA_BBLIND, LAYER_VIAS ); + m_view->SetRequired( LAYER_VIA_THROUGH, LAYER_VIAS ); + + // Pad visibility + m_view->SetRequired( LAYER_PADS_TH, LAYER_PADS ); + m_view->SetRequired( LAYER_PAD_FR, LAYER_PADS ); + m_view->SetRequired( LAYER_PAD_BK, LAYER_PADS ); + // Front modules m_view->SetRequired( LAYER_PAD_FR, F_Cu ); m_view->SetRequired( LAYER_MOD_TEXT_FR, LAYER_MOD_FR ); diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 011aab2b82..68b6dddb16 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -86,8 +86,10 @@ #include #include // for DIALOG_DRC_WINDOW_NAME definition #include +#include #include + #include #if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON) @@ -196,9 +198,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : SetBoard( new BOARD() ); - // Create the PCB_LAYER_WIDGET *after* SetBoard(): - m_Layers = new PCB_LAYER_WIDGET( this, GetCanvas() ); - wxIcon icon; icon.CopyFromBitmap( KiBitmap( icon_pcbnew_xpm ) ); SetIcon( icon ); @@ -225,8 +224,10 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : // Create the infobar m_infoBar = new WX_INFOBAR( this, &m_auimgr ); + m_appearancePanel = new APPEARANCE_CONTROLS( this, GetCanvas() ); + m_auimgr.SetManagedWindow( this ); - m_auimgr.SetFlags( wxAUI_MGR_LIVE_RESIZE ); + m_auimgr.SetFlags( wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE ); // Horizontal items; layers 4 - 6 m_auimgr.AddPane( m_mainToolBar, @@ -246,10 +247,12 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : EDA_PANE().VToolbar().Name( "MicrowaveToolbar" ).Right().Layer(2) ); m_auimgr.AddPane( m_drawToolBar, EDA_PANE().VToolbar().Name( "ToolsToolbar" ).Right().Layer(3) ); - m_auimgr.AddPane( m_Layers, - EDA_PANE().Palette().Name( "LayersManager" ).Right().Layer(4) - .Caption( _( "Layers Manager" ) ).PaneBorder( false ) - .MinSize( 80, -1 ).BestSize( m_Layers->GetBestSize() ).Maximize() ); + + m_auimgr.AddPane( m_appearancePanel, + EDA_PANE().Name( "LayersManager" ).Right().Layer( 4 ) + .Caption( _( "Appearance" ) ).MinSize( 150, -1 ) + .BestSize( m_appearancePanel->GetBestSize() ) ); + m_auimgr.AddPane( m_selectionFilterPanel, EDA_PANE().Palette().Name( "SelectionFilter" ).Right().Layer( 4 ) .Caption( _( "Selection Filter" ) ).PaneBorder( false ).Position( 2 ) @@ -261,11 +264,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_auimgr.GetPane( "SelectionFilter" ).Show( m_show_layer_manager_tools ); m_auimgr.GetPane( "MicrowaveToolbar" ).Show( m_show_microwave_tools ); - m_Layers->ReFillRender(); // Update colors in Render after the config is read - ReFillLayerWidget(); // this is near end and after ReFillRender() - // because contents establish size - syncLayerWidgetLayer(); - // The selection filter doesn't need to grow in the vertical direction when docked m_auimgr.GetPane( "SelectionFilter" ).dock_proportion = 0; @@ -365,8 +363,11 @@ PCB_EDIT_FRAME::~PCB_EDIT_FRAME() if( m_toolManager ) m_toolManager->ShutdownAllTools(); + if( GetBoard() ) + GetBoard()->RemoveListener( m_appearancePanel ); + delete m_selectionFilterPanel; - delete m_Layers; + delete m_appearancePanel; } @@ -472,34 +473,6 @@ void PCB_EDIT_FRAME::setupTools() } -void PCB_EDIT_FRAME::ReFillLayerWidget() -{ - ENUM_MAP& layerEnum = ENUM_MAP::Instance(); - - layerEnum.Choices().Clear(); - layerEnum.Undefined( UNDEFINED_LAYER ); - - for( LSEQ seq = LSET::AllLayersMask().Seq(); seq; ++seq ) - layerEnum.Map( *seq, GetBoard()->GetLayerName( *seq ) ); - - wxWindowUpdateLocker no_update( m_Layers ); - m_Layers->ReFill(); - - wxAuiPaneInfo& lyrs = m_auimgr.GetPane( m_Layers ); - - wxSize bestz = m_Layers->GetBestSize(); - - lyrs.MinSize( bestz ); - lyrs.BestSize( bestz ); - lyrs.FloatingSize( bestz ); - - if( lyrs.IsDocked() ) - m_auimgr.Update(); - else - m_Layers->SetSize( bestz ); -} - - void PCB_EDIT_FRAME::OnQuit( wxCommandEvent& event ) { if( event.GetId() == wxID_EXIT ) @@ -748,7 +721,7 @@ void PCB_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer ) { PCB_BASE_FRAME::SetActiveLayer( aLayer ); - syncLayerWidgetLayer(); + m_appearancePanel->OnLayerChanged(); m_toolManager->RunAction( PCB_ACTIONS::layerChanged ); // notify other tools GetCanvas()->SetFocus(); // allow capture of hotkeys @@ -772,14 +745,11 @@ void PCB_EDIT_FRAME::onBoardLoaded() m_infoBar->ShowMessage( "Board file is read only.", wxICON_WARNING ); } - // Re-create layers manager based on layer info in board - ReFillLayerWidget(); ReCreateLayerBox(); + m_appearancePanel->OnBoardChanged(); // Sync layer and item visibility - syncLayerVisibilities(); - syncLayerWidgetLayer(); - SyncRenderStates(); + GetCanvas()->SyncLayersVisibility( m_Pcb ); SetElementVisibility( LAYER_RATSNEST, GetDisplayOptions().m_ShowGlobalRatsnest ); @@ -800,29 +770,15 @@ void PCB_EDIT_FRAME::onBoardLoaded() } -void PCB_EDIT_FRAME::syncLayerWidgetLayer() +void PCB_EDIT_FRAME::OnDisplayOptionsChanged() { - m_Layers->SelectLayer( GetActiveLayer() ); - m_Layers->OnLayerSelected(); -} - - -void PCB_EDIT_FRAME::SyncRenderStates() -{ - m_Layers->ReFillRender(); -} - - -void PCB_EDIT_FRAME::syncLayerVisibilities() -{ - m_Layers->SyncLayerVisibilities(); - GetCanvas()->SyncLayersVisibility( m_Pcb ); + m_appearancePanel->UpdateDisplayOptions(); } void PCB_EDIT_FRAME::OnUpdateLayerAlpha( wxUpdateUIEvent & ) { - m_Layers->SyncLayerAlphaIndicators(); + m_appearancePanel->OnLayerAlphaChanged(); } @@ -841,16 +797,6 @@ void PCB_EDIT_FRAME::SetElementVisibility( GAL_LAYER_ID aElement, bool aNewState GetCanvas()->GetView()->SetLayerVisible( aElement , aNewState ); GetBoard()->SetElementVisibility( aElement, aNewState ); - m_Layers->SetRenderState( aElement, aNewState ); -} - - -void PCB_EDIT_FRAME::SetVisibleAlls() -{ - GetBoard()->SetVisibleAlls(); - - for( GAL_LAYER_ID ii = GAL_LAYER_ID_START; ii < GAL_LAYER_ID_BITMASK_END; ++ii ) - m_Layers->SetRenderState( ii, true ); } @@ -859,23 +805,12 @@ void PCB_EDIT_FRAME::ShowChangedLanguage() // call my base class PCB_BASE_EDIT_FRAME::ShowChangedLanguage(); - // update the layer manager - m_Layers->Freeze(); - - wxAuiPaneInfo& pane_info = m_auimgr.GetPane( m_Layers ); - pane_info.Caption( _( "Visibles" ) ); + // TODO(JE) APPEARANCE + wxAuiPaneInfo& pane_info = m_auimgr.GetPane( m_appearancePanel ); + pane_info.Caption( _( "Appearance" ) ); m_auimgr.Update(); - m_Layers->SetLayersManagerTabsText(); - ReFillLayerWidget(); - // m_Layers->ReFillRender(); // SyncRenderStates() does this - - // upate the layer widget to match board visibility states, both layers and render columns. - syncLayerVisibilities(); - syncLayerWidgetLayer(); - SyncRenderStates(); - - m_Layers->Thaw(); + m_appearancePanel->OnBoardChanged(); // pcbnew-specific toolbars ReCreateMicrowaveVToolbar(); @@ -965,17 +900,16 @@ void PCB_EDIT_FRAME::UpdateUserInterface() m_SelLayerBox->SetLayerSelection( GetActiveLayer() ); - // Update the layer manager - m_Layers->Freeze(); - ReFillLayerWidget(); - // m_Layers->ReFillRender(); // SyncRenderStates() does this + ENUM_MAP& layerEnum = ENUM_MAP::Instance(); - // upate the layer widget to match board visibility states, both layers and render columns. - syncLayerVisibilities(); - syncLayerWidgetLayer(); - SyncRenderStates(); + layerEnum.Choices().Clear(); + layerEnum.Undefined( UNDEFINED_LAYER ); - m_Layers->Thaw(); + for( LSEQ seq = LSET::AllLayersMask().Seq(); seq; ++seq ) + layerEnum.Map( *seq, GetBoard()->GetLayerName( *seq ) ); + + // Stackup and/or color theme may have changed + m_appearancePanel->OnBoardChanged(); } @@ -1009,12 +943,6 @@ void PCB_EDIT_FRAME::SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) { // switches currently used canvas (Cairo / OpenGL). PCB_BASE_FRAME::SwitchCanvas( aCanvasType ); - - // The base class method *does not* reinitialize the layers manager. We must upate the - // layer widget to match board visibility states, both layers and render columns. - syncLayerVisibilities(); - syncLayerWidgetLayer(); - SyncRenderStates(); } diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index 5d22bd0f5e..12d30e4054 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -88,6 +88,7 @@ class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME { friend struct PCB::IFACE; friend class PCB_LAYER_WIDGET; + friend class APPEARANCE_CONTROLS; /// The auxiliary right vertical tool bar used to access the microwave tools. ACTION_TOOLBAR* m_microWaveToolBar; @@ -205,25 +206,6 @@ protected: */ void onBoardLoaded(); - /** - * Function syncLayerWidgetLayer - * updates the currently layer "selection" within the PCB_LAYER_WIDGET. - * The currently selected layer is defined by the return value of GetActiveLayer(). - *

- * This function cannot be inline without including layer_widget.h in - * here and we do not want to do that. - *

- */ - void syncLayerWidgetLayer(); - - /** - * Function syncLayerVisibilities - * updates each "Layer" checkbox in the layer widget according - * to each layer's current visibility determined by IsLayerVisible(), and is - * helpful immediately after loading a BOARD which may have state information in it. - */ - void syncLayerVisibilities(); - /** * Function doAutoSave * performs auto save when the board has been modified and not saved within the @@ -486,13 +468,15 @@ public: */ void SetActiveLayer( PCB_LAYER_ID aLayer ) override; - PCB_LAYER_WIDGET* GetLayerManager() { return m_Layers; } + APPEARANCE_CONTROLS* GetAppearancePanel() { return m_appearancePanel; } /** * Update the UI to reflect changes to the current layer's transparency. */ void OnUpdateLayerAlpha( wxUpdateUIEvent& aEvent ) override; + void OnDisplayOptionsChanged() override; + /** * Function IsElementVisible * tests whether a given element category is visible. Keep this as an @@ -512,26 +496,6 @@ public: */ void SetElementVisibility( GAL_LAYER_ID aElement, bool aNewState ); - /** - * Function SetVisibleAlls - * Set the status of all visible element categories and layers to VISIBLE - */ - void SetVisibleAlls(); - - /** - * Function ReFillLayerWidget - * changes out all the layers in m_Layers and may be called upon - * loading a new BOARD. - */ - void ReFillLayerWidget(); - - /** - * Updates the "Render" colors and checkboxes in the layer widget according - * to current toggle values determined by IsElementVisible(), and is helpful - * immediately after loading a BOARD which may have state information in it. - */ - void SyncRenderStates(); - ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas() void ActivateGalCanvas() override; diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 91923150b5..d59cff8bf4 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -58,7 +58,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS() m_netNamesOnTracks = true; m_netNamesOnVias = true; m_zoneOutlines = true; - m_displayZone = DZ_SHOW_FILLED; + m_zoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FILLED; m_clearance = CL_NONE; m_sketchGraphics = false; m_sketchText = false; @@ -66,6 +66,11 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS() m_netColorMode = NET_COLOR_MODE::RATSNEST; m_contrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL; + m_trackOpacity = 1.0; + m_viaOpacity = 1.0; + m_padOpacity = 1.0; + m_zoneOpacity = 1.0; + // By default everything should be displayed as filled for( unsigned int i = 0; i < arrayDim( m_sketchMode ); ++i ) { @@ -175,20 +180,7 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOption } // Zone display settings - switch( aOptions.m_DisplayZonesMode ) - { - case 0: - m_displayZone = DZ_SHOW_FILLED; - break; - - case 1: - m_displayZone = DZ_HIDE_FILLED; - break; - - case 2: - m_displayZone = DZ_SHOW_OUTLINED; - break; - } + m_zoneDisplayMode = aOptions.m_ZoneDisplayMode; // Clearance settings switch( aOptions.m_ShowTrackClearanceMode ) @@ -219,39 +211,27 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOption m_contrastModeDisplay = aOptions.m_ContrastModeDisplay; + m_netColorMode = aOptions.m_NetColorMode; + + m_trackOpacity = aOptions.m_TrackOpacity; + m_viaOpacity = aOptions.m_ViaOpacity; + m_padOpacity = aOptions.m_PadOpacity; + m_zoneOpacity = aOptions.m_ZoneOpacity; + m_showPageLimits = aShowPageLimits; } -void PCB_RENDER_SETTINGS::LoadNetSettings( const NET_SETTINGS& aSettings, const NETINFO_LIST& aList, - const std::set& aHiddenNets ) -{ - m_netColors.clear(); - - for( const auto& pair : aSettings.m_PcbNetColors ) - { - if( NETINFO_ITEM* net = aList.GetNetItem( pair.first ) ) - m_netColors[net->GetNet()] = pair.second; - } - - m_netclassColors.clear(); - - for( const auto& pair : aSettings.m_NetClasses ) - { - if( pair.second->GetPcbColor() != COLOR4D::UNSPECIFIED ) - m_netclassColors[pair.first] = pair.second->GetPcbColor(); - } - - m_hiddenNets = aHiddenNets; -} - - -const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const +COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const { int netCode = -1; const EDA_ITEM* item = dynamic_cast( aItem ); const BOARD_CONNECTED_ITEM* conItem = dynamic_cast ( aItem ); + // Zones should pull from the copper layer + if( item && item->Type() == PCB_ZONE_AREA_T && IsZoneLayer( aLayer ) ) + aLayer = aLayer - LAYER_ZONE_START; + // Make items invisible in "other layers hidden" contrast mode if( m_contrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN && m_activeLayers.count( aLayer ) == 0 ) return COLOR4D::CLEAR; @@ -261,76 +241,84 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer && m_activeLayers.count( aLayer ) == 0 ) return COLOR4D::CLEAR; + // Normal path: get the layer base color + COLOR4D color = m_layerColors[aLayer]; + if( item ) { // Selection disambiguation if( item->IsBrightened() ) - { return m_selectionCandidateColor; - } // Don't let pads that *should* be NPTHs get lost if( item->Type() == PCB_PAD_T && dyn_cast( item )->PadShouldBeNPTH() ) aLayer = LAYER_MOD_TEXT_INVISIBLE; if( item->IsSelected() ) - return m_layerColorsSel[aLayer]; - - if( item->Type() == PCB_MARKER_T ) - return m_layerColors[aLayer]; - - // For vias, some layers depend on other layers in high contrast mode - if( m_hiContrastEnabled && item->Type() == PCB_VIA_T && - ( aLayer == LAYER_VIAS_HOLES || - aLayer == LAYER_VIA_THROUGH || - aLayer == LAYER_VIA_MICROVIA || - aLayer == LAYER_VIA_BBLIND ) ) - { - const VIA* via = static_cast( item ); - const BOARD* pcb = static_cast( item->GetParent() ); - bool viaActiveLayer = false; - - for( auto activeLayer : m_activeLayers ) - { - auto lay_id = static_cast( activeLayer ); - viaActiveLayer |= via->IsOnLayer( lay_id ) && pcb->IsLayerVisible( lay_id ); - } - - if( viaActiveLayer ) - return m_layerColors[aLayer]; - else - return m_hiContrastColor[aLayer]; - } + color = m_layerColorsSel[aLayer]; + } + else + { + return m_layerColors[aLayer]; } // Try to obtain the netcode for the item if( conItem ) netCode = conItem->GetNetCode(); - // Single net highlight mode - if( m_highlightEnabled && m_highlightNetcodes.count( netCode ) ) - return m_layerColorsHi[aLayer]; - - // Return grayish color for non-highlighted layers in the dimmed high contrast mode - if( m_contrastModeDisplay == HIGH_CONTRAST_MODE::DIMMED && m_activeLayers.count( aLayer ) == 0 ) - return m_hiContrastColor[aLayer]; - - // Catch the case when highlight and high-contraste modes are enabled - // and we are drawing a not highlighted track - if( m_highlightEnabled ) - return m_layerColorsDark[aLayer]; - // Apply net color overrides if( conItem && m_netColorMode == NET_COLOR_MODE::ALL ) { if( m_netColors.count( conItem->GetNetCode() ) ) - return m_netColors.at( conItem->GetNetCode() ); + color = m_netColors.at( conItem->GetNetCode() ); else if( m_netclassColors.count( conItem->GetNetClassName() ) ) - return m_netclassColors.at( conItem->GetNetClassName() ); + color = m_netclassColors.at( conItem->GetNetClassName() ); } + // Single net highlight mode + if( m_highlightEnabled ) + color = m_highlightNetcodes.count( netCode ) ? m_layerColorsHi[aLayer] + : m_layerColorsDark[aLayer]; + + // Return grayish color for non-highlighted layers in the dimmed high contrast mode + if( m_contrastModeDisplay == HIGH_CONTRAST_MODE::DIMMED && m_activeLayers.count( aLayer ) == 0 ) + color = m_hiContrastColor[aLayer]; + + // For vias, some layers depend on other layers in high contrast mode + if( m_hiContrastEnabled && item->Type() == PCB_VIA_T && + ( aLayer == LAYER_VIAS_HOLES || + aLayer == LAYER_VIA_THROUGH || + aLayer == LAYER_VIA_MICROVIA || + aLayer == LAYER_VIA_BBLIND ) ) + { + const VIA* via = static_cast( item ); + const BOARD* pcb = static_cast( item->GetParent() ); + bool viaActiveLayer = false; + + for( auto activeLayer : m_activeLayers ) + { + auto lay_id = static_cast( activeLayer ); + viaActiveLayer |= via->IsOnLayer( lay_id ) && pcb->IsLayerVisible( lay_id ); + } + + if( viaActiveLayer ) + color = m_layerColors[aLayer]; + else + color = m_hiContrastColor[aLayer]; + } + + // Apply per-type opacity overrides + if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T ) + color.a *= m_trackOpacity; + else if( item->Type() == PCB_VIA_T ) + color.a *= m_viaOpacity; + else if( item->Type() == PCB_PAD_T ) + color.a *= m_padOpacity; + else if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T ) + color.a *= m_zoneOpacity; + // No special modificators enabled - return m_layerColors[aLayer]; + return color; } @@ -494,7 +482,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) else if( IsCopperLayer( aLayer ) ) { // Draw a regular track - const COLOR4D& color = m_pcbSettings.GetColor( aTrack, aLayer ); + COLOR4D color = m_pcbSettings.GetColor( aTrack, aLayer ); bool outline_mode = m_pcbSettings.m_sketchMode[LAYER_TRACKS]; m_gal->SetStrokeColor( color ); m_gal->SetFillColor( color ); @@ -528,7 +516,7 @@ void PCB_PAINTER::draw( const ARC* aArc, int aLayer ) if( IsCopperLayer( aLayer ) ) { // Draw a regular track - const COLOR4D& color = m_pcbSettings.GetColor( aArc, aLayer ); + COLOR4D color = m_pcbSettings.GetColor( aArc, aLayer ); bool outline_mode = m_pcbSettings.m_sketchMode[LAYER_TRACKS]; m_gal->SetStrokeColor( color ); m_gal->SetFillColor( color ); @@ -623,7 +611,7 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer ) radius = getDrillSize(aVia) / 2.0 ; bool sketchMode = false; - const COLOR4D& color = m_pcbSettings.GetColor( aVia, aLayer ); + COLOR4D color = m_pcbSettings.GetColor( aVia, aLayer ); switch( aVia->GetViaType() ) { @@ -1179,14 +1167,21 @@ void PCB_PAINTER::draw( const PCB_GROUP* aGroup, int aLayer ) void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone, int aLayer ) { - PCB_LAYER_ID layer = static_cast( aLayer ); + /** + * aLayer will be the virtual zone layer (LAYER_ZONE_START, ... in GAL_LAYER_ID) + * This is used for draw ordering in the GAL. + * The color for the zone comes from the associated copper layer ( aLayer - LAYER_ZONE_START ) + * and the visibility comes from the combination of that copper layer and LAYER_ZONES + */ + wxASSERT( IsZoneLayer( aLayer ) ); + PCB_LAYER_ID layer = static_cast( aLayer - LAYER_ZONE_START ); if( !aZone->IsOnLayer( layer ) ) return; - const COLOR4D& color = m_pcbSettings.GetColor( aZone, aLayer ); + COLOR4D color = m_pcbSettings.GetColor( aZone, layer ); std::deque corners; - PCB_RENDER_SETTINGS::DISPLAY_ZONE_MODE displayMode = m_pcbSettings.m_displayZone; + ZONE_DISPLAY_MODE displayMode = m_pcbSettings.m_zoneDisplayMode; // Draw the outline const SHAPE_POLY_SET* outline = aZone->Outline(); @@ -1221,7 +1216,7 @@ void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone, int aLayer ) } // Draw the filling - if( displayMode != PCB_RENDER_SETTINGS::DZ_HIDE_FILLED ) + if( displayMode != ZONE_DISPLAY_MODE::HIDE_FILLED ) { const SHAPE_POLY_SET& polySet = aZone->GetFilledPolysList( layer ); @@ -1234,12 +1229,12 @@ void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone, int aLayer ) m_gal->SetFillColor( color ); m_gal->SetLineWidth( outline_thickness ); - if( displayMode == PCB_RENDER_SETTINGS::DZ_SHOW_FILLED ) + if( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED ) { m_gal->SetIsFill( true ); m_gal->SetIsStroke( outline_thickness > 0 ); } - else if( displayMode == PCB_RENDER_SETTINGS::DZ_SHOW_OUTLINED ) + else if( displayMode == ZONE_DISPLAY_MODE::SHOW_OUTLINED ) { m_gal->SetIsFill( false ); m_gal->SetIsStroke( true ); diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index 114269cae3..409f0ba038 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -82,22 +82,6 @@ public: CL_EXISTING = 0x20 }; - ///> Determines how zones should be displayed - enum DISPLAY_ZONE_MODE - { - DZ_HIDE_FILLED = 0, - DZ_SHOW_FILLED, - DZ_SHOW_OUTLINED - }; - - ///> Determines how net color overrides should be applied - enum class NET_COLOR_MODE - { - OFF, ///< Net (and netclass) colors are not shown - RATSNEST, ///< Net/netclass colors are shown on ratsnest lines only - ALL ///< Net/netclass colors are shown on all net copper - }; - PCB_RENDER_SETTINGS(); /** @@ -108,19 +92,10 @@ public: */ void LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOptions, bool aShowPageLimits ); - /** - * Loads net-specific render settings - * @param aSettings is the NET_SETTINGS for the current proejct - * @param aList is the list of nets on the board - * @param aHiddenNets is a list of nets to hide from the ratsnest - */ - void LoadNetSettings( const NET_SETTINGS& aSettings, const NETINFO_LIST& aList, - const std::set& aHiddenNets ); - virtual void LoadColors( const COLOR_SETTINGS* aSettings ) override; /// @copydoc RENDER_SETTINGS::GetColor() - virtual const COLOR4D& GetColor( const VIEW_ITEM* aItem, int aLayer ) const override; + virtual COLOR4D GetColor( const VIEW_ITEM* aItem, int aLayer ) const override; /** * Function SetSketchMode @@ -243,7 +218,7 @@ protected: static const double MAX_FONT_SIZE; ///> Option for different display modes for zones - DISPLAY_ZONE_MODE m_displayZone; + ZONE_DISPLAY_MODE m_zoneDisplayMode; ///> Clearance visibility settings int m_clearance; @@ -265,6 +240,12 @@ protected: ///> How to display inactive layers (HIGH_CONTRAST_MODE:NORMAL, DIMMED or HIDDEN ) HIGH_CONTRAST_MODE m_contrastModeDisplay; + + // These opacity overrides multiply with any opacity in the base layer color + double m_trackOpacity; ///< Opacity override for all tracks + double m_viaOpacity; ///< Opacity override for all types of via + double m_padOpacity; ///< Opacity override for SMD pads and PTHs + double m_zoneOpacity; ///< Opacity override for filled zones }; diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index c45b79aaf8..395a1457d0 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -98,11 +99,16 @@ bool PCB_EDIT_FRAME::LoadProjectSettings() pglayout.SetPageLayout( filename ); + // Load render settings that aren't stored in PCB_DISPLAY_OPTIONS + + NET_SETTINGS& netSettings = project.NetSettings(); + NETINFO_LIST& nets = GetBoard()->GetNetInfo(); + KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( GetCanvas()->GetView()->GetPainter()->GetSettings() ); - NETINFO_LIST& nets = GetBoard()->GetNetInfo(); - std::set hiddenNets; + std::set& hiddenNets = rs->GetHiddenNets(); + hiddenNets.clear(); for( const wxString& hidden : localSettings.m_HiddenNets ) { @@ -110,7 +116,26 @@ bool PCB_EDIT_FRAME::LoadProjectSettings() hiddenNets.insert( net->GetNet() ); } - rs->LoadNetSettings( project.NetSettings(), nets, hiddenNets ); + std::map& netColors = rs->GetNetColorMap(); + netColors.clear(); + + for( const auto& pair : netSettings.m_PcbNetColors ) + { + if( NETINFO_ITEM* net = nets.GetNetItem( pair.first ) ) + netColors[net->GetNet()] = pair.second; + } + + std::map& netclassColors = rs->GetNetclassColorMap(); + netclassColors.clear(); + + for( const auto& pair : netSettings.m_NetClasses ) + { + if( pair.second->GetPcbColor() != COLOR4D::UNSPECIFIED ) + netclassColors[pair.first] = pair.second->GetPcbColor(); + } + + m_appearancePanel->SetUserLayerPresets( project.m_LayerPresets ); + m_appearancePanel->ApplyLayerPreset( localSettings.m_ActiveLayerPreset ); SELECTION_FILTER_OPTIONS& filterOpts = GetToolManager()->GetTool()->GetFilter(); @@ -119,6 +144,11 @@ bool PCB_EDIT_FRAME::LoadProjectSettings() PCB_DISPLAY_OPTIONS opts = GetDisplayOptions(); opts.m_ContrastModeDisplay = localSettings.m_ContrastModeDisplay; + opts.m_NetColorMode = localSettings.m_NetColorMode; + opts.m_TrackOpacity = localSettings.m_TrackOpacity; + opts.m_ViaOpacity = localSettings.m_ViaOpacity; + opts.m_PadOpacity = localSettings.m_PadOpacity; + opts.m_ZoneOpacity = localSettings.m_ZoneOpacity; SetDisplayOptions( opts ); SetActiveLayer( localSettings.m_ActiveLayer ); @@ -146,11 +176,26 @@ void PCB_EDIT_FRAME::SaveProjectSettings() // TODO: Can this be pulled out of BASE_SCREEN? project.m_BoardPageLayoutDescrFile = BASE_SCREEN::m_PageLayoutDescrFileName; + project.m_LayerPresets = m_appearancePanel->GetUserLayerPresets(); + RecordDRCExclusions(); - localSettings.m_ActiveLayer = GetActiveLayer(); + // Save appearance control settings - localSettings.m_ContrastModeDisplay = GetDisplayOptions().m_ContrastModeDisplay; + localSettings.m_ActiveLayer = GetActiveLayer(); + localSettings.m_ActiveLayerPreset = m_appearancePanel->GetActiveLayerPreset(); + + const PCB_DISPLAY_OPTIONS& displayOpts = GetDisplayOptions(); + + localSettings.m_ContrastModeDisplay = displayOpts.m_ContrastModeDisplay; + localSettings.m_NetColorMode = displayOpts.m_NetColorMode; + localSettings.m_TrackOpacity = displayOpts.m_TrackOpacity; + localSettings.m_ViaOpacity = displayOpts.m_ViaOpacity; + localSettings.m_PadOpacity = displayOpts.m_PadOpacity; + localSettings.m_ZoneOpacity = displayOpts.m_ZoneOpacity; + localSettings.m_ZoneDisplayMode = displayOpts.m_ZoneDisplayMode; + + // Save render settings that aren't stored in PCB_DISPLAY_OPTIONS KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( GetCanvas()->GetView()->GetPainter()->GetSettings() ); @@ -165,6 +210,25 @@ void PCB_EDIT_FRAME::SaveProjectSettings() localSettings.m_HiddenNets.emplace_back( net->GetNetname() ); } + NET_SETTINGS& netSettings = project.NetSettings(); + + netSettings.m_PcbNetColors.clear(); + + for( const auto& pair : rs->GetNetColorMap() ) + { + if( NETINFO_ITEM* net = nets.GetNetItem( pair.first ) ) + netSettings.m_PcbNetColors[net->GetNetname()] = pair.second; + } + + std::map& netclassColors = rs->GetNetclassColorMap(); + + // NOTE: this assumes netclasses will have already been updated, which I think is the case + for( const auto& pair : netSettings.m_NetClasses ) + { + if( netclassColors.count( pair.first ) ) + pair.second->SetPcbColor( netclassColors.at( pair.first ) ); + } + SELECTION_FILTER_OPTIONS& filterOpts = GetToolManager()->GetTool()->GetFilter(); localSettings.m_SelectionFilter = filterOpts; diff --git a/pcbnew/pcbnew_settings.cpp b/pcbnew/pcbnew_settings.cpp index b6ba9b1173..be419854a6 100644 --- a/pcbnew/pcbnew_settings.cpp +++ b/pcbnew/pcbnew_settings.cpp @@ -165,8 +165,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS() m_params.emplace_back( new PARAM( "pcb_display.via_fill", &m_Display.m_DisplayViaFill, true ) ); - m_params.emplace_back( - new PARAM( "pcb_display.zone_mode", &m_Display.m_DisplayZonesMode, 0, 0, 2 ) ); + m_params.emplace_back( new PARAM_ENUM( "pcb_display.zone_mode", + &m_Display.m_ZoneDisplayMode, ZONE_DISPLAY_MODE::SHOW_FILLED, + ZONE_DISPLAY_MODE::SHOW_OUTLINED, ZONE_DISPLAY_MODE::SHOW_FILLED ) ); m_params.emplace_back( new PARAM( "plot.line_width", &m_PlotLineWidth, 0.1, 0.01, 5.0 ) ); diff --git a/pcbnew/ratsnest/ratsnest_viewitem.cpp b/pcbnew/ratsnest/ratsnest_viewitem.cpp index a4a47e4a10..193c9bf6b3 100644 --- a/pcbnew/ratsnest/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest/ratsnest_viewitem.cpp @@ -76,15 +76,16 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const gal->SetLineWidth( 1.0 ); auto rs = static_cast( aView->GetPainter()->GetSettings() ); - COLOR4D defaultColor = rs->GetColor( nullptr, LAYER_RATSNEST ); - COLOR4D color = defaultColor; - - bool colorByNet = rs->GetNetColorMode() != PCB_RENDER_SETTINGS::NET_COLOR_MODE::OFF; + COLOR4D defaultColor = rs->GetColor( nullptr, LAYER_RATSNEST ); + COLOR4D color = defaultColor; + const bool colorByNet = rs->GetNetColorMode() != NET_COLOR_MODE::OFF; std::set highlightedNets = rs->GetHighlightNetCodes(); const std::set& hiddenNets = rs->GetHiddenNets(); - std::map& netColors = rs->GetNetColorMap(); + std::map& netColors = rs->GetNetColorMap(); + std::map& netclassColors = rs->GetNetclassColorMap(); + const std::map& netclassMap = m_data->GetNetclassMap(); const bool curved_ratsnest = rs->GetCurvedRatsnestLinesEnabled(); @@ -96,9 +97,15 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const if( colorByNet && netColors.count( l.netCode ) ) color = netColors.at( l.netCode ); + else if( colorByNet && netclassMap.count( l.netCode ) + && netclassColors.count( netclassMap.at( l.netCode ) ) ) + color = netclassColors.at( netclassMap.at( l.netCode ) ); else color = defaultColor; + if( color == COLOR4D::UNSPECIFIED ) + color = defaultColor; + gal->SetStrokeColor( color.Brightened( 0.5 ) ); if ( l.a == l.b ) @@ -137,9 +144,15 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const if( colorByNet && netColors.count( i ) ) color = netColors.at( i ); + else if( colorByNet && netclassMap.count( i ) + && netclassColors.count( netclassMap.at( i ) ) ) + color = netclassColors.at( netclassMap.at( i ) ); else color = defaultColor; + if( color == COLOR4D::UNSPECIFIED ) + color = defaultColor; + // Draw the "static" ratsnest if( highlightedNets.count( i ) ) gal->SetStrokeColor( color.Brightened(0.8) ); diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 4f4a66558b..8d9a5bcde8 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -868,9 +868,6 @@ bool ROUTER_TOOL::prepareInteractive() editFrame->SetActiveLayer( ToLAYER_ID( routingLayer ) ); - // Force layer visible - editFrame->GetLayerManager()->SetLayerVisible( routingLayer, true ); - // for some reason I don't understand, GetNetclass() may return null sometimes... if( m_startItem && m_startItem->Net() >= 0 && m_startItem->Parent() && m_startItem->Parent()->GetNetClass() ) diff --git a/pcbnew/swig/layers_id_colors_and_visibility.i b/pcbnew/swig/layers_id_colors_and_visibility.i index ac1436dc0f..0d4ce3fd5e 100644 --- a/pcbnew/swig/layers_id_colors_and_visibility.i +++ b/pcbnew/swig/layers_id_colors_and_visibility.i @@ -33,6 +33,10 @@ */ %ignore operator+(const GAL_LAYER_ID&, int); +// Force the GAL_LAYER_ID version to be exposed +%ignore GAL_SET::set(int, bool); +%ignore GAL_SET::set(int); + %include layers_id_colors_and_visibility.h // Extend LSET by 2 methods to add or remove layers from the layer list diff --git a/pcbnew/toolbars_pcb_editor.cpp b/pcbnew/toolbars_pcb_editor.cpp index ddc5869982..c9f68df610 100644 --- a/pcbnew/toolbars_pcb_editor.cpp +++ b/pcbnew/toolbars_pcb_editor.cpp @@ -704,7 +704,7 @@ void PCB_EDIT_FRAME::SyncToolbars() auto& opts = GetDisplayOptions(); KIGFX::GAL_DISPLAY_OPTIONS& galOpts = GetGalDisplayOptions(); - int zoneMode = opts.m_DisplayZonesMode; + ZONE_DISPLAY_MODE zoneMode = opts.m_ZoneDisplayMode; m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() ); m_mainToolBar->Toggle( ACTIONS::undo, GetUndoCommandCount() > 0 ); @@ -731,15 +731,18 @@ void PCB_EDIT_FRAME::SyncToolbars() m_optionsToolBar->Toggle( PCB_ACTIONS::showLayersManager, LayerManagerShown() ); m_optionsToolBar->Toggle( PCB_ACTIONS::showMicrowaveToolbar, MicrowaveToolbarShown() ); - bool hcm = opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL; + m_optionsToolBar->Toggle( PCB_ACTIONS::zoneDisplayEnable, + zoneMode == ZONE_DISPLAY_MODE::SHOW_FILLED ); + m_optionsToolBar->Toggle( PCB_ACTIONS::zoneDisplayDisable, + zoneMode == ZONE_DISPLAY_MODE::HIDE_FILLED ); + m_optionsToolBar->Toggle( PCB_ACTIONS::zoneDisplayOutlines, + zoneMode == ZONE_DISPLAY_MODE::SHOW_OUTLINED ); - m_optionsToolBar->Toggle( PCB_ACTIONS::zoneDisplayEnable, zoneMode == 0 ); - m_optionsToolBar->Toggle( PCB_ACTIONS::zoneDisplayDisable, zoneMode == 1 ); - m_optionsToolBar->Toggle( PCB_ACTIONS::zoneDisplayOutlines, zoneMode == 2 ); m_optionsToolBar->Toggle( PCB_ACTIONS::trackDisplayMode, !opts.m_DisplayPcbTrackFill ); m_optionsToolBar->Toggle( PCB_ACTIONS::viaDisplayMode, !opts.m_DisplayViaFill ); m_optionsToolBar->Toggle( PCB_ACTIONS::padDisplayMode, !opts.m_DisplayPadFill ); - m_optionsToolBar->Toggle( ACTIONS::highContrastMode, hcm ); + m_optionsToolBar->Toggle( ACTIONS::highContrastMode, + opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL ); m_optionsToolBar->Refresh(); TOGGLE_TOOL( m_drawToolBar, ACTIONS::selectionTool ); diff --git a/pcbnew/tools/pcb_inspection_tool.cpp b/pcbnew/tools/pcb_inspection_tool.cpp index bae93b21d9..86fcdc1319 100644 --- a/pcbnew/tools/pcb_inspection_tool.cpp +++ b/pcbnew/tools/pcb_inspection_tool.cpp @@ -272,18 +272,19 @@ int PCB_INSPECTION_TOOL::HighlightItem( const TOOL_EVENT& aEvent ) int PCB_INSPECTION_TOOL::HighlightNet( const TOOL_EVENT& aEvent ) { - int netcode = aEvent.Parameter(); - KIGFX::RENDER_SETTINGS* settings = m_toolMgr->GetView()->GetPainter()->GetSettings(); + int netcode = aEvent.Parameter(); + KIGFX::RENDER_SETTINGS* settings = m_toolMgr->GetView()->GetPainter()->GetSettings(); + const std::set& highlighted = settings->GetHighlightNetCodes(); if( netcode > 0 ) { - m_lastNetcode = *settings->GetHighlightNetCodes().begin(); + m_lastNetcode = highlighted.empty() ? -1 : *highlighted.begin(); settings->SetHighlight( true, netcode ); m_toolMgr->GetView()->UpdateAllLayersColor(); } else if( aEvent.IsAction( &PCB_ACTIONS::toggleLastNetHighlight ) ) { - int temp = *settings->GetHighlightNetCodes().begin(); + int temp = highlighted.empty() ? -1 : *highlighted.begin(); settings->SetHighlight( true, m_lastNetcode ); m_toolMgr->GetView()->UpdateAllLayersColor(); m_lastNetcode = temp; diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 90adaa23aa..f9f7b5914a 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -184,13 +184,16 @@ int PCBNEW_CONTROL::ZoneDisplayMode( const TOOL_EVENT& aEvent ) // Apply new display options to the GAL canvas if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayEnable ) ) - opts.m_DisplayZonesMode = 0; + opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_FILLED; else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayDisable ) ) - opts.m_DisplayZonesMode = 1; + opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::HIDE_FILLED; else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayOutlines ) ) - opts.m_DisplayZonesMode = 2; + opts.m_ZoneDisplayMode = ZONE_DISPLAY_MODE::SHOW_OUTLINED; else if( aEvent.IsAction( &PCB_ACTIONS::zoneDisplayToggle ) ) - opts.m_DisplayZonesMode = ( opts.m_DisplayZonesMode + 1 ) % 3; + { + int nextMode = ( static_cast( opts.m_ZoneDisplayMode ) + 1 ) % 3; + opts.m_ZoneDisplayMode = static_cast( nextMode ); + } else wxFAIL; diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index a46b3f9d65..d9029d4d1f 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -66,9 +66,6 @@ public: // Rotate through the available high-contrast modes int HighContrastModeCycle( const TOOL_EVENT& aEvent ); - // Layer view presets - int ApplyLayerPreset( const TOOL_EVENT& aEvent ); - // Layer control int LayerSwitch( const TOOL_EVENT& aEvent ); int LayerNext( const TOOL_EVENT& aEvent ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index d737f90d4c..42e3fc7b29 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -460,15 +460,17 @@ const GENERAL_COLLECTORS_GUIDE SELECTION_TOOL::getCollectorsGuide() const GENERAL_COLLECTORS_GUIDE guide( board()->GetVisibleLayers(), (PCB_LAYER_ID) view()->GetTopLayer(), view() ); + bool padsDisabled = !board()->IsElementVisible( LAYER_PADS ); + // account for the globals guide.SetIgnoreMTextsMarkedNoShow( ! board()->IsElementVisible( LAYER_MOD_TEXT_INVISIBLE ) ); guide.SetIgnoreMTextsOnBack( ! board()->IsElementVisible( LAYER_MOD_TEXT_BK ) ); guide.SetIgnoreMTextsOnFront( ! board()->IsElementVisible( LAYER_MOD_TEXT_FR ) ); guide.SetIgnoreModulesOnBack( ! board()->IsElementVisible( LAYER_MOD_BK ) ); guide.SetIgnoreModulesOnFront( ! board()->IsElementVisible( LAYER_MOD_FR ) ); - guide.SetIgnorePadsOnBack( ! board()->IsElementVisible( LAYER_PAD_BK ) ); - guide.SetIgnorePadsOnFront( ! board()->IsElementVisible( LAYER_PAD_FR ) ); - guide.SetIgnoreThroughHolePads( ! board()->IsElementVisible( LAYER_PADS_TH ) ); + guide.SetIgnorePadsOnBack( padsDisabled || ! board()->IsElementVisible( LAYER_PAD_BK ) ); + guide.SetIgnorePadsOnFront( padsDisabled || ! board()->IsElementVisible( LAYER_PAD_FR ) ); + guide.SetIgnoreThroughHolePads( padsDisabled || ! board()->IsElementVisible( LAYER_PADS_TH ) ); guide.SetIgnoreModulesVals( ! board()->IsElementVisible( LAYER_MOD_VALUES ) ); guide.SetIgnoreModulesRefs( ! board()->IsElementVisible( LAYER_MOD_REFERENCES ) ); guide.SetIgnoreThroughVias( ! board()->IsElementVisible( LAYER_VIA_THROUGH ) ); @@ -488,7 +490,7 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag, GENERAL_COLLECTOR collector; auto& displayOpts = m_frame->GetDisplayOptions(); - guide.SetIgnoreZoneFills( displayOpts.m_DisplayZonesMode != 0 ); + guide.SetIgnoreZoneFills( displayOpts.m_ZoneDisplayMode != ZONE_DISPLAY_MODE::SHOW_FILLED ); if( m_enteredGroup && !m_enteredGroup->GetBoundingBox().Contains( wxPoint( aWhere.x, aWhere.y ) ) ) @@ -1045,12 +1047,22 @@ void SELECTION_TOOL::selectAllItemsOnNet( int aNetCode ) auto connectivity = board()->GetConnectivity(); for( BOARD_CONNECTED_ITEM* item : connectivity->GetNetItems( aNetCode, types ) ) - select( item ); + if( itemPassesFilter( item ) ) + select( item ); } int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent ) { + // If we've been passed an argument, just select that netcode + int netcode = aEvent.Parameter(); + + if( netcode > 0 ) + { + selectAllItemsOnNet( netcode ); + return 0; + } + if( !selectCursor() ) return 0; diff --git a/pcbnew/widgets/appearance_controls.cpp b/pcbnew/widgets/appearance_controls.cpp new file mode 100644 index 0000000000..6482a26777 --- /dev/null +++ b/pcbnew/widgets/appearance_controls.cpp @@ -0,0 +1,1907 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 Jon Evans + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/// Template for object appearance settings +const APPEARANCE_CONTROLS::APPEARANCE_SETTING APPEARANCE_CONTROLS::s_objectSettings[] = { + +#define RR APPEARANCE_CONTROLS::APPEARANCE_SETTING // Render Row abbreviation to reduce source width + + // text id tooltip opacity slider + RR( _( "Tracks" ), LAYER_TRACKS, _( "Show tracks" ), true ), + RR( _( "Vias" ), LAYER_VIAS, _( "Show all vias" ), true ), + RR( _( "Pads" ), LAYER_PADS, _( "Show all pads" ), true ), + RR( _( "Zones" ), LAYER_ZONES, _( "Show copper zones" ), true ), + RR(), + RR( _( "Footprints Front" ), LAYER_MOD_FR, _( "Show footprints that are on board's front" ) ), + RR( _( "Footprints Back" ), LAYER_MOD_BK, _( "Show footprints that are on board's back" ) ), + RR( _( "Values" ), LAYER_MOD_VALUES, _( "Show footprint values" ) ), + RR( _( "References" ), LAYER_MOD_REFERENCES, _( "Show footprint references" ) ), + RR( _( "Footprint Text" ), LAYER_MOD_TEXT_FR, _( "Show footprint text" ) ), + RR( _( "Hidden Text" ), LAYER_MOD_TEXT_INVISIBLE, _( "Show footprint text marked as invisible" ) ), + RR(), + RR( _( "Ratsnest" ), LAYER_RATSNEST, _( "Show unconnected nets as a ratsnest") ), + RR( _( "No-Connects" ), LAYER_NO_CONNECTS, _( "Show a marker on pads which have no net connected" ) ), + RR( _( "DRC Warnings" ), LAYER_DRC_WARNING, _( "DRC violations with a Warning severity" ) ), + RR( _( "DRC Errors" ), LAYER_DRC_ERROR, _( "DRC violations with an Error severity" ) ), + RR( _( "DRC Exclusions" ), LAYER_DRC_EXCLUSION, _( "DRC violations which have been individually excluded" ) ), + RR( _( "Anchors" ), LAYER_ANCHOR, _( "Show footprint and text origins as a cross" ) ), + RR( _( "Worksheet" ), LAYER_WORKSHEET, _( "Show worksheet" ) ), + RR( _( "Grid" ), LAYER_GRID, _( "Show the (x,y) grid dots" ) ) +}; + +// These are the built-in layer presets that cannot be deleted + +LAYER_PRESET APPEARANCE_CONTROLS::presetNoLayers( _( "No Layers" ), LSET() ); + +LAYER_PRESET APPEARANCE_CONTROLS::presetAllLayers( _( "All Layers" ), LSET::AllLayersMask() ); + +LAYER_PRESET APPEARANCE_CONTROLS::presetAllCopper( _( "All Copper Layers" ), LSET::AllCuMask() ); + +LAYER_PRESET APPEARANCE_CONTROLS::presetInnerCopper( _( "Inner Copper Layers" ), + LSET::InternalCuMask().set( Edge_Cuts ) ); + +LAYER_PRESET APPEARANCE_CONTROLS::presetFront( _( "Front Layers" ), + LSET::FrontMask().set( Edge_Cuts ) ); + +LAYER_PRESET APPEARANCE_CONTROLS::presetFrontAssembly( _( "Front Assembly View" ), + LSET::FrontAssembly().set( Edge_Cuts ), GAL_SET::DefaultVisible(), F_SilkS ); + +LAYER_PRESET APPEARANCE_CONTROLS::presetBack( _( "Back Layers" ), + LSET::BackMask().set( Edge_Cuts ) ); + +LAYER_PRESET APPEARANCE_CONTROLS::presetBackAssembly( _( "Back Assembly View" ), + LSET::BackAssembly().set( Edge_Cuts ), GAL_SET::DefaultVisible(), B_SilkS ); + + +APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFocusOwner, + bool aFpEditorMode ) : + APPEARANCE_CONTROLS_BASE( aParent ), + m_frame( aParent ), + m_board( nullptr ), + m_currentPreset( nullptr ), + m_layerContextMenu( nullptr ), + m_contextMenuNetCode( 0 ) +{ + int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x; + m_iconProvider = new ROW_ICON_PROVIDER( indicatorSize ); + int pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize(); + int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y ); + + m_btnNetInspector->SetBitmapLabel( KiBitmap( list_nets_xpm ) ); + m_btnConfigureNetClasses->SetBitmapLabel( KiBitmap( options_generic_xpm ) ); + m_btnDeletePreset->SetBitmapLabel( KiBitmap( trash_xpm ) ); + + m_txtNetFilter->SetHint( _( "Filter nets" ) ); + + if( screenHeight <= 900 && pointSize >= indicatorSize ) + pointSize = pointSize * 8 / 10; + + m_pointSize = pointSize; + +#ifdef __WXMAC__ + wxFont font = m_notebook->GetFont(); + font.SetPointSize( m_pointSize ); + m_notebook->SetFont( font ); +#endif + + auto setHighContrastMode = + [&]( HIGH_CONTRAST_MODE aMode ) + { + PCB_DISPLAY_OPTIONS opts = m_frame->GetDisplayOptions(); + opts.m_ContrastModeDisplay = aMode; + // TODO(JE) why both? + m_frame->SetDisplayOptions( opts ); + m_frame->GetCanvas()->GetView()->UpdateDisplayOptions( opts ); + m_frame->GetCanvas()->SetHighContrastLayer( m_frame->GetActiveLayer() ); + m_frame->GetCanvas()->Refresh(); + + // TODO: remove once EVT_UPDATE_UI works + m_frame->SyncToolbars(); + }; + + m_rbHighContrastNormal->Bind( wxEVT_RADIOBUTTON, + [=]( wxCommandEvent& aEvent ) + { + setHighContrastMode( HIGH_CONTRAST_MODE::NORMAL ); + } ); + + m_rbHighContrastDim->Bind( wxEVT_RADIOBUTTON, + [=]( wxCommandEvent& aEvent ) + { + setHighContrastMode( HIGH_CONTRAST_MODE::DIMMED ); + } ); + + m_rbHighContrastOff->Bind( wxEVT_RADIOBUTTON, + [=]( wxCommandEvent& aEvent ) + { + setHighContrastMode( HIGH_CONTRAST_MODE::HIDDEN ); + } ); + + m_cbLayerPresets->Bind( wxEVT_CHOICE, &APPEARANCE_CONTROLS::onLayerPresetChanged, this ); + + m_btnNetInspector->Bind( wxEVT_BUTTON, + [&]( wxCommandEvent& aEvent ) + { + m_frame->GetToolManager()->RunAction( PCB_ACTIONS::listNets, true ); + } ); + + m_btnConfigureNetClasses->Bind( wxEVT_BUTTON, + [&]( wxCommandEvent& aEvent ) + { + // This panel should only be visible in the PCB_EDIT_FRAME anyway + if( PCB_EDIT_FRAME* editframe = dynamic_cast( m_frame ) ) + editframe->ShowBoardSetupDialog( _( "Net Classes" ) ); + } ); + + m_cbFlipBoard->SetValue( m_frame->GetCanvas()->GetView()->IsMirroredX() ); + m_cbFlipBoard->Bind( wxEVT_CHECKBOX, + [&]( wxCommandEvent& aEvent ) + { + m_frame->GetToolManager()->RunAction( PCB_ACTIONS::flipBoard, true ); + } ); + + m_paneLayerDisplay->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + loadDefaultLayerPresets(); + rebuildObjects(); + OnBoardChanged(); + + Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::OnLayerContextMenu, this, + ID_CHANGE_COLOR, ID_LAST_VALUE ); + + m_rbNetColorAll->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorModeChanged, this ); + m_rbNetColorOff->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorModeChanged, this ); + m_rbNetColorRatsnest->Bind( wxEVT_RADIOBUTTON, + &APPEARANCE_CONTROLS::onNetColorModeChanged, this ); +} + + +wxSize APPEARANCE_CONTROLS::GetBestSize() const +{ + wxSize size( 240, 480 ); + // TODO(JE) appropriate logic + return size; +} + + +void APPEARANCE_CONTROLS::OnLayerDisplayPaneChanged( wxCollapsiblePaneEvent& event ) +{ + // Because wxWidgets is broken and will not properly lay these out automatically + m_panelLayers->Fit(); + m_sizerOuter->Layout(); +} + + +void APPEARANCE_CONTROLS::OnNetDisplayPaneChanged( wxCollapsiblePaneEvent& event ) +{ + // Because wxWidgets is broken and will not properly lay these out automatically + m_panelNetsAndClasses->Fit(); + m_sizerOuter->Layout(); +} + + +void APPEARANCE_CONTROLS::OnNotebookPageChanged( wxNotebookEvent& aEvent ) +{ + // Work around wxMac issue where the notebook pages are blank +#ifdef __WXMAC__ + int page = aEvent.GetSelection(); + + if( page >= 0 ) + m_notebook->ChangeSelection( static_cast( page ) ); +#endif + + // Because wxWidgets is broken and will send click events to children of the collapsible + // panes even if they are collapsed without this + m_panelLayers->Fit(); + m_panelNetsAndClasses->Fit(); + m_sizerOuter->Layout(); +} + + +void APPEARANCE_CONTROLS::OnBoardChanged() +{ + Freeze(); + rebuildLayers(); + rebuildLayerContextMenu(); + syncColorsAndVisibility(); + syncObjectSettings(); + rebuildNets(); + rebuildLayerPresetsWidget(); + syncLayerPresetSelection(); + + UpdateDisplayOptions(); + + m_board = m_frame->GetBoard(); + + if( m_board ) + m_board->AddListener( this ); + + Thaw(); + Refresh(); +} + + +void APPEARANCE_CONTROLS::OnBoardNetSettingsChanged( BOARD& aBoard ) +{ + handleBoardItemsChanged(); +} + + +void APPEARANCE_CONTROLS::OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aBoardItem ) +{ + if( aBoardItem->Type() == PCB_NETINFO_T ) + handleBoardItemsChanged(); +} + + +void APPEARANCE_CONTROLS::OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM* aBoardItem ) +{ + if( aBoardItem->Type() == PCB_NETINFO_T ) + handleBoardItemsChanged(); +} + + +void APPEARANCE_CONTROLS::OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aBoardItem ) +{ + if( aBoardItem->Type() == PCB_NETINFO_T ) + handleBoardItemsChanged(); +} + + + +void APPEARANCE_CONTROLS::handleBoardItemsChanged() +{ + Freeze(); + rebuildNets(); + Thaw(); +} + + +void APPEARANCE_CONTROLS::OnColorThemeChanged() +{ + syncColorsAndVisibility(); + syncObjectSettings(); +} + + +void APPEARANCE_CONTROLS::OnLayerChanged() +{ + static wxColour normalColor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ); + static wxColour highlightColor = wxSystemSettings::GetColour( wxSYS_COLOUR_SCROLLBAR ); + + PCB_LAYER_ID current = m_frame->GetActiveLayer(); + + for( std::unique_ptr& setting : m_layerSettings ) + { + LAYER_NUM layer = setting->id; + + if( setting->ctl_panel ) + { + setting->ctl_panel->SetBackgroundColour( current == layer ? + highlightColor : normalColor ); + } + + if( setting->ctl_indicator ) + { + setting->ctl_indicator->SetIndicatorState( current == layer ? + ROW_ICON_PROVIDER::STATE::ON : + ROW_ICON_PROVIDER::STATE::OFF ); + } + } + +#ifdef __WXMAC__ + Refresh(); +#endif +} + + +void APPEARANCE_CONTROLS::SetLayerVisible( LAYER_NUM aLayer, bool isVisible ) +{ + BOARD* board = m_frame->GetBoard(); + LSET visible = board->GetVisibleLayers(); + PCB_LAYER_ID layer = ToLAYER_ID( aLayer ); + + if( visible.test( layer ) == isVisible ) + return; + + visible.set( layer, isVisible ); + board->SetVisibleLayers( visible ); + + m_frame->GetCanvas()->GetView()->SetLayerVisible( layer, isVisible ); + + syncColorsAndVisibility(); +} + + +void APPEARANCE_CONTROLS::SetObjectVisible( GAL_LAYER_ID aLayer, bool isVisible ) +{ + // Currently only used for the grid, so we just update the ui + if( m_objectSettingsMap.count( aLayer ) ) + { + APPEARANCE_SETTING* setting = m_objectSettingsMap.at( aLayer ); + setting->ctl_visibility->SetValue( isVisible ); + } +} + + +void APPEARANCE_CONTROLS::OnLayerAlphaChanged() +{ + // TODO(JE) Is this even needed if the layer alphas are getting directly updated? + // Maybe we just need the "down" arrow to indicate if the alpha is below 1 + +#if 0 + static constexpr double alphaEpsilon = 0.04; + + PCB_LAYER_ID current = m_frame->GetActiveLayer(); + COLOR_SETTINGS* theme = m_frame->GetColorSettings(); + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* rs = painter->GetSettings(); + + for( APPEARANCE_SETTING& setting : m_layerSettings ) + { + if( !setting.ctl_indicator ) + continue; + + COLOR4D layerColor = theme->GetColor( setting.id ); + COLOR4D screenColor = rs->GetLayerColor( setting.id ); + + if( std::abs( screenColor.a - layerColor.a ) > alphaEpsilon ) + { + if( screenColor.a < layerColor.a ) + setting.ctl_indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::DOWN ); + else + setting.ctl_indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::UP ); + } + else + { + setting.ctl_indicator->SetIndicatorState( setting.id == current ? + ROW_ICON_PROVIDER::STATE::ON : + ROW_ICON_PROVIDER::STATE::OFF ); + } + } +#endif +} + + +void APPEARANCE_CONTROLS::UpdateDisplayOptions() +{ + const PCB_DISPLAY_OPTIONS& options = m_frame->GetDisplayOptions(); + + switch( options.m_ContrastModeDisplay ) + { + case HIGH_CONTRAST_MODE::NORMAL: + m_rbHighContrastNormal->SetValue( true ); + break; + + case HIGH_CONTRAST_MODE::DIMMED: + m_rbHighContrastDim->SetValue( true ); + break; + + case HIGH_CONTRAST_MODE::HIDDEN: + m_rbHighContrastOff->SetValue( true ); + break; + } + + switch( options.m_NetColorMode ) + { + case NET_COLOR_MODE::ALL: + m_rbNetColorAll->SetValue( true ); + break; + + case NET_COLOR_MODE::RATSNEST: + m_rbNetColorRatsnest->SetValue( true ); + break; + + case NET_COLOR_MODE::OFF: + m_rbNetColorOff->SetValue( true ); + break; + } + + wxASSERT( m_objectSettingsMap.count( LAYER_RATSNEST ) ); + APPEARANCE_SETTING* ratsnest = m_objectSettingsMap.at( LAYER_RATSNEST ); + ratsnest->ctl_visibility->SetValue( options.m_ShowGlobalRatsnest ); +} + + +std::vector APPEARANCE_CONTROLS::GetUserLayerPresets() const +{ + std::vector ret; + + for( const auto& pair : m_layerPresets ) + if( !pair.second.readOnly ) + ret.emplace_back( pair.second ); + + return ret; +} + + +void APPEARANCE_CONTROLS::SetUserLayerPresets( std::vector& aPresetList ) +{ + // Reset to defaults + loadDefaultLayerPresets(); + + for( const LAYER_PRESET& preset : aPresetList ) + { + if( m_layerPresets.count( preset.name ) ) + continue; + + m_layerPresets[preset.name] = preset; + } + + rebuildLayerPresetsWidget(); +} + + +void APPEARANCE_CONTROLS::loadDefaultLayerPresets() +{ + m_layerPresets.clear(); + + // Load the read-only defaults + for( const LAYER_PRESET& preset : { presetAllLayers, presetAllCopper, presetInnerCopper, + presetFront, presetFrontAssembly, presetBack, + presetBackAssembly } ) + { + m_layerPresets[preset.name] = preset; + m_layerPresets[preset.name].readOnly = true; + } +} + + +void APPEARANCE_CONTROLS::ApplyLayerPreset( const wxString& aPresetName ) +{ + updateLayerPresetSelection( aPresetName ); + + wxCommandEvent dummy; + onLayerPresetChanged( dummy ); +} + + +void APPEARANCE_CONTROLS::ApplyLayerPreset( const LAYER_PRESET& aPreset ) +{ + if( m_layerPresets.count( aPreset.name ) ) + m_currentPreset = &m_layerPresets[aPreset.name]; + else + m_currentPreset = nullptr; + + updateLayerPresetSelection( aPreset.name ); + doApplyLayerPreset( aPreset ); +} + + +void APPEARANCE_CONTROLS::rebuildLayers() +{ + BOARD* board = m_frame->GetBoard(); + LSET enabled = board->GetEnabledLayers(); + LSET visible = board->GetVisibleLayers(); + + COLOR_SETTINGS* theme = m_frame->GetColorSettings(); + COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND ); + + m_layerSettings.clear(); + m_layers_outer_sizer->Clear( true ); + + auto appendLayer = + [&]( std::unique_ptr& aSetting ) + { + int layer = aSetting->id; + + wxPanel* panel = new wxPanel( m_windowLayers, layer ); + wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL ); + panel->SetSizer( sizer ); + + aSetting->visible = visible[layer]; + + // TODO(JE) consider restyling this indicator + INDICATOR_ICON* indicator = new INDICATOR_ICON( panel, *m_iconProvider, + ROW_ICON_PROVIDER::STATE::OFF, layer ); + + COLOR_SWATCH* swatch = new COLOR_SWATCH( panel, COLOR4D::UNSPECIFIED, layer, + bgColor, theme->GetColor( layer ), false ); + swatch->SetToolTip( _( "Left double click or middle click for color change, " + "right click for menu" ) ); + + BITMAP_TOGGLE* btn_visible = + new BITMAP_TOGGLE( panel, layer, KiBitmap( visibility_xpm ), + KiBitmap( visibility_off_xpm ), aSetting->visible ); + btn_visible->SetToolTip( _( "Show or hide this layer" ) ); + + wxStaticText* label = new wxStaticText( panel, layer, aSetting->label ); + label->Wrap( -1 ); + label->SetToolTip( aSetting->tooltip ); + + sizer->Add( indicator, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 2 ); + sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 ); + sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 ); + sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 ); + + m_layers_outer_sizer->Add( panel, 0, wxEXPAND, 0 ); + + aSetting->ctl_panel = panel; + aSetting->ctl_indicator = indicator; + aSetting->ctl_visibility = btn_visible; + aSetting->ctl_color = swatch; + aSetting->ctl_text = label; + + panel->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerClick, this ); + indicator->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerClick, this ); + swatch->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerClick, this ); + label->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerClick, this ); + + btn_visible->Bind( TOGGLE_CHANGED, + [&]( wxCommandEvent& aEvent ) + { + int layId = static_cast( aEvent.GetEventObject() )->GetId(); + bool isVisible = aEvent.GetInt(); + + wxASSERT( layId >= 0 && layId < PCB_LAYER_ID_COUNT ); + + onLayerVisibilityChanged( static_cast( layId ), + isVisible, true ); + } ); + + swatch->Bind( COLOR_SWATCH_CHANGED, + &APPEARANCE_CONTROLS::OnColorSwatchChanged, this ); + + auto rightClickHandler = + [&]( wxMouseEvent& aEvent ) + { + wxASSERT( m_layerContextMenu ); + PopupMenu( m_layerContextMenu ); + }; + + panel->Bind( wxEVT_RIGHT_DOWN, rightClickHandler ); + indicator->Bind( wxEVT_RIGHT_DOWN, rightClickHandler ); + swatch->Bind( wxEVT_RIGHT_DOWN, rightClickHandler ); + btn_visible->Bind( wxEVT_RIGHT_DOWN, rightClickHandler ); + label->Bind( wxEVT_RIGHT_DOWN, rightClickHandler ); + }; + + wxString dsc; + + // show all coppers first, with front on top, back on bottom, then technical layers + for( LSEQ cu_stack = enabled.CuStack(); cu_stack; ++cu_stack ) + { + PCB_LAYER_ID layer = *cu_stack; + + switch( layer ) + { + case F_Cu: + dsc = _( "Front copper layer" ); + break; + + case B_Cu: + dsc = _( "Back copper layer" ); + break; + + default: + dsc = _( "Inner copper layer" ); + break; + } + + m_layerSettings.emplace_back( + std::make_unique( board->GetLayerName( layer ), layer, dsc ) ); + + std::unique_ptr& setting = m_layerSettings.back(); + + m_layerSettingsMap[layer] = setting.get(); + + appendLayer( setting ); + + // TODO(JE) +#ifdef NOTYET + if( m_fp_editor_mode && LSET::ForbiddenFootprintLayers().test( layer ) ) + { + getLayerComp( GetLayerRowCount()-1, COLUMN_COLOR_LYRNAME )->Enable( false ); + getLayerComp( GetLayerRowCount()-1, COLUMN_COLORBM )->SetToolTip( wxEmptyString ); + } +#endif + } + + // technical layers are shown in this order: + // Because they are static, wxGetTranslation must be explicitly + // called for tooltips. + static const struct { + PCB_LAYER_ID layerId; + wxString tooltip; + } non_cu_seq[] = { + { F_Adhes, _( "Adhesive on board's front" ) }, + { B_Adhes, _( "Adhesive on board's back" ) }, + { F_Paste, _( "Solder paste on board's front" ) }, + { B_Paste, _( "Solder paste on board's back" ) }, + { F_SilkS, _( "Silkscreen on board's front" ) }, + { B_SilkS, _( "Silkscreen on board's back" ) }, + { F_Mask, _( "Solder mask on board's front" ) }, + { B_Mask, _( "Solder mask on board's back" ) }, + { Dwgs_User, _( "Explanatory drawings" ) }, + { Cmts_User, _( "Explanatory comments" ) }, + { Eco1_User, _( "User defined meaning" ) }, + { Eco2_User, _( "User defined meaning" ) }, + { Edge_Cuts, _( "Board's perimeter definition" ) }, + { Margin, _( "Board's edge setback outline" ) }, + { F_CrtYd, _( "Footprint courtyards on board's front" ) }, + { B_CrtYd, _( "Footprint courtyards on board's back" ) }, + { F_Fab, _( "Footprint assembly on board's front" ) }, + { B_Fab, _( "Footprint assembly on board's back" ) } + }; + + for( const auto& entry : non_cu_seq ) + { + PCB_LAYER_ID layer = entry.layerId; + + if( !enabled[layer] ) + continue; + + m_layerSettings.emplace_back( std::make_unique( + board->GetLayerName( layer ), layer, wxGetTranslation( entry.tooltip ) ) ); + + std::unique_ptr& setting = m_layerSettings.back(); + + m_layerSettingsMap[layer] = setting.get(); + + appendLayer( setting ); + + // TODO(JE) +#ifdef NOTYET + if( m_fp_editor_mode && LSET::ForbiddenFootprintLayers().test( layer ) ) + { + getLayerComp( GetLayerRowCount()-1, COLUMN_COLOR_LYRNAME )->Enable( false ); + getLayerComp( GetLayerRowCount()-1, COLUMN_COLORBM )->SetToolTip( wxEmptyString ); + } +#endif + } + + m_layers_outer_sizer->Layout(); +} + + +void APPEARANCE_CONTROLS::rebuildLayerContextMenu() +{ + delete m_layerContextMenu; + m_layerContextMenu = new wxMenu; + + AddMenuItem( m_layerContextMenu, ID_SHOW_ALL_COPPER_LAYERS, + _( "Show All Copper Layers" ), + KiBitmap( select_layer_pair_xpm ) ); + AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_COPPER_LAYERS, + _( "Hide All Copper Layers" ), + KiBitmap( show_no_copper_layers_xpm ) ); + + m_layerContextMenu->AppendSeparator(); + + AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_BUT_ACTIVE, + _( "Hide All Layers But Active" ), + KiBitmap( select_w_layer_xpm ) ); + + m_layerContextMenu->AppendSeparator(); + + AddMenuItem( m_layerContextMenu, ID_SHOW_ALL_NON_COPPER, _( "Show All Non Copper Layers" ), + KiBitmap( select_w_layer_xpm ) ); + + AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_NON_COPPER, _( "Hide All Non Copper Layers" ), + KiBitmap( show_no_copper_layers_xpm ) ); + + m_layerContextMenu->AppendSeparator(); + + AddMenuItem( m_layerContextMenu, ID_PRESET_ALL_LAYERS, _( "Show All Layers" ), + KiBitmap( show_all_layers_xpm ) ); + + AddMenuItem( m_layerContextMenu, ID_PRESET_NO_LAYERS, _( "Hide All Layers" ), + KiBitmap( show_no_layers_xpm ) ); + + m_layerContextMenu->AppendSeparator(); + + AddMenuItem( m_layerContextMenu, ID_PRESET_FRONT_ASSEMBLY, + _( "Show Only Front Assembly Layers" ), KiBitmap( shape_3d_xpm ) ); + + AddMenuItem( m_layerContextMenu, ID_PRESET_FRONT, _( "Show Only Front Layers" ), + KiBitmap( show_all_front_layers_xpm ) ); + + // Only show the internal layer option if internal layers are enabled + if( m_frame->GetBoard()->GetCopperLayerCount() > 2 ) + { + AddMenuItem( m_layerContextMenu, ID_PRESET_INNER_COPPER, _( "Show Only Inner Layers" ), + KiBitmap( show_all_copper_layers_xpm ) ); + } + + AddMenuItem( m_layerContextMenu, ID_PRESET_BACK, _( "Show Only Back Layers" ), + KiBitmap( show_all_back_layers_xpm ) ); + + AddMenuItem( m_layerContextMenu, ID_PRESET_BACK_ASSEMBLY, _( "Show Only Back Assembly Layers" ), + KiBitmap( shape_3d_back_xpm ) ); +} + + +void APPEARANCE_CONTROLS::OnLayerContextMenu( wxCommandEvent& aEvent ) +{ + BOARD* board = m_frame->GetBoard(); + LSET visible = board->GetVisibleLayers(); + + PCB_LAYER_ID current = m_frame->GetActiveLayer(); + + switch( aEvent.GetId() ) + { + case ID_PRESET_NO_LAYERS: + ApplyLayerPreset( presetNoLayers ); + return; + + case ID_PRESET_ALL_LAYERS: + ApplyLayerPreset( presetAllLayers ); + return; + + case ID_SHOW_ALL_COPPER_LAYERS: + { + visible |= presetAllCopper.layers; + board->SetVisibleLayers( visible ); + break; + } + + case ID_HIDE_ALL_BUT_ACTIVE: + ApplyLayerPreset( presetNoLayers ); + SetLayerVisible( current, true ); + break; + + case ID_HIDE_ALL_COPPER_LAYERS: + { + visible &= ~presetAllCopper.layers; + + if( !visible.test( current ) ) + m_frame->SetActiveLayer( *visible.Seq().begin() ); + + board->SetVisibleLayers( visible ); + break; + } + + case ID_HIDE_ALL_NON_COPPER: + { + visible &= presetAllCopper.layers; + + if( !visible.test( current ) ) + m_frame->SetActiveLayer( *visible.Seq().begin() ); + + board->SetVisibleLayers( visible ); + break; + } + + case ID_SHOW_ALL_NON_COPPER: + { + visible |= ~presetAllCopper.layers; + + board->SetVisibleLayers( visible ); + break; + } + + case ID_PRESET_FRONT_ASSEMBLY: + ApplyLayerPreset( presetFrontAssembly ); + return; + + case ID_PRESET_FRONT: + ApplyLayerPreset( presetFront ); + return; + + case ID_PRESET_INNER_COPPER: + ApplyLayerPreset( presetInnerCopper ); + return; + + case ID_PRESET_BACK: + ApplyLayerPreset( presetBack ); + return; + + case ID_PRESET_BACK_ASSEMBLY: + ApplyLayerPreset( presetBackAssembly ); + return; + } + + syncLayerPresetSelection(); + syncColorsAndVisibility(); + m_frame->GetCanvas()->SyncLayersVisibility( board ); + m_frame->GetCanvas()->Refresh(); +} + + +void APPEARANCE_CONTROLS::syncColorsAndVisibility() +{ + BOARD* board = m_frame->GetBoard(); + LSET visible = board->GetVisibleLayers(); + GAL_SET objects = board->GetVisibleElements(); + + Freeze(); + + for( std::unique_ptr& setting : m_layerSettings ) + { + LAYER_NUM layer = setting->id; + + if( setting->ctl_visibility ) + setting->ctl_visibility->SetValue( visible[layer] ); + + if( setting->ctl_color ) + { + const COLOR4D& color = m_frame->GetColorSettings()->GetColor( layer ); + setting->ctl_color->SetSwatchColor( color, false ); + } + } + + for( std::unique_ptr& setting : m_objectSettings ) + { + GAL_LAYER_ID layer = static_cast( setting->id ); + + if( setting->ctl_visibility ) + setting->ctl_visibility->SetValue( objects.Contains( layer ) ); + + if( setting->ctl_color ) + { + const COLOR4D& color = m_frame->GetColorSettings()->GetColor( layer ); + setting->ctl_color->SetSwatchColor( color, false ); + } + } + + // Update indicators and panel background colors + OnLayerChanged(); + + Thaw(); + + m_windowLayers->Refresh(); +} + + +void APPEARANCE_CONTROLS::onLayerClick( wxMouseEvent& aEvent ) +{ + auto eventSource = static_cast( aEvent.GetEventObject() ); + + PCB_LAYER_ID layer = ToLAYER_ID( eventSource->GetId() ); + + // TODO(JE) +#ifdef NOTYET + if( m_fp_editor_mode && LSET::ForbiddenFootprintLayers().test( layer ) ) + return false; +#endif + + m_frame->SetActiveLayer( layer ); +} + + +void APPEARANCE_CONTROLS::onLayerVisibilityChanged( PCB_LAYER_ID aLayer, bool isVisible, + bool isFinal ) +{ + BOARD* board = m_frame->GetBoard(); + + LSET visibleLayers = board->GetVisibleLayers(); + + if( visibleLayers.test( aLayer ) != isVisible ) + { + visibleLayers.set( aLayer, isVisible ); + + board->SetVisibleLayers( visibleLayers ); + + m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible ); + } + + syncLayerPresetSelection(); + + if( isFinal ) + m_frame->GetCanvas()->Refresh(); +} + + +void APPEARANCE_CONTROLS::onObjectVisibilityChanged( GAL_LAYER_ID aLayer, bool isVisible, + bool isFinal ) +{ + BOARD* board = m_frame->GetBoard(); + GAL_SET visible = board->GetVisibleElements(); + + // Special-case controls + switch( aLayer ) + { + case LAYER_RATSNEST: + { + // don't touch the layers. ratsnest is enabled on per-item basis. + m_frame->GetCanvas()->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED ); + m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, true ); + + if( m_frame->IsType( FRAME_PCB_EDITOR ) ) + { + PCB_DISPLAY_OPTIONS opt = m_frame->GetDisplayOptions(); + opt.m_ShowGlobalRatsnest = isVisible; + m_frame->SetDisplayOptions( opt ); + + // TODO(ISM): Remove once EVT_UPDATE_UI works + m_frame->SyncToolbars(); + } + + break; + } + + case LAYER_GRID: + m_frame->SetGridVisibility( isVisible ); + m_frame->GetCanvas()->Refresh(); + syncLayerPresetSelection(); + break; + + default: + break; + } + + if( visible.Contains( aLayer ) != isVisible ) + { + visible.set( aLayer, isVisible ); + board->SetVisibleElements( visible ); + m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible ); + syncLayerPresetSelection(); + } + + if( isFinal ) + m_frame->GetCanvas()->Refresh(); +} + + +void APPEARANCE_CONTROLS::rebuildObjects() +{ + BOARD* board = m_frame->GetBoard(); + COLOR_SETTINGS* theme = m_frame->GetColorSettings(); + COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND ); + GAL_SET visible = board->GetVisibleElements(); + + m_objectSettings.clear(); + m_objectsSizer->Clear( true ); + + auto appendObject = + [&]( int aRow, std::unique_ptr& aSetting ) + { + int layer = aSetting->id; + + aSetting->visible = visible.Contains( ToGalLayer( layer ) ); + COLOR4D color = theme->GetColor( layer ); + COLOR4D defColor = theme->GetDefaultColor( layer ); + + if( color != COLOR4D::UNSPECIFIED ) + { + COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowObjects, color, layer, bgColor, + defColor, false ); + swatch->SetToolTip( _( "Left double click or middle click for color change, " + "right click for menu" ) ); + + m_objectsSizer->Add( swatch, wxGBPosition( aRow, 0 ), wxDefaultSpan, + wxALIGN_CENTER_VERTICAL | wxEXPAND | wxLEFT | wxRIGHT, 5 ); + aSetting->ctl_color = swatch; + + swatch->Bind( COLOR_SWATCH_CHANGED, + &APPEARANCE_CONTROLS::OnColorSwatchChanged, this ); + } + + BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE( m_windowObjects, layer, + KiBitmap( visibility_xpm ), KiBitmap( visibility_off_xpm ), + aSetting->visible ); + + wxString tip; + tip.Printf( _( "Show or hide %s" ), aSetting->label.Lower() ); + btn_visible->SetToolTip( tip ); + + m_objectsSizer->Add( btn_visible, wxGBPosition( aRow, 1 ), wxDefaultSpan, + wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 ); + aSetting->ctl_visibility = btn_visible; + + btn_visible->Bind( TOGGLE_CHANGED, + [&]( wxCommandEvent& aEvent ) + { + int id = static_cast( aEvent.GetEventObject() )->GetId(); + bool isVisible = aEvent.GetInt(); + onObjectVisibilityChanged( ToGalLayer( id ), isVisible, true ); + } ); + + wxStaticText* label = new wxStaticText( m_windowObjects, layer, aSetting->label ); + label->Wrap( -1 ); + label->SetToolTip( aSetting->tooltip ); + + wxGBSpan labelSpan( 1, aSetting->can_control_opacity ? 1 : 2 ); + + m_objectsSizer->Add( label, wxGBPosition( aRow, 2 ), labelSpan, + wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 ); + + if( aSetting->can_control_opacity ) + { + wxSlider* slider = new wxSlider( m_windowObjects, wxID_ANY, 100, 0, 100, + wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL ); +#ifdef __WXMAC__ + slider->SetMinSize( wxSize( 100, 32 ) ); +#else + slider->SetMinSize( wxSize( 100, -1 ) ); +#endif + + tip.Printf( _( "Set opacity of %s" ), aSetting->label.Lower() ); + slider->SetToolTip( tip ); + + m_objectsSizer->Add( slider, wxGBPosition( aRow, 3 ), wxDefaultSpan, + wxALIGN_CENTER_VERTICAL | wxRIGHT | wxEXPAND, 5 ); + aSetting->ctl_opacity = slider; + + auto opacitySliderHandler = + [=]( wxCommandEvent& aEvent ) + { + wxSlider* ctrl = static_cast( aEvent.GetEventObject() ); + int value = ctrl->GetValue(); + onObjectOpacitySlider( layer, value / 100.0f ); + }; + + slider->Bind( wxEVT_SCROLL_CHANGED, opacitySliderHandler ); + slider->Bind( wxEVT_SCROLL_THUMBTRACK, opacitySliderHandler ); + } + + aSetting->ctl_text = label; + }; + + m_objectsSizer->SetEmptyCellSize( wxSize( m_pointSize, m_pointSize ) ); + + int gridRow = 0; + + for( unsigned row = 0; row < arrayDim( s_objectSettings ); ++row ) + { + // TODO(JE) +#ifdef NOTYET + if( m_fp_editor_mode && !isAllowedInFpMode( setting.id ) ) + continue; +#endif + + if( !s_objectSettings[row].spacer ) + { + m_objectSettings.emplace_back( + std::make_unique( s_objectSettings[row] ) ); + + std::unique_ptr& setting = m_objectSettings.back(); + + // Because s_render_rows is created static, we must explicitly call + // wxGetTranslation for texts which are internationalized (tool tips + // and item names) + setting->tooltip = wxGetTranslation( s_objectSettings[row].tooltip ); + setting->label = wxGetTranslation( s_objectSettings[row].label ); + + appendObject( gridRow, setting ); + + m_objectSettingsMap[ToGalLayer( setting->id )] = setting.get(); + } + + gridRow++; + } + + m_objectsSizer->AddGrowableCol( 3, 1 ); + m_objectsSizer->Layout(); +} + + +void APPEARANCE_CONTROLS::syncObjectSettings() +{ + BOARD* board = m_frame->GetBoard(); + GAL_SET visible = board->GetVisibleElements(); + + const PCB_DISPLAY_OPTIONS& opts = m_frame->GetDisplayOptions(); + + for( std::unique_ptr& setting : m_objectSettings ) + { + if( setting->spacer ) + continue; + + GAL_LAYER_ID layer = ToGalLayer( setting->id ); + + if( setting->ctl_visibility ) + setting->ctl_visibility->SetValue( visible.Contains( layer ) ); + + if( setting->ctl_color ) + { + COLOR4D color = m_frame->GetColorSettings()->GetColor( setting->id ); + setting->ctl_color->SetSwatchColor( color, false ); + } + } + + wxASSERT( m_objectSettingsMap.count( LAYER_TRACKS ) + && m_objectSettingsMap.count( LAYER_VIAS ) + && m_objectSettingsMap.count( LAYER_PADS ) + && m_objectSettingsMap.count( LAYER_ZONES ) ); + + m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 ); + m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 ); + m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 ); + m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 ); +} + + +void APPEARANCE_CONTROLS::rebuildNets() +{ + BOARD* board = m_frame->GetBoard(); + COLOR_SETTINGS* theme = m_frame->GetColorSettings(); + COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND ); + + 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, false ); + setting->ctl_color->SetToolTip( _( "Left double click or middle click for color " + "change, right click for menu" ) ); + + if( color == COLOR4D::UNSPECIFIED ) + setting->ctl_color->Hide(); + + 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(); + + if( s->GetSwatchColor() == COLOR4D::UNSPECIFIED ) + s->Hide(); + + m_frame->GetCanvas()->RedrawRatsnest(); + m_frame->GetCanvas()->Refresh(); + } ); + + 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 %s" ), aNet->GetShortNetname() ); + setting->ctl_visibility->SetToolTip( tip ); + + setting->ctl_text = new wxStaticText( setting->ctl_panel, id, + aNet->GetShortNetname() ); + setting->ctl_text->Wrap( -1 ); + + int flags = wxALIGN_CENTER_VERTICAL | wxRIGHT; + + sizer->Add( setting->ctl_color, 0, flags | wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5 ); + sizer->Add( setting->ctl_visibility, 0, flags, 5 ); + sizer->Add( setting->ctl_text, 1, flags, 5 ); + + m_netsOuterSizer->Add( setting->ctl_panel, 0, wxEXPAND, 0 ); + + 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 ); + } ); + + 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 %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, NETCLASSPTR aClass ) + { + wxString name = aClass->GetName(); + + m_netclassSettings.emplace_back( std::make_unique() ); + APPEARANCE_SETTING* setting = m_netclassSettings.back().get(); + m_netclassSettingsMap[name] = setting; + + setting->ctl_panel = new wxPanel( m_netclassScrolledWindow, aId ); + wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL ); + setting->ctl_panel->SetSizer( sizer ); + + COLOR4D color = netclassColors.count( name ) ? netclassColors.at( name ) : + COLOR4D::UNSPECIFIED; + + setting->ctl_color = new COLOR_SWATCH( setting->ctl_panel, color, aId, bgColor, + COLOR4D::UNSPECIFIED, false ); + setting->ctl_color->SetToolTip( _( "Left double click or middle click for color " + "change, right click for menu" ) ); + + if( color == COLOR4D::UNSPECIFIED ) + setting->ctl_color->Hide(); + + setting->ctl_color->Bind( COLOR_SWATCH_CHANGED, + &APPEARANCE_CONTROLS::onNetclassColorChanged, this ); + + // TODO(JE) need to calculate the state for these buttons + setting->ctl_visibility = + new BITMAP_TOGGLE( setting->ctl_panel, aId, KiBitmap( visibility_xpm ), + KiBitmap( visibility_off_xpm ), true ); + + wxString tip; + tip.Printf( _( "Show or hide %s" ), name ); + setting->ctl_visibility->SetToolTip( tip ); + + setting->ctl_text = new wxStaticText( setting->ctl_panel, aId, name ); + setting->ctl_text->Wrap( -1 ); + + int flags = wxALIGN_CENTER_VERTICAL | wxRIGHT; + + sizer->Add( setting->ctl_color, 0, flags | wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5 ); + sizer->Add( setting->ctl_visibility, 0, flags, 5 ); + sizer->Add( setting->ctl_text, 1, flags, 5 ); + + m_netclassOuterSizer->Add( setting->ctl_panel, 0, wxEXPAND, 0 ); + + setting->ctl_visibility->Bind( TOGGLE_CHANGED, + &APPEARANCE_CONTROLS::onNetclassVisibilityChanged, + this ); + + auto menuHandler = + [&, name]( wxMouseEvent& aEvent ) + { + m_contextMenuNetclass = name; + + wxMenu menu; + + menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR, + _( "Set netclass color" ), wxEmptyString, + wxITEM_NORMAL ) ); + menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET, + wxString::Format( _( "Highlight nets in %s" ), name ), + wxEmptyString, wxITEM_NORMAL ) ); + menu.Append( new wxMenuItem( &menu, ID_SELECT_NET, + wxString::Format( _( "Select nets in %s" ), name ), + wxEmptyString, wxITEM_NORMAL ) ); + + menu.AppendSeparator(); + + menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS, + _( "Show all netclasses" ), wxEmptyString, wxITEM_NORMAL ) ); + menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS, + _( "Hide all other netclasses" ), wxEmptyString, + wxITEM_NORMAL ) ); + + menu.Bind( wxEVT_COMMAND_MENU_SELECTED, + &APPEARANCE_CONTROLS::onNetclassContextMenu, 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 ); + }; + + 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(); + + for( const auto& pair : classes ) + names.emplace_back( pair.first ); + + std::sort( names.begin(), names.end() ); + + m_netclassIdMap.clear(); + + int idx = wxID_HIGHEST + nets.size(); + + for( const wxString& name : names ) + { + m_netclassIdMap[idx] = name; + appendNetclass( idx++, classes.at( name ) ); + } + + m_netsOuterSizer->Layout(); + m_netclassOuterSizer->Layout(); + //m_netsTabSplitter->Layout(); +} + + +void APPEARANCE_CONTROLS::rebuildLayerPresetsWidget() +{ + m_cbLayerPresets->Clear(); + + for( auto& pair : m_layerPresets ) + m_cbLayerPresets->Append( pair.first, static_cast( &pair.second ) ); + + m_cbLayerPresets->Append( wxT( "-----" ) ); + m_cbLayerPresets->Append( _( "Save new preset" ) ); + + m_cbLayerPresets->SetSelection( 0 ); + + // At least the build in presets should always be present + wxASSERT( !m_layerPresets.empty() ); + + // Default preset: all layers + m_currentPreset = &m_layerPresets[presetAllLayers.name]; +} + + +void APPEARANCE_CONTROLS::syncLayerPresetSelection() +{ + BOARD* board = m_frame->GetBoard(); + LSET visibleLayers = board->GetVisibleLayers(); + GAL_SET visibleObjects = board->GetVisibleElements(); + + auto it = std::find_if( m_layerPresets.begin(), m_layerPresets.end(), + [&]( const auto& aPair ) + { + return ( aPair.second.layers == visibleLayers + && aPair.second.renderLayers == visibleObjects ); + } ); + + if( it != m_layerPresets.end() ) + m_cbLayerPresets->SetStringSelection( it->first ); + else + m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 2 ); // separator + + m_currentPreset = static_cast( + m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) ); + + updateDeleteLayerPresetButton(); +} + + +void APPEARANCE_CONTROLS::updateLayerPresetSelection( const wxString& aName ) +{ + int idx = m_cbLayerPresets->FindString( aName ); + + if( idx >= 0 && m_cbLayerPresets->GetSelection() != idx ) + { + m_cbLayerPresets->SetSelection( idx ); + m_currentPreset = static_cast( m_cbLayerPresets->GetClientData( idx ) ); + updateDeleteLayerPresetButton(); + } + else if( idx < 0 ) + { + m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 2 ); // separator + updateDeleteLayerPresetButton(); + } +} + + +void APPEARANCE_CONTROLS::onLayerPresetChanged( wxCommandEvent& aEvent ) +{ + BOARD* board = m_frame->GetBoard(); + + int count = m_cbLayerPresets->GetCount(); + int index = m_cbLayerPresets->GetSelection(); + + auto resetSelection = + [&]() + { + if( m_currentPreset ) + m_cbLayerPresets->SetStringSelection( m_currentPreset->name ); + else + m_cbLayerPresets->SetSelection( count - 2 ); + }; + + if( index == count - 2 ) + { + // Separator: reject the selection + resetSelection(); + return; + } + else if( index == count - 1 ) + { + // Save current state to new preset + wxTextEntryDialog dlg( this, _( "New layer preset name:" ), _( "Save Layer Preset" ) ); + + if( dlg.ShowModal() != wxID_OK ) + { + resetSelection(); + return; + } + + wxString name = dlg.GetValue(); + + if( m_layerPresets.count( name ) ) + { + wxMessageBox( _( "Preset already exists!" ) ); + resetSelection(); + return; + } + + m_layerPresets[name] = LAYER_PRESET( name, board->GetVisibleLayers(), + board->GetVisibleElements(), UNSELECTED_LAYER ); + + LAYER_PRESET* preset = &m_layerPresets[name]; + m_currentPreset = preset; + + index = m_cbLayerPresets->Insert( name, index - 1, static_cast( preset ) ); + m_cbLayerPresets->SetSelection( index ); + m_btnDeletePreset->Enable(); + + return; + } + + LAYER_PRESET* preset = static_cast( m_cbLayerPresets->GetClientData( index ) ); + m_currentPreset = preset; + + updateDeleteLayerPresetButton(); + + doApplyLayerPreset( *preset ); +} + + +void APPEARANCE_CONTROLS::doApplyLayerPreset( const LAYER_PRESET& aPreset ) +{ + BOARD* board = m_frame->GetBoard(); + + board->SetVisibleLayers( aPreset.layers ); + board->SetVisibleElements( aPreset.renderLayers ); + + // If the preset doesn't have an explicit active layer to restore, we can at least + // force the active layer to be something in the preset's layer set + if( aPreset.activeLayer != UNSELECTED_LAYER ) + m_frame->SetActiveLayer( aPreset.activeLayer ); + else if( aPreset.layers.any() && !aPreset.layers.test( m_frame->GetActiveLayer() ) ) + m_frame->SetActiveLayer( *aPreset.layers.Seq().begin() ); + + m_frame->GetCanvas()->SyncLayersVisibility( board ); + m_frame->GetCanvas()->Refresh(); + + syncColorsAndVisibility(); +} + + +void APPEARANCE_CONTROLS::updateDeleteLayerPresetButton() +{ + bool enable = m_currentPreset && !m_currentPreset->readOnly; + + m_btnDeletePreset->Enable( enable ); + m_btnDeletePreset->SetToolTip( enable ? _( "Delete this layer preset " ) : + _( "This preset cannot be deleted" ) ); +} + + +void APPEARANCE_CONTROLS::OnBtnDeleteLayerPreset( wxCommandEvent& event ) +{ + LAYER_PRESET* current = static_cast( + m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) ); + + // Button should not be enabled if we are not on an active preset + wxASSERT( current && current == m_currentPreset ); + + if( current->readOnly ) + return; + + int index = m_cbLayerPresets->GetSelection(); + + m_layerPresets.erase( current->name ); + m_cbLayerPresets->Delete( index ); + m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 2 ); + m_currentPreset = nullptr; +} + + +void APPEARANCE_CONTROLS::OnColorSwatchChanged( wxCommandEvent& aEvent ) +{ + COLOR_SWATCH* swatch = static_cast( aEvent.GetEventObject() ); + COLOR4D newColor = swatch->GetSwatchColor(); + LAYER_NUM layer = swatch->GetId(); + + COLOR_SETTINGS* cs = m_frame->GetColorSettings(); + cs->SetColor( layer, newColor ); + + m_frame->GetCanvas()->UpdateColors(); + + KIGFX::VIEW* view = m_frame->GetCanvas()->GetView(); + view->UpdateLayerColor( layer ); + view->UpdateLayerColor( GetNetnameLayer( layer ) ); + + m_frame->ReCreateHToolbar(); + m_frame->GetCanvas()->Refresh(); + + if( layer == LAYER_PCB_BACKGROUND ) + m_frame->SetDrawBgColor( newColor ); +} + + +void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity ) +{ + PCB_DISPLAY_OPTIONS options = m_frame->GetDisplayOptions(); + + switch( aLayer ) + { + case static_cast( LAYER_TRACKS ): + options.m_TrackOpacity = aOpacity; + break; + + case static_cast( LAYER_VIAS ): + options.m_ViaOpacity = aOpacity; + break; + + case static_cast( LAYER_PADS ): + options.m_PadOpacity = aOpacity; + break; + + case static_cast( LAYER_ZONES ): + options.m_ZoneOpacity = aOpacity; + break; + + default: + return; + } + + m_frame->SetDisplayOptions( options ); +} + + +void APPEARANCE_CONTROLS::onNetContextMenu( wxCommandEvent& aEvent ) +{ + 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 ); + } + + break; + } + + case ID_HIGHLIGHT_NET: + m_frame->GetToolManager()->RunAction( PCB_ACTIONS::highlightNet, true, + m_contextMenuNetCode ); + break; + + case ID_SELECT_NET: + m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectNet, true, + m_contextMenuNetCode ); + 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 ); + } + + 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 ); + } + + break; + } + + default: + break; + } + + m_frame->GetCanvas()->RedrawRatsnest(); + m_frame->GetCanvas()->Refresh(); + + m_contextMenuNetCode = 0; +} + + +void APPEARANCE_CONTROLS::onNetclassVisibilityChanged( wxCommandEvent& aEvent ) +{ + wxString className = netclassNameFromEvent( aEvent ); + bool show = aEvent.GetInt(); + showNetclass( className, show ); +} + + +void APPEARANCE_CONTROLS::showNetclass( const wxString& aClassName, bool aShow ) +{ + BOARD* board = m_frame->GetBoard(); + NETCLASSES& classes = board->GetDesignSettings().GetNetClasses(); + NETCLASSPTR netclass = classes.Find( aClassName ); + + if( !netclass ) + return; + + NETINFO_LIST& nets = board->GetNetInfo(); + TOOL_MANAGER* manager = m_frame->GetToolManager(); + + for( const wxString& member : *netclass ) + { + int code = nets.GetNetItem( member )->GetNet(); + + if( m_netSettingsMap.count( code ) ) + { + APPEARANCE_SETTING* setting = m_netSettingsMap.at( code ); + setting->ctl_visibility->SetValue( aShow ); + } + + const TOOL_ACTION& action = aShow ? PCB_ACTIONS::showNet : PCB_ACTIONS::hideNet; + manager->RunAction( action, true, code ); + } +} + + +void APPEARANCE_CONTROLS::onNetclassColorChanged( wxCommandEvent& aEvent ) +{ + KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( + m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings() ); + + std::map& netclassColors = rs->GetNetclassColorMap(); + + COLOR_SWATCH* swatch = static_cast( aEvent.GetEventObject() ); + wxString className = netclassNameFromEvent( aEvent ); + + netclassColors[className] = swatch->GetSwatchColor(); + + if( swatch->GetSwatchColor() == COLOR4D::UNSPECIFIED ) + swatch->Hide(); + + m_frame->GetCanvas()->RedrawRatsnest(); + m_frame->GetCanvas()->Refresh(); +} + + +wxString APPEARANCE_CONTROLS::netclassNameFromEvent( wxEvent& aEvent ) +{ + COLOR_SWATCH* s = static_cast( aEvent.GetEventObject() ); + int classId = s->GetId(); + + wxASSERT( m_netclassIdMap.count( classId ) ); + return m_netclassIdMap.at( classId ); +} + + +void APPEARANCE_CONTROLS::onNetColorModeChanged( wxCommandEvent& aEvent ) +{ + PCB_DISPLAY_OPTIONS options = m_frame->GetDisplayOptions(); + + if( m_rbNetColorAll->GetValue() ) + options.m_NetColorMode = NET_COLOR_MODE::ALL; + else if( m_rbNetColorRatsnest->GetValue() ) + options.m_NetColorMode = NET_COLOR_MODE::RATSNEST; + else + options.m_NetColorMode = NET_COLOR_MODE::OFF; + + m_frame->SetDisplayOptions( options ); +} + + +void APPEARANCE_CONTROLS::onNetclassContextMenu( wxCommandEvent& aEvent ) +{ + KIGFX::VIEW* view = m_frame->GetCanvas()->GetView(); + KIGFX::PCB_RENDER_SETTINGS* rs = + static_cast( view->GetPainter()->GetSettings() ); + + BOARD* board = m_frame->GetBoard(); + NETINFO_LIST& nets = board->GetNetInfo(); + NETCLASSES& classes = board->GetDesignSettings().GetNetClasses(); + NETCLASSPTR netclass = classes.Find( m_contextMenuNetclass ); + + APPEARANCE_SETTING* setting = m_netclassSettingsMap.count( m_contextMenuNetclass ) ? + m_netclassSettingsMap.at( m_contextMenuNetclass ) : nullptr; + + switch( aEvent.GetId() ) + { + case ID_SET_NET_COLOR: + { + if( setting ) + { + setting->ctl_color->GetNewSwatchColor(); + + COLOR4D color = setting->ctl_color->GetSwatchColor(); + + setting->ctl_color->Show( color != COLOR4D::UNSPECIFIED ); + + std::map& netclassColors = rs->GetNetclassColorMap(); + + if( color != COLOR4D::UNSPECIFIED ) + netclassColors[m_contextMenuNetclass] = color; + else + netclassColors.erase( m_contextMenuNetclass ); + } + + break; + } + + case ID_HIGHLIGHT_NET: + { + if( netclass ) + { + bool first = true; + + for( const wxString& member : *netclass ) + { + if( NETINFO_ITEM* net = nets.GetNetItem( member ) ) + { + int code = net->GetNet(); + + if( first ) + { + board->SetHighLightNet( code ); + rs->SetHighlight( true, code ); + first = false; + } + else + { + board->SetHighLightNet( code, true ); + rs->SetHighlight( true, code, true ); + } + } + } + + view->UpdateAllLayersColor(); + board->HighLightON(); + } + break; + } + + case ID_SELECT_NET: + { + if( netclass ) + { + for( const wxString& member : *netclass ) + { + if( NETINFO_ITEM* net = nets.GetNetItem( member ) ) + { + int code = net->GetNet(); + m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectNet, true, code ); + } + } + } + break; + } + + case ID_SHOW_ALL_NETS: + { + for( const auto& pair : classes.NetClasses() ) + { + showNetclass( pair.first ); + + if( m_netclassSettingsMap.count( pair.first ) ) + m_netclassSettingsMap.at( pair.first )->ctl_visibility->SetValue( true ); + } + + break; + } + + case ID_HIDE_OTHER_NETS: + { + for( const auto& pair : classes.NetClasses() ) + { + bool show = pair.first == m_contextMenuNetclass; + + showNetclass( pair.first, show ); + + if( m_netclassSettingsMap.count( pair.first ) ) + m_netclassSettingsMap.at( pair.first )->ctl_visibility->SetValue( show ); + } + + break; + } + + default: + break; + } + + m_frame->GetCanvas()->RedrawRatsnest(); + m_frame->GetCanvas()->Refresh(); + + m_contextMenuNetclass.clear(); +} diff --git a/pcbnew/widgets/appearance_controls.h b/pcbnew/widgets/appearance_controls.h new file mode 100644 index 0000000000..30dfdc9f13 --- /dev/null +++ b/pcbnew/widgets/appearance_controls.h @@ -0,0 +1,286 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 Jon Evans + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 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 _APPEARANCE_CONTROLS_H +#define _APPEARANCE_CONTROLS_H + +#include + +#include +#include +#include +#include +#include + + +class BITMAP_TOGGLE; +class COLOR_SWATCH; +class INDICATOR_ICON; +class PCB_BASE_FRAME; +class ROW_ICON_PROVIDER; + +using KIGFX::COLOR4D; + + +class APPEARANCE_CONTROLS : public APPEARANCE_CONTROLS_BASE, public BOARD_LISTENER +{ +public: + + /** + * Container for an appearance setting (can control a single board layer, or GAL layer, etc) + */ + struct APPEARANCE_SETTING + { + int id; + wxString label; + wxString tooltip; + bool visible; + bool can_control_opacity; + bool spacer; + + wxPanel* ctl_panel; + INDICATOR_ICON* ctl_indicator; + BITMAP_TOGGLE* ctl_visibility; + COLOR_SWATCH* ctl_color; + wxStaticText* ctl_text; + wxSlider* ctl_opacity; + + APPEARANCE_SETTING( const wxString& aLabel, int aId, + const wxString& aTooltip = wxEmptyString, + bool aCanControlOpacity = false ) + { + label = aLabel; + id = aId; + tooltip = aTooltip; + spacer = false; + visible = true; + + can_control_opacity = aCanControlOpacity; + + ctl_panel = nullptr; + ctl_indicator = nullptr; + ctl_visibility = nullptr; + ctl_color = nullptr; + ctl_text = nullptr; + ctl_opacity = nullptr; + } + + APPEARANCE_SETTING() : + id( -1 ), label( "" ), tooltip( "" ), visible( false ), + can_control_opacity( false ), spacer( true ) + { + } + }; + + APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFocusOwner, bool aFpEditor = false ); + + wxSize GetBestSize() const; + + ///> Updates the panel contents from the application and board models + void OnBoardChanged(); + + void OnBoardNetSettingsChanged( BOARD& aBoard ) override; + + void OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aBoardItem ) override; + + void OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM* aBoardItem ) override; + + void OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aBoardItem ) override; + + ///> Updates the colors on all the widgets from the new chosen color theme + void OnColorThemeChanged(); + + ///> Updates the widget when the active board layer is changed + void OnLayerChanged(); + + ///> Manually update visibility for a given layer + void SetLayerVisible( LAYER_NUM aLayer, bool isVisible ); + + void SetObjectVisible( GAL_LAYER_ID aLayer, bool isVisible = true ); + + ///> Updates the manual layer alpha overrides + void OnLayerAlphaChanged(); + + void UpdateDisplayOptions(); + + ///> Returns a list of the layer presets created by the user + std::vector GetUserLayerPresets() const; + + ///> Updates the current layer presets from those saved in the project file + void SetUserLayerPresets( std::vector& aPresetList ); + + void ApplyLayerPreset( const wxString& aPresetName ); + + void ApplyLayerPreset( const LAYER_PRESET& aPreset ); + + wxString GetActiveLayerPreset() const + { + if( m_currentPreset ) + return m_currentPreset->name; + else + return wxEmptyString; + } + + void OnColorSwatchChanged( wxCommandEvent& aEvent ); + + void OnLayerContextMenu( wxCommandEvent& aEvent ); + +protected: + + void OnLayerDisplayPaneChanged( wxCollapsiblePaneEvent& event ) override; + + void OnNetDisplayPaneChanged( wxCollapsiblePaneEvent& event ) override; + + void OnBtnDeleteLayerPreset( wxCommandEvent& event ) override; + + void OnNotebookPageChanged( wxNotebookEvent& event ) override; + +private: + PCB_BASE_FRAME* m_frame; + + static const APPEARANCE_SETTING s_objectSettings[]; + + ROW_ICON_PROVIDER* m_iconProvider; + + BOARD* m_board; + + std::vector> m_layerSettings; + + std::map m_layerSettingsMap; + + std::vector> m_objectSettings; + + std::map m_objectSettingsMap; + + std::vector> m_netSettings; + + std::map m_netSettingsMap; + + std::vector> m_netclassSettings; + + std::map m_netclassSettingsMap; + + // TODO(JE) Move preset storage to the PCBNEW_CONTROL tool + + // Storage for all layer presets + std::map m_layerPresets; + + LAYER_PRESET* m_currentPreset; + + wxMenu* m_layerContextMenu; + + /// 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; + + // The built-in layer presets + + static LAYER_PRESET presetNoLayers; + static LAYER_PRESET presetAllLayers; + static LAYER_PRESET presetAllCopper; + static LAYER_PRESET presetInnerCopper; + static LAYER_PRESET presetFront; + static LAYER_PRESET presetFrontAssembly; + static LAYER_PRESET presetBack; + static LAYER_PRESET presetBackAssembly; + + int m_pointSize; + + enum POPUP_ID + { + ID_CHANGE_COLOR = wxID_HIGHEST, + ID_SET_NET_COLOR, + ID_CLEAR_NET_COLOR, + ID_SHOW_ALL_NETS, + ID_HIDE_OTHER_NETS, + ID_HIGHLIGHT_NET, + ID_SELECT_NET, + ID_SHOW_ALL_COPPER_LAYERS, + ID_HIDE_ALL_COPPER_LAYERS, + ID_HIDE_ALL_BUT_ACTIVE, + ID_PRESET_NO_LAYERS, + ID_PRESET_ALL_LAYERS, + ID_PRESET_FRONT, + ID_PRESET_FRONT_ASSEMBLY, + ID_PRESET_INNER_COPPER, + ID_PRESET_BACK, + ID_PRESET_BACK_ASSEMBLY, + ID_HIDE_ALL_NON_COPPER, + ID_SHOW_ALL_NON_COPPER, + ID_LAST_VALUE + }; + + void rebuildLayers(); + + void rebuildLayerContextMenu(); + + void syncColorsAndVisibility(); + + void rebuildObjects(); + + void syncObjectSettings(); + + void rebuildNets(); + + void loadDefaultLayerPresets(); + + void rebuildLayerPresetsWidget(); + + void syncLayerPresetSelection(); + + void updateDeleteLayerPresetButton(); + + void onLayerClick( wxMouseEvent& aEvent ); + + void onLayerVisibilityChanged( PCB_LAYER_ID aLayer, bool isVisible, bool isFinal ); + + void onObjectVisibilityChanged( GAL_LAYER_ID aLayer, bool isVisible, bool isFinal ); + + void onObjectOpacitySlider( int aLayer, float aOpacity ); + + void updateLayerPresetSelection( const wxString& aName ); + + void onLayerPresetChanged( wxCommandEvent& aEvent ); + + void doApplyLayerPreset( const LAYER_PRESET& aPreset ); + + void onNetclassVisibilityChanged( wxCommandEvent& aEvent ); + + void showNetclass( const wxString& aClassName, bool aShow = true ); + + void onNetContextMenu( wxCommandEvent& aEvent ); + + void onNetclassColorChanged( wxCommandEvent& aEvent ); + + wxString netclassNameFromEvent( wxEvent& aEvent ); + + void onNetColorModeChanged( wxCommandEvent& aEvent ); + + void onNetclassContextMenu( wxCommandEvent& aEvent ); + + void handleBoardItemsChanged(); +}; + +#endif diff --git a/pcbnew/widgets/appearance_controls_base.cpp b/pcbnew/widgets/appearance_controls_base.cpp new file mode 100644 index 0000000000..5e34dc85d7 --- /dev/null +++ b/pcbnew/widgets/appearance_controls_base.cpp @@ -0,0 +1,283 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Oct 26 2018) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "appearance_controls_base.h" + +/////////////////////////////////////////////////////////////////////////// + +APPEARANCE_CONTROLS_BASE::APPEARANCE_CONTROLS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) +{ + this->SetFont( wxFont( 9, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) ); + + m_sizerOuter = new wxBoxSizer( wxVERTICAL ); + + m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_panelLayers = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panelLayersSizer = new wxBoxSizer( wxVERTICAL ); + + m_windowLayers = new wxScrolledWindow( m_panelLayers, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL ); + m_windowLayers->SetScrollRate( 0, 5 ); + m_windowLayers->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + m_layers_outer_sizer = new wxBoxSizer( wxVERTICAL ); + + + m_windowLayers->SetSizer( m_layers_outer_sizer ); + m_windowLayers->Layout(); + m_layers_outer_sizer->Fit( m_windowLayers ); + m_panelLayersSizer->Add( m_windowLayers, 1, wxEXPAND | wxALL, 5 ); + + m_paneLayerDisplay = new wxCollapsiblePane( m_panelLayers, wxID_ANY, wxT("Layer Display Options"), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE|wxCP_NO_TLW_RESIZE|wxBORDER_NONE|wxCLIP_CHILDREN|wxFULL_REPAINT_ON_RESIZE ); + m_paneLayerDisplay->Collapse( true ); + + wxBoxSizer* bSizer121; + bSizer121 = new wxBoxSizer( wxVERTICAL ); + + m_staticText13 = new wxStaticText( m_paneLayerDisplay->GetPane(), wxID_ANY, wxT("Show non-active layers as:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText13->Wrap( -1 ); + bSizer121->Add( m_staticText13, 0, wxALL, 5 ); + + wxBoxSizer* bSizer19; + bSizer19 = new wxBoxSizer( wxHORIZONTAL ); + + m_rbHighContrastNormal = new wxRadioButton( m_paneLayerDisplay->GetPane(), wxID_ANY, wxT("Normal"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + m_rbHighContrastNormal->SetValue( true ); + m_rbHighContrastNormal->SetToolTip( wxT("Non-active layers will be shown in full color") ); + + bSizer19->Add( m_rbHighContrastNormal, 0, wxALL, 5 ); + + m_rbHighContrastDim = new wxRadioButton( m_paneLayerDisplay->GetPane(), wxID_ANY, wxT("Dimmed"), wxDefaultPosition, wxDefaultSize, 0 ); + m_rbHighContrastDim->SetToolTip( wxT("Non-active layers will be dimmed") ); + + bSizer19->Add( m_rbHighContrastDim, 0, wxALL, 5 ); + + m_rbHighContrastOff = new wxRadioButton( m_paneLayerDisplay->GetPane(), wxID_ANY, wxT("Off"), wxDefaultPosition, wxDefaultSize, 0 ); + m_rbHighContrastOff->SetToolTip( wxT("Non-active layers will be hidden") ); + + bSizer19->Add( m_rbHighContrastOff, 0, wxALL, 5 ); + + + bSizer121->Add( bSizer19, 0, wxEXPAND, 5 ); + + m_staticline5 = new wxStaticLine( m_paneLayerDisplay->GetPane(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer121->Add( m_staticline5, 0, wxEXPAND | wxALL, 5 ); + + m_cbFlipBoard = new wxCheckBox( m_paneLayerDisplay->GetPane(), wxID_ANY, wxT("Flip board view"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer121->Add( m_cbFlipBoard, 0, wxALL, 5 ); + + + m_paneLayerDisplay->GetPane()->SetSizer( bSizer121 ); + m_paneLayerDisplay->GetPane()->Layout(); + bSizer121->Fit( m_paneLayerDisplay->GetPane() ); + m_panelLayersSizer->Add( m_paneLayerDisplay, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 ); + + + m_panelLayers->SetSizer( m_panelLayersSizer ); + m_panelLayers->Layout(); + m_panelLayersSizer->Fit( m_panelLayers ); + m_notebook->AddPage( m_panelLayers, wxT("Layers"), true ); + m_panelObjects = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panelObjects->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + m_objectsPanelSizer = new wxBoxSizer( wxVERTICAL ); + + m_windowObjects = new wxScrolledWindow( m_panelObjects, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL ); + m_windowObjects->SetScrollRate( 0, 5 ); + m_windowObjects->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + m_objectsSizer = new wxGridBagSizer( 0, 0 ); + m_objectsSizer->SetFlexibleDirection( wxBOTH ); + m_objectsSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + + m_windowObjects->SetSizer( m_objectsSizer ); + m_windowObjects->Layout(); + m_objectsSizer->Fit( m_windowObjects ); + m_objectsPanelSizer->Add( m_windowObjects, 1, wxEXPAND | wxALL, 5 ); + + + m_panelObjects->SetSizer( m_objectsPanelSizer ); + m_panelObjects->Layout(); + m_objectsPanelSizer->Fit( m_panelObjects ); + m_notebook->AddPage( m_panelObjects, wxT("Objects"), false ); + m_panelNetsAndClasses = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer16; + bSizer16 = new wxBoxSizer( wxVERTICAL ); + + m_netsTabSplitter = new wxSplitterWindow( m_panelNetsAndClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE ); + m_netsTabSplitter->SetSashGravity( 0.8 ); + m_netsTabSplitter->Connect( wxEVT_IDLE, wxIdleEventHandler( APPEARANCE_CONTROLS_BASE::m_netsTabSplitterOnIdle ), NULL, this ); + m_netsTabSplitter->SetMinimumPaneSize( 80 ); + + m_panelNets = new wxPanel( m_netsTabSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer192; + bSizer192 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer17; + bSizer17 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText141 = new wxStaticText( m_panelNets, wxID_ANY, wxT("Nets"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText141->Wrap( -1 ); + m_staticText141->SetFont( wxFont( 9, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); + + bSizer17->Add( m_staticText141, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); + + m_txtNetFilter = new wxTextCtrl( m_panelNets, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_txtNetFilter->Hide(); + + bSizer17->Add( m_txtNetFilter, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxTOP, 5 ); + + m_btnNetInspector = new wxBitmapButton( m_panelNets, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBORDER_NONE ); + m_btnNetInspector->SetToolTip( wxT("Show the Net Inspector") ); + + bSizer17->Add( m_btnNetInspector, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 ); + + + 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_netsScrolledWindow->SetSizer( m_netsOuterSizer ); + m_netsScrolledWindow->Layout(); + m_netsOuterSizer->Fit( m_netsScrolledWindow ); + bSizer192->Add( m_netsScrolledWindow, 1, wxEXPAND | wxALL, 5 ); + + + m_panelNets->SetSizer( bSizer192 ); + m_panelNets->Layout(); + bSizer192->Fit( m_panelNets ); + m_panelNetclasses = new wxPanel( m_netsTabSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText14 = new wxStaticText( m_panelNetclasses, wxID_ANY, wxT("Net Classes"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText14->Wrap( -1 ); + m_staticText14->SetFont( wxFont( 9, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); + + bSizer20->Add( m_staticText14, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); + + m_btnConfigureNetClasses = new wxBitmapButton( m_panelNetclasses, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|wxBORDER_NONE ); + m_btnConfigureNetClasses->SetToolTip( wxT("Configure net classes") ); + + bSizer20->Add( m_btnConfigureNetClasses, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); + + + bSizer21->Add( bSizer20, 0, wxEXPAND, 5 ); + + m_netclassScrolledWindow = new wxScrolledWindow( m_panelNetclasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL ); + m_netclassScrolledWindow->SetScrollRate( 5, 5 ); + m_netclassOuterSizer = new wxBoxSizer( wxVERTICAL ); + + + m_netclassScrolledWindow->SetSizer( m_netclassOuterSizer ); + m_netclassScrolledWindow->Layout(); + m_netclassOuterSizer->Fit( m_netclassScrolledWindow ); + bSizer21->Add( m_netclassScrolledWindow, 1, wxEXPAND | wxALL, 5 ); + + + m_panelNetclasses->SetSizer( bSizer21 ); + m_panelNetclasses->Layout(); + bSizer21->Fit( m_panelNetclasses ); + m_netsTabSplitter->SplitHorizontally( m_panelNets, m_panelNetclasses, 300 ); + 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( true ); + + wxBoxSizer* bSizer1211; + bSizer1211 = new wxBoxSizer( wxVERTICAL ); + + m_staticText131 = new wxStaticText( m_paneNetDisplay->GetPane(), wxID_ANY, wxT("Show net colors on:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText131->Wrap( -1 ); + m_staticText131->SetToolTip( wxT("Choose when to show net and netclass colors") ); + + bSizer1211->Add( m_staticText131, 0, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer191; + bSizer191 = new wxBoxSizer( wxHORIZONTAL ); + + m_rbNetColorOff = new wxRadioButton( m_paneNetDisplay->GetPane(), wxID_ANY, wxT("Off"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + m_rbNetColorOff->SetToolTip( wxT("Net and netclass colors are not shown") ); + + bSizer191->Add( m_rbNetColorOff, 0, wxLEFT|wxTOP, 5 ); + + m_rbNetColorRatsnest = new wxRadioButton( m_paneNetDisplay->GetPane(), wxID_ANY, wxT("Ratsnest"), wxDefaultPosition, wxDefaultSize, 0 ); + m_rbNetColorRatsnest->SetValue( true ); + m_rbNetColorRatsnest->SetToolTip( wxT("Net and netclass colors are shown on the ratsnest only") ); + + bSizer191->Add( m_rbNetColorRatsnest, 0, wxLEFT|wxTOP, 5 ); + + m_rbNetColorAll = new wxRadioButton( m_paneNetDisplay->GetPane(), wxID_ANY, wxT("All Items"), wxDefaultPosition, wxDefaultSize, 0 ); + m_rbNetColorAll->SetToolTip( wxT("Net and netclass colors are shown on all copper items") ); + + bSizer191->Add( m_rbNetColorAll, 0, wxALL, 5 ); + + + bSizer1211->Add( bSizer191, 0, wxEXPAND, 5 ); + + + m_paneNetDisplay->GetPane()->SetSizer( bSizer1211 ); + m_paneNetDisplay->GetPane()->Layout(); + bSizer1211->Fit( m_paneNetDisplay->GetPane() ); + bSizer16->Add( m_paneNetDisplay, 0, wxEXPAND | wxALL, 5 ); + + + m_panelNetsAndClasses->SetSizer( bSizer16 ); + m_panelNetsAndClasses->Layout(); + bSizer16->Fit( m_panelNetsAndClasses ); + m_notebook->AddPage( m_panelNetsAndClasses, wxT("Nets"), false ); + + m_sizerOuter->Add( m_notebook, 1, wxEXPAND | wxALL, 5 ); + + wxStaticBoxSizer* presetsSizer; + presetsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("Layer Presets") ), wxHORIZONTAL ); + + wxString m_cbLayerPresetsChoices[] = { wxT("All Layers"), wxT("(unsaved)") }; + int m_cbLayerPresetsNChoices = sizeof( m_cbLayerPresetsChoices ) / sizeof( wxString ); + m_cbLayerPresets = new wxChoice( presetsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbLayerPresetsNChoices, m_cbLayerPresetsChoices, 0 ); + m_cbLayerPresets->SetSelection( 1 ); + presetsSizer->Add( m_cbLayerPresets, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_btnDeletePreset = new wxBitmapButton( presetsSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + m_btnDeletePreset->Enable( false ); + m_btnDeletePreset->SetToolTip( wxT("Delete this layer preset") ); + + presetsSizer->Add( m_btnDeletePreset, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 ); + + + m_sizerOuter->Add( presetsSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); + + + this->SetSizer( m_sizerOuter ); + this->Layout(); + + // Connect Events + m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( APPEARANCE_CONTROLS_BASE::OnNotebookPageChanged ), NULL, this ); + m_paneLayerDisplay->Connect( wxEVT_COLLAPSIBLEPANE_CHANGED, wxCollapsiblePaneEventHandler( APPEARANCE_CONTROLS_BASE::OnLayerDisplayPaneChanged ), NULL, this ); + m_cbFlipBoard->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( APPEARANCE_CONTROLS_BASE::OnFlipBoardChecked ), NULL, this ); + m_paneNetDisplay->Connect( wxEVT_COLLAPSIBLEPANE_CHANGED, wxCollapsiblePaneEventHandler( APPEARANCE_CONTROLS_BASE::OnNetDisplayPaneChanged ), NULL, this ); + m_cbLayerPresets->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_BASE::OnLayerPresetChanged ), NULL, this ); + m_btnDeletePreset->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( APPEARANCE_CONTROLS_BASE::OnBtnDeleteLayerPreset ), NULL, this ); +} + +APPEARANCE_CONTROLS_BASE::~APPEARANCE_CONTROLS_BASE() +{ + // Disconnect Events + m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( APPEARANCE_CONTROLS_BASE::OnNotebookPageChanged ), NULL, this ); + m_paneLayerDisplay->Disconnect( wxEVT_COLLAPSIBLEPANE_CHANGED, wxCollapsiblePaneEventHandler( APPEARANCE_CONTROLS_BASE::OnLayerDisplayPaneChanged ), NULL, this ); + m_cbFlipBoard->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( APPEARANCE_CONTROLS_BASE::OnFlipBoardChecked ), NULL, this ); + m_paneNetDisplay->Disconnect( wxEVT_COLLAPSIBLEPANE_CHANGED, wxCollapsiblePaneEventHandler( APPEARANCE_CONTROLS_BASE::OnNetDisplayPaneChanged ), NULL, this ); + m_cbLayerPresets->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( APPEARANCE_CONTROLS_BASE::OnLayerPresetChanged ), NULL, this ); + m_btnDeletePreset->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( APPEARANCE_CONTROLS_BASE::OnBtnDeleteLayerPreset ), NULL, this ); + +} diff --git a/pcbnew/widgets/appearance_controls_base.fbp b/pcbnew/widgets/appearance_controls_base.fbp new file mode 100644 index 0000000000..31a9b60949 --- /dev/null +++ b/pcbnew/widgets/appearance_controls_base.fbp @@ -0,0 +1,2055 @@ + + + + + ; + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + appearance_controls_base + 1000 + none + + 0 + Appearance Panel + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + + 1 + 1 + impl_virtual + + ,90,90,9,70,0 + 0 + wxID_ANY + + + APPEARANCE_CONTROLS_BASE + + 275,762 + ; ; forward_declare + + + + wxTAB_TRAVERSAL + + + m_sizerOuter + wxVERTICAL + protected + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_notebook + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + OnNotebookPageChanged + + + Layers + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panelLayers + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + m_panelLayersSizer + wxVERTICAL + protected + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + wxSYS_COLOUR_WINDOW + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_windowLayers + 1 + + + protected + 1 + + Resizable + 0 + 5 + 1 + + ; ; forward_declare + 0 + + + + wxHSCROLL|wxVSCROLL + + + m_layers_outer_sizer + wxVERTICAL + protected + + + + + 5 + wxBOTTOM|wxEXPAND|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Layer Display Options + + 0 + + + 0 + + 1 + m_paneLayerDisplay + 1 + + + protected + 1 + + Resizable + 1 + + wxCP_DEFAULT_STYLE|wxCP_NO_TLW_RESIZE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE|wxCLIP_CHILDREN|wxFULL_REPAINT_ON_RESIZE + OnLayerDisplayPaneChanged + + + bSizer121 + wxVERTICAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Show non-active layers as: + 0 + + 0 + + + 0 + + 1 + m_staticText13 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND + 0 + + + bSizer19 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Normal + + 0 + + + 0 + + 1 + m_rbHighContrastNormal + 1 + + + protected + 1 + + Resizable + 1 + + wxRB_GROUP + ; ; forward_declare + 0 + Non-active layers will be shown in full color + + wxFILTER_NONE + wxDefaultValidator + + 1 + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Dimmed + + 0 + + + 0 + + 1 + m_rbHighContrastDim + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Non-active layers will be dimmed + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Off + + 0 + + + 0 + + 1 + m_rbHighContrastOff + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Non-active layers will be hidden + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + + + 5 + wxEXPAND | wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline5 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + ; ; forward_declare + 0 + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Flip board view + + 0 + + + 0 + + 1 + m_cbFlipBoard + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnFlipBoardChecked + + + + + + + + + + + Objects + 0 + + 1 + 1 + 1 + 1 + + + + + + wxSYS_COLOUR_WINDOW + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panelObjects + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + m_objectsPanelSizer + wxVERTICAL + protected + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + wxSYS_COLOUR_WINDOW + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_windowObjects + 1 + + + protected + 1 + + Resizable + 0 + 5 + 1 + + ; ; forward_declare + 0 + + + + wxHSCROLL|wxVSCROLL + + + wxBOTH + + + 0 + + m_objectsSizer + wxFLEX_GROWMODE_SPECIFIED + protected + 0 + + + + + + + + + Nets + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panelNetsAndClasses + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + bSizer16 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 80 + + 0 + + 1 + m_netsTabSplitter + 1 + + + protected + 1 + + Resizable + 0.8 + 300 + -1 + 1 + + wxSPLIT_HORIZONTAL + wxSP_3D|wxSP_LIVE_UPDATE + ; ; forward_declare + 0 + + + + + + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panelNets + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + bSizer192 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer17 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,92,9,70,0 + 0 + 0 + wxID_ANY + Nets + 0 + + 0 + + + 0 + + 1 + m_staticText141 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxTOP + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 1 + wxID_ANY + + 0 + + + + 0 + + 1 + m_txtNetFilter + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Net Inspector + + 0 + + 0 + + + 0 + + 1 + m_btnNetInspector + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + Show the Net Inspector + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_netsScrolledWindow + 1 + + + protected + 1 + + Resizable + 5 + 5 + 1 + + ; ; forward_declare + 0 + + + + wxHSCROLL|wxVSCROLL + + + m_netsOuterSizer + wxVERTICAL + protected + + + + + + + + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panelNetclasses + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer20 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,92,9,70,0 + 0 + 0 + wxID_ANY + Net Classes + 0 + + 0 + + + 0 + + 1 + m_staticText14 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Configure Net Classes + + 0 + + 0 + + + 0 + + 1 + m_btnConfigureNetClasses + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + Configure net classes + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_netclassScrolledWindow + 1 + + + protected + 1 + + Resizable + 5 + 5 + 1 + + ; ; forward_declare + 0 + + + + wxHSCROLL|wxVSCROLL + + + m_netclassOuterSizer + wxVERTICAL + protected + + + + + + + + + + 5 + wxEXPAND | wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Net Display Options + + 0 + + + 0 + + 1 + m_paneNetDisplay + 1 + + + protected + 1 + + Resizable + 1 + + wxCP_DEFAULT_STYLE|wxCP_NO_TLW_RESIZE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnNetDisplayPaneChanged + + + bSizer1211 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Show net colors on: + 0 + + 0 + + + 0 + + 1 + m_staticText131 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Choose when to show net and netclass colors + + + + -1 + + + + 5 + wxEXPAND + 0 + + + bSizer191 + wxHORIZONTAL + none + + 5 + wxLEFT|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Off + + 0 + + + 0 + + 1 + m_rbNetColorOff + 1 + + + protected + 1 + + Resizable + 1 + + wxRB_GROUP + ; ; forward_declare + 0 + Net and netclass colors are not shown + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + 5 + wxLEFT|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Ratsnest + + 0 + + + 0 + + 1 + m_rbNetColorRatsnest + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Net and netclass colors are shown on the ratsnest only + + wxFILTER_NONE + wxDefaultValidator + + 1 + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + All Items + + 0 + + + 0 + + 1 + m_rbNetColorAll + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Net and netclass colors are shown on all copper items + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT + 0 + + wxID_ANY + Layer Presets + + presetsSizer + wxHORIZONTAL + 1 + none + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "All Layers" "(unsaved)" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_cbLayerPresets + 1 + + + protected + 1 + + Resizable + 1 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnLayerPresetChanged + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 0 + + 1 + + + 0 + 0 + wxID_ANY + New Preset + + 0 + + 0 + + + 0 + + 1 + m_btnDeletePreset + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + Delete this layer preset + + wxFILTER_NONE + wxDefaultValidator + + + + + OnBtnDeleteLayerPreset + + + + + + + + diff --git a/pcbnew/widgets/appearance_controls_base.h b/pcbnew/widgets/appearance_controls_base.h new file mode 100644 index 0000000000..5ab6cae588 --- /dev/null +++ b/pcbnew/widgets/appearance_controls_base.h @@ -0,0 +1,107 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Oct 26 2018) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class APPEARANCE_CONTROLS_BASE +/////////////////////////////////////////////////////////////////////////////// +class APPEARANCE_CONTROLS_BASE : public wxPanel +{ + private: + + protected: + wxBoxSizer* m_sizerOuter; + wxNotebook* m_notebook; + wxPanel* m_panelLayers; + wxBoxSizer* m_panelLayersSizer; + wxScrolledWindow* m_windowLayers; + wxBoxSizer* m_layers_outer_sizer; + wxCollapsiblePane* m_paneLayerDisplay; + wxStaticText* m_staticText13; + wxRadioButton* m_rbHighContrastNormal; + wxRadioButton* m_rbHighContrastDim; + wxRadioButton* m_rbHighContrastOff; + wxStaticLine* m_staticline5; + wxCheckBox* m_cbFlipBoard; + wxPanel* m_panelObjects; + wxBoxSizer* m_objectsPanelSizer; + wxScrolledWindow* m_windowObjects; + wxGridBagSizer* m_objectsSizer; + wxPanel* m_panelNetsAndClasses; + wxSplitterWindow* m_netsTabSplitter; + wxPanel* m_panelNets; + wxStaticText* m_staticText141; + wxTextCtrl* m_txtNetFilter; + wxBitmapButton* m_btnNetInspector; + wxScrolledWindow* m_netsScrolledWindow; + wxBoxSizer* m_netsOuterSizer; + wxPanel* m_panelNetclasses; + wxStaticText* m_staticText14; + wxBitmapButton* m_btnConfigureNetClasses; + wxScrolledWindow* m_netclassScrolledWindow; + wxBoxSizer* m_netclassOuterSizer; + wxCollapsiblePane* m_paneNetDisplay; + wxStaticText* m_staticText131; + wxRadioButton* m_rbNetColorOff; + wxRadioButton* m_rbNetColorRatsnest; + wxRadioButton* m_rbNetColorAll; + wxChoice* m_cbLayerPresets; + wxBitmapButton* m_btnDeletePreset; + + // Virtual event handlers, overide them in your derived class + virtual void OnNotebookPageChanged( wxNotebookEvent& event ) { event.Skip(); } + virtual void OnLayerDisplayPaneChanged( wxCollapsiblePaneEvent& event ) { event.Skip(); } + virtual void OnFlipBoardChecked( wxCommandEvent& event ) { event.Skip(); } + virtual void OnNetDisplayPaneChanged( wxCollapsiblePaneEvent& event ) { event.Skip(); } + virtual void OnLayerPresetChanged( wxCommandEvent& event ) { event.Skip(); } + virtual void OnBtnDeleteLayerPreset( wxCommandEvent& event ) { event.Skip(); } + + + public: + + APPEARANCE_CONTROLS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 275,762 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); + ~APPEARANCE_CONTROLS_BASE(); + + void m_netsTabSplitterOnIdle( wxIdleEvent& ) + { + m_netsTabSplitter->SetSashPosition( 300 ); + m_netsTabSplitter->Disconnect( wxEVT_IDLE, wxIdleEventHandler( APPEARANCE_CONTROLS_BASE::m_netsTabSplitterOnIdle ), NULL, this ); + } + +}; +