Add Position Relative tool

This commit is contained in:
Russell Oliver 2017-05-10 23:55:03 +10:00 committed by Maciej Suminski
parent f0c8391a46
commit aeb23188f1
13 changed files with 2696 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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 );
}

View File

@ -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__

View File

@ -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,

View File

@ -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,

View File

@ -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 );

View File

@ -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;

View File

@ -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() );
}

View File

@ -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

View File

@ -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 );
} }