Add Position Relative tool
This commit is contained in:
parent
f0c8391a46
commit
aeb23188f1
|
@ -134,6 +134,8 @@ set( PCBNEW_DIALOGS
|
||||||
dialogs/dialog_pad_properties_base.cpp
|
dialogs/dialog_pad_properties_base.cpp
|
||||||
dialogs/dialog_plot_base.cpp
|
dialogs/dialog_plot_base.cpp
|
||||||
dialogs/dialog_plot.cpp
|
dialogs/dialog_plot.cpp
|
||||||
|
dialogs/dialog_position_relative.cpp
|
||||||
|
dialogs/dialog_position_relative_base.cpp
|
||||||
dialogs/dialog_print_for_modedit.cpp
|
dialogs/dialog_print_for_modedit.cpp
|
||||||
dialogs/dialog_print_for_modedit_base.cpp
|
dialogs/dialog_print_for_modedit_base.cpp
|
||||||
dialogs/dialog_print_using_printer.cpp
|
dialogs/dialog_print_using_printer.cpp
|
||||||
|
@ -309,6 +311,7 @@ set( PCBNEW_CLASS_SRCS
|
||||||
tools/point_editor.cpp
|
tools/point_editor.cpp
|
||||||
tools/drawing_tool.cpp
|
tools/drawing_tool.cpp
|
||||||
tools/edit_tool.cpp
|
tools/edit_tool.cpp
|
||||||
|
tools/position_relative_tool.cpp
|
||||||
tools/pcbnew_control.cpp
|
tools/pcbnew_control.cpp
|
||||||
tools/pcb_editor_control.cpp
|
tools/pcb_editor_control.cpp
|
||||||
tools/microwave_tool.cpp
|
tools/microwave_tool.cpp
|
||||||
|
|
|
@ -0,0 +1,232 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 John Beard, john.j.beard@gmail.com
|
||||||
|
* Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <wxPcbStruct.h>
|
||||||
|
#include <base_units.h>
|
||||||
|
#include <macros.h>
|
||||||
|
|
||||||
|
#include <module_editor_frame.h>
|
||||||
|
|
||||||
|
#include "dialog_position_relative.h"
|
||||||
|
#include "tools/pcb_actions.h"
|
||||||
|
|
||||||
|
// initialise statics
|
||||||
|
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, double& rotation, wxPoint& anchorPosition ) :
|
||||||
|
DIALOG_POSITION_RELATIVE_BASE( aParent ),
|
||||||
|
m_toolMgr( toolMgr ),
|
||||||
|
m_translation( translation ),
|
||||||
|
m_rotation( rotation ),
|
||||||
|
m_anchor_position( anchorPosition )
|
||||||
|
{
|
||||||
|
// set the unit labels
|
||||||
|
m_xUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
|
||||||
|
m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
|
||||||
|
|
||||||
|
// tabbing goes through the entries in sequence
|
||||||
|
m_yEntry->MoveAfterInTabOrder( m_xEntry );
|
||||||
|
m_rotEntry->MoveAfterInTabOrder( m_yEntry );
|
||||||
|
|
||||||
|
// and set up the entries according to the saved options
|
||||||
|
m_polarCoords->SetValue( m_options.polarCoords );
|
||||||
|
m_xEntry->SetValue( wxString::FromDouble( m_options.entry1 ) );
|
||||||
|
m_yEntry->SetValue( wxString::FromDouble( m_options.entry2 ) );
|
||||||
|
m_rotEntry->SetValue( wxString::FromDouble( m_options.entryRotation ) );
|
||||||
|
updateDlgTexts( m_polarCoords->IsChecked() );
|
||||||
|
|
||||||
|
m_stdButtonsOK->SetDefault();
|
||||||
|
|
||||||
|
GetSizer()->SetSizeHints( this );
|
||||||
|
Layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DIALOG_POSITION_RELATIVE::~DIALOG_POSITION_RELATIVE()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, double& q )
|
||||||
|
{
|
||||||
|
// convert to polar coordinates
|
||||||
|
r = hypot( x, y );
|
||||||
|
|
||||||
|
q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DIALOG_POSITION_RELATIVE::GetTranslationInIU( wxPoint& val, bool polar )
|
||||||
|
{
|
||||||
|
if( polar )
|
||||||
|
{
|
||||||
|
const int r = ValueFromTextCtrl( *m_xEntry );
|
||||||
|
const double q = DoubleValueFromString( DEGREES, m_yEntry->GetValue() );
|
||||||
|
|
||||||
|
val.x = r * cos( DEG2RAD( q / 10.0 ) );
|
||||||
|
val.y = r * sin( DEG2RAD( q / 10.0 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// direct read
|
||||||
|
val.x = ValueFromTextCtrl( *m_xEntry );
|
||||||
|
val.y = ValueFromTextCtrl( *m_yEntry );
|
||||||
|
}
|
||||||
|
|
||||||
|
// no validation to do here, but in future, you could return false here
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
bool newPolar = m_polarCoords->IsChecked();
|
||||||
|
|
||||||
|
updateDlgTexts( newPolar );
|
||||||
|
wxPoint val;
|
||||||
|
|
||||||
|
// get the value as previously stored
|
||||||
|
GetTranslationInIU( val, !newPolar );
|
||||||
|
|
||||||
|
if( newPolar )
|
||||||
|
{
|
||||||
|
// convert to polar coordinates
|
||||||
|
double r, q;
|
||||||
|
ToPolarDeg( val.x, val.y, r, q );
|
||||||
|
|
||||||
|
PutValueInLocalUnits( *m_xEntry, KiROUND( r / 10.0 ) * 10 );
|
||||||
|
m_yEntry->SetValue( wxString::FromDouble( q ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// vector is already in Cartesian, so just render out
|
||||||
|
// note - round off the last decimal place (10nm) to prevent
|
||||||
|
// (some) rounding causing errors when round-tripping
|
||||||
|
// you can never eliminate entirely, however
|
||||||
|
PutValueInLocalUnits( *m_xEntry, KiROUND( val.x / 10.0 ) * 10 );
|
||||||
|
PutValueInLocalUnits( *m_yEntry, KiROUND( val.y / 10.0 ) * 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_POSITION_RELATIVE::updateDlgTexts( bool aPolar )
|
||||||
|
{
|
||||||
|
if( aPolar )
|
||||||
|
{
|
||||||
|
m_xLabel->SetLabelText( _( "Distance:" ) ); // Polar radius
|
||||||
|
m_yLabel->SetLabelText( _( "Angle:" ) ); // Polar theta or angle
|
||||||
|
|
||||||
|
m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( DEGREES ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_xLabel->SetLabelText( _( "Move vector X:" ) );
|
||||||
|
m_yLabel->SetLabelText( _( "Move vector Y:" ) );
|
||||||
|
|
||||||
|
m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
wxObject* obj = event.GetEventObject();
|
||||||
|
wxTextCtrl* entry = NULL;
|
||||||
|
|
||||||
|
if( obj == m_clearX )
|
||||||
|
{
|
||||||
|
entry = m_xEntry;
|
||||||
|
}
|
||||||
|
else if( obj == m_clearY )
|
||||||
|
{
|
||||||
|
entry = m_yEntry;
|
||||||
|
}
|
||||||
|
else if( obj == m_clearRot )
|
||||||
|
{
|
||||||
|
entry = m_rotEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( entry )
|
||||||
|
entry->SetValue( "0" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
|
||||||
|
|
||||||
|
POSITION_RELATIVE_TOOL* posrelTool = m_toolMgr->GetTool<POSITION_RELATIVE_TOOL>();
|
||||||
|
assert( posrelTool );
|
||||||
|
m_toolMgr->RunAction( PCB_ACTIONS::selectpositionRelativeItem, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_POSITION_RELATIVE::UpdateAchor( BOARD_ITEM* aBoardItem )
|
||||||
|
{
|
||||||
|
m_anchor_position = aBoardItem->GetPosition();
|
||||||
|
|
||||||
|
PutValueInLocalUnits( *m_anchor_x, m_anchor_position.x );
|
||||||
|
PutValueInLocalUnits( *m_anchor_y, m_anchor_position.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
m_rotation = DoubleValueFromString( DEGREES, m_rotEntry->GetValue() );
|
||||||
|
|
||||||
|
// for the output, we only deliver a Cartesian vector
|
||||||
|
bool ok = GetTranslationInIU( m_translation, m_polarCoords->IsChecked() );
|
||||||
|
|
||||||
|
if( ok )
|
||||||
|
{
|
||||||
|
// save the settings
|
||||||
|
m_options.polarCoords = m_polarCoords->GetValue();
|
||||||
|
m_options.entry1 = DoubleValueFromString( UNSCALED_UNITS, m_xEntry->GetValue() );
|
||||||
|
m_options.entry2 = DoubleValueFromString( UNSCALED_UNITS, m_yEntry->GetValue() );
|
||||||
|
m_options.entryRotation = DoubleValueFromString( UNSCALED_UNITS, m_rotEntry->GetValue() );
|
||||||
|
POSITION_RELATIVE_TOOL* posrelTool = m_toolMgr->GetTool<POSITION_RELATIVE_TOOL>();
|
||||||
|
assert( posrelTool );
|
||||||
|
|
||||||
|
|
||||||
|
posrelTool->RelativeItemSelectionMove( m_anchor_position, m_translation, m_rotation );
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_POSITION_RELATIVE::OnTextFocusLost( wxFocusEvent& event )
|
||||||
|
{
|
||||||
|
wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
|
||||||
|
|
||||||
|
if( obj->GetValue().IsEmpty() )
|
||||||
|
obj->SetValue( "0" );
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 John Beard, john.j.beard@gmail.com
|
||||||
|
* Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DIALOG_POSITION_RELATIVE__
|
||||||
|
#define __DIALOG_POSITION_RELATIVE__
|
||||||
|
|
||||||
|
// Include the wxFormBuider header base:
|
||||||
|
#include <vector>
|
||||||
|
#include <dialogs/dialog_position_relative_base.h>
|
||||||
|
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include "tools/position_relative_tool.h"
|
||||||
|
|
||||||
|
class DIALOG_POSITION_RELATIVE : public DIALOG_POSITION_RELATIVE_BASE
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
TOOL_MANAGER* m_toolMgr;
|
||||||
|
wxPoint& m_translation;
|
||||||
|
double& m_rotation;
|
||||||
|
wxPoint& m_anchor_position;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor and destructor
|
||||||
|
DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, TOOL_MANAGER* toolMgr, wxPoint& translation,
|
||||||
|
double& rotation, wxPoint& anchorposition );
|
||||||
|
~DIALOG_POSITION_RELATIVE();
|
||||||
|
|
||||||
|
void UpdateAchor( BOARD_ITEM* aBoardItem );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Reset a text field to be 0 if it was exited while blank
|
||||||
|
*/
|
||||||
|
void OnTextFocusLost( wxFocusEvent& event ) override;
|
||||||
|
|
||||||
|
void OnPolarChanged( wxCommandEvent& event ) override;
|
||||||
|
void OnClear( wxCommandEvent& event ) override;
|
||||||
|
|
||||||
|
void OnSelectItemClick( wxCommandEvent& event ) override;
|
||||||
|
void OnOkClick( wxCommandEvent& event ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a given Cartesian point into a polar representation.
|
||||||
|
*
|
||||||
|
* Linear units are not considered, the answer is in the same units as given
|
||||||
|
* Angle is returned in degrees
|
||||||
|
*/
|
||||||
|
void ToPolarDeg( double x, double y, double& r, double& q );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the (Cartesian) translation described by the text entries
|
||||||
|
* @param val output translation vector
|
||||||
|
* @param polar interpret as polar coords
|
||||||
|
* @return false if error (though the text conversion functions don't report errors)
|
||||||
|
*/
|
||||||
|
bool GetTranslationInIU( wxPoint& val, bool polar );
|
||||||
|
|
||||||
|
// Update texts (comments) after changing the coordinates type (polar/cartesian)
|
||||||
|
void updateDlgTexts( bool aPolar );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistent dialog options
|
||||||
|
*/
|
||||||
|
struct POSITION_RELATIVE_OPTIONS
|
||||||
|
{
|
||||||
|
bool polarCoords;
|
||||||
|
double entry1;
|
||||||
|
double entry2;
|
||||||
|
double entryRotation;
|
||||||
|
|
||||||
|
POSITION_RELATIVE_OPTIONS() :
|
||||||
|
polarCoords( false ),
|
||||||
|
entry1( 0 ),
|
||||||
|
entry2( 0 ),
|
||||||
|
entryRotation( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// persistent settings
|
||||||
|
static POSITION_RELATIVE_OPTIONS m_options;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __DIALOG_POSITION_RELATIVE__
|
|
@ -0,0 +1,134 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version Jun 17 2015)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "dialog_position_relative_base.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DIALOG_POSITION_RELATIVE_BASE::DIALOG_POSITION_RELATIVE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
||||||
|
{
|
||||||
|
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
|
||||||
|
|
||||||
|
wxBoxSizer* bMainSizer;
|
||||||
|
bMainSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
m_polarCoords = new wxCheckBox( this, wxID_ANY, _("Use polar coordinates"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
bMainSizer->Add( m_polarCoords, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
wxFlexGridSizer* fgSizer2;
|
||||||
|
fgSizer2 = new wxFlexGridSizer( 0, 4, 0, 0 );
|
||||||
|
fgSizer2->AddGrowableCol( 1 );
|
||||||
|
fgSizer2->SetFlexibleDirection( wxBOTH );
|
||||||
|
fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||||
|
|
||||||
|
m_xLabel = new wxStaticText( this, wxID_ANY, _("x:"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
|
||||||
|
m_xLabel->Wrap( -1 );
|
||||||
|
fgSizer2->Add( m_xLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
|
||||||
|
|
||||||
|
m_xEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer2->Add( m_xEntry, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_xUnit = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_xUnit->Wrap( -1 );
|
||||||
|
fgSizer2->Add( m_xUnit, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 );
|
||||||
|
|
||||||
|
m_clearX = new wxButton( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
|
||||||
|
fgSizer2->Add( m_clearX, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
m_yLabel = new wxStaticText( this, wxID_ANY, _("y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_yLabel->Wrap( -1 );
|
||||||
|
fgSizer2->Add( m_yLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
|
||||||
|
|
||||||
|
m_yEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer2->Add( m_yEntry, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_yUnit = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_yUnit->Wrap( -1 );
|
||||||
|
fgSizer2->Add( m_yUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
m_clearY = new wxButton( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
|
||||||
|
fgSizer2->Add( m_clearY, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
m_rotLabel = new wxStaticText( this, wxID_ANY, _("Item rotation:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_rotLabel->Wrap( -1 );
|
||||||
|
fgSizer2->Add( m_rotLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
|
||||||
|
|
||||||
|
m_rotEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer2->Add( m_rotEntry, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_rotUnit = new wxStaticText( this, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_rotUnit->Wrap( -1 );
|
||||||
|
fgSizer2->Add( m_rotUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
m_clearRot = new wxButton( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
|
||||||
|
fgSizer2->Add( m_clearRot, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
m_anchor_xLabel = new wxStaticText( this, wxID_ANY, _("Anchor X:"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
|
||||||
|
m_anchor_xLabel->Wrap( -1 );
|
||||||
|
fgSizer2->Add( m_anchor_xLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
|
||||||
|
|
||||||
|
m_anchor_x = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer2->Add( m_anchor_x, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
m_anchor_yLabel = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
|
||||||
|
m_anchor_yLabel->Wrap( -1 );
|
||||||
|
fgSizer2->Add( m_anchor_yLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
|
||||||
|
|
||||||
|
m_anchor_y = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
fgSizer2->Add( m_anchor_y, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
bMainSizer->Add( fgSizer2, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
|
||||||
|
|
||||||
|
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||||
|
bMainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
|
||||||
|
|
||||||
|
m_select_anchor_button = new wxButton( this, wxID_ANY, _("Select Anchor Item"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
bMainSizer->Add( m_select_anchor_button, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
m_stdButtons = new wxStdDialogButtonSizer();
|
||||||
|
m_stdButtonsOK = new wxButton( this, wxID_OK );
|
||||||
|
m_stdButtons->AddButton( m_stdButtonsOK );
|
||||||
|
m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
|
||||||
|
m_stdButtons->AddButton( m_stdButtonsCancel );
|
||||||
|
m_stdButtons->Realize();
|
||||||
|
|
||||||
|
bMainSizer->Add( m_stdButtons, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
this->SetSizer( bMainSizer );
|
||||||
|
this->Layout();
|
||||||
|
bMainSizer->Fit( this );
|
||||||
|
|
||||||
|
// Connect Events
|
||||||
|
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnClose ) );
|
||||||
|
m_polarCoords->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnPolarChanged ), 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 );
|
||||||
|
m_clearY->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnClear ), NULL, this );
|
||||||
|
m_rotEntry->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnTextFocusLost ), NULL, this );
|
||||||
|
m_clearRot->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnClear ), NULL, this );
|
||||||
|
m_select_anchor_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnSelectItemClick ), NULL, this );
|
||||||
|
m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnOkClick ), NULL, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
DIALOG_POSITION_RELATIVE_BASE::~DIALOG_POSITION_RELATIVE_BASE()
|
||||||
|
{
|
||||||
|
// Disconnect Events
|
||||||
|
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnClose ) );
|
||||||
|
m_polarCoords->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnPolarChanged ), 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 );
|
||||||
|
m_clearY->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnClear ), NULL, this );
|
||||||
|
m_rotEntry->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnTextFocusLost ), NULL, this );
|
||||||
|
m_clearRot->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnClear ), NULL, this );
|
||||||
|
m_select_anchor_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnSelectItemClick ), NULL, this );
|
||||||
|
m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_POSITION_RELATIVE_BASE::OnOkClick ), NULL, this );
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version Jun 17 2015)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __DIALOG_POSITION_RELATIVE_BASE_H__
|
||||||
|
#define __DIALOG_POSITION_RELATIVE_BASE_H__
|
||||||
|
|
||||||
|
#include <wx/artprov.h>
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/intl.h>
|
||||||
|
class DIALOG_SHIM;
|
||||||
|
|
||||||
|
#include "dialog_shim.h"
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include <wx/checkbox.h>
|
||||||
|
#include <wx/gdicmn.h>
|
||||||
|
#include <wx/font.h>
|
||||||
|
#include <wx/colour.h>
|
||||||
|
#include <wx/settings.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
#include <wx/button.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/statline.h>
|
||||||
|
#include <wx/dialog.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Class DIALOG_POSITION_RELATIVE_BASE
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class DIALOG_POSITION_RELATIVE_BASE : public DIALOG_SHIM
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxCheckBox* m_polarCoords;
|
||||||
|
wxStaticText* m_xLabel;
|
||||||
|
wxTextCtrl* m_xEntry;
|
||||||
|
wxStaticText* m_xUnit;
|
||||||
|
wxButton* m_clearX;
|
||||||
|
wxStaticText* m_yLabel;
|
||||||
|
wxTextCtrl* m_yEntry;
|
||||||
|
wxStaticText* m_yUnit;
|
||||||
|
wxButton* m_clearY;
|
||||||
|
wxStaticText* m_rotLabel;
|
||||||
|
wxTextCtrl* m_rotEntry;
|
||||||
|
wxStaticText* m_rotUnit;
|
||||||
|
wxButton* m_clearRot;
|
||||||
|
wxStaticText* m_anchor_xLabel;
|
||||||
|
wxTextCtrl* m_anchor_x;
|
||||||
|
wxStaticText* m_anchor_yLabel;
|
||||||
|
wxTextCtrl* m_anchor_y;
|
||||||
|
wxStaticLine* m_staticline1;
|
||||||
|
wxButton* m_select_anchor_button;
|
||||||
|
wxStdDialogButtonSizer* m_stdButtons;
|
||||||
|
wxButton* m_stdButtonsOK;
|
||||||
|
wxButton* m_stdButtonsCancel;
|
||||||
|
|
||||||
|
// Virtual event handlers, overide them in your derived class
|
||||||
|
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnPolarChanged( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnTextFocusLost( wxFocusEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnClear( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnSelectItemClick( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DIALOG_POSITION_RELATIVE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Position Relative"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||||
|
~DIALOG_POSITION_RELATIVE_BASE();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__DIALOG_POSITION_RELATIVE_BASE_H__
|
|
@ -117,6 +117,7 @@ static EDA_HOTKEY HkFlipItem( _HKI( "Flip Item" ), HK_FLIP_ITEM, 'F' );
|
||||||
static EDA_HOTKEY HkRotateItem( _HKI( "Rotate Item" ), HK_ROTATE_ITEM, 'R' );
|
static EDA_HOTKEY HkRotateItem( _HKI( "Rotate Item" ), HK_ROTATE_ITEM, 'R' );
|
||||||
static EDA_HOTKEY HkMoveItem( _HKI( "Move Item" ), HK_MOVE_ITEM, 'M' );
|
static EDA_HOTKEY HkMoveItem( _HKI( "Move Item" ), HK_MOVE_ITEM, 'M' );
|
||||||
static EDA_HOTKEY HkMoveItemExact( _HKI( "Move Item Exactly" ), HK_MOVE_ITEM_EXACT, 'M' + GR_KB_CTRL );
|
static EDA_HOTKEY HkMoveItemExact( _HKI( "Move Item Exactly" ), HK_MOVE_ITEM_EXACT, 'M' + GR_KB_CTRL );
|
||||||
|
static EDA_HOTKEY HkPositionItemRelative( _HKI( "Position Item Relative" ), HK_POSITION_RELATIVE, 'R' + GR_KB_CTRL );
|
||||||
static EDA_HOTKEY HkDuplicateItem( _HKI( "Duplicate Item" ), HK_DUPLICATE_ITEM, 'D' + GR_KB_CTRL );
|
static EDA_HOTKEY HkDuplicateItem( _HKI( "Duplicate Item" ), HK_DUPLICATE_ITEM, 'D' + GR_KB_CTRL );
|
||||||
static EDA_HOTKEY HkDuplicateItemAndIncrement( _HKI( "Duplicate Item and Increment" ),
|
static EDA_HOTKEY HkDuplicateItemAndIncrement( _HKI( "Duplicate Item and Increment" ),
|
||||||
HK_DUPLICATE_ITEM_AND_INCREMENT, 'D' + GR_KB_SHIFTCTRL );
|
HK_DUPLICATE_ITEM_AND_INCREMENT, 'D' + GR_KB_SHIFTCTRL );
|
||||||
|
@ -262,7 +263,7 @@ EDA_HOTKEY* board_edit_Hotkey_List[] =
|
||||||
&HkPlaceItem, &HkCopyItem,
|
&HkPlaceItem, &HkCopyItem,
|
||||||
&HkMoveItem,
|
&HkMoveItem,
|
||||||
&HkFlipItem,
|
&HkFlipItem,
|
||||||
&HkRotateItem, &HkMoveItemExact,
|
&HkRotateItem, &HkMoveItemExact, &HkPositionItemRelative,
|
||||||
&HkDuplicateItem, &HkDuplicateItemAndIncrement, &HkCreateArray,
|
&HkDuplicateItem, &HkDuplicateItemAndIncrement, &HkCreateArray,
|
||||||
&HkDragFootprint,
|
&HkDragFootprint,
|
||||||
&HkGetAndMoveFootprint, &HkLock_Unlock_Footprint, &HkSavefile, &HkSavefileAs,
|
&HkGetAndMoveFootprint, &HkLock_Unlock_Footprint, &HkSavefile, &HkSavefileAs,
|
||||||
|
|
|
@ -42,6 +42,7 @@ enum hotkey_id_commnand {
|
||||||
HK_COPY_ITEM,
|
HK_COPY_ITEM,
|
||||||
HK_MOVE_ITEM,
|
HK_MOVE_ITEM,
|
||||||
HK_MOVE_ITEM_EXACT,
|
HK_MOVE_ITEM_EXACT,
|
||||||
|
HK_POSITION_RELATIVE,
|
||||||
HK_DRAG_ITEM,
|
HK_DRAG_ITEM,
|
||||||
HK_GET_AND_MOVE_FOOTPRINT,
|
HK_GET_AND_MOVE_FOOTPRINT,
|
||||||
HK_LOCK_UNLOCK_FOOTPRINT,
|
HK_LOCK_UNLOCK_FOOTPRINT,
|
||||||
|
|
|
@ -202,6 +202,7 @@ bool EDIT_TOOL::Init()
|
||||||
menu.AddItem( PCB_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 )
|
menu.AddItem( PCB_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 )
|
||||||
|| SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::Tracks ) );
|
|| SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::Tracks ) );
|
||||||
menu.AddItem( PCB_ACTIONS::moveExact, SELECTION_CONDITIONS::NotEmpty );
|
menu.AddItem( PCB_ACTIONS::moveExact, SELECTION_CONDITIONS::NotEmpty );
|
||||||
|
menu.AddItem( PCB_ACTIONS::positionRelative, SELECTION_CONDITIONS::NotEmpty );
|
||||||
menu.AddItem( PCB_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
|
menu.AddItem( PCB_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
|
||||||
menu.AddItem( PCB_ACTIONS::createArray, SELECTION_CONDITIONS::NotEmpty );
|
menu.AddItem( PCB_ACTIONS::createArray, SELECTION_CONDITIONS::NotEmpty );
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,12 @@ public:
|
||||||
/// Distributes items evenly along the vertical axis
|
/// Distributes items evenly along the vertical axis
|
||||||
static TOOL_ACTION distributeVertically;
|
static TOOL_ACTION distributeVertically;
|
||||||
|
|
||||||
|
// Position Relative Tool
|
||||||
|
/// Activation of the position relative tool
|
||||||
|
static TOOL_ACTION positionRelative;
|
||||||
|
|
||||||
|
/// Selection of anchor item for position relative tool
|
||||||
|
static TOOL_ACTION selectpositionRelativeItem;
|
||||||
|
|
||||||
// Display modes
|
// Display modes
|
||||||
static TOOL_ACTION trackDisplayMode;
|
static TOOL_ACTION trackDisplayMode;
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BOOST_BIND_NO_PLACEHOLDERS
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <class_module.h>
|
||||||
|
#include <class_edge_mod.h>
|
||||||
|
#include <class_zone.h>
|
||||||
|
#include <collectors.h>
|
||||||
|
#include <wxPcbStruct.h>
|
||||||
|
#include <kiway.h>
|
||||||
|
#include <class_draw_panel_gal.h>
|
||||||
|
#include <module_editor_frame.h>
|
||||||
|
#include <array_creator.h>
|
||||||
|
#include <pcbnew_id.h>
|
||||||
|
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <view/view_controls.h>
|
||||||
|
#include <view/view.h>
|
||||||
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
#include <ratsnest_data.h>
|
||||||
|
#include <confirm.h>
|
||||||
|
#include <bitmaps.h>
|
||||||
|
#include <hotkeys.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
#include "pcb_actions.h"
|
||||||
|
#include "selection_tool.h"
|
||||||
|
#include "edit_tool.h"
|
||||||
|
#include "grid_helper.h"
|
||||||
|
#include "picker_tool.h"
|
||||||
|
#include "position_relative_tool.h"
|
||||||
|
|
||||||
|
#include <router/router_tool.h>
|
||||||
|
|
||||||
|
#include <dialogs/dialog_move_exact.h>
|
||||||
|
#include <dialogs/dialog_position_relative.h>
|
||||||
|
#include <dialogs/dialog_track_via_properties.h>
|
||||||
|
#include <dialogs/dialog_exchange_modules.h>
|
||||||
|
|
||||||
|
#include <tools/tool_event_utils.h>
|
||||||
|
|
||||||
|
#include <preview_items/ruler_item.h>
|
||||||
|
|
||||||
|
#include <board_commit.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Position relative tool actions
|
||||||
|
|
||||||
|
TOOL_ACTION PCB_ACTIONS::positionRelative( "pcbnew.PositionRelative.positionRelative",
|
||||||
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_POSITION_RELATIVE ),
|
||||||
|
_( "Position Relative to..." ), _(
|
||||||
|
"Positions the selected item(s) by an exact amount relative to another" ),
|
||||||
|
move_module_xpm );
|
||||||
|
|
||||||
|
|
||||||
|
TOOL_ACTION PCB_ACTIONS::selectpositionRelativeItem(
|
||||||
|
"pcbnew.PositionRelative.selectpositionRelativeItem",
|
||||||
|
AS_GLOBAL,
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
nullptr );
|
||||||
|
|
||||||
|
POSITION_RELATIVE_TOOL::POSITION_RELATIVE_TOOL() :
|
||||||
|
PCB_TOOL( "pcbnew.PositionRelative" ), m_selectionTool( NULL )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POSITION_RELATIVE_TOOL::Reset( RESET_REASON aReason )
|
||||||
|
{
|
||||||
|
if( aReason != RUN )
|
||||||
|
m_commit.reset( new BOARD_COMMIT( this ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool POSITION_RELATIVE_TOOL::Init()
|
||||||
|
{
|
||||||
|
// Find the selection tool, so they can cooperate
|
||||||
|
m_selectionTool =
|
||||||
|
static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
|
||||||
|
|
||||||
|
if( !m_selectionTool )
|
||||||
|
{
|
||||||
|
DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
const auto& selection = m_selectionTool->RequestSelection();
|
||||||
|
|
||||||
|
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( selection.Empty() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
m_position_relative_selection = selection;
|
||||||
|
|
||||||
|
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
|
m_position_relative_rotation = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if( !m_position_relative_dialog )
|
||||||
|
m_position_relative_dialog = new DIALOG_POSITION_RELATIVE( editFrame,
|
||||||
|
m_toolMgr,
|
||||||
|
m_position_relative_translation,
|
||||||
|
m_position_relative_rotation,
|
||||||
|
m_anchor_position );
|
||||||
|
|
||||||
|
m_position_relative_dialog->Show( true );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool selectPRitem( TOOL_MANAGER* aToolMgr,
|
||||||
|
BOARD_ITEM* m_anchor_item,
|
||||||
|
const VECTOR2D& aPosition )
|
||||||
|
{
|
||||||
|
SELECTION_TOOL* selectionTool = aToolMgr->GetTool<SELECTION_TOOL>();
|
||||||
|
POSITION_RELATIVE_TOOL* positionRelativeTool = aToolMgr->GetTool<POSITION_RELATIVE_TOOL>();
|
||||||
|
|
||||||
|
assert( selectionTool );
|
||||||
|
assert( positionRelativeTool );
|
||||||
|
|
||||||
|
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
||||||
|
selectionTool->SanitizeSelection();
|
||||||
|
|
||||||
|
const SELECTION& selection = selectionTool->GetSelection();
|
||||||
|
|
||||||
|
if( selection.Empty() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
m_anchor_item = static_cast<BOARD_ITEM*>( selection.Front() );
|
||||||
|
positionRelativeTool->m_position_relative_dialog->UpdateAchor( m_anchor_item );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOARD_ITEM* POSITION_RELATIVE_TOOL::GetAnchorItem()
|
||||||
|
{
|
||||||
|
return m_anchor_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint anchorPosition,
|
||||||
|
wxPoint relativePosition,
|
||||||
|
double rotation )
|
||||||
|
{
|
||||||
|
VECTOR2I rp = m_position_relative_selection.GetCenter();
|
||||||
|
wxPoint rotPoint( rp.x, rp.y );
|
||||||
|
wxPoint translation = anchorPosition + relativePosition - rotPoint;
|
||||||
|
|
||||||
|
for( auto item : m_position_relative_selection )
|
||||||
|
{
|
||||||
|
m_commit->Modify( item );
|
||||||
|
|
||||||
|
static_cast<BOARD_ITEM*>( item )->Rotate( rotPoint, rotation );
|
||||||
|
static_cast<BOARD_ITEM*>( item )->Move( translation );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_commit->Push( _( "Positon Relative" ) );
|
||||||
|
|
||||||
|
if( m_position_relative_selection.IsHover() )
|
||||||
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int POSITION_RELATIVE_TOOL::SelectPositionRelativeItem( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
Activate();
|
||||||
|
|
||||||
|
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||||
|
assert( picker );
|
||||||
|
|
||||||
|
picker->SetSnapping( false );
|
||||||
|
picker->SetClickHandler( std::bind( selectPRitem, m_toolMgr, m_anchor_item, _1 ) );
|
||||||
|
picker->Activate();
|
||||||
|
Wait();
|
||||||
|
|
||||||
|
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() );
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2015 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __POSITION_RELATIVE_TOOL_H
|
||||||
|
#define __POSITION_RELATIVE_TOOL_H
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
#include <tools/pcb_tool.h>
|
||||||
|
#include "selection_tool.h"
|
||||||
|
#include "dialogs/dialog_position_relative.h"
|
||||||
|
#include "dialogs/dialog_position_relative_base.h"
|
||||||
|
|
||||||
|
class BOARD_COMMIT;
|
||||||
|
class BOARD_ITEM;
|
||||||
|
class SELECTION_TOOL;
|
||||||
|
class DIALOG_POSITION_RELATIVE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class POSITION_RELATIVE_TOOL
|
||||||
|
*
|
||||||
|
* The interactive edit tool. Allows to move, rotate, flip and change properties of items selected
|
||||||
|
* using the pcbnew.InteractiveSelection tool.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class POSITION_RELATIVE_TOOL : public PCB_TOOL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
POSITION_RELATIVE_TOOL();
|
||||||
|
|
||||||
|
void Reset( RESET_REASON aReason );
|
||||||
|
|
||||||
|
/// @copydoc POSITION_RELATIVE_TOOL::Init()
|
||||||
|
bool Init() override;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function PositionRelative()
|
||||||
|
*
|
||||||
|
* Invokes a dialog box to allow positioning of the item relative to another by an exact amount.
|
||||||
|
*/
|
||||||
|
int PositionRelative( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SelectPositionRelativeItem()
|
||||||
|
*
|
||||||
|
* Invokes the picker tool to select the item to which the previos selection will be placed relative to.
|
||||||
|
*/
|
||||||
|
int SelectPositionRelativeItem( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function RelativeItemSelectionMove()
|
||||||
|
*
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
///> Sets up handlers for various events.
|
||||||
|
void SetTransitions() override;
|
||||||
|
|
||||||
|
DIALOG_POSITION_RELATIVE* m_position_relative_dialog;
|
||||||
|
|
||||||
|
private:
|
||||||
|
///> Selection tool used for obtaining selected items
|
||||||
|
SELECTION_TOOL* m_selectionTool;
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<BOARD_COMMIT> m_commit;
|
||||||
|
|
||||||
|
///> Last anchor item selected by Position Relative To function.
|
||||||
|
BOARD_ITEM* m_anchor_item;
|
||||||
|
|
||||||
|
///> Translation for position relative function.
|
||||||
|
wxPoint m_position_relative_translation;
|
||||||
|
|
||||||
|
///> Anchor position for positive relative function.
|
||||||
|
wxPoint m_anchor_position;
|
||||||
|
|
||||||
|
///> Rotation for positive relative function.
|
||||||
|
double m_position_relative_rotation;
|
||||||
|
|
||||||
|
///> Selected that will be moved by Position relative function.
|
||||||
|
SELECTION m_position_relative_selection;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -39,6 +39,7 @@
|
||||||
#include <tools/placement_tool.h>
|
#include <tools/placement_tool.h>
|
||||||
#include <tools/pad_tool.h>
|
#include <tools/pad_tool.h>
|
||||||
#include <tools/microwave_tool.h>
|
#include <tools/microwave_tool.h>
|
||||||
|
#include <tools/position_relative_tool.h>
|
||||||
#include <tools/pcb_actions.h>
|
#include <tools/pcb_actions.h>
|
||||||
|
|
||||||
#include <router/router_tool.h>
|
#include <router/router_tool.h>
|
||||||
|
@ -60,4 +61,5 @@ void PCB_ACTIONS::RegisterAllTools( TOOL_MANAGER* aToolManager )
|
||||||
aToolManager->RegisterTool( new PCB_EDITOR_CONTROL );
|
aToolManager->RegisterTool( new PCB_EDITOR_CONTROL );
|
||||||
aToolManager->RegisterTool( new PLACEMENT_TOOL );
|
aToolManager->RegisterTool( new PLACEMENT_TOOL );
|
||||||
aToolManager->RegisterTool( new MICROWAVE_TOOL );
|
aToolManager->RegisterTool( new MICROWAVE_TOOL );
|
||||||
|
aToolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue