Bring PICKER_TOOL in line with other tools.
Use standard Magnetize() to handle grid and magnetic pads. Use the standard menu from PCB_TOOL. Delegating the menu to the SELECTION_TOOL just caused grief. Also brings clients (such as Position Relative To) into line, and implements better Cancel behaviour. Also improves visibility of modal status messages: - moves Select Anchor message from status bar to popup - moves Select Reference message from dialog to popup Fixes: lp:1786727 * https://bugs.launchpad.net/kicad/+bug/1786727
This commit is contained in:
parent
24149a87fa
commit
30bb911154
|
@ -101,6 +101,8 @@ void STATUS_POPUP::onExpire( wxTimerEvent& aEvent )
|
|||
STATUS_TEXT_POPUP::STATUS_TEXT_POPUP( EDA_DRAW_FRAME* aParent ) :
|
||||
STATUS_POPUP( aParent )
|
||||
{
|
||||
m_panel->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNSHADOW ) );
|
||||
|
||||
m_statusLine = new wxStaticText( m_panel, wxID_ANY, wxEmptyString ) ;
|
||||
m_topSizer->Add( m_statusLine, 1, wxALL | wxEXPAND, 5 );
|
||||
}
|
||||
|
|
|
@ -30,12 +30,12 @@
|
|||
DIALOG_POSITION_RELATIVE::POSITION_RELATIVE_OPTIONS DIALOG_POSITION_RELATIVE::m_options;
|
||||
|
||||
|
||||
DIALOG_POSITION_RELATIVE::DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, TOOL_MANAGER* toolMgr,
|
||||
wxPoint& translation, wxPoint& anchorPosition ) :
|
||||
DIALOG_POSITION_RELATIVE::DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, wxPoint& translation,
|
||||
wxPoint& anchor ) :
|
||||
DIALOG_POSITION_RELATIVE_BASE( aParent ),
|
||||
m_toolMgr( toolMgr ),
|
||||
m_toolMgr( aParent->GetToolManager() ),
|
||||
m_translation( translation ),
|
||||
m_anchor_position( anchorPosition ),
|
||||
m_anchor_position( anchor ),
|
||||
m_xOffset( aParent, m_xLabel, m_xEntry, m_xUnit ),
|
||||
m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit )
|
||||
{
|
||||
|
@ -115,7 +115,6 @@ void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
|
|||
m_xOffset.SetValue( KiROUND( val.x / 10.0 ) * 10 );
|
||||
m_yOffset.SetValue( KiROUND( val.y / 10.0 ) * 10 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,25 +156,25 @@ void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event )
|
|||
|
||||
POSITION_RELATIVE_TOOL* posrelTool = m_toolMgr->GetTool<POSITION_RELATIVE_TOOL>();
|
||||
wxASSERT( posrelTool );
|
||||
|
||||
m_referenceInfo->SetLabel( _( "Reference item: <click item on canvas to select>" ) );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectpositionRelativeItem, true );
|
||||
|
||||
Hide();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_POSITION_RELATIVE::UpdateAnchor( BOARD_ITEM* aItem )
|
||||
void DIALOG_POSITION_RELATIVE::UpdateAnchor( EDA_ITEM* aItem )
|
||||
{
|
||||
wxString reference = _( "<none selected>" );
|
||||
|
||||
if( aItem )
|
||||
{
|
||||
m_anchor_position = aItem->GetPosition();
|
||||
m_anchor_position = dynamic_cast<BOARD_ITEM*>( aItem )->GetPosition();
|
||||
reference = aItem->GetSelectMenuText( GetUserUnits() );
|
||||
}
|
||||
|
||||
m_referenceInfo->SetLabel( _( "Reference item: " ) + reference );
|
||||
|
||||
Raise(); // required at least on OSX
|
||||
Show( true );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,11 +45,10 @@ private:
|
|||
|
||||
public:
|
||||
// Constructor and destructor
|
||||
DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, TOOL_MANAGER* toolMgr,
|
||||
wxPoint& translation, wxPoint& anchorposition );
|
||||
DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, wxPoint& translation, wxPoint& anchor );
|
||||
~DIALOG_POSITION_RELATIVE() { };
|
||||
|
||||
void UpdateAnchor( BOARD_ITEM* aItem );
|
||||
void UpdateAnchor( EDA_ITEM* aItem );
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -24,13 +24,6 @@
|
|||
#include "pns_router.h"
|
||||
#include "pns_meander_placer.h"
|
||||
|
||||
PNS_TUNE_STATUS_POPUP::PNS_TUNE_STATUS_POPUP( EDA_DRAW_FRAME* aParent ) :
|
||||
STATUS_TEXT_POPUP( aParent )
|
||||
{
|
||||
m_panel->SetBackgroundColour( wxColour( 64, 64, 64 ) );
|
||||
}
|
||||
|
||||
|
||||
void PNS_TUNE_STATUS_POPUP::UpdateStatus( PNS::ROUTER* aRouter )
|
||||
{
|
||||
PNS::MEANDER_PLACER_BASE* placer = dynamic_cast<PNS::MEANDER_PLACER_BASE*>( aRouter->Placer() );
|
||||
|
|
|
@ -37,7 +37,9 @@ class ROUTER;
|
|||
class PNS_TUNE_STATUS_POPUP : public STATUS_TEXT_POPUP
|
||||
{
|
||||
public:
|
||||
PNS_TUNE_STATUS_POPUP( EDA_DRAW_FRAME* aParent );
|
||||
PNS_TUNE_STATUS_POPUP( EDA_DRAW_FRAME* aParent ) :
|
||||
STATUS_TEXT_POPUP( aParent )
|
||||
{ }
|
||||
|
||||
void UpdateStatus( PNS::ROUTER* aRouter );
|
||||
};
|
||||
|
|
|
@ -192,11 +192,6 @@ private:
|
|||
GRAPHIC_POLYGON
|
||||
};
|
||||
|
||||
///> Shows the context menu for the drawing tool
|
||||
///> This menu consists of normal UI functions (zoom, grid, etc)
|
||||
///> And any suitable global functions for the active drawing type.
|
||||
void showContextMenu();
|
||||
|
||||
///> Starts drawing a selected shape (i.e. DRAWSEGMENT).
|
||||
///> @param aShape is the type of created shape (@see STROKE_T).
|
||||
///> @param aGraphic is an object that is going to be used by the tool for drawing. It has to
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include <footprint_edit_frame.h>
|
||||
#include <array_creator.h>
|
||||
#include <pcbnew_id.h>
|
||||
|
||||
#include <status_popup.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <view/view.h>
|
||||
|
@ -83,22 +83,6 @@ TOOL_ACTION PCB_ACTIONS::editFootprintInFpEditor( "pcbnew.InteractiveEdit.editFo
|
|||
_( "Opens the selected footprint in the Footprint Editor" ),
|
||||
module_editor_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::copyPadToSettings( "pcbnew.InteractiveEdit.copyPadToSettings",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Copy Pad Properties to Default Pad Properties" ),
|
||||
_( "Copies the properties of the selected pad to the default pad properties." ) );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::copySettingsToPads( "pcbnew.InteractiveEdit.copySettingsToPads",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Copy Default Pad Properties to Pads" ),
|
||||
_( "Copies the default pad properties to the selected pad(s)." ) );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::globalEditPads( "pcbnew.InteractiveEdit.globalPadEdit",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Push Pad Settings..." ),
|
||||
_( "Copies the selected pad's properties to all pads in its footprint (or similar footprints)." ),
|
||||
push_pad_settings_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::editActivate( "pcbnew.InteractiveEdit",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Edit Activate" ), "", move_xpm, AF_ACTIVATE );
|
||||
|
@ -1395,47 +1379,66 @@ int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
|
|||
|
||||
bool EDIT_TOOL::pickCopyReferencePoint( VECTOR2I& aP )
|
||||
{
|
||||
STATUS_TEXT_POPUP statusPopup( frame() );
|
||||
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||
assert( picker );
|
||||
bool picking = true;
|
||||
bool retVal = true;
|
||||
|
||||
statusPopup.SetText( _( "Select reference point for the copy..." ) );
|
||||
picker->Activate();
|
||||
picker->SetClickHandler( [&]( const VECTOR2D& aPoint ) -> bool
|
||||
{
|
||||
aP = aPoint;
|
||||
statusPopup.SetText( _( "Selection copied." ) );
|
||||
statusPopup.Expire( 800 );
|
||||
picking = false;
|
||||
return false; // we don't need any more points
|
||||
} );
|
||||
picker->SetCancelHandler( [&]()
|
||||
{
|
||||
statusPopup.SetText( _( "Copy cancelled." ) );
|
||||
statusPopup.Expire( 800 );
|
||||
picking = false;
|
||||
retVal = false;
|
||||
} );
|
||||
|
||||
while ( picker->IsPicking() )
|
||||
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
|
||||
statusPopup.Popup();
|
||||
|
||||
while( picking )
|
||||
{
|
||||
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
|
||||
Wait();
|
||||
}
|
||||
|
||||
if( !picker->GetPoint() )
|
||||
return false;
|
||||
|
||||
aP = *picker->GetPoint();
|
||||
return true;
|
||||
statusPopup.Hide();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
|
||||
int EDIT_TOOL::doCopyToClipboard( bool withAnchor )
|
||||
{
|
||||
CLIPBOARD_IO io;
|
||||
VECTOR2I refPoint;
|
||||
|
||||
Activate();
|
||||
|
||||
auto item1 = MSG_PANEL_ITEM( "", _( "Select reference point for the block being copied..." ),
|
||||
COLOR4D::BLACK );
|
||||
|
||||
std::vector<MSG_PANEL_ITEM> msgItems = { item1 };
|
||||
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 1;
|
||||
|
||||
frame()->SetMsgPanel( msgItems );
|
||||
bool rv = pickCopyReferencePoint( refPoint );
|
||||
frame()->SetMsgPanel( board() );
|
||||
if( withAnchor )
|
||||
{
|
||||
VECTOR2I refPoint;
|
||||
bool rv = pickCopyReferencePoint( refPoint );
|
||||
frame()->SetMsgPanel( board() );
|
||||
|
||||
if( !rv )
|
||||
return 1;
|
||||
if( !rv )
|
||||
return 1;
|
||||
|
||||
selection.SetReferencePoint( refPoint );
|
||||
}
|
||||
|
||||
selection.SetReferencePoint( refPoint );
|
||||
io.SetBoard( board() );
|
||||
io.SaveSelection( selection );
|
||||
|
||||
|
@ -1443,6 +1446,18 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return doCopyToClipboard( true );
|
||||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::copyToClipboardWithAnchor( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return doCopyToClipboard( true );
|
||||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::cutToClipboard( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( !copyToClipboard( aEvent ) )
|
||||
|
|
|
@ -168,6 +168,10 @@ public:
|
|||
*/
|
||||
int copyToClipboard( const TOOL_EVENT& aEvent );
|
||||
|
||||
int copyToClipboardWithAnchor( const TOOL_EVENT& aEvent );
|
||||
|
||||
int doCopyToClipboard( bool withAnchor );
|
||||
|
||||
/**
|
||||
* Function cutToClipboard()
|
||||
* Cuts the current selection to the clipboard by formatting it as a fake pcb
|
||||
|
|
|
@ -402,9 +402,6 @@ public:
|
|||
static TOOL_ACTION findMove;
|
||||
|
||||
static TOOL_ACTION editFootprintInFpEditor;
|
||||
static TOOL_ACTION copyPadToSettings;
|
||||
static TOOL_ACTION copySettingsToPads;
|
||||
static TOOL_ACTION globalEditPads;
|
||||
|
||||
|
||||
///> @copydoc COMMON_ACTIONS::TranslateLegacyId()
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "picker_tool.h"
|
||||
#include "pcb_actions.h"
|
||||
#include "grid_helper.h"
|
||||
|
||||
#include <pcbnew_id.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
@ -33,6 +33,10 @@
|
|||
#include "selection_tool.h"
|
||||
|
||||
|
||||
extern bool Magnetize( PCB_BASE_EDIT_FRAME* frame, int aCurrentTool,
|
||||
wxSize aGridSize, wxPoint on_grid, wxPoint* curpos );
|
||||
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::pickerTool( "pcbnew.Picker", AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE );
|
||||
|
||||
|
||||
|
@ -43,51 +47,34 @@ PICKER_TOOL::PICKER_TOOL()
|
|||
}
|
||||
|
||||
|
||||
bool PICKER_TOOL::Init()
|
||||
{
|
||||
auto activeToolCondition = [ this ] ( const SELECTION& aSel ) {
|
||||
return ( frame()->GetToolId() != ID_NO_TOOL_SELECTED );
|
||||
};
|
||||
|
||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
|
||||
// We delegate our context menu to the Selection tool, so make sure it has a
|
||||
// "Cancel" item at the top.
|
||||
if( selTool )
|
||||
{
|
||||
auto& toolMenu = selTool->GetToolMenu();
|
||||
auto& menu = toolMenu.GetMenu();
|
||||
|
||||
menu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1000 );
|
||||
menu.AddSeparator( activeToolCondition, 1000 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||
GRID_HELPER grid( frame() );
|
||||
|
||||
assert( !m_picking );
|
||||
m_picking = true;
|
||||
m_picked = NULLOPT;
|
||||
|
||||
setControls();
|
||||
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
auto mousePos = controls->GetMousePosition();
|
||||
auto p = grid.BestSnapAnchor( mousePos, nullptr );
|
||||
controls->ForceCursorPosition( true, p );
|
||||
// TODO: magnetic pad & track processing needs to move to VIEW_CONTROLS.
|
||||
wxPoint pos( controls->GetMousePosition().x, controls->GetMousePosition().y );
|
||||
frame()->SetMousePosition( pos );
|
||||
|
||||
wxRealPoint gridSize = frame()->GetScreen()->GetGridSize();
|
||||
wxSize igridsize;
|
||||
igridsize.x = KiROUND( gridSize.x );
|
||||
igridsize.y = KiROUND( gridSize.y );
|
||||
|
||||
if( Magnetize( frame(), ID_PCB_HIGHLIGHT_BUTT, igridsize, pos, &pos ) )
|
||||
controls->ForceCursorPosition( true, pos );
|
||||
else
|
||||
controls->ForceCursorPosition( false );
|
||||
|
||||
if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
bool getNext = false;
|
||||
|
||||
m_picked = VECTOR2D( p );
|
||||
m_picked = VECTOR2D( controls->GetCursorPosition() );
|
||||
|
||||
if( m_clickHandler )
|
||||
{
|
||||
|
@ -109,7 +96,24 @@ int PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
else if( evt->IsCancel() || TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
|
||||
{
|
||||
if( m_cancelHandler )
|
||||
{
|
||||
try
|
||||
{
|
||||
(*m_cancelHandler)();
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
std::cerr << "PICKER_TOOL cancel handler error: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
m_menu.ShowContextMenu();
|
||||
|
||||
else
|
||||
m_toolMgr->PassEvent();
|
||||
|
@ -136,8 +140,9 @@ void PICKER_TOOL::reset()
|
|||
m_cursorCapture = false;
|
||||
m_autoPanning = false;
|
||||
|
||||
m_picking = false;
|
||||
m_picked = NULLOPT;
|
||||
m_clickHandler = NULLOPT;
|
||||
m_cancelHandler = NULLOPT;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,11 +37,9 @@ public:
|
|||
PICKER_TOOL();
|
||||
~PICKER_TOOL() {}
|
||||
|
||||
///> Mouse event click handler type.
|
||||
///> Event handler types.
|
||||
typedef std::function<bool(const VECTOR2D&)> CLICK_HANDLER;
|
||||
|
||||
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||
bool Init() override;
|
||||
typedef std::function<void(void)> CANCEL_HANDLER;
|
||||
|
||||
///> @copydoc TOOL_INTERACTIVE::Reset()
|
||||
void Reset( RESET_REASON aReason ) override {}
|
||||
|
@ -73,22 +71,6 @@ public:
|
|||
*/
|
||||
inline void SetCursorCapture( bool aEnable ) { m_cursorCapture = aEnable; }
|
||||
|
||||
/**
|
||||
* Function GetPoint()
|
||||
* Returns picked point.
|
||||
*/
|
||||
inline OPT<VECTOR2D> GetPoint() const
|
||||
{
|
||||
assert( !m_picking );
|
||||
return m_picked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IsPicking()
|
||||
* Returns information whether the tool is still active.
|
||||
*/
|
||||
bool IsPicking() const { return m_picking; }
|
||||
|
||||
/**
|
||||
* Function SetClickHandler()
|
||||
* Sets a handler for mouse click event. Handler may decide to receive further click by
|
||||
|
@ -100,6 +82,16 @@ public:
|
|||
m_clickHandler = aHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetCancelHandler()
|
||||
* Sets a handler for cancel events (ESC or context-menu Cancel).
|
||||
*/
|
||||
inline void SetCancelHandler( CANCEL_HANDLER aHandler )
|
||||
{
|
||||
assert( !m_cancelHandler );
|
||||
m_cancelHandler = aHandler;
|
||||
}
|
||||
|
||||
///> @copydoc TOOL_INTERACTIVE::setTransitions();
|
||||
void setTransitions() override;
|
||||
|
||||
|
@ -110,15 +102,13 @@ private:
|
|||
bool m_cursorCapture;
|
||||
bool m_autoPanning;
|
||||
|
||||
///> Optional mouse click event handler.
|
||||
///> Optional event handlers.
|
||||
OPT<CLICK_HANDLER> m_clickHandler;
|
||||
OPT<CANCEL_HANDLER> m_cancelHandler;
|
||||
|
||||
///> Picked point (if any).
|
||||
OPT<VECTOR2D> m_picked;
|
||||
|
||||
///> Activity status.
|
||||
bool m_picking;
|
||||
|
||||
///> Reinitializes tool to its initial state.
|
||||
void reset();
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ using namespace std::placeholders;
|
|||
#include "picker_tool.h"
|
||||
|
||||
#include <dialogs/dialog_position_relative.h>
|
||||
|
||||
#include <status_popup.h>
|
||||
#include <board_commit.h>
|
||||
#include <hotkeys.h>
|
||||
#include <bitmaps.h>
|
||||
|
@ -54,7 +54,7 @@ TOOL_ACTION PCB_ACTIONS::selectpositionRelativeItem(
|
|||
|
||||
POSITION_RELATIVE_TOOL::POSITION_RELATIVE_TOOL() :
|
||||
PCB_TOOL( "pcbnew.PositionRelative" ),
|
||||
m_position_relative_dialog( NULL ),
|
||||
m_dialog( NULL ),
|
||||
m_selectionTool( NULL ),
|
||||
m_anchor_item( NULL )
|
||||
{
|
||||
|
@ -71,16 +71,9 @@ void POSITION_RELATIVE_TOOL::Reset( RESET_REASON aReason )
|
|||
bool POSITION_RELATIVE_TOOL::Init()
|
||||
{
|
||||
// Find the selection tool, so they can cooperate
|
||||
m_selectionTool =
|
||||
static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
|
||||
m_selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
|
||||
if( !m_selectionTool )
|
||||
{
|
||||
DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return m_selectionTool != nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,55 +88,28 @@ int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
|
|||
|
||||
const auto& selection = m_selectionTool->RequestSelection( filter );
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED || selection.Empty() )
|
||||
return 0;
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
m_selection = selection;
|
||||
|
||||
m_position_relative_selection = selection;
|
||||
if( !m_dialog )
|
||||
m_dialog = new DIALOG_POSITION_RELATIVE( editFrame, m_translation, m_anchor );
|
||||
|
||||
if( !m_position_relative_dialog )
|
||||
m_position_relative_dialog = new DIALOG_POSITION_RELATIVE( editFrame,
|
||||
m_toolMgr,
|
||||
m_position_relative_translation,
|
||||
m_anchor_position );
|
||||
|
||||
m_position_relative_dialog->Show( true );
|
||||
m_dialog->Show( true );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static bool selectPRitem( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
||||
int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint anchor, wxPoint relativePosition,
|
||||
double rotation )
|
||||
{
|
||||
SELECTION_TOOL* selectionTool = aToolMgr->GetTool<SELECTION_TOOL>();
|
||||
POSITION_RELATIVE_TOOL* positionRelativeTool = aToolMgr->GetTool<POSITION_RELATIVE_TOOL>();
|
||||
wxCHECK( selectionTool, false );
|
||||
wxCHECK( positionRelativeTool, false );
|
||||
|
||||
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
const SELECTION& selection = selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
|
||||
if( selection.Empty() )
|
||||
return true;
|
||||
|
||||
positionRelativeTool->UpdateAnchor( static_cast<BOARD_ITEM*>( selection.Front() ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint anchorPosition,
|
||||
wxPoint relativePosition,
|
||||
double rotation )
|
||||
{
|
||||
VECTOR2I rp = m_position_relative_selection.GetCenter();
|
||||
VECTOR2I rp = m_selection.GetCenter();
|
||||
wxPoint rotPoint( rp.x, rp.y );
|
||||
wxPoint translation = anchorPosition + relativePosition - rotPoint;
|
||||
wxPoint translation = anchor + relativePosition - rotPoint;
|
||||
|
||||
for( auto item : m_position_relative_selection )
|
||||
for( auto item : m_selection )
|
||||
{
|
||||
m_commit->Modify( item );
|
||||
|
||||
|
@ -153,7 +119,7 @@ int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint anchorPosition,
|
|||
|
||||
m_commit->Push( _( "Position Relative" ) );
|
||||
|
||||
if( m_position_relative_selection.IsHover() )
|
||||
if( m_selection.IsHover() )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
||||
|
@ -166,26 +132,54 @@ int POSITION_RELATIVE_TOOL::SelectPositionRelativeItem( const TOOL_EVENT& aEvent
|
|||
Activate();
|
||||
|
||||
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||
assert( picker );
|
||||
STATUS_TEXT_POPUP statusPopup( frame() );
|
||||
bool picking = true;
|
||||
|
||||
statusPopup.SetText( _( "Select reference item..." ) );
|
||||
picker->SetSnapping( false );
|
||||
picker->SetClickHandler( std::bind( selectPRitem, m_toolMgr, _1 ) );
|
||||
picker->Activate();
|
||||
Wait();
|
||||
|
||||
picker->SetClickHandler( [&]( const VECTOR2D& aPoint ) -> bool
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
const SELECTION& sel = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
|
||||
if( sel.Empty() )
|
||||
return true; // still looking for an item
|
||||
|
||||
m_anchor_item = sel.Front();
|
||||
statusPopup.Hide();
|
||||
|
||||
if( m_dialog )
|
||||
m_dialog->UpdateAnchor( sel.Front() );
|
||||
|
||||
picking = false;
|
||||
return false; // got our item; don't need any more
|
||||
} );
|
||||
|
||||
picker->SetCancelHandler( [&]()
|
||||
{
|
||||
statusPopup.Hide();
|
||||
|
||||
if( m_dialog )
|
||||
m_dialog->UpdateAnchor( m_anchor_item );
|
||||
|
||||
picking = false;
|
||||
} );
|
||||
|
||||
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
|
||||
statusPopup.Popup();
|
||||
|
||||
while( picking )
|
||||
{
|
||||
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
|
||||
Wait();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void POSITION_RELATIVE_TOOL::UpdateAnchor( BOARD_ITEM* aItem )
|
||||
{
|
||||
m_anchor_item = aItem;
|
||||
|
||||
if( m_position_relative_dialog )
|
||||
m_position_relative_dialog->UpdateAnchor( aItem );
|
||||
}
|
||||
|
||||
|
||||
void POSITION_RELATIVE_TOOL::setTransitions()
|
||||
{
|
||||
Go( &POSITION_RELATIVE_TOOL::PositionRelative, PCB_ACTIONS::positionRelative.MakeEvent() );
|
||||
|
|
|
@ -72,47 +72,24 @@ public:
|
|||
* Positions the m_position_relative_selection selection relative to anchorpostion using the given translation and rotation.
|
||||
* Rotation is around the center of the selection.
|
||||
*/
|
||||
int RelativeItemSelectionMove( wxPoint anchorposition, wxPoint translation, double rotation );
|
||||
|
||||
/**
|
||||
* Function GetAnchorItem()
|
||||
*
|
||||
* Gets the last selected anchor item.
|
||||
*/
|
||||
BOARD_ITEM* GetAnchorItem()
|
||||
{
|
||||
return m_anchor_item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function UpdateAnchor()
|
||||
*
|
||||
* Selects the item to be used as the reference for relative move operation.
|
||||
*/
|
||||
void UpdateAnchor( BOARD_ITEM* aItem );
|
||||
int RelativeItemSelectionMove( wxPoint anchor, wxPoint translation, double rotation );
|
||||
|
||||
///> Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
private:
|
||||
DIALOG_POSITION_RELATIVE* m_position_relative_dialog;
|
||||
DIALOG_POSITION_RELATIVE* m_dialog;
|
||||
|
||||
///> Selection tool used for obtaining selected items
|
||||
SELECTION_TOOL* m_selectionTool;
|
||||
SELECTION m_selection;
|
||||
|
||||
std::unique_ptr<BOARD_COMMIT> m_commit;
|
||||
|
||||
///> Last anchor item selected by Position Relative To function.
|
||||
BOARD_ITEM* m_anchor_item;
|
||||
EDA_ITEM* m_anchor_item;
|
||||
wxPoint m_anchor;
|
||||
|
||||
///> Translation for Position Relative To function.
|
||||
wxPoint m_position_relative_translation;
|
||||
|
||||
///> Anchor position for Position Relative To function.
|
||||
wxPoint m_anchor_position;
|
||||
|
||||
///> Selection that will be moved by Position Relative To function.
|
||||
SELECTION m_position_relative_selection;
|
||||
wxPoint m_translation;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue