From 422be4badb8755e58af7d1034e9a8980c95e19f7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH] DXF drawing placement tool for GAL. --- pcbnew/tools/common_actions.cpp | 7 ++ pcbnew/tools/common_actions.h | 3 + pcbnew/tools/drawing_tool.cpp | 192 ++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 8 +- 4 files changed, 209 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index a1b6966a06..e8ac80fcef 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -109,6 +109,10 @@ TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.InteractiveDrawing.placePad", AS_GLOBAL, 0, "Add pads", "Add pads", AF_ACTIVATE ); +TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF", + AS_GLOBAL, 0, + "", "", AF_ACTIVATE ); + TOOL_ACTION COMMON_ACTIONS::setAnchor( "pcbnew.InteractiveDrawing.setAnchor", AS_GLOBAL, 0, "Place the footprint anchor", "Place the footprint anchor", @@ -358,6 +362,9 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_MODEDIT_PAD_TOOL: return COMMON_ACTIONS::placePad.MakeEvent(); + case ID_GEN_IMPORT_DXF_FILE: + return COMMON_ACTIONS::placeDXF.MakeEvent(); + case ID_MODEDIT_ANCHOR_TOOL: return COMMON_ACTIONS::setAnchor.MakeEvent(); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 2cd367c05d..2abaf054bd 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -99,6 +99,9 @@ public: /// Activation of the drawing tool (placing a PAD) static TOOL_ACTION placePad; + /// Activation of the drawing tool (placing a drawing from DXF file) + static TOOL_ACTION placeDXF; + /// Activation of the drawing tool (placing the footprint anchor) static TOOL_ACTION setAnchor; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index d3da87ce44..dda1d36b6e 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -700,6 +701,196 @@ int DRAWING_TOOL::PlacePad( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::PlaceDXF( TOOL_EVENT& aEvent ) +{ + DIALOG_DXF_IMPORT dlg( m_frame ); + int dlgResult = dlg.ShowModal(); + + const std::list& list = dlg.GetImportedItems(); + MODULE* module = m_board->m_Modules; + + if( dlgResult != wxID_OK || module == NULL || list.empty() ) + { + setTransitions(); + + return 0; + } + + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + VECTOR2I delta = cursorPos - (*list.begin())->GetPosition(); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + + // Build the undo list & add items to the current view + std::list::const_iterator it, itEnd; + for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) + { + BOARD_ITEM* item = *it; + BOARD_ITEM* converted = NULL; + + // Modules use different types for the same things, + // so we need to convert imported items to appropriate classes. + switch( item->Type() ) + { + case PCB_LINE_T: + { + if( m_editModules ) + { + converted = new EDGE_MODULE( module ); + *static_cast( converted ) = *static_cast( item ); + converted->Move( wxPoint( delta.x, delta.y ) ); + preview.Add( converted ); + delete item; + } + else + { + preview.Add( item ); + } + + break; + } + + case PCB_TEXT_T: + { + if( m_editModules ) + { + converted = new TEXTE_MODULE( module ); + *static_cast( converted ) = *static_cast( item ); + converted->Move( wxPoint( delta.x, delta.y ) ); + preview.Add( converted ); + delete item; + } + else + { + preview.Add( item ); + } + break; + } + + default: + assert( false ); // there is a type that is currently not handled here + break; + } + } + + BOARD_ITEM* firstItem = static_cast( *preview.Begin() ); + m_view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsMotion() ) + { + delta = cursorPos - firstItem->GetPosition(); + + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + static_cast( *it )->Move( wxPoint( delta.x, delta.y ) ); + + preview.ViewUpdate(); + } + + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + static_cast( *it )->Rotate( wxPoint( cursorPos.x, cursorPos.y ), + m_frame->GetRotationAngle() ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + static_cast( *it )->Flip( wxPoint( cursorPos.x, cursorPos.y ) ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsCancel() || evt->IsActivate() ) + { + preview.FreeItems(); + break; + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + // Place the drawing + + if( m_editModules ) + { + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + module->SetLastEditTime(); + + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + { + BOARD_ITEM* item = static_cast( *it ); + module->Add( item ); + + switch( item->Type() ) + { + case PCB_MODULE_TEXT_T: + static_cast( item )->SetLocalCoord(); + break; + + case PCB_MODULE_EDGE_T: + static_cast( item )->SetLocalCoord(); + break; + + default: + assert( false ); + break; + } + + m_view->Add( item ); + } + } + else + { + PICKED_ITEMS_LIST picklist; + + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + { + BOARD_ITEM* item = static_cast( *it ); + m_board->Add( item ); + + ITEM_PICKER itemWrapper( item, UR_NEW ); + picklist.PushItem( itemWrapper ); + + m_view->Add( item ); + } + + m_frame->SaveCopyInUndoList( picklist, UR_NEW ); + } + + m_frame->OnModify(); + + break; + } + } + + preview.Clear(); + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + int DRAWING_TOOL::SetAnchor( TOOL_EVENT& aEvent ) { assert( m_editModules ); @@ -1580,5 +1771,6 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); Go( &DRAWING_TOOL::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() ); Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 293674a81f..b1bc2675b3 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -122,10 +122,16 @@ public: /** * Function PlacePad() - * Places a pad in the module editor. + * Places a pad in module editor. */ int PlacePad( TOOL_EVENT& aEvent ); + /** + * Function PlaceDXF() + * Places a drawing imported from a DXF file in module editor. + */ + int PlaceDXF( TOOL_EVENT& aEvent ); + /** * Function SetAnchor() * Places the footprint anchor (only in module editor).