mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-20 20:11:41 +00:00
ADDED: Position items relative to arbitrary reference point
Fixes https://gitlab.com/kicad/code/kicad/-/issues/4756
This commit is contained in:
parent
c9af2f318f
commit
bd946313dc
common/tool
include/tool
pcbnew
@ -162,4 +162,13 @@ VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint, const VECTOR2D& aGrid,
|
||||
bool GRID_HELPER::canUseGrid() const
|
||||
{
|
||||
return m_enableGrid && m_toolMgr->GetView()->GetGAL()->GetGridSnapping();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::optional<VECTOR2I> GRID_HELPER::GetSnappedPoint() const
|
||||
{
|
||||
if( m_snapItem )
|
||||
return m_snapItem->pos;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ int PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
setCursor();
|
||||
VECTOR2D cursorPos = controls->GetCursorPosition( m_snap && m_frame->IsGridVisible() );
|
||||
m_modifiers = aEvent.Modifier();
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsActivate() )
|
||||
{
|
||||
|
@ -115,6 +115,8 @@ public:
|
||||
void SetMaskFlag( int aFlag ) { m_maskTypes |= aFlag; }
|
||||
void ClearMaskFlag( int aFlag ) { m_maskTypes = m_maskTypes & ~aFlag; }
|
||||
|
||||
std::optional<VECTOR2I> GetSnappedPoint() const;
|
||||
|
||||
enum ANCHOR_FLAGS {
|
||||
CORNER = 1,
|
||||
OUTLINE = 2,
|
||||
|
@ -106,6 +106,8 @@ public:
|
||||
m_finalizeHandler = aHandler;
|
||||
}
|
||||
|
||||
int CurrentModifiers() const { return m_modifiers; }
|
||||
|
||||
protected:
|
||||
///< Reinitializes tool to its initial state.
|
||||
virtual void reset();
|
||||
@ -113,6 +115,7 @@ protected:
|
||||
EDA_DRAW_FRAME* m_frame;
|
||||
KICURSOR m_cursor;
|
||||
bool m_snap;
|
||||
int m_modifiers;
|
||||
|
||||
std::optional<CLICK_HANDLER> m_clickHandler;
|
||||
std::optional<MOTION_HANDLER> m_motionHandler;
|
||||
|
@ -215,7 +215,19 @@ void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event )
|
||||
|
||||
POSITION_RELATIVE_TOOL* posrelTool = m_toolMgr->GetTool<POSITION_RELATIVE_TOOL>();
|
||||
wxASSERT( posrelTool );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectpositionRelativeItem );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectPositionRelativeItem );
|
||||
|
||||
Hide();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_POSITION_RELATIVE::OnSelectPointClick( wxCommandEvent& event )
|
||||
{
|
||||
event.Skip();
|
||||
|
||||
POSITION_RELATIVE_TOOL* posrelTool = m_toolMgr->GetTool<POSITION_RELATIVE_TOOL>();
|
||||
wxASSERT( posrelTool );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectPositionRelativePoint );
|
||||
|
||||
Hide();
|
||||
}
|
||||
@ -244,6 +256,13 @@ void DIALOG_POSITION_RELATIVE::updateAnchorInfo( BOARD_ITEM* aItem )
|
||||
m_referenceInfo->SetLabel( wxString::Format( _( "Reference item: %s" ), msg ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case ANCHOR_POINT:
|
||||
m_referenceInfo->SetLabel( wxString::Format(
|
||||
_( "Reference location: selected point (%s, %s)" ),
|
||||
m_parentFrame->MessageTextFromValue( m_anchorItemPosition.x ),
|
||||
m_parentFrame->MessageTextFromValue( m_anchorItemPosition.y ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,6 +278,7 @@ VECTOR2I DIALOG_POSITION_RELATIVE::getAnchorPos()
|
||||
return static_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() )->GetScreen()->m_LocalOrigin;
|
||||
|
||||
case ANCHOR_ITEM:
|
||||
case ANCHOR_POINT:
|
||||
return m_anchorItemPosition;
|
||||
}
|
||||
|
||||
@ -295,6 +315,19 @@ void DIALOG_POSITION_RELATIVE::UpdateAnchor( EDA_ITEM* aItem )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_POSITION_RELATIVE::UpdateAnchor( std::optional<VECTOR2I> aPoint )
|
||||
{
|
||||
m_options.anchorType = ANCHOR_POINT;
|
||||
|
||||
if( aPoint )
|
||||
m_anchorItemPosition = *aPoint;
|
||||
|
||||
updateAnchorInfo( nullptr );
|
||||
|
||||
Show( true );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
|
||||
{
|
||||
// for the output, we only deliver a Cartesian vector
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
~DIALOG_POSITION_RELATIVE() { };
|
||||
|
||||
void UpdateAnchor( EDA_ITEM* aItem );
|
||||
void UpdateAnchor( std::optional<VECTOR2I> aPoint );
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -51,6 +52,7 @@ private:
|
||||
void OnClear( wxCommandEvent& event ) override;
|
||||
|
||||
void OnSelectItemClick( wxCommandEvent& event ) override;
|
||||
void OnSelectPointClick( wxCommandEvent& event ) override;
|
||||
void OnUseGridOriginClick( wxCommandEvent& event ) override;
|
||||
void OnUseUserOriginClick( wxCommandEvent& event ) override;
|
||||
void OnOkClick( wxCommandEvent& event ) override;
|
||||
@ -87,7 +89,8 @@ private:
|
||||
{
|
||||
ANCHOR_GRID_ORIGIN,
|
||||
ANCHOR_USER_ORIGIN,
|
||||
ANCHOR_ITEM
|
||||
ANCHOR_ITEM,
|
||||
ANCHOR_POINT
|
||||
};
|
||||
|
||||
struct POSITION_RELATIVE_OPTIONS
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@ -23,7 +23,7 @@ DIALOG_POSITION_RELATIVE_BASE::DIALOG_POSITION_RELATIVE_BASE( wxWindow* parent,
|
||||
m_referenceInfo->Wrap( -1 );
|
||||
m_referenceInfo->SetMinSize( wxSize( 340,-1 ) );
|
||||
|
||||
bUpperSizer->Add( m_referenceInfo, 0, wxALL, 5 );
|
||||
bUpperSizer->Add( m_referenceInfo, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bUpperSizer->Add( 0, 0, 0, wxEXPAND, 5 );
|
||||
@ -42,6 +42,9 @@ DIALOG_POSITION_RELATIVE_BASE::DIALOG_POSITION_RELATIVE_BASE( wxWindow* parent,
|
||||
|
||||
bSizerButtOpts->Add( m_select_anchor_button, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_select_point_button = new wxButton( this, wxID_ANY, _("Select Point..."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerButtOpts->Add( m_select_point_button, 1, wxALL, 5 );
|
||||
|
||||
|
||||
bUpperSizer->Add( bSizerButtOpts, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
|
||||
|
||||
@ -132,6 +135,7 @@ DIALOG_POSITION_RELATIVE_BASE::DIALOG_POSITION_RELATIVE_BASE( wxWindow* parent,
|
||||
m_user_origin_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnUseUserOriginClick ), NULL, this );
|
||||
m_grid_origin_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnUseGridOriginClick ), NULL, this );
|
||||
m_select_anchor_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnSelectItemClick ), NULL, this );
|
||||
m_select_point_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnSelectPointClick ), NULL, this );
|
||||
m_xEntry->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnTextFocusLost ), NULL, this );
|
||||
m_clearX->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnClear ), NULL, this );
|
||||
m_yEntry->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnTextFocusLost ), NULL, this );
|
||||
@ -147,6 +151,7 @@ DIALOG_POSITION_RELATIVE_BASE::~DIALOG_POSITION_RELATIVE_BASE()
|
||||
m_user_origin_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnUseUserOriginClick ), NULL, this );
|
||||
m_grid_origin_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnUseGridOriginClick ), NULL, this );
|
||||
m_select_anchor_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnSelectItemClick ), NULL, this );
|
||||
m_select_point_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnSelectPointClick ), NULL, this );
|
||||
m_xEntry->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnTextFocusLost ), NULL, this );
|
||||
m_clearX->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnClear ), NULL, this );
|
||||
m_yEntry->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnTextFocusLost ), NULL, this );
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@ -29,7 +29,6 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class DIALOG_POSITION_RELATIVE_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -42,6 +41,7 @@ class DIALOG_POSITION_RELATIVE_BASE : public DIALOG_SHIM
|
||||
wxButton* m_user_origin_button;
|
||||
wxButton* m_grid_origin_button;
|
||||
wxButton* m_select_anchor_button;
|
||||
wxButton* m_select_point_button;
|
||||
wxStaticLine* m_staticline2;
|
||||
wxStaticText* m_xLabel;
|
||||
wxTextCtrl* m_xEntry;
|
||||
@ -61,6 +61,7 @@ class DIALOG_POSITION_RELATIVE_BASE : public DIALOG_SHIM
|
||||
virtual void OnUseUserOriginClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnUseGridOriginClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnSelectItemClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnSelectPointClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTextFocusLost( wxFocusEvent& event ) { event.Skip(); }
|
||||
virtual void OnClear( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnPolarChanged( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
@ -2021,10 +2021,14 @@ TOOL_ACTION PCB_ACTIONS::positionRelative( TOOL_ACTION_ARGS()
|
||||
.Tooltip( _( "Positions the selected item(s) by an exact amount relative to another" ) )
|
||||
.Icon( BITMAPS::move_relative ) );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectpositionRelativeItem( TOOL_ACTION_ARGS()
|
||||
TOOL_ACTION PCB_ACTIONS::selectPositionRelativeItem( TOOL_ACTION_ARGS()
|
||||
.Name( "pcbnew.PositionRelative.selectpositionRelativeItem" )
|
||||
.Scope( AS_GLOBAL ) );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectPositionRelativePoint( TOOL_ACTION_ARGS()
|
||||
.Name( "pcbnew.PositionRelative.selectPositionRelativePoint" )
|
||||
.Scope( AS_GLOBAL ) );
|
||||
|
||||
|
||||
// PCB_SELECTION_TOOL
|
||||
//
|
||||
@ -2480,4 +2484,4 @@ const TOOL_EVENT PCB_EVENTS::SnappingModeChangedByKeyEvent( TC_MESSAGE, TA_ACTIO
|
||||
"common.Interactive.snappingModeChangedByKey" );
|
||||
|
||||
const TOOL_EVENT PCB_EVENTS::LayerPairPresetChangedByKeyEvent( TC_MESSAGE, TA_ACTION,
|
||||
"pcbnew.Control.layerPairPresetChangedByKey" );
|
||||
"pcbnew.Control.layerPairPresetChangedByKey" );
|
||||
|
@ -321,7 +321,8 @@ public:
|
||||
static TOOL_ACTION positionRelative;
|
||||
|
||||
/// Selection of anchor item for position relative tool
|
||||
static TOOL_ACTION selectpositionRelativeItem;
|
||||
static TOOL_ACTION selectPositionRelativeItem;
|
||||
static TOOL_ACTION selectPositionRelativePoint;
|
||||
|
||||
// Display modes
|
||||
static TOOL_ACTION showRatsnest;
|
||||
|
@ -28,6 +28,7 @@ using namespace std::placeholders;
|
||||
#include <kiplatform/ui.h>
|
||||
#include <tools/position_relative_tool.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/pcb_grid_helper.h>
|
||||
#include <tools/pcb_selection_tool.h>
|
||||
#include <tools/pcb_picker_tool.h>
|
||||
#include <dialogs/dialog_position_relative.h>
|
||||
@ -229,9 +230,79 @@ int POSITION_RELATIVE_TOOL::SelectPositionRelativeItem( const TOOL_EVENT& aEvent
|
||||
}
|
||||
|
||||
|
||||
int POSITION_RELATIVE_TOOL::SelectPositionRelativePoint( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
PCB_PICKER_TOOL* picker = m_toolMgr->GetTool<PCB_PICKER_TOOL>();
|
||||
STATUS_TEXT_POPUP statusPopup( frame() );
|
||||
bool done = false;
|
||||
|
||||
PCB_GRID_HELPER grid_helper( m_toolMgr, frame()->GetMagneticItemsSettings() );
|
||||
|
||||
Activate();
|
||||
|
||||
statusPopup.SetText( _( "Click on reference point..." ) );
|
||||
|
||||
picker->SetClickHandler(
|
||||
[&]( const VECTOR2D& aPoint ) -> bool
|
||||
{
|
||||
std::optional<VECTOR2I> snapped = grid_helper.GetSnappedPoint();
|
||||
|
||||
statusPopup.Hide();
|
||||
|
||||
if( m_dialog )
|
||||
m_dialog->UpdateAnchor( snapped ? *snapped : VECTOR2I( aPoint ) );
|
||||
|
||||
return false; // got our item; don't need any more
|
||||
} );
|
||||
|
||||
picker->SetMotionHandler(
|
||||
[&] ( const VECTOR2D& aPos )
|
||||
{
|
||||
grid_helper.SetSnap( !( picker->CurrentModifiers() & MD_SHIFT ) );
|
||||
statusPopup.Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, -50 ) );
|
||||
} );
|
||||
|
||||
picker->SetCancelHandler(
|
||||
[&]()
|
||||
{
|
||||
statusPopup.Hide();
|
||||
|
||||
if( m_dialog )
|
||||
m_dialog->UpdateAnchor( std::nullopt );
|
||||
} );
|
||||
|
||||
picker->SetFinalizeHandler(
|
||||
[&]( const int& aFinalState )
|
||||
{
|
||||
done = true;
|
||||
} );
|
||||
|
||||
statusPopup.Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, -50 ) );
|
||||
statusPopup.Popup();
|
||||
canvas()->SetStatusPopup( statusPopup.GetPanel() );
|
||||
|
||||
m_toolMgr->RunAction( ACTIONS::pickerTool, &aEvent );
|
||||
|
||||
while( !done )
|
||||
{
|
||||
// Pass events unless we receive a null event, then we must shut down
|
||||
if( TOOL_EVENT* evt = Wait() )
|
||||
evt->SetPassEvent();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
canvas()->SetStatusPopup( nullptr );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void POSITION_RELATIVE_TOOL::setTransitions()
|
||||
{
|
||||
Go( &POSITION_RELATIVE_TOOL::PositionRelative, PCB_ACTIONS::positionRelative.MakeEvent() );
|
||||
Go( &POSITION_RELATIVE_TOOL::SelectPositionRelativeItem,
|
||||
PCB_ACTIONS::selectpositionRelativeItem.MakeEvent() );
|
||||
PCB_ACTIONS::selectPositionRelativeItem.MakeEvent() );
|
||||
Go( &POSITION_RELATIVE_TOOL::SelectPositionRelativePoint,
|
||||
PCB_ACTIONS::selectPositionRelativePoint.MakeEvent() );
|
||||
}
|
||||
|
@ -63,6 +63,12 @@ public:
|
||||
*/
|
||||
int SelectPositionRelativeItem( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Invoke the picker tool to select the point to which the previous selection will be placed
|
||||
* relative to.
|
||||
*/
|
||||
int SelectPositionRelativePoint( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Return the position of the selected item(s)
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user