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,146 +1186,157 @@ 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();
if( !m_meander ) while( TOOL_EVENT* evt = Wait() )
{ {
// First click; create a meander setCursor();
VECTOR2D cursorPos = controls->GetMousePosition();
generatorTool->HighlightNet( nullptr ); if( evt->IsCancelInteractive() || evt->IsActivate() )
{
m_frame->SetActiveLayer( m_pickerItem->GetLayer() ); if( m_meander )
m_meander = PCB_GENERATOR_MEANDERS::CreateNew( generatorTool, m_frame,
m_pickerItem );
int dummyDist;
int dummyClearance = std::numeric_limits<int>::max() / 2;
VECTOR2I closestPt;
m_pickerItem->GetEffectiveShape()->Collide( aPosition, dummyClearance,
&dummyDist, &closestPt );
m_meander->SetPosition( closestPt );
m_preview.Add( m_meander );
return true; // keep going
}
else
{
// Second click; we're done
BOARD_COMMIT commit( m_frame );
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
}
} );
picker->SetMotionHandler(
[this]( const VECTOR2D& aPos )
{ {
BOARD* board = m_frame->GetBoard(); // First click already made; clean up meander preview
PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>(); m_meander->EditRevert( generatorTool, m_board, m_frame, nullptr );
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 ) ); m_preview.Clear();
collector.Collect( board, { PCB_TRACE_T, PCB_ARC_T }, aPos, guide );
if( collector.GetCount() > 1 ) delete m_meander;
selectionTool->GuessSelectionCandidates( collector, aPos ); m_meander = nullptr;
}
BOARD_ITEM* item = collector.GetCount() == 1 ? collector[ 0 ] : nullptr; break;
}
if( !m_meander ) else if( evt->IsClick( BUT_LEFT ) && m_pickerItem )
{ {
// First click not yet made; we're in highlight-net-under-cursor mode if( !m_meander )
if( !m_pickerItem )
{
m_pickerItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
generatorTool->HighlightNet( m_pickerItem );
}
else
{
m_pickerItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
generatorTool->UpdateHighlightedNet( m_pickerItem );
}
}
else
{
// First click already made; we're in preview-meander mode
m_meander->SetEnd( aPos );
if( m_meander->GetPosition() != m_meander->GetEnd() )
{
m_meander->EditStart( generatorTool, m_board, m_frame, nullptr );
m_meander->Update( generatorTool, m_board, m_frame, nullptr );
m_statusPopup->Popup();
canvas()->SetStatusPopup( m_statusPopup.get() );
m_view->Update( &m_preview );
m_meander->UpdateStatus( generatorTool, m_frame, m_statusPopup.get() );
m_statusPopup->Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, 20 ) );
}
}
} );
picker->SetCancelHandler(
[this]()
{ {
GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool<GENERATOR_TOOL>(); // First click; create a meander
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;
}
} );
picker->SetFinalizeHandler(
[this]( const int& aFinalState )
{
PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
GENERATOR_TOOL* generatorTool = m_toolMgr->GetTool<GENERATOR_TOOL>();
canvas()->SetStatusPopup( nullptr );
m_statusPopup->Hide();
generatorTool->HighlightNet( nullptr ); generatorTool->HighlightNet( nullptr );
m_preview.Clear(); m_frame->SetActiveLayer( m_pickerItem->GetLayer() );
m_view->Remove( &m_preview ); m_meander = PCB_GENERATOR_MEANDERS::CreateNew( generatorTool, m_frame,
m_pickerItem );
if( m_meander ) int dummyDist;
selectionTool->AddItemToSel( m_meander ); int dummyClearance = std::numeric_limits<int>::max() / 2;
VECTOR2I closestPt;
// Ensure the cursor gets changed & updated m_pickerItem->GetEffectiveShape()->Collide( cursorPos, dummyClearance,
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); &dummyDist, &closestPt );
m_frame->GetCanvas()->Refresh(); m_meander->SetPosition( closestPt );
} );
m_toolMgr->RunAction( ACTIONS::pickerTool, &aEvent ); m_preview.Add( m_meander );
}
else
{
// Second click; we're done
BOARD_COMMIT commit( m_frame );
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" ) );
break;
}
}
else if( evt->IsMotion() )
{
if( !m_meander )
{
// 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 )
{
m_pickerItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
generatorTool->HighlightNet( m_pickerItem );
}
else
{
m_pickerItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
generatorTool->UpdateHighlightedNet( m_pickerItem );
}
}
else
{
// First click already made; we're in preview-meander mode
m_meander->SetEnd( cursorPos );
if( m_meander->GetPosition() != m_meander->GetEnd() )
{
m_meander->EditStart( generatorTool, m_board, m_frame, nullptr );
m_meander->Update( generatorTool, m_board, m_frame, nullptr );
m_statusPopup->Popup();
canvas()->SetStatusPopup( m_statusPopup.get() );
m_view->Update( &m_preview );
m_meander->UpdateStatus( generatorTool, m_frame, m_statusPopup.get() );
m_statusPopup->Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, 20 ) );
}
}
}
else if( evt->IsClick( BUT_RIGHT ) )
{
PCB_SELECTION dummy;
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 );
m_statusPopup->Hide();
generatorTool->HighlightNet( nullptr );
m_preview.Clear();
m_view->Remove( &m_preview );
m_frame->GetCanvas()->Refresh();
if( m_meander )
selectionTool->AddItemToSel( m_meander );
m_frame->PopTool( aEvent );
return 0; return 0;
} }