Unroll from PICKER_TOOL so we can handle amplitude/spacing events.

This commit is contained in:
Jeff Young 2023-10-11 14:43:54 +01:00
parent a57c9967f3
commit 1aeccc5895
2 changed files with 149 additions and 127 deletions

View File

@ -52,7 +52,8 @@ public:
}; };
PICKER_TOOL_BASE() : PICKER_TOOL_BASE() :
m_frame( nullptr ) m_frame( nullptr ),
m_snap( false )
{ {
reset(); reset();
} }

View File

@ -45,6 +45,7 @@
#include <tools/generator_tool.h> #include <tools/generator_tool.h>
#include <tools/pcb_picker_tool.h> #include <tools/pcb_picker_tool.h>
#include <tools/pcb_selection_tool.h> #include <tools/pcb_selection_tool.h>
#include <tools/zone_filler_tool.h>
#include <preview_items/draw_context.h> #include <preview_items/draw_context.h>
#include <view/view.h> #include <view/view.h>
@ -1162,13 +1163,22 @@ const wxString PCB_GENERATOR_MEANDERS::GENERATOR_TYPE = wxS( "meanders" );
int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent ) int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent )
{ {
PCB_PICKER_TOOL* picker = m_toolMgr->GetTool<PCB_PICKER_TOOL>(); if( m_inDrawingTool )
return 0;
REENTRANCY_GUARD guard( &m_inDrawingTool );
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
// Deactivate other tools; particularly important if another PICKER is currently running m_frame->PushTool( aEvent );
Activate(); Activate();
KIGFX::VIEW_CONTROLS* controls = getViewControls();
BOARD* board = m_frame->GetBoard();
PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide();
GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool<GENERATOR_TOOL>();
m_pickerItem = nullptr; m_pickerItem = nullptr;
m_meander = nullptr; m_meander = nullptr;
@ -1176,16 +1186,38 @@ int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent )
m_preview.Clear(); m_preview.Clear();
m_view->Add( &m_preview ); m_view->Add( &m_preview );
picker->SetCursor( KICURSOR::BULLSEYE ); auto setCursor =
[&]()
picker->SetClickHandler(
[this]( const VECTOR2D& aPosition ) -> bool
{ {
if( !m_pickerItem ) m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::BULLSEYE );
return true; // keep going (ignore click with no target) controls->ShowCursor( true );
};
GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool<GENERATOR_TOOL>(); // Set initial cursor
setCursor();
while( TOOL_EVENT* evt = Wait() )
{
setCursor();
VECTOR2D cursorPos = controls->GetMousePosition();
if( evt->IsCancelInteractive() || evt->IsActivate() )
{
if( m_meander )
{
// First click already made; clean up meander preview
m_meander->EditRevert( generatorTool, m_board, m_frame, nullptr );
m_preview.Clear();
delete m_meander;
m_meander = nullptr;
}
break;
}
else if( evt->IsClick( BUT_LEFT ) && m_pickerItem )
{
if( !m_meander ) if( !m_meander )
{ {
// First click; create a meander // First click; create a meander
@ -1200,12 +1232,11 @@ int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent )
int dummyClearance = std::numeric_limits<int>::max() / 2; int dummyClearance = std::numeric_limits<int>::max() / 2;
VECTOR2I closestPt; VECTOR2I closestPt;
m_pickerItem->GetEffectiveShape()->Collide( aPosition, dummyClearance, m_pickerItem->GetEffectiveShape()->Collide( cursorPos, dummyClearance,
&dummyDist, &closestPt ); &dummyDist, &closestPt );
m_meander->SetPosition( closestPt ); m_meander->SetPosition( closestPt );
m_preview.Add( m_meander ); m_preview.Add( m_meander );
return true; // keep going
} }
else else
{ {
@ -1214,34 +1245,26 @@ int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent )
m_meander->EditStart( generatorTool, m_board, m_frame, &commit ); m_meander->EditStart( generatorTool, m_board, m_frame, &commit );
m_meander->Update( generatorTool, m_board, m_frame, &commit ); m_meander->Update( generatorTool, m_board, m_frame, &commit );
m_meander->EditPush( generatorTool, m_board, m_frame, &commit, m_meander->EditPush( generatorTool, m_board, m_frame, &commit, _( "Place Meander" ) );
_( "Place Meander" ) );
return false; // exit picker tool break;
} }
} ); }
else if( evt->IsMotion() )
picker->SetMotionHandler(
[this]( const VECTOR2D& aPos )
{ {
BOARD* board = m_frame->GetBoard();
PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide();
GENERAL_COLLECTOR collector;
GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool<GENERATOR_TOOL>();
collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
collector.Collect( board, { PCB_TRACE_T, PCB_ARC_T }, aPos, guide );
if( collector.GetCount() > 1 )
selectionTool->GuessSelectionCandidates( collector, aPos );
BOARD_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
if( !m_meander ) if( !m_meander )
{ {
// First click not yet made; we're in highlight-net-under-cursor mode // First click not yet made; we're in highlight-net-under-cursor mode
GENERAL_COLLECTOR collector;
collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
collector.Collect( board, { PCB_TRACE_T, PCB_ARC_T }, cursorPos, guide );
if( collector.GetCount() > 1 )
selectionTool->GuessSelectionCandidates( collector, cursorPos );
BOARD_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr;
if( !m_pickerItem ) if( !m_pickerItem )
{ {
m_pickerItem = static_cast<BOARD_CONNECTED_ITEM*>( item ); m_pickerItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
@ -1257,7 +1280,7 @@ int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent )
{ {
// First click already made; we're in preview-meander mode // First click already made; we're in preview-meander mode
m_meander->SetEnd( aPos ); m_meander->SetEnd( cursorPos );
if( m_meander->GetPosition() != m_meander->GetEnd() ) if( m_meander->GetPosition() != m_meander->GetEnd() )
{ {
@ -1273,30 +1296,32 @@ int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent )
m_statusPopup->Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, 20 ) ); m_statusPopup->Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, 20 ) );
} }
} }
} );
picker->SetCancelHandler(
[this]()
{
GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool<GENERATOR_TOOL>();
if( m_meander )
{
// First click already made; clean up meander preview
m_meander->EditRevert( generatorTool, m_board, m_frame, nullptr );
m_preview.Clear();
delete m_meander;
m_meander = nullptr;
} }
} ); else if( evt->IsClick( BUT_RIGHT ) )
picker->SetFinalizeHandler(
[this]( const int& aFinalState )
{ {
PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>(); PCB_SELECTION dummy;
GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool<GENERATOR_TOOL>(); m_menu.ShowContextMenu( dummy );
}
// TODO: It'd be nice to be able to say "don't allow any non-trivial editing actions",
// but we don't at present have that, so we just knock out some of the egregious ones.
else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
{
wxBell();
}
else
{
evt->SetPassEvent();
}
controls->CaptureCursor( m_meander != nullptr );
controls->SetAutoPan( m_meander != nullptr );
}
controls->CaptureCursor( false );
controls->SetAutoPan( false );
controls->ForceCursorPosition( false );
controls->ShowCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
canvas()->SetStatusPopup( nullptr ); canvas()->SetStatusPopup( nullptr );
m_statusPopup->Hide(); m_statusPopup->Hide();
@ -1306,16 +1331,12 @@ int DRAWING_TOOL::PlaceMeander( const TOOL_EVENT& aEvent )
m_preview.Clear(); m_preview.Clear();
m_view->Remove( &m_preview ); m_view->Remove( &m_preview );
m_frame->GetCanvas()->Refresh();
if( m_meander ) if( m_meander )
selectionTool->AddItemToSel( m_meander ); selectionTool->AddItemToSel( m_meander );
// Ensure the cursor gets changed & updated m_frame->PopTool( aEvent );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_frame->GetCanvas()->Refresh();
} );
m_toolMgr->RunAction( ACTIONS::pickerTool, &aEvent );
return 0; return 0;
} }