diff --git a/api/proto/board/board_commands.proto b/api/proto/board/board_commands.proto index a7143d172a..088c04f5e1 100644 --- a/api/proto/board/board_commands.proto +++ b/api/proto/board/board_commands.proto @@ -123,7 +123,7 @@ message RefillZones * Utilities */ -// returns kiapi.common.commands.BoundingBoxResponse +// returns kiapi.common.types.Box2 message GetTextExtents { // A temporary text item to calculate the bounding box for diff --git a/api/proto/common/commands/editor_commands.proto b/api/proto/common/commands/editor_commands.proto index c48dcb0e9a..44b6cbee9f 100644 --- a/api/proto/common/commands/editor_commands.proto +++ b/api/proto/common/commands/editor_commands.proto @@ -261,17 +261,29 @@ message DeleteItemsResponse repeated ItemDeletionResult deleted_items = 3; } -message GetItemBoundingBox +enum BoundingBoxMode +{ + BBM_UNKNOWN = 0; + BBM_ITEM_ONLY = 1; + BBM_ITEM_AND_CHILD_TEXT = 2; +} + +message GetBoundingBox { kiapi.common.types.ItemHeader header = 1; - kiapi.common.types.KIID id = 2; + repeated kiapi.common.types.KIID items = 2; + + // Some item types can have independently-movable text as children (e.g. footprints) + // This mode controls whether or not these are included in the box + BoundingBoxMode mode = 3; } -message BoundingBoxResponse +message GetBoundingBoxResponse { - kiapi.common.types.Vector2 position = 1; - kiapi.common.types.Vector2 size = 2; + repeated kiapi.common.types.KIID items = 1; + + repeated kiapi.common.types.Box2 boxes = 2; } // Tests if a certain point falls within tolerance of an item's geometry diff --git a/api/proto/common/types/base_types.proto b/api/proto/common/types/base_types.proto index aa47eed6e7..5de82fb9f3 100644 --- a/api/proto/common/types/base_types.proto +++ b/api/proto/common/types/base_types.proto @@ -191,6 +191,12 @@ message Vector3 int64 z_nm = 3; } +message Box2 +{ + kiapi.common.types.Vector2 position = 1; + kiapi.common.types.Vector2 size = 2; +} + // Describes a quantity of distance (size, length, etc). All coordinates are in nanometers. message Distance { diff --git a/common/api/api_utils.cpp b/common/api/api_utils.cpp index b66ffcc7fa..bd0808113e 100644 --- a/common/api/api_utils.cpp +++ b/common/api/api_utils.cpp @@ -66,18 +66,32 @@ types::LibraryIdentifier LibIdToProto( const LIB_ID& aId ) } -void PackVector2( kiapi::common::types::Vector2& aOutput, const VECTOR2I aInput ) +void PackVector2( types::Vector2& aOutput, const VECTOR2I& aInput ) { aOutput.set_x_nm( aInput.x ); aOutput.set_y_nm( aInput.y ); } + VECTOR2I UnpackVector2( const types::Vector2& aInput ) { return VECTOR2I( aInput.x_nm(), aInput.y_nm() ); } +void PackBox2( types::Box2& aOutput, const BOX2I& aInput ) +{ + PackVector2( *aOutput.mutable_position(), aInput.GetOrigin() ); + PackVector2( *aOutput.mutable_size(), aInput.GetSize() ); +} + + +BOX2I UnpackBox2( const types::Box2& aInput ) +{ + return BOX2I( UnpackVector2( aInput.position() ), UnpackVector2( aInput.size() ) ); +} + + void PackPolyLine( kiapi::common::types::PolyLine& aOutput, const SHAPE_LINE_CHAIN& aSlc ) { for( int vertex = 0; vertex < aSlc.PointCount(); vertex = aSlc.NextShape( vertex ) ) diff --git a/include/api/api_utils.h b/include/api/api_utils.h index 8abfb62527..005e4c718c 100644 --- a/include/api/api_utils.h +++ b/include/api/api_utils.h @@ -42,10 +42,14 @@ LIB_ID LibIdFromProto( const types::LibraryIdentifier& aId ); types::LibraryIdentifier LibIdToProto( const LIB_ID& aId ); -void PackVector2( kiapi::common::types::Vector2& aOutput, const VECTOR2I aInput ); +void PackVector2( types::Vector2& aOutput, const VECTOR2I& aInput ); VECTOR2I UnpackVector2( const types::Vector2& aInput ); +void PackBox2( types::Box2& aOutput, const BOX2I& aInput ); + +BOX2I UnpackBox2( const types::Box2& aInput ); + void PackPolyLine( kiapi::common::types::PolyLine& aOutput, const SHAPE_LINE_CHAIN& aSlc ); SHAPE_LINE_CHAIN UnpackPolyLine( const kiapi::common::types::PolyLine& aInput ); diff --git a/pcbnew/api/api_handler_pcb.cpp b/pcbnew/api/api_handler_pcb.cpp index 386c1a7831..9411ad7ca9 100644 --- a/pcbnew/api/api_handler_pcb.cpp +++ b/pcbnew/api/api_handler_pcb.cpp @@ -63,7 +63,9 @@ API_HANDLER_PCB::API_HANDLER_PCB( PCB_EDIT_FRAME* aFrame ) : registerHandler( &API_HANDLER_PCB::handleGetStackup ); registerHandler( &API_HANDLER_PCB::handleGetGraphicsDefaults ); - registerHandler( + registerHandler( + &API_HANDLER_PCB::handleGetBoundingBox ); + registerHandler( &API_HANDLER_PCB::handleGetTextExtents ); registerHandler( &API_HANDLER_PCB::handleGetPadShapeAsPolygon ); @@ -571,7 +573,48 @@ HANDLER_RESULT API_HANDLER_PCB::handleGetGraphicsDefau } -HANDLER_RESULT API_HANDLER_PCB::handleGetTextExtents( +HANDLER_RESULT API_HANDLER_PCB::handleGetBoundingBox( GetBoundingBox& aMsg, + const HANDLER_CONTEXT& aCtx ) +{ + if( std::optional busy = checkForBusy() ) + return tl::unexpected( *busy ); + + if( !validateItemHeaderDocument( aMsg.header() ) ) + { + ApiResponseStatus e; + // No message needed for AS_UNHANDLED; this is an internal flag for the API server + e.set_status( ApiStatusCode::AS_UNHANDLED ); + return tl::unexpected( e ); + } + + GetBoundingBoxResponse response; + bool includeText = aMsg.mode() == BoundingBoxMode::BBM_ITEM_AND_CHILD_TEXT; + + for( const types::KIID& idMsg : aMsg.items() ) + { + KIID id( idMsg.value() ); + std::optional optItem = getItemById( id ); + + if( !optItem ) + continue; + + BOARD_ITEM* item = *optItem; + BOX2I bbox; + + if( item->Type() == PCB_FOOTPRINT_T ) + bbox = static_cast( item )->GetBoundingBox( includeText ); + else + bbox = item->GetBoundingBox(); + + response.add_items()->set_value( idMsg.value() ); + PackBox2( *response.add_boxes(), bbox ); + } + + return response; +} + + +HANDLER_RESULT API_HANDLER_PCB::handleGetTextExtents( GetTextExtents& aMsg, const HANDLER_CONTEXT& aCtx ) { @@ -588,7 +631,7 @@ HANDLER_RESULT API_HANDLER_PCB::handleGetTextExte return tl::unexpected( e ); } - commands::BoundingBoxResponse response; + types::Box2 response; BOX2I bbox = text.GetTextBox(); EDA_ANGLE angle = text.GetTextAngle(); diff --git a/pcbnew/api/api_handler_pcb.h b/pcbnew/api/api_handler_pcb.h index 8c48483a2c..88fa320fe6 100644 --- a/pcbnew/api/api_handler_pcb.h +++ b/pcbnew/api/api_handler_pcb.h @@ -72,7 +72,10 @@ private: HANDLER_RESULT handleGetGraphicsDefaults( GetGraphicsDefaults& aMsg, const HANDLER_CONTEXT& aCtx ); - HANDLER_RESULT handleGetTextExtents( GetTextExtents& aMsg, + HANDLER_RESULT handleGetBoundingBox( commands::GetBoundingBox& aMsg, + const HANDLER_CONTEXT& aCtx ); + + HANDLER_RESULT handleGetTextExtents( GetTextExtents& aMsg, const HANDLER_CONTEXT& aCtx ); HANDLER_RESULT handleGetPadShapeAsPolygon( GetPadShapeAsPolygon& aMsg,