From b662ff495640c99ef68033d55408247d0d383b7e Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 9 Oct 2023 15:22:16 +0100 Subject: [PATCH] Improve graphical feedback while placing a meander. --- pcbnew/board_commit.h | 3 +- pcbnew/generators/pcb_generator_meanders.cpp | 149 +++++++++++++++---- pcbnew/pcb_generator.cpp | 12 +- pcbnew/pcb_generator.h | 6 +- pcbnew/tools/drawing_tool.h | 6 + pcbnew/tools/generator_tool.cpp | 10 +- pcbnew/tools/pcb_actions.cpp | 4 +- 7 files changed, 144 insertions(+), 46 deletions(-) diff --git a/pcbnew/board_commit.h b/pcbnew/board_commit.h index f6532a895f..e9729becdc 100644 --- a/pcbnew/board_commit.h +++ b/pcbnew/board_commit.h @@ -54,8 +54,7 @@ public: BOARD* GetBoard() const; - virtual void Push( const wxString& aMessage = wxT( "A commit" ), - int aCommitFlags = 0 ) override; + virtual void Push( const wxString& aMessage = wxEmptyString, int aCommitFlags = 0 ) override; virtual void Revert() override; COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, diff --git a/pcbnew/generators/pcb_generator_meanders.cpp b/pcbnew/generators/pcb_generator_meanders.cpp index c8a3937d64..d1e1b1c345 100644 --- a/pcbnew/generators/pcb_generator_meanders.cpp +++ b/pcbnew/generators/pcb_generator_meanders.cpp @@ -25,12 +25,13 @@ #include #include -#include #include #include #include #include +#include +#include #include #include @@ -39,9 +40,10 @@ #include #include #include +#include +#include #include -#include #include #include @@ -208,7 +210,8 @@ public: void EditStart( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_EDIT_FRAME* aFrame, BOARD_COMMIT* aCommit ) override { - aCommit->Modify( this ); + if( aCommit ) + aCommit->Modify( this ); int layer = GetLayer(); PNS::ROUTER* router = aTool->Router(); @@ -572,10 +575,8 @@ public: // LINE does not have a separate remover, as LINEs are never truly a member of the tree for( PNS::LINKED_ITEM* li : line->Links() ) { - if( li->Parent() ) - { + if( li->Parent() && aCommit ) aCommit->Remove( li->Parent() ); - } } world->Remove( *line ); @@ -631,14 +632,12 @@ public: m_tuningInfo = placer->TuningInfo( aFrame->GetUserUnits() ); m_tuningStatus = placer->TuningStatus(); - if( !aCommit->Empty() ) - aCommit->Push( "Update meander" ); - return true; } void EditPush( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_EDIT_FRAME* aFrame, - BOARD_COMMIT* aCommit ) override + BOARD_COMMIT* aCommit, const wxString& aCommitMsg = wxEmptyString, + int aCommitFlags = 0 ) override { PNS::ROUTER* router = aTool->Router(); @@ -663,7 +662,7 @@ public: } } - aCommit->Push( "Meander edit", APPEND_UNDO ); + aCommit->Push( aCommitMsg, aCommitFlags ); } bool MakeEditPoints( std::shared_ptr points ) const override @@ -1026,29 +1025,129 @@ const wxString PCB_GENERATOR_MEANDERS::DISPLAY_NAME = _HKI( "Meanders" ); const wxString PCB_GENERATOR_MEANDERS::GENERATOR_TYPE = wxS( "meanders" ); +#define HITTEST_THRESHOLD_PIXELS 5 + + int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent ) { - VECTOR2I tableSize; + PCB_PICKER_TOOL* picker = m_toolMgr->GetTool(); - m_frame->SetActiveLayer( Edge_Cuts ); + m_toolMgr->RunAction( PCB_ACTIONS::selectionClear ); - std::vector preview; - std::vector items; + // Deactivate other tools; particularly important if another PICKER is currently running + Activate(); - PCB_SHAPE* circle = new PCB_SHAPE( nullptr, SHAPE_T::CIRCLE ); - circle->SetEnd( VECTOR2I( pcbIUScale.mmToIU( 2 ), 0 ) ); - circle->SetLayer( m_frame->GetActiveLayer() ); + m_pickerItem = nullptr; + m_meander = nullptr; - preview.push_back( circle ); + picker->SetCursor( KICURSOR::BULLSEYE ); - PCB_GENERATOR_MEANDERS* generator = new PCB_GENERATOR_MEANDERS( m_board ); + picker->SetClickHandler( + [this]( const VECTOR2D& aPosition ) -> bool + { + if( m_pickerItem ) + { + if( !m_meander ) + { + // First click; create a meander generator - items.push_back( generator ); + m_toolMgr->GetTool()->UnbrightenItem( m_pickerItem ); + m_frame->SetActiveLayer( m_pickerItem->GetLayer() ); - if( InteractivePlaceWithPreview( aEvent, items, preview, nullptr ) != -1 ) - { - m_toolMgr->RunAction( PCB_ACTIONS::regenerateItem, generator ); - } + m_meander = new PCB_GENERATOR_MEANDERS( m_board, m_pickerItem->GetLayer() ); + + int dummyDist; + int dummyClearance = std::numeric_limits::max() / 2; + VECTOR2I closestPt; + + m_pickerItem->GetEffectiveShape()->Collide( aPosition, dummyClearance, + &dummyDist, &closestPt ); + m_meander->SetPosition( closestPt ); + } + else + { + // Second click; we're done + BOARD_COMMIT commit( m_frame ); + GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool(); + + m_meander->EditStart( generatorTool, m_board, m_frame, &commit ); + m_meander->Update( generatorTool, m_board, m_frame, &commit ); + m_meander->EditPush( generatorTool, m_board, m_frame, &commit, + _( "Place Meander" ) ); + + return false; // exit picker tool + } + } + + return true; + } ); + + picker->SetMotionHandler( + [this]( const VECTOR2D& aPos ) + { + BOARD* board = m_frame->GetBoard(); + PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); + GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); + GENERAL_COLLECTOR collector; + + collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) ); + collector.Collect( board, { PCB_TRACE_T, PCB_ARC_T }, aPos, guide ); + + if( collector.GetCount() > 1 ) + selTool->GuessSelectionCandidates( collector, aPos ); + + BOARD_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr; + + if( !m_meander ) + { + // First click not yet made; we're in brighten-track-under-cursor mode + + if( m_pickerItem != item ) + { + if( m_pickerItem ) + selTool->UnbrightenItem( m_pickerItem ); + + m_pickerItem = item; + + if( m_pickerItem ) + selTool->BrightenItem( m_pickerItem ); + } + } + else + { + // First click alread made; we're in preview-meander mode + + m_meander->SetEnd( aPos ); + + if( m_meander->GetPosition() != m_meander->GetEnd() ) + { + GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool(); + + m_meander->EditStart( generatorTool, m_board, m_frame, nullptr ); + m_meander->Update( generatorTool, m_board, m_frame, nullptr ); + } + } + } ); + + picker->SetCancelHandler( + [this]() + { + if( m_pickerItem ) + m_toolMgr->GetTool()->UnbrightenItem( m_pickerItem ); + + delete m_meander; + m_meander = nullptr; + } ); + + picker->SetFinalizeHandler( + [this]( const int& aFinalState ) + { + // Ensure the cursor gets changed & updated + m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); + m_frame->GetCanvas()->Refresh(); + } ); + + m_toolMgr->RunAction( ACTIONS::pickerTool, &aEvent ); return 0; } diff --git a/pcbnew/pcb_generator.cpp b/pcbnew/pcb_generator.cpp index d5191df5ab..c51f351b99 100644 --- a/pcbnew/pcb_generator.cpp +++ b/pcbnew/pcb_generator.cpp @@ -47,15 +47,13 @@ void PCB_GENERATOR::EditStart( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_ED { aCommit->Modify( aItem ); } ); - - aCommit->Push( "Generator edit start" ); } void PCB_GENERATOR::EditPush( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_EDIT_FRAME* aFrame, - BOARD_COMMIT* aCommit ) + BOARD_COMMIT* aCommit, const wxString& aCommitMsg, int aCommitFlags ) { - aCommit->Push( "Generator edit end", APPEND_UNDO ); + aCommit->Push( aCommitMsg, aCommitFlags ); } @@ -120,12 +118,6 @@ const BOX2I PCB_GENERATOR::GetBoundingBox() const } -VECTOR2I PCB_GENERATOR::GetPosition() const -{ - return m_origin; -} - - void PCB_GENERATOR::Move( const VECTOR2I& aMoveVector ) { m_origin += aMoveVector; diff --git a/pcbnew/pcb_generator.h b/pcbnew/pcb_generator.h index 8b907c7b89..b06a354538 100644 --- a/pcbnew/pcb_generator.h +++ b/pcbnew/pcb_generator.h @@ -50,7 +50,8 @@ public: BOARD_COMMIT* aCommit ); virtual void EditPush( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_EDIT_FRAME* aFrame, - BOARD_COMMIT* aCommit ); + BOARD_COMMIT* aCommit, const wxString& aCommitMsg = wxEmptyString, + int aCommitFlags = 0 ); virtual void EditRevert( GENERATOR_TOOL* aTool, BOARD* aBoard, PCB_BASE_EDIT_FRAME* aFrame, BOARD_COMMIT* aCommit ); @@ -72,7 +73,8 @@ public: const BOX2I GetBoundingBox() const override; - VECTOR2I GetPosition() const override; + VECTOR2I GetPosition() const override { return m_origin; } + void SetPosition( const VECTOR2I& aPos ) override { m_origin = aPos; } void Move( const VECTOR2I& aMoveVector ) override; diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 9dc3fd568e..fa9975d725 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -43,6 +43,8 @@ class BOARD; class PCB_BASE_EDIT_FRAME; class PCB_SHAPE; class POLYGON_GEOM_MANAGER; +class PCB_GENERATOR_MEANDERS; + /** * Tool responsible for drawing graphical elements like lines, arcs, circles, etc. @@ -350,6 +352,10 @@ private: STROKE_PARAMS m_stroke; // Current stroke for multi-segment drawing TEXT_ATTRIBUTES m_textAttrs; + BOARD_ITEM* m_pickerItem; + PCB_GENERATOR_MEANDERS* m_meander; + + static const unsigned int WIDTH_STEP; // Amount of width change for one -/+ key press static const unsigned int COORDS_PADDING; // Padding from coordinates limits for this tool diff --git a/pcbnew/tools/generator_tool.cpp b/pcbnew/tools/generator_tool.cpp index 31dbe41794..13b8c36b2d 100644 --- a/pcbnew/tools/generator_tool.cpp +++ b/pcbnew/tools/generator_tool.cpp @@ -113,7 +113,7 @@ int GENERATOR_TOOL::RegenerateAll( const TOOL_EVENT& aEvent ) { gen->EditStart( this, board(), frame(), commit ); gen->Update( this, board(), frame(), commit ); - gen->EditPush( this, board(), frame(), commit ); + gen->EditPush( this, board(), frame(), commit, _( "Regenerate" ), APPEND_UNDO ); } return 0; @@ -140,7 +140,7 @@ int GENERATOR_TOOL::RegenerateOutdated( const TOOL_EVENT& aEvent ) { gen->EditStart( this, board(), frame(), commit ); gen->Update( this, board(), frame(), commit ); - gen->EditPush( this, board(), frame(), commit ); + gen->EditPush( this, board(), frame(), commit, _( "Regenerate Outdated" ), APPEND_UNDO ); } return 0; @@ -188,7 +188,7 @@ int GENERATOR_TOOL::RegenerateSelected( const TOOL_EVENT& aEvent ) { gen->EditStart( this, board(), frame(), commit ); gen->Update( this, board(), frame(), commit ); - gen->EditPush( this, board(), frame(), commit ); + gen->EditPush( this, board(), frame(), commit, _( "Regenerate Selected" ), APPEND_UNDO ); } return 0; @@ -207,7 +207,7 @@ int GENERATOR_TOOL::RegenerateItem( const TOOL_EVENT& aEvent ) gen->EditStart( this, board(), frame(), commit ); gen->Update( this, board(), frame(), commit ); - gen->EditPush( this, board(), frame(), commit ); + gen->EditPush( this, board(), frame(), commit, _( "Regenerate Item" ) ); return 0; } @@ -231,7 +231,7 @@ int GENERATOR_TOOL::GenEditAction( const TOOL_EVENT& aEvent ) } else if( aEvent.IsAction( &PCB_ACTIONS::genPushEdit ) ) { - gen->EditPush( this, board(), frame(), commit ); + gen->EditPush( this, board(), frame(), commit, wxEmptyString, APPEND_UNDO ); wxASSERT( commit->Empty() ); } diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index 5524dcef9f..52346c41e4 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -189,8 +189,8 @@ TOOL_ACTION PCB_ACTIONS::drawTextBox( TOOL_ACTION_ARGS() TOOL_ACTION PCB_ACTIONS::placeMeanders( TOOL_ACTION_ARGS() .Name( "pcbnew.InteractiveDrawing.placeMeanders" ) .Scope( AS_GLOBAL ) - .MenuText( _( "Add Meanders" ) ) - .Tooltip( _( "Add meanders for length tuning" ) ) + .MenuText( _( "Add Meander" ) ) + .Tooltip( _( "Add meander for length tuning" ) ) .Icon( BITMAPS::ps_tune_length ) .Flags( AF_ACTIVATE ) );