From 19c748048cefd4c9f986aff99501152f6a3d5e5f Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sun, 29 Dec 2024 22:02:23 -0500 Subject: [PATCH] API: Add some board editor appearance settings Fixes https://gitlab.com/kicad/code/kicad/-/issues/18269 --- api/proto/board/board_commands.proto | 61 +++++++++++++++++ pcbnew/api/api_handler_pcb.cpp | 63 ++++++++++++++++++ pcbnew/api/api_handler_pcb.h | 6 ++ pcbnew/api/api_pcb_enums.cpp | 98 ++++++++++++++++++++++++++++ qa/tests/api/test_api_enums.cpp | 19 +++++- 5 files changed, 246 insertions(+), 1 deletion(-) diff --git a/api/proto/board/board_commands.proto b/api/proto/board/board_commands.proto index 178f04f6ea..04ad03b2aa 100644 --- a/api/proto/board/board_commands.proto +++ b/api/proto/board/board_commands.proto @@ -186,6 +186,67 @@ message SetActiveLayer kiapi.board.types.BoardLayer layer = 2; } +enum InactiveLayerDisplayMode +{ + ILDM_UNKNOWN = 0; + // Inactive layers are shown + ILDM_NORMAL = 1; + // Inactive layers are shown with dimmed colors + ILDM_DIMMED = 2; + // Inactive layers are hidden + ILDM_HIDDEN = 3; +} + +enum NetColorDisplayMode +{ + NCDM_UNKNOWN = 0; + // Net and netclass colors are shown in the ratsnest and on all copper items + NCDM_ALL = 1; + // Net and netclass colors are shown in the ratsnest only + NCDM_RATSNEST = 2; + // Net and netclass colors are not shown + NCDM_OFF = 3; +} + +enum BoardFlipMode +{ + BFM_UNKNOWN = 0; + // Normal ("non-flipped") mode + BFM_NORMAL = 1; + // "Flipped" mode, viewed from the back and mirrored around the X axis + BFM_FLIPPED_X = 2; +} + +enum RatsnestDisplayMode +{ + RDM_UNKNOWN = 0; + // Ratsnest lines are drawn to objects even if they are on hidden layers + RDM_ALL_LAYERS = 1; + // Ratsnest lines are hidden when at least one endpoint is an item on a hidden layer + RDM_VISIBLE_LAYERS = 2; +} + +message BoardEditorAppearanceSettings +{ + InactiveLayerDisplayMode inactive_layer_display = 1; + + NetColorDisplayMode net_color_display = 2; + + BoardFlipMode board_flip = 3; + + RatsnestDisplayMode ratsnest_display = 4; +} + +// Returns BoardEditorAppearanceSettings +message GetBoardEditorAppearanceSettings +{ +} + +message SetBoardEditorAppearanceSettings +{ + BoardEditorAppearanceSettings settings = 1; +} + //// Interactive commands //// // These commands begin an interactive operation in the editor. // They return a response immediately, but the editor will become busy diff --git a/pcbnew/api/api_handler_pcb.cpp b/pcbnew/api/api_handler_pcb.cpp index f7ef3958d8..e8142bfe3a 100644 --- a/pcbnew/api/api_handler_pcb.cpp +++ b/pcbnew/api/api_handler_pcb.cpp @@ -88,6 +88,10 @@ API_HANDLER_PCB::API_HANDLER_PCB( PCB_EDIT_FRAME* aFrame ) : registerHandler( &API_HANDLER_PCB::handleSetVisibleLayers ); registerHandler( &API_HANDLER_PCB::handleGetActiveLayer ); registerHandler( &API_HANDLER_PCB::handleSetActiveLayer ); + registerHandler( + &API_HANDLER_PCB::handleGetBoardEditorAppearanceSettings ); + registerHandler( + &API_HANDLER_PCB::handleSetBoardEditorAppearanceSettings ); } @@ -1008,3 +1012,62 @@ HANDLER_RESULT API_HANDLER_PCB::handleSetActiveLayer( frame()->SetActiveLayer( layer ); return Empty(); } + + +HANDLER_RESULT API_HANDLER_PCB::handleGetBoardEditorAppearanceSettings( + const HANDLER_CONTEXT& aCtx ) +{ + BoardEditorAppearanceSettings reply; + + // TODO: might be nice to put all these things in one place and have it derive SERIALIZABLE + + const PCB_DISPLAY_OPTIONS& displayOptions = frame()->GetDisplayOptions(); + + reply.set_inactive_layer_display( ToProtoEnum( + displayOptions.m_ContrastModeDisplay ) ); + reply.set_net_color_display( + ToProtoEnum( displayOptions.m_NetColorMode ) ); + + reply.set_board_flip( frame()->GetCanvas()->GetView()->IsMirroredX() + ? BoardFlipMode::BFM_FLIPPED_X + : BoardFlipMode::BFM_NORMAL ); + + PCBNEW_SETTINGS* editorSettings = frame()->GetPcbNewSettings(); + + reply.set_ratsnest_display( ToProtoEnum( + editorSettings->m_Display.m_RatsnestMode ) ); + + return reply; +} + + +HANDLER_RESULT API_HANDLER_PCB::handleSetBoardEditorAppearanceSettings( + const HANDLER_CONTEXT& aCtx ) +{ + PCB_DISPLAY_OPTIONS options = frame()->GetDisplayOptions(); + KIGFX::PCB_VIEW* view = frame()->GetCanvas()->GetView(); + PCBNEW_SETTINGS* editorSettings = frame()->GetPcbNewSettings(); + const BoardEditorAppearanceSettings& newSettings = aCtx.Request.settings(); + + options.m_ContrastModeDisplay = + FromProtoEnum( newSettings.inactive_layer_display() ); + options.m_NetColorMode = + FromProtoEnum( newSettings.net_color_display() ); + + bool flip = newSettings.board_flip() == BoardFlipMode::BFM_FLIPPED_X; + + if( flip != view->IsMirroredX() ) + { + view->SetMirror( !view->IsMirroredX(), view->IsMirroredY() ); + view->RecacheAllItems(); + } + + editorSettings->m_Display.m_RatsnestMode = + FromProtoEnum( newSettings.ratsnest_display() ); + + frame()->SetDisplayOptions( options ); + frame()->GetCanvas()->GetView()->UpdateAllLayersColor(); + frame()->GetCanvas()->Refresh(); + + return Empty(); +} diff --git a/pcbnew/api/api_handler_pcb.h b/pcbnew/api/api_handler_pcb.h index ab6bc3d676..80c9ed6458 100644 --- a/pcbnew/api/api_handler_pcb.h +++ b/pcbnew/api/api_handler_pcb.h @@ -104,6 +104,12 @@ private: HANDLER_RESULT handleGetActiveLayer( const HANDLER_CONTEXT& aCtx ); HANDLER_RESULT handleSetActiveLayer( const HANDLER_CONTEXT& aCtx ); + HANDLER_RESULT handleGetBoardEditorAppearanceSettings( + const HANDLER_CONTEXT& aCtx ); + + HANDLER_RESULT handleSetBoardEditorAppearanceSettings( + const HANDLER_CONTEXT& aCtx ); + protected: std::unique_ptr createCommit() override; diff --git a/pcbnew/api/api_pcb_enums.cpp b/pcbnew/api/api_pcb_enums.cpp index 81b887affe..343db97da6 100644 --- a/pcbnew/api/api_pcb_enums.cpp +++ b/pcbnew/api/api_pcb_enums.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include // Adding something new here? Add it to test_api_enums.cpp! @@ -668,4 +670,100 @@ DIM_UNITS_MODE FromProtoEnum( types::DimensionUnit aValue ) } +template<> +commands::InactiveLayerDisplayMode ToProtoEnum( HIGH_CONTRAST_MODE aValue ) +{ + switch( aValue ) + { + case HIGH_CONTRAST_MODE::NORMAL: return commands::InactiveLayerDisplayMode::ILDM_NORMAL; + case HIGH_CONTRAST_MODE::DIMMED: return commands::InactiveLayerDisplayMode::ILDM_DIMMED; + case HIGH_CONTRAST_MODE::HIDDEN: return commands::InactiveLayerDisplayMode::ILDM_HIDDEN; + + default: + wxCHECK_MSG( false, commands::InactiveLayerDisplayMode::ILDM_NORMAL, + "Unhandled case in ToProtoEnum"); + } +} + + +template<> +HIGH_CONTRAST_MODE FromProtoEnum( commands::InactiveLayerDisplayMode aValue ) +{ + switch( aValue ) + { + case commands::InactiveLayerDisplayMode::ILDM_DIMMED: return HIGH_CONTRAST_MODE::DIMMED; + case commands::InactiveLayerDisplayMode::ILDM_HIDDEN: return HIGH_CONTRAST_MODE::HIDDEN; + case commands::InactiveLayerDisplayMode::ILDM_UNKNOWN: + case commands::InactiveLayerDisplayMode::ILDM_NORMAL: return HIGH_CONTRAST_MODE::NORMAL; + + default: + wxCHECK_MSG( false, HIGH_CONTRAST_MODE::NORMAL, + "Unhandled case in FromProtoEnum" ); + } +} + + +template<> +commands::NetColorDisplayMode ToProtoEnum( NET_COLOR_MODE aValue ) +{ + switch( aValue ) + { + case NET_COLOR_MODE::ALL: return commands::NetColorDisplayMode::NCDM_ALL; + case NET_COLOR_MODE::RATSNEST: return commands::NetColorDisplayMode::NCDM_RATSNEST; + case NET_COLOR_MODE::OFF: return commands::NetColorDisplayMode::NCDM_OFF; + + default: + wxCHECK_MSG( false, commands::NetColorDisplayMode::NCDM_UNKNOWN, + "Unhandled case in ToProtoEnum"); + } +} + + +template<> +NET_COLOR_MODE FromProtoEnum( commands::NetColorDisplayMode aValue ) +{ + switch( aValue ) + { + case commands::NetColorDisplayMode::NCDM_ALL: return NET_COLOR_MODE::ALL; + case commands::NetColorDisplayMode::NCDM_OFF: return NET_COLOR_MODE::OFF; + case commands::NetColorDisplayMode::NCDM_UNKNOWN: + case commands::NetColorDisplayMode::NCDM_RATSNEST: return NET_COLOR_MODE::RATSNEST; + + default: + wxCHECK_MSG( false, NET_COLOR_MODE::RATSNEST, + "Unhandled case in FromProtoEnum" ); + } +} + + +template<> +commands::RatsnestDisplayMode ToProtoEnum( RATSNEST_MODE aValue ) +{ + switch( aValue ) + { + case RATSNEST_MODE::ALL: return commands::RatsnestDisplayMode::RDM_ALL_LAYERS; + case RATSNEST_MODE::VISIBLE: return commands::RatsnestDisplayMode::RDM_VISIBLE_LAYERS; + + default: + wxCHECK_MSG( false, commands::RatsnestDisplayMode::RDM_UNKNOWN, + "Unhandled case in ToProtoEnum"); + } +} + + +template<> +RATSNEST_MODE FromProtoEnum( commands::RatsnestDisplayMode aValue ) +{ + switch( aValue ) + { + case commands::RatsnestDisplayMode::RDM_VISIBLE_LAYERS: return RATSNEST_MODE::VISIBLE; + case commands::RatsnestDisplayMode::RDM_UNKNOWN: + case commands::RatsnestDisplayMode::RDM_ALL_LAYERS: return RATSNEST_MODE::ALL; + + default: + wxCHECK_MSG( false, RATSNEST_MODE::ALL, + "Unhandled case in FromProtoEnum" ); + } +} + // Adding something new here? Add it to test_api_enums.cpp! diff --git a/qa/tests/api/test_api_enums.cpp b/qa/tests/api/test_api_enums.cpp index 39d2500be7..5b913fc97e 100644 --- a/qa/tests/api/test_api_enums.cpp +++ b/qa/tests/api/test_api_enums.cpp @@ -26,16 +26,18 @@ // Common #include #include -#include #include #include #include #include // Board-specific +#include +#include #include #include #include +#include #include #include @@ -244,4 +246,19 @@ BOOST_AUTO_TEST_CASE( DimensionUnit ) testEnums(); } +BOOST_AUTO_TEST_CASE( InactiveLayerDisplayMode ) +{ + testEnums(); +} + +BOOST_AUTO_TEST_CASE( NetColorDisplayMode ) +{ + testEnums(); +} + +BOOST_AUTO_TEST_CASE( RatsnestDisplayMode ) +{ + testEnums(); +} + BOOST_AUTO_TEST_SUITE_END()