diff --git a/api/proto/board/board_commands.proto b/api/proto/board/board_commands.proto index 33846c0e17..178f04f6ea 100644 --- a/api/proto/board/board_commands.proto +++ b/api/proto/board/board_commands.proto @@ -148,6 +148,44 @@ message PadShapeAsPolygonResponse repeated kiapi.common.types.PolygonWithHoles polygons = 2; } +// PCB editor commands + +// returns BoardLayers +message GetVisibleLayers +{ + kiapi.common.types.DocumentSpecifier board = 1; +} + +message BoardLayerResponse +{ + kiapi.board.types.BoardLayer layer = 1; +} + +message BoardLayers +{ + repeated kiapi.board.types.BoardLayer layers = 1; +} + +message SetVisibleLayers +{ + kiapi.common.types.DocumentSpecifier board = 1; + + repeated kiapi.board.types.BoardLayer layers = 2; +} + +// returns BoardLayerResponse +message GetActiveLayer +{ + kiapi.common.types.DocumentSpecifier board = 1; +} + +message SetActiveLayer +{ + kiapi.common.types.DocumentSpecifier board = 1; + + kiapi.board.types.BoardLayer layer = 2; +} + //// 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/api/proto/board/board_types.proto b/api/proto/board/board_types.proto index d87276120b..3acdd9e21b 100644 --- a/api/proto/board/board_types.proto +++ b/api/proto/board/board_types.proto @@ -88,6 +88,7 @@ enum BoardLayer BL_User_7 = 59; BL_User_8 = 60; BL_User_9 = 61; + BL_Rescue = 62; } message NetCode diff --git a/common/api/api_enums.cpp b/common/api/api_enums.cpp index 12fe941077..8465cf4e53 100644 --- a/common/api/api_enums.cpp +++ b/common/api/api_enums.cpp @@ -213,6 +213,7 @@ PCB_LAYER_ID FromProtoEnum( board::types::BoardLayer aValue ) case board::types::BoardLayer::BL_User_7: return User_7; case board::types::BoardLayer::BL_User_8: return User_8; case board::types::BoardLayer::BL_User_9: return User_9; + case board::types::BoardLayer::BL_Rescue: return Rescue; case board::types::BoardLayer::BL_UNKNOWN: return UNDEFINED_LAYER; default: @@ -288,6 +289,7 @@ board::types::BoardLayer ToProtoEnum( PCB_LAYER_ID aValue ) case User_7: return board::types::BoardLayer::BL_User_7; case User_8: return board::types::BoardLayer::BL_User_8; case User_9: return board::types::BoardLayer::BL_User_9; + case Rescue: return board::types::BoardLayer::BL_Rescue; default: wxCHECK_MSG( false, board::types::BoardLayer::BL_UNKNOWN, "Unhandled case in ToProtoEnum"); diff --git a/pcbnew/api/api_handler_pcb.cpp b/pcbnew/api/api_handler_pcb.cpp index dc29515988..13ed60fa95 100644 --- a/pcbnew/api/api_handler_pcb.cpp +++ b/pcbnew/api/api_handler_pcb.cpp @@ -44,6 +44,7 @@ #include #include +#include using namespace kiapi::common::commands; using types::CommandStatus; @@ -83,6 +84,10 @@ API_HANDLER_PCB::API_HANDLER_PCB( PCB_EDIT_FRAME* aFrame ) : &API_HANDLER_PCB::handleSaveSelectionToString ); registerHandler( &API_HANDLER_PCB::handleParseAndCreateItemsFromString ); + registerHandler( &API_HANDLER_PCB::handleGetVisibleLayers ); + registerHandler( &API_HANDLER_PCB::handleSetVisibleLayers ); + registerHandler( &API_HANDLER_PCB::handleGetActiveLayer ); + registerHandler( &API_HANDLER_PCB::handleSetActiveLayer ); } @@ -917,3 +922,94 @@ HANDLER_RESULT API_HANDLER_PCB::handleParseAndCreateItemsFr CreateItemsResponse response; return response; } + + +HANDLER_RESULT API_HANDLER_PCB::handleGetVisibleLayers( GetVisibleLayers& aMsg, + const HANDLER_CONTEXT& aCtx ) +{ + HANDLER_RESULT documentValidation = validateDocument( aMsg.board() ); + + if( !documentValidation ) + return tl::unexpected( documentValidation.error() ); + + BoardLayers response; + + for( PCB_LAYER_ID layer : frame()->GetBoard()->GetVisibleLayers() ) + response.add_layers( ToProtoEnum( layer ) ); + + return response; +} + + +HANDLER_RESULT API_HANDLER_PCB::handleSetVisibleLayers( SetVisibleLayers& aMsg, + const HANDLER_CONTEXT& aCtx ) +{ + if( std::optional busy = checkForBusy() ) + return tl::unexpected( *busy ); + + HANDLER_RESULT documentValidation = validateDocument( aMsg.board() ); + + if( !documentValidation ) + return tl::unexpected( documentValidation.error() ); + + LSET visible; + LSET enabled = frame()->GetBoard()->GetEnabledLayers(); + + for( int layerIdx : aMsg.layers() ) + { + PCB_LAYER_ID layer = + FromProtoEnum( static_cast( layerIdx ) ); + + if( enabled.Contains( layer ) ) + visible.set( layer ); + } + + frame()->GetBoard()->SetVisibleLayers( visible ); + frame()->GetAppearancePanel()->OnBoardChanged(); + frame()->GetCanvas()->SyncLayersVisibility( frame()->GetBoard() ); + frame()->Refresh(); + return Empty(); +} + + +HANDLER_RESULT API_HANDLER_PCB::handleGetActiveLayer( + GetActiveLayer& aMsg, const HANDLER_CONTEXT& aCtx ) +{ + HANDLER_RESULT documentValidation = validateDocument( aMsg.board() ); + + if( !documentValidation ) + return tl::unexpected( documentValidation.error() ); + + BoardLayerResponse response; + response.set_layer( + ToProtoEnum( frame()->GetActiveLayer() ) ); + + return response; +} + + +HANDLER_RESULT API_HANDLER_PCB::handleSetActiveLayer( SetActiveLayer& aMsg, + const HANDLER_CONTEXT& aCtx ) +{ + if( std::optional busy = checkForBusy() ) + return tl::unexpected( *busy ); + + HANDLER_RESULT documentValidation = validateDocument( aMsg.board() ); + + if( !documentValidation ) + return tl::unexpected( documentValidation.error() ); + + PCB_LAYER_ID layer = FromProtoEnum( aMsg.layer() ); + + if( !frame()->GetBoard()->GetEnabledLayers().Contains( layer ) ) + { + ApiResponseStatus err; + err.set_status( ApiStatusCode::AS_BAD_REQUEST ); + err.set_error_message( fmt::format( "Layer {} is not a valid layer for the given board", + magic_enum::enum_name( layer ) ) ); + return tl::unexpected( err ); + } + + frame()->SetActiveLayer( layer ); + return Empty(); +} diff --git a/pcbnew/api/api_handler_pcb.h b/pcbnew/api/api_handler_pcb.h index 0e6246c057..a3709735cc 100644 --- a/pcbnew/api/api_handler_pcb.h +++ b/pcbnew/api/api_handler_pcb.h @@ -102,6 +102,16 @@ private: HANDLER_RESULT handleParseAndCreateItemsFromString( commands::ParseAndCreateItemsFromString& aMsg, const HANDLER_CONTEXT& aCtx ); + HANDLER_RESULT handleGetVisibleLayers( GetVisibleLayers& aMsg, + const HANDLER_CONTEXT& aCtx ); + + HANDLER_RESULT handleSetVisibleLayers( SetVisibleLayers& aMsg, + const HANDLER_CONTEXT& aCtx ); + + HANDLER_RESULT handleGetActiveLayer( GetActiveLayer& aMsg, + const HANDLER_CONTEXT& aCtx ); + HANDLER_RESULT handleSetActiveLayer( SetActiveLayer& aMsg, const HANDLER_CONTEXT& aCtx ); + protected: std::unique_ptr createCommit() override;