Implement modern tools for LibEdit.
This commit is contained in:
parent
40f41133b3
commit
ea0941cab3
|
@ -71,8 +71,7 @@ or not, has a `TOOL_ACTION` instance. This provides:
|
||||||
|
|
||||||
GAL tools inherit the `TOOL_BASE` class. A Pcbnew tool will generally
|
GAL tools inherit the `TOOL_BASE` class. A Pcbnew tool will generally
|
||||||
inherit from `PCB_TOOL`, which is a `TOOL_INTERACTIVE`, which is
|
inherit from `PCB_TOOL`, which is a `TOOL_INTERACTIVE`, which is
|
||||||
a `TOOL_BASE`. In the future, Eeschema tools will be developed in a similar
|
a `TOOL_BASE`. Eeschema tools inherit directly from `TOOL_INTERACTIVE`.
|
||||||
manner.
|
|
||||||
|
|
||||||
The tool class for a tool can be fairly lightweight - much of the
|
The tool class for a tool can be fairly lightweight - much of the
|
||||||
functionality is inherited from the tool's base classes. These base
|
functionality is inherited from the tool's base classes. These base
|
||||||
|
@ -546,22 +545,8 @@ Below you will find the contents of useless_tool.cpp:
|
||||||
|
|
||||||
The last step is to register the tool in the tool manager.
|
The last step is to register the tool in the tool manager.
|
||||||
|
|
||||||
This is done by adding a new instance of the tool to the
|
This is done in the frame's `setupTools()` function for whichever
|
||||||
`registerAllTools()` function in `pcbnew/tools/tools_common.cpp`.
|
`EDA_DRAW_FRAME` support that tool.
|
||||||
|
|
||||||
// add your tool header
|
|
||||||
#include <tools/useless_tool.h>
|
|
||||||
|
|
||||||
void registerAllTools( TOOL_MANAGER *aToolManager )
|
|
||||||
{
|
|
||||||
....
|
|
||||||
aToolManager->RegisterTool( new USELESS_TOOL );
|
|
||||||
....
|
|
||||||
}
|
|
||||||
|
|
||||||
If your new tool applies in the module editor, you also need to do this
|
|
||||||
in `FOOTPRINT_EDIT_FRAME::setupTools()`. Generally, each kind of
|
|
||||||
`EDA_DRAW_FRAME` that can use GAL will have a place to do this.
|
|
||||||
|
|
||||||
## Build and run {#tutorial-summary}
|
## Build and run {#tutorial-summary}
|
||||||
|
|
||||||
|
|
|
@ -397,6 +397,8 @@ set( COMMON_SRCS
|
||||||
tool/common_tools.cpp
|
tool/common_tools.cpp
|
||||||
tool/conditional_menu.cpp
|
tool/conditional_menu.cpp
|
||||||
tool/context_menu.cpp
|
tool/context_menu.cpp
|
||||||
|
tool/edit_constraints.cpp
|
||||||
|
tool/edit_points.cpp
|
||||||
tool/grid_menu.cpp
|
tool/grid_menu.cpp
|
||||||
tool/selection_conditions.cpp
|
tool/selection_conditions.cpp
|
||||||
tool/tool_action.cpp
|
tool/tool_action.cpp
|
||||||
|
|
|
@ -48,6 +48,14 @@ EDA_TEXT::EDA_TEXT( const wxString& text ) :
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
|
||||||
|
m_Text( aText.m_Text ),
|
||||||
|
m_e( aText.m_e )
|
||||||
|
{
|
||||||
|
m_shown_text = UnescapeString( m_Text );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EDA_TEXT::~EDA_TEXT()
|
EDA_TEXT::~EDA_TEXT()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,20 +22,11 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @file block_commande.cpp
|
|
||||||
* @brief Common routines for managing on block commands.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <gr_basic.h>
|
#include <gr_basic.h>
|
||||||
#include <draw_frame.h>
|
#include <draw_frame.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <base_struct.h>
|
|
||||||
#include <base_screen.h>
|
|
||||||
#include <class_drawpanel.h>
|
|
||||||
#include <confirm.h>
|
|
||||||
#include <block_commande.h>
|
#include <block_commande.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,148 +43,41 @@ BLOCK_SELECTOR::BLOCK_SELECTOR() :
|
||||||
|
|
||||||
BLOCK_SELECTOR::~BLOCK_SELECTOR()
|
BLOCK_SELECTOR::~BLOCK_SELECTOR()
|
||||||
{
|
{
|
||||||
ClearListAndDeleteItems();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BLOCK_SELECTOR::SetMessageBlock( EDA_DRAW_FRAME* frame )
|
void BLOCK_SELECTOR::SetMessageBlock( EDA_DRAW_FRAME* frame )
|
||||||
{
|
{
|
||||||
wxString msg;
|
|
||||||
|
|
||||||
switch( m_command )
|
|
||||||
{
|
|
||||||
case BLOCK_IDLE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_MOVE: // Move
|
|
||||||
case BLOCK_PRESELECT_MOVE: // Move with preselection list
|
|
||||||
case BLOCK_MOVE_EXACT:
|
|
||||||
msg = _( "Block Move" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_DRAG: // Drag
|
|
||||||
msg = _( "Block Drag" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_DRAG_ITEM: // Drag
|
|
||||||
msg = _( "Drag item" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_DUPLICATE: // Duplicate
|
|
||||||
msg = _( "Block Duplicate" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_DELETE: // Delete
|
|
||||||
msg = _( "Block Delete" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_COPY: // Copy
|
|
||||||
msg = _( "Block Copy" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_PASTE:
|
|
||||||
msg = _( "Block Paste" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_ZOOM: // Window Zoom
|
|
||||||
msg = _( "Zoom to selection" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_FLIP: // Flip
|
|
||||||
msg = _( "Block Flip" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_ABORT:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
msg = wxT( "???" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->DisplayToolMsg( msg );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BLOCK_SELECTOR::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
|
void BLOCK_SELECTOR::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
|
||||||
GR_DRAWMODE aDrawMode, COLOR4D aColor )
|
GR_DRAWMODE aDrawMode, COLOR4D aColor )
|
||||||
{
|
{
|
||||||
if( !aDC )
|
|
||||||
return;
|
|
||||||
|
|
||||||
int w = GetWidth();
|
|
||||||
int h = GetHeight();
|
|
||||||
|
|
||||||
GRSetDrawMode( aDC, aDrawMode );
|
|
||||||
|
|
||||||
if( w == 0 || h == 0 )
|
|
||||||
GRLine( aPanel->GetClipBox(), aDC, GetX() + aOffset.x, GetY() + aOffset.y,
|
|
||||||
GetRight() + aOffset.x, GetBottom() + aOffset.y, 0, aColor );
|
|
||||||
else
|
|
||||||
GRRect( aPanel->GetClipBox(), aDC, GetX() + aOffset.x, GetY() + aOffset.y,
|
|
||||||
GetRight() + aOffset.x, GetBottom() + aOffset.y, 0, aColor );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BLOCK_SELECTOR::InitData( EDA_DRAW_PANEL* aPanel, const wxPoint& startpos )
|
void BLOCK_SELECTOR::InitData( EDA_DRAW_PANEL* aPanel, const wxPoint& startpos )
|
||||||
{
|
{
|
||||||
m_state = STATE_BLOCK_INIT;
|
|
||||||
SetOrigin( startpos );
|
|
||||||
SetSize( wxSize( 0, 0 ) );
|
|
||||||
m_items.ClearItemsList();
|
|
||||||
aPanel->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BLOCK_SELECTOR::ClearItemsList()
|
void BLOCK_SELECTOR::ClearItemsList()
|
||||||
{
|
{
|
||||||
m_items.ClearItemsList();
|
|
||||||
m_appendUndo = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BLOCK_SELECTOR::ClearListAndDeleteItems()
|
void BLOCK_SELECTOR::ClearListAndDeleteItems()
|
||||||
{
|
{
|
||||||
m_items.ClearListAndDeleteItems();
|
|
||||||
m_appendUndo = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BLOCK_SELECTOR::PushItem( ITEM_PICKER& aItem )
|
void BLOCK_SELECTOR::PushItem( ITEM_PICKER& aItem )
|
||||||
{
|
{
|
||||||
m_items.PushItem( aItem );
|
|
||||||
m_appendUndo = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BLOCK_SELECTOR::Clear()
|
void BLOCK_SELECTOR::Clear()
|
||||||
{
|
{
|
||||||
if( m_command != BLOCK_IDLE )
|
|
||||||
{
|
|
||||||
m_command = BLOCK_IDLE;
|
|
||||||
m_state = STATE_NO_BLOCK;
|
|
||||||
ClearItemsList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbortBlockCurrentCommand( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
|
|
||||||
{
|
|
||||||
BASE_SCREEN* screen = aPanel->GetScreen();
|
|
||||||
|
|
||||||
if( aPanel->IsMouseCaptured() )
|
|
||||||
{
|
|
||||||
aPanel->SetMouseCapture( NULL, NULL );
|
|
||||||
screen->SetCurItem( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
screen->m_BlockLocate.SetCommand( BLOCK_ABORT );
|
|
||||||
aPanel->GetParent()->HandleBlockEnd( aDC );
|
|
||||||
|
|
||||||
aPanel->GetParent()->DisplayToolMsg( wxEmptyString );
|
|
||||||
|
|
||||||
// ugly, but temporary
|
|
||||||
auto gal_panel = dynamic_cast<EDA_DRAW_PANEL_GAL*>( aPanel );
|
|
||||||
|
|
||||||
if( gal_panel )
|
|
||||||
gal_panel->SetDefaultCursor();
|
|
||||||
}
|
|
||||||
|
|
|
@ -546,6 +546,7 @@ void EDA_DRAW_FRAME::OnMouseEvent( wxMouseEvent& event )
|
||||||
|
|
||||||
void EDA_DRAW_FRAME::DisplayToolMsg( const wxString& msg )
|
void EDA_DRAW_FRAME::DisplayToolMsg( const wxString& msg )
|
||||||
{
|
{
|
||||||
|
m_toolMsg = msg;
|
||||||
SetStatusText( msg, 5 );
|
SetStatusText( msg, 5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -588,6 +588,7 @@ void EDA_DRAW_FRAME::OnMouseEvent( wxMouseEvent& event )
|
||||||
|
|
||||||
void EDA_DRAW_FRAME::DisplayToolMsg( const wxString& msg )
|
void EDA_DRAW_FRAME::DisplayToolMsg( const wxString& msg )
|
||||||
{
|
{
|
||||||
|
m_toolMsg = msg;
|
||||||
SetStatusText( msg, 5 );
|
SetStatusText( msg, 5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,3 +152,5 @@ const TOOL_EVENT EVENTS::UnselectedEvent( TC_MESSAGE, TA_ACTION, "common.Interac
|
||||||
///> Event sent after selection is cleared.
|
///> Event sent after selection is cleared.
|
||||||
const TOOL_EVENT EVENTS::ClearedEvent( TC_MESSAGE, TA_ACTION, "common.Interactive.cleared" );
|
const TOOL_EVENT EVENTS::ClearedEvent( TC_MESSAGE, TA_ACTION, "common.Interactive.cleared" );
|
||||||
|
|
||||||
|
const TOOL_EVENT EVENTS::SelectedItemsModified( TC_MESSAGE, TA_ACTION, "common.Interactive.modified" );
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "edit_constraints.h"
|
#include "edit_constraints.h"
|
||||||
#include "edit_points.h"
|
#include "tool/edit_points.h"
|
||||||
|
|
||||||
#include <geometry/seg.h>
|
#include <geometry/seg.h>
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gal/graphics_abstraction_layer.h>
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
#include "edit_points.h"
|
#include <gal/color4d.h>
|
||||||
|
#include "tool/edit_points.h"
|
||||||
|
|
||||||
bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
|
bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
|
||||||
{
|
{
|
||||||
|
@ -244,7 +245,10 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||||
{
|
{
|
||||||
auto gal = aView->GetGAL();
|
auto gal = aView->GetGAL();
|
||||||
|
|
||||||
gal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
|
if( aView->GetGAL()->GetClearColor().GetBrightness() > 0.5 )
|
||||||
|
gal->SetFillColor( KIGFX::COLOR4D( 0, 0, 0, 1.0 ) );
|
||||||
|
else
|
||||||
|
gal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
|
||||||
gal->SetIsFill( true );
|
gal->SetIsFill( true );
|
||||||
gal->SetIsStroke( false );
|
gal->SetIsStroke( false );
|
||||||
gal->PushDepth();
|
gal->PushDepth();
|
|
@ -51,8 +51,11 @@ public:
|
||||||
*
|
*
|
||||||
* @param aPoint stores coordinates for EDIT_POINT.
|
* @param aPoint stores coordinates for EDIT_POINT.
|
||||||
*/
|
*/
|
||||||
EDIT_POINT( const VECTOR2I& aPoint ) :
|
EDIT_POINT( const VECTOR2I& aPoint, EDA_ITEM* aConnection = nullptr ) :
|
||||||
m_position( aPoint ) {};
|
m_position( aPoint ),
|
||||||
|
m_connection( aConnection )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~EDIT_POINT() {}
|
virtual ~EDIT_POINT() {}
|
||||||
|
|
||||||
|
@ -67,6 +70,11 @@ public:
|
||||||
return m_position;
|
return m_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual EDA_ITEM* GetConnection() const
|
||||||
|
{
|
||||||
|
return m_connection;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetX()
|
* Function GetX()
|
||||||
*
|
*
|
||||||
|
@ -99,6 +107,12 @@ public:
|
||||||
m_position = aPosition;
|
m_position = aPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void SetPosition( int x, int y )
|
||||||
|
{
|
||||||
|
m_position.x = x;
|
||||||
|
m_position.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function WithinPoint()
|
* Function WithinPoint()
|
||||||
*
|
*
|
||||||
|
@ -172,7 +186,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///> Position of EDIT_POINT
|
///> Position of EDIT_POINT
|
||||||
VECTOR2I m_position;
|
VECTOR2I m_position;
|
||||||
|
|
||||||
|
///> An optional item to a connected item. Used to mimic polyLine behaviour
|
||||||
|
///> with individual line segments.
|
||||||
|
EDA_ITEM* m_connection;
|
||||||
|
|
||||||
///> Constraint for the point, NULL if none
|
///> Constraint for the point, NULL if none
|
||||||
std::shared_ptr<EDIT_CONSTRAINT<EDIT_POINT> > m_constraint;
|
std::shared_ptr<EDIT_CONSTRAINT<EDIT_POINT> > m_constraint;
|
||||||
|
@ -347,9 +365,9 @@ public:
|
||||||
* Adds an EDIT_POINT.
|
* Adds an EDIT_POINT.
|
||||||
* @param aPoint are coordinates of the new point.
|
* @param aPoint are coordinates of the new point.
|
||||||
*/
|
*/
|
||||||
void AddPoint( const VECTOR2I& aPoint )
|
void AddPoint( const VECTOR2I& aPoint, EDA_ITEM* aConnection = nullptr )
|
||||||
{
|
{
|
||||||
AddPoint( EDIT_POINT( aPoint ) );
|
AddPoint( EDIT_POINT( aPoint, aConnection ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -111,17 +111,14 @@ set( EESCHEMA_WIDGETS
|
||||||
|
|
||||||
|
|
||||||
set ( EESCHEMA_LIBEDIT_SRCS
|
set ( EESCHEMA_LIBEDIT_SRCS
|
||||||
libedit/block_libedit.cpp
|
|
||||||
libedit/controller.cpp
|
libedit/controller.cpp
|
||||||
libedit/libedit.cpp
|
libedit/libedit.cpp
|
||||||
libedit/libedit_onleftclick.cpp
|
|
||||||
libedit/libedit_onrightclick.cpp
|
libedit/libedit_onrightclick.cpp
|
||||||
libedit/libedit_plot_component.cpp
|
libedit/libedit_plot_component.cpp
|
||||||
libedit/libedit_undo_redo.cpp
|
libedit/libedit_undo_redo.cpp
|
||||||
libedit/lib_edit_frame.cpp
|
libedit/lib_edit_frame.cpp
|
||||||
libedit/libfield.cpp
|
libedit/libfield.cpp
|
||||||
libedit/menubar_libedit.cpp
|
libedit/menubar_libedit.cpp
|
||||||
libedit/symbdraw.cpp
|
|
||||||
libedit/symbedit.cpp
|
libedit/symbedit.cpp
|
||||||
libedit/toolbars_libedit.cpp
|
libedit/toolbars_libedit.cpp
|
||||||
libedit/lib_export.cpp
|
libedit/lib_export.cpp
|
||||||
|
@ -138,7 +135,6 @@ set( EESCHEMA_SRCS
|
||||||
annotate.cpp
|
annotate.cpp
|
||||||
autoplace_fields.cpp
|
autoplace_fields.cpp
|
||||||
backanno.cpp
|
backanno.cpp
|
||||||
block.cpp
|
|
||||||
bus_alias.cpp
|
bus_alias.cpp
|
||||||
bus-wire-junction.cpp
|
bus-wire-junction.cpp
|
||||||
class_libentry.cpp
|
class_libentry.cpp
|
||||||
|
@ -234,15 +230,18 @@ set( EESCHEMA_SRCS
|
||||||
netlist_exporters/netlist_exporter_pspice.cpp
|
netlist_exporters/netlist_exporter_pspice.cpp
|
||||||
|
|
||||||
tools/lib_drawing_tools.cpp
|
tools/lib_drawing_tools.cpp
|
||||||
|
tools/lib_edit_tool.cpp
|
||||||
|
tools/lib_move_tool.cpp
|
||||||
tools/lib_pin_tool.cpp
|
tools/lib_pin_tool.cpp
|
||||||
|
tools/point_editor.cpp
|
||||||
tools/sch_actions.cpp
|
tools/sch_actions.cpp
|
||||||
tools/sch_drawing_tools.cpp
|
tools/sch_drawing_tools.cpp
|
||||||
tools/sch_edit_tool.cpp
|
tools/sch_edit_tool.cpp
|
||||||
tools/sch_editor_control.cpp
|
tools/sch_editor_control.cpp
|
||||||
tools/sch_inspection_tool.cpp
|
tools/inspection_tool.cpp
|
||||||
tools/sch_wire_bus_tool.cpp
|
tools/sch_wire_bus_tool.cpp
|
||||||
tools/sch_move_tool.cpp
|
tools/sch_move_tool.cpp
|
||||||
tools/sch_picker_tool.cpp
|
tools/picker_tool.cpp
|
||||||
tools/sch_selection_tool.cpp
|
tools/sch_selection_tool.cpp
|
||||||
tools/selection.cpp
|
tools/selection.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
|
||||||
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@gmail.com>
|
|
||||||
* Copyright (C) 2004-2019 KiCad Developers, see change_log.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 <fctsys.h>
|
|
||||||
#include <pgm_base.h>
|
|
||||||
#include <gr_basic.h>
|
|
||||||
#include <sch_draw_panel.h>
|
|
||||||
#include <confirm.h>
|
|
||||||
#include <sch_edit_frame.h>
|
|
||||||
#include <tool/tool_manager.h>
|
|
||||||
#include <general.h>
|
|
||||||
#include <class_library.h>
|
|
||||||
#include <lib_pin.h>
|
|
||||||
#include <sch_bus_entry.h>
|
|
||||||
#include <sch_marker.h>
|
|
||||||
#include <sch_junction.h>
|
|
||||||
#include <sch_line.h>
|
|
||||||
#include <sch_no_connect.h>
|
|
||||||
#include <sch_text.h>
|
|
||||||
#include <sch_component.h>
|
|
||||||
#include <sch_sheet.h>
|
|
||||||
#include <sch_sheet_path.h>
|
|
||||||
|
|
||||||
#include <preview_items/selection_area.h>
|
|
||||||
#include <sch_view.h>
|
|
||||||
#include <view/view_group.h>
|
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::InitBlockPasteInfos()
|
|
||||||
{
|
|
||||||
wxFAIL_MSG( "How did we get here? Should have gone through modern toolset..." );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
|
|
||||||
{
|
|
||||||
wxFAIL_MSG( "How did we get here? Should have gone through modern toolset..." );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
|
||||||
{
|
|
||||||
wxFAIL_MSG( "How did we get here? Should have gone through modern toolset..." );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DrawAndSizingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
|
|
||||||
bool aErase )
|
|
||||||
{
|
|
||||||
auto panel =static_cast<SCH_DRAW_PANEL*>(aPanel);
|
|
||||||
auto area = panel->GetView()->GetSelectionArea();
|
|
||||||
auto frame = static_cast<EDA_BASE_FRAME*>(aPanel->GetParent());
|
|
||||||
|
|
||||||
BLOCK_SELECTOR* block;
|
|
||||||
bool isLibEdit = frame->IsType( FRAME_SCH_LIB_EDITOR );
|
|
||||||
|
|
||||||
block = &aPanel->GetScreen()->m_BlockLocate;
|
|
||||||
block->SetMoveVector( wxPoint( 0, 0 ) );
|
|
||||||
block->SetLastCursorPosition( aPanel->GetParent()->GetCrossHairPosition( isLibEdit ) );
|
|
||||||
block->SetEnd( aPanel->GetParent()->GetCrossHairPosition() );
|
|
||||||
|
|
||||||
panel->GetView()->ClearPreview();
|
|
||||||
panel->GetView()->ClearHiddenFlags();
|
|
||||||
|
|
||||||
area->SetOrigin( block->GetOrigin() );;
|
|
||||||
area->SetEnd( block->GetEnd() );
|
|
||||||
|
|
||||||
panel->GetView()->SetVisible( area );
|
|
||||||
panel->GetView()->Hide( area, false );
|
|
||||||
panel->GetView()->Update( area );
|
|
||||||
|
|
||||||
if( block->GetState() == STATE_BLOCK_INIT )
|
|
||||||
{
|
|
||||||
if( block->GetWidth() || block->GetHeight() )
|
|
||||||
// 2nd point exists: the rectangle is not surface anywhere
|
|
||||||
block->SetState( STATE_BLOCK_END );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -267,7 +267,7 @@ LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) :
|
||||||
|
|
||||||
for( LIB_ITEM& oldItem : aPart.m_drawings )
|
for( LIB_ITEM& oldItem : aPart.m_drawings )
|
||||||
{
|
{
|
||||||
if( oldItem.IsNew() )
|
if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
newItem = (LIB_ITEM*) oldItem.Clone();
|
newItem = (LIB_ITEM*) oldItem.Clone();
|
||||||
|
|
|
@ -147,8 +147,7 @@ bool DIALOG_LIB_EDIT_TEXT::TransferDataFromWindow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_parent->GetDrawItem() )
|
m_parent->SetMsgPanel( m_graphicText );
|
||||||
m_parent->SetMsgPanel( m_parent->GetDrawItem() );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,9 +143,6 @@ enum id_eeschema_frm
|
||||||
ID_POPUP_SCH_SELECT_UNIT_CMP_MAX = ID_POPUP_SCH_SELECT_UNIT1
|
ID_POPUP_SCH_SELECT_UNIT_CMP_MAX = ID_POPUP_SCH_SELECT_UNIT1
|
||||||
+ MAX_UNIT_COUNT_PER_PACKAGE,
|
+ MAX_UNIT_COUNT_PER_PACKAGE,
|
||||||
|
|
||||||
ID_SELECT_ITEM_START,
|
|
||||||
ID_SELECT_ITEM_END = ID_SELECT_ITEM_START + MAX_SELECT_ITEM_IDS,
|
|
||||||
|
|
||||||
// Change orientation command IDs.
|
// Change orientation command IDs.
|
||||||
ID_SCH_MIRROR_X,
|
ID_SCH_MIRROR_X,
|
||||||
ID_SCH_MIRROR_Y,
|
ID_SCH_MIRROR_Y,
|
||||||
|
@ -162,7 +159,6 @@ enum id_eeschema_frm
|
||||||
ID_SCH_DELETE,
|
ID_SCH_DELETE,
|
||||||
ID_SCH_END_LINE_WIRE_OR_BUS,
|
ID_SCH_END_LINE_WIRE_OR_BUS,
|
||||||
ID_SCH_UNFOLD_BUS,
|
ID_SCH_UNFOLD_BUS,
|
||||||
ID_SCH_RESIZE_SHEET,
|
|
||||||
|
|
||||||
ID_AUTOPLACE_FIELDS,
|
ID_AUTOPLACE_FIELDS,
|
||||||
|
|
||||||
|
@ -215,14 +211,7 @@ enum id_eeschema_frm
|
||||||
ID_LIBEDIT_EXPORT_BODY_BUTT,
|
ID_LIBEDIT_EXPORT_BODY_BUTT,
|
||||||
ID_LIBEDIT_DELETE_ITEM_BUTT,
|
ID_LIBEDIT_DELETE_ITEM_BUTT,
|
||||||
|
|
||||||
/* Change orientation command ID */
|
|
||||||
ID_LIBEDIT_ROTATE_ITEM,
|
|
||||||
ID_LIBEDIT_MIRROR_X,
|
|
||||||
ID_LIBEDIT_MIRROR_Y,
|
|
||||||
ID_LIBEDIT_ORIENT_NORMAL,
|
|
||||||
|
|
||||||
/* Library editor context menu IDs */
|
/* Library editor context menu IDs */
|
||||||
ID_LIBEDIT_EDIT_PIN,
|
|
||||||
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
|
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
|
||||||
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM,
|
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM,
|
||||||
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM,
|
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM,
|
||||||
|
@ -230,8 +219,6 @@ enum id_eeschema_frm
|
||||||
ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
|
ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
|
||||||
ID_POPUP_LIBEDIT_DELETE_ITEM,
|
ID_POPUP_LIBEDIT_DELETE_ITEM,
|
||||||
ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
ID_POPUP_LIBEDIT_MODIFY_ITEM,
|
||||||
ID_POPUP_LIBEDIT_CANCEL_EDITING,
|
|
||||||
ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
|
|
||||||
ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM,
|
ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM,
|
||||||
ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT,
|
ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT,
|
||||||
|
|
||||||
|
|
|
@ -193,8 +193,6 @@ static EDA_HOTKEY HkDuplicateItem( _HKI( "Duplicate" ), HK_DUPLICATE, 'D' + GR_K
|
||||||
|
|
||||||
static EDA_HOTKEY HkDrag( _HKI( "Drag Item" ), HK_DRAG, 'G',
|
static EDA_HOTKEY HkDrag( _HKI( "Drag Item" ), HK_DRAG, 'G',
|
||||||
ID_SCH_DRAG );
|
ID_SCH_DRAG );
|
||||||
static EDA_HOTKEY HkMove2Drag( _HKI( "Move Block -> Drag Block" ),
|
|
||||||
HK_MOVEBLOCK_TO_DRAGBLOCK, '\t', ID_POPUP_DRAG_BLOCK );
|
|
||||||
static EDA_HOTKEY HkInsert( _HKI( "Repeat Last Item" ), HK_REPEAT_LAST, WXK_INSERT );
|
static EDA_HOTKEY HkInsert( _HKI( "Repeat Last Item" ), HK_REPEAT_LAST, WXK_INSERT );
|
||||||
static EDA_HOTKEY HkDelete( _HKI( "Delete Item" ), HK_DELETE, WXK_DELETE );
|
static EDA_HOTKEY HkDelete( _HKI( "Delete Item" ), HK_DELETE, WXK_DELETE );
|
||||||
|
|
||||||
|
@ -213,7 +211,6 @@ static EDA_HOTKEY HkZoomSelection( _HKI( "Zoom to Selection" ), HK_ZOOM_SELECTIO
|
||||||
static EDA_HOTKEY HkCreatePin( _HKI( "Create Pin" ), HK_LIBEDIT_CREATE_PIN, 'P',
|
static EDA_HOTKEY HkCreatePin( _HKI( "Create Pin" ), HK_LIBEDIT_CREATE_PIN, 'P',
|
||||||
ID_LIBEDIT_PIN_BUTT );
|
ID_LIBEDIT_PIN_BUTT );
|
||||||
static EDA_HOTKEY HkInsertPin( _HKI( "Repeat Pin" ), HK_REPEAT_LAST, WXK_INSERT );
|
static EDA_HOTKEY HkInsertPin( _HKI( "Repeat Pin" ), HK_REPEAT_LAST, WXK_INSERT );
|
||||||
static EDA_HOTKEY HkMoveLibItem( _HKI( "Move Library Item" ), HK_LIBEDIT_MOVE_GRAPHIC_ITEM, 'M' );
|
|
||||||
static EDA_HOTKEY HkViewDoc( _HKI( "Show Datasheet" ), HK_LIBEDIT_VIEW_DOC, 'D' + GR_KB_ALT,
|
static EDA_HOTKEY HkViewDoc( _HKI( "Show Datasheet" ), HK_LIBEDIT_VIEW_DOC, 'D' + GR_KB_ALT,
|
||||||
ID_LIBEDIT_VIEW_DOC );
|
ID_LIBEDIT_VIEW_DOC );
|
||||||
|
|
||||||
|
@ -296,9 +293,13 @@ static EDA_HOTKEY* common_Hotkey_List[] =
|
||||||
&HkZoomSelection,
|
&HkZoomSelection,
|
||||||
&HkResetLocalCoord,
|
&HkResetLocalCoord,
|
||||||
&HkEdit,
|
&HkEdit,
|
||||||
|
&HkDuplicateItem,
|
||||||
&HkDelete,
|
&HkDelete,
|
||||||
&HkRotate,
|
&HkRotate,
|
||||||
&HkDrag,
|
&HkDrag,
|
||||||
|
&HkMove,
|
||||||
|
&HkMirrorX,
|
||||||
|
&HkMirrorY,
|
||||||
&HkMouseLeftClick,
|
&HkMouseLeftClick,
|
||||||
&HkMouseLeftDClick,
|
&HkMouseLeftDClick,
|
||||||
NULL
|
NULL
|
||||||
|
@ -314,6 +315,13 @@ static EDA_HOTKEY* common_basic_Hotkey_List[] =
|
||||||
&HkZoomCenter,
|
&HkZoomCenter,
|
||||||
&HkZoomAuto,
|
&HkZoomAuto,
|
||||||
&HkResetLocalCoord,
|
&HkResetLocalCoord,
|
||||||
|
&HkEdit,
|
||||||
|
&HkDuplicateItem,
|
||||||
|
&HkDelete,
|
||||||
|
&HkRotate,
|
||||||
|
&HkMove,
|
||||||
|
&HkMirrorX,
|
||||||
|
&HkMirrorY,
|
||||||
&HkMouseLeftClick,
|
&HkMouseLeftClick,
|
||||||
&HkMouseLeftDClick,
|
&HkMouseLeftDClick,
|
||||||
NULL
|
NULL
|
||||||
|
@ -327,13 +335,8 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
|
||||||
&HkFindNextMarker,
|
&HkFindNextMarker,
|
||||||
&HkFindReplace,
|
&HkFindReplace,
|
||||||
&HkInsert,
|
&HkInsert,
|
||||||
&HkMove2Drag,
|
|
||||||
&HkMove,
|
|
||||||
&HkDuplicateItem,
|
|
||||||
&HkAddComponent,
|
&HkAddComponent,
|
||||||
&HkAddPower,
|
&HkAddPower,
|
||||||
&HkMirrorX,
|
|
||||||
&HkMirrorY,
|
|
||||||
&HkEditValue,
|
&HkEditValue,
|
||||||
&HkEditReference,
|
&HkEditReference,
|
||||||
&HkEditFootprint,
|
&HkEditFootprint,
|
||||||
|
@ -369,9 +372,6 @@ static EDA_HOTKEY* libEdit_Hotkey_List[] =
|
||||||
{
|
{
|
||||||
&HkCreatePin,
|
&HkCreatePin,
|
||||||
&HkInsertPin,
|
&HkInsertPin,
|
||||||
&HkMoveLibItem,
|
|
||||||
&HkMirrorX,
|
|
||||||
&HkMirrorY,
|
|
||||||
&HkViewDoc,
|
&HkViewDoc,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -541,7 +541,9 @@ bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
||||||
if( aHotKey == 0 )
|
if( aHotKey == 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
|
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
|
||||||
|
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||||
|
SELECTION& selection = selTool->GetSelection();
|
||||||
|
|
||||||
cmd.SetEventObject( this );
|
cmd.SetEventObject( this );
|
||||||
|
|
||||||
|
@ -558,11 +560,6 @@ bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
||||||
if( hotKey == NULL )
|
if( hotKey == NULL )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// itemInEdit == false means no item currently edited. We can ask for editing a new item
|
|
||||||
bool itemInEdit = IsEditingDrawItem();
|
|
||||||
|
|
||||||
bool blocInProgress = GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK;
|
|
||||||
|
|
||||||
switch( hotKey->m_Idcommand )
|
switch( hotKey->m_Idcommand )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
@ -582,11 +579,6 @@ bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
||||||
GetScreen()->m_O_Curseur = GetCrossHairPosition();
|
GetScreen()->m_O_Curseur = GetCrossHairPosition();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HK_ZOOM_IN:
|
|
||||||
case HK_ZOOM_OUT:
|
|
||||||
case HK_ZOOM_REDRAW:
|
|
||||||
case HK_ZOOM_CENTER:
|
|
||||||
case HK_ZOOM_AUTO:
|
|
||||||
case HK_EDIT_PASTE:
|
case HK_EDIT_PASTE:
|
||||||
case HK_EDIT_COPY:
|
case HK_EDIT_COPY:
|
||||||
case HK_EDIT_CUT:
|
case HK_EDIT_CUT:
|
||||||
|
@ -596,138 +588,12 @@ bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
||||||
|
|
||||||
case HK_UNDO:
|
case HK_UNDO:
|
||||||
case HK_REDO:
|
case HK_REDO:
|
||||||
if( !itemInEdit )
|
if( SCH_CONDITIONS::Idle( selection ) )
|
||||||
{
|
{
|
||||||
cmd.SetId( hotKey->m_IdMenuEvent );
|
cmd.SetId( hotKey->m_IdMenuEvent );
|
||||||
GetEventHandler()->ProcessEvent( cmd );
|
GetEventHandler()->ProcessEvent( cmd );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HK_REPEAT_LAST:
|
|
||||||
if( ! itemInEdit )
|
|
||||||
{
|
|
||||||
if( m_lastDrawItem && !m_lastDrawItem->InEditMode() &&
|
|
||||||
( m_lastDrawItem->Type() == LIB_PIN_T ) )
|
|
||||||
RepeatPinItem( aDC, (LIB_PIN*) m_lastDrawItem );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_EDIT:
|
|
||||||
if ( !itemInEdit )
|
|
||||||
SetDrawItem( LocateItemUsingCursor( aPosition ) );
|
|
||||||
|
|
||||||
if( GetDrawItem() )
|
|
||||||
{
|
|
||||||
switch( GetDrawItem()->Type() )
|
|
||||||
{
|
|
||||||
case LIB_PIN_T:
|
|
||||||
cmd.SetId( ID_LIBEDIT_EDIT_PIN );
|
|
||||||
GetEventHandler()->ProcessEvent( cmd );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_ARC_T:
|
|
||||||
case LIB_CIRCLE_T:
|
|
||||||
case LIB_RECTANGLE_T:
|
|
||||||
case LIB_POLYLINE_T:
|
|
||||||
case LIB_TEXT_T:
|
|
||||||
cmd.SetId( ID_POPUP_LIBEDIT_BODY_EDIT_ITEM );
|
|
||||||
GetEventHandler()->ProcessEvent( cmd );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_FIELD_T:
|
|
||||||
cmd.SetId( ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM );
|
|
||||||
GetEventHandler()->ProcessEvent( cmd );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_ROTATE:
|
|
||||||
if ( !itemInEdit && !blocInProgress )
|
|
||||||
SetDrawItem( LocateItemUsingCursor( aPosition ) );
|
|
||||||
|
|
||||||
if( blocInProgress || GetDrawItem() )
|
|
||||||
{
|
|
||||||
cmd.SetId( ID_LIBEDIT_ROTATE_ITEM );
|
|
||||||
OnRotate( cmd );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_LIBEDIT_CREATE_PIN:
|
|
||||||
if( ! itemInEdit )
|
|
||||||
{
|
|
||||||
SetToolID( ID_LIBEDIT_PIN_BUTT, wxCURSOR_PENCIL, _( "Add Pin" ) );
|
|
||||||
OnLeftClick( aDC, aPosition );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_LIBEDIT_MOVE_GRAPHIC_ITEM:
|
|
||||||
if( !itemInEdit && !blocInProgress )
|
|
||||||
{
|
|
||||||
SetDrawItem( LocateItemUsingCursor( aPosition ) );
|
|
||||||
|
|
||||||
if( GetDrawItem() )
|
|
||||||
{
|
|
||||||
cmd.SetId( ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST );
|
|
||||||
Process_Special_Functions( cmd );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_DRAG:
|
|
||||||
if( !itemInEdit && !blocInProgress )
|
|
||||||
{
|
|
||||||
SetDrawItem( LocateItemUsingCursor( aPosition ) );
|
|
||||||
|
|
||||||
if( GetDrawItem() )
|
|
||||||
{
|
|
||||||
cmd.SetId( ID_POPUP_LIBEDIT_MODIFY_ITEM );
|
|
||||||
Process_Special_Functions( cmd );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_MIRROR_Y: // Mirror Y
|
|
||||||
if( !itemInEdit && !blocInProgress )
|
|
||||||
SetDrawItem( LocateItemUsingCursor( aPosition ) );
|
|
||||||
|
|
||||||
if( blocInProgress || GetDrawItem() )
|
|
||||||
{
|
|
||||||
cmd.SetId( ID_LIBEDIT_MIRROR_Y );
|
|
||||||
OnOrient( cmd );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_MIRROR_X: // Mirror X
|
|
||||||
if( !itemInEdit && !blocInProgress )
|
|
||||||
SetDrawItem( LocateItemUsingCursor( aPosition ) );
|
|
||||||
|
|
||||||
if( blocInProgress || GetDrawItem() )
|
|
||||||
{
|
|
||||||
cmd.SetId( ID_LIBEDIT_MIRROR_X );
|
|
||||||
OnOrient( cmd );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_LEFT_CLICK:
|
|
||||||
case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
|
|
||||||
if( GetScreen()->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
|
|
||||||
{
|
|
||||||
GetCanvas()->SetAutoPanRequest( false );
|
|
||||||
HandleBlockPlace( aDC );
|
|
||||||
}
|
|
||||||
else if( GetScreen()->m_BlockLocate.GetState() == STATE_NO_BLOCK )
|
|
||||||
{
|
|
||||||
auto pos = GetCrossHairPosition();
|
|
||||||
OnLeftClick( aDC, pos );
|
|
||||||
|
|
||||||
if( hotKey->m_Idcommand == HK_LEFT_DCLICK )
|
|
||||||
OnLeftDClick( aDC, pos );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hot key handled.
|
// Hot key handled.
|
||||||
|
@ -781,15 +647,6 @@ bool LIB_VIEW_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
||||||
GetScreen()->m_O_Curseur = GetCrossHairPosition();
|
GetScreen()->m_O_Curseur = GetCrossHairPosition();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HK_LEFT_CLICK:
|
|
||||||
OnLeftClick( aDC, aPosition );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
|
|
||||||
OnLeftClick( aDC, aPosition );
|
|
||||||
OnLeftDClick( aDC, aPosition );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HK_ZOOM_IN:
|
case HK_ZOOM_IN:
|
||||||
cmd.SetId( ID_KEY_ZOOM_IN );
|
cmd.SetId( ID_KEY_ZOOM_IN );
|
||||||
GetEventHandler()->ProcessEvent( cmd );
|
GetEventHandler()->ProcessEvent( cmd );
|
||||||
|
|
|
@ -47,42 +47,6 @@ static inline wxPoint twoPointVector( const wxPoint &startPoint, const wxPoint &
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! @brief Given three points A B C, compute the circumcenter of the resulting triangle
|
|
||||||
//! reference: http://en.wikipedia.org/wiki/Circumscribed_circle
|
|
||||||
//! Coordinates of circumcenter in Cartesian coordinates
|
|
||||||
static wxPoint calcCenter( const wxPoint& A, const wxPoint& B, const wxPoint& C )
|
|
||||||
{
|
|
||||||
double circumCenterX, circumCenterY;
|
|
||||||
double Ax = (double) A.x;
|
|
||||||
double Ay = (double) A.y;
|
|
||||||
double Bx = (double) B.x;
|
|
||||||
double By = (double) B.y;
|
|
||||||
double Cx = (double) C.x;
|
|
||||||
double Cy = (double) C.y;
|
|
||||||
|
|
||||||
wxPoint circumCenter;
|
|
||||||
|
|
||||||
double D = 2.0 * ( Ax * ( By - Cy ) + Bx * ( Cy - Ay ) + Cx * ( Ay - By ) );
|
|
||||||
|
|
||||||
// prevent division / 0
|
|
||||||
if( fabs( D ) < 1e-7 )
|
|
||||||
D = 1e-7;
|
|
||||||
|
|
||||||
circumCenterX = ( (Ay * Ay + Ax * Ax) * (By - Cy) +
|
|
||||||
(By * By + Bx * Bx) * (Cy - Ay) +
|
|
||||||
(Cy * Cy + Cx * Cx) * (Ay - By) ) / D;
|
|
||||||
|
|
||||||
circumCenterY = ( (Ay * Ay + Ax * Ax) * (Cx - Bx) +
|
|
||||||
(By * By + Bx * Bx) * (Ax - Cx) +
|
|
||||||
(Cy * Cy + Cx * Cx) * (Bx - Ax) ) / D;
|
|
||||||
|
|
||||||
circumCenter.x = (int) circumCenterX;
|
|
||||||
circumCenter.y = (int) circumCenterY;
|
|
||||||
|
|
||||||
return circumCenter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent )
|
LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent )
|
||||||
{
|
{
|
||||||
m_Radius = 0;
|
m_Radius = 0;
|
||||||
|
@ -310,7 +274,7 @@ void LIB_ARC::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
||||||
{
|
{
|
||||||
pen_size = std::max( 0, pen_size );
|
pen_size = std::max( 0, pen_size );
|
||||||
aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
|
aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
|
||||||
aPlotter->Arc( pos, -t2, -t1, m_Radius, already_filled ? NO_FILL : m_Fill, GetPenSize() );
|
aPlotter->Arc( pos, -t2, -t1, m_Radius, already_filled ? NO_FILL : m_Fill, pen_size );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,23 +319,14 @@ void LIB_ARC::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOf
|
||||||
FILL_T fill = aData ? NO_FILL : m_Fill;
|
FILL_T fill = aData ? NO_FILL : m_Fill;
|
||||||
|
|
||||||
EDA_RECT* const clipbox = aPanel? aPanel->GetClipBox() : NULL;
|
EDA_RECT* const clipbox = aPanel? aPanel->GetClipBox() : NULL;
|
||||||
|
int penSize = GetPenSize();
|
||||||
|
|
||||||
if( fill == FILLED_WITH_BG_BODYCOLOR )
|
if( fill == FILLED_WITH_BG_BODYCOLOR )
|
||||||
{
|
GRFilledArc( clipbox, aDC, posc.x, posc.y, pt1, pt2, m_Radius, penSize, bgColor, bgColor );
|
||||||
GRFilledArc( clipbox, aDC, posc.x, posc.y, pt1, pt2, m_Radius, GetPenSize( ),
|
|
||||||
bgColor, bgColor );
|
|
||||||
}
|
|
||||||
else if( fill == FILLED_SHAPE && !aData )
|
else if( fill == FILLED_SHAPE && !aData )
|
||||||
{
|
GRFilledArc( clipbox, aDC, posc.x, posc.y, pt1, pt2, m_Radius, color, color );
|
||||||
GRFilledArc( clipbox, aDC, posc.x, posc.y, pt1, pt2, m_Radius,
|
|
||||||
color, color );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
GRArc1( clipbox, aDC, pos1.x, pos1.y, pos2.x, pos2.y, posc.x, posc.y, penSize, color );
|
||||||
|
|
||||||
GRArc1( clipbox, aDC, pos1.x, pos1.y, pos2.x, pos2.y, posc.x, posc.y, GetPenSize(),
|
|
||||||
color );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -545,81 +500,7 @@ void LIB_ARC::EndEdit( const wxPoint& aPosition )
|
||||||
|
|
||||||
void LIB_ARC::CalcEdit( const wxPoint& aPosition )
|
void LIB_ARC::CalcEdit( const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
if( IsResized() )
|
if( IsNew() )
|
||||||
{
|
|
||||||
wxPoint newCenterPoint, startPos, endPos;
|
|
||||||
|
|
||||||
// Choose the point of the arc to be adjusted
|
|
||||||
if( m_editSelectPoint == ARC_STATUS_START )
|
|
||||||
{
|
|
||||||
startPos = aPosition;
|
|
||||||
endPos = m_ArcEnd;
|
|
||||||
}
|
|
||||||
else if( m_editSelectPoint == ARC_STATUS_END )
|
|
||||||
{
|
|
||||||
endPos = aPosition;
|
|
||||||
startPos = m_ArcStart;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Use the cursor for adjusting the arc curvature
|
|
||||||
startPos = m_ArcStart;
|
|
||||||
endPos = m_ArcEnd;
|
|
||||||
|
|
||||||
// If the distance is too small, use the old center point
|
|
||||||
// else the new center point is calculated over the three points start/end/cursor
|
|
||||||
if( DistanceLinePoint( startPos, endPos, aPosition ) > MINIMUM_SELECTION_DISTANCE )
|
|
||||||
{
|
|
||||||
newCenterPoint = calcCenter( startPos, aPosition, endPos );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newCenterPoint = m_Pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine if the arc angle is larger than 180 degrees -> this happens if both
|
|
||||||
// points (cursor position, center point) lie on the same side of the vector
|
|
||||||
// start-end
|
|
||||||
double crossA = CrossProduct( twoPointVector( startPos, endPos ),
|
|
||||||
twoPointVector( endPos, aPosition ) );
|
|
||||||
double crossB = CrossProduct( twoPointVector( startPos, endPos ),
|
|
||||||
twoPointVector( endPos, newCenterPoint ) );
|
|
||||||
|
|
||||||
if( ( crossA < 0 && crossB < 0 ) || ( crossA >= 0 && crossB >= 0 ) )
|
|
||||||
newCenterPoint = m_Pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_editSelectPoint == ARC_STATUS_START || m_editSelectPoint == ARC_STATUS_END )
|
|
||||||
{
|
|
||||||
// Compute the new center point when the start/end points are modified
|
|
||||||
wxPoint middlePoint = wxPoint( (startPos.x + endPos.x) / 2,
|
|
||||||
(startPos.y + endPos.y) / 2 );
|
|
||||||
|
|
||||||
wxPoint startEndVector = twoPointVector( startPos, endPos );
|
|
||||||
wxPoint perpendicularVector = wxPoint( -startEndVector.y, startEndVector.x );
|
|
||||||
double lengthPerpendicularVector = EuclideanNorm( perpendicularVector );
|
|
||||||
|
|
||||||
// prevent too large values, division / 0
|
|
||||||
if( lengthPerpendicularVector < 1e-1 )
|
|
||||||
lengthPerpendicularVector = 1e-1;
|
|
||||||
|
|
||||||
perpendicularVector.x = (int) ( (double) perpendicularVector.x *
|
|
||||||
m_editCenterDistance /
|
|
||||||
lengthPerpendicularVector ) * m_editDirection;
|
|
||||||
perpendicularVector.y = (int) ( (double) perpendicularVector.y *
|
|
||||||
m_editCenterDistance /
|
|
||||||
lengthPerpendicularVector ) * m_editDirection;
|
|
||||||
|
|
||||||
newCenterPoint = middlePoint + perpendicularVector;
|
|
||||||
|
|
||||||
m_ArcStart = startPos;
|
|
||||||
m_ArcEnd = endPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Pos = newCenterPoint;
|
|
||||||
CalcRadiusAngles();
|
|
||||||
}
|
|
||||||
else if( IsNew() )
|
|
||||||
{
|
{
|
||||||
if( m_editState == 1 )
|
if( m_editState == 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
LIB_CIRCLE::LIB_CIRCLE( LIB_PART* aParent ) :
|
LIB_CIRCLE::LIB_CIRCLE( LIB_PART* aParent ) :
|
||||||
LIB_ITEM( LIB_CIRCLE_T, aParent )
|
LIB_ITEM( LIB_CIRCLE_T, aParent )
|
||||||
{
|
{
|
||||||
m_Radius = 0;
|
|
||||||
m_Width = 0;
|
m_Width = 0;
|
||||||
m_Fill = NO_FILL;
|
m_Fill = NO_FILL;
|
||||||
m_isFillable = true;
|
m_isFillable = true;
|
||||||
|
@ -57,7 +56,7 @@ bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef, int aAccuracy ) const
|
||||||
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
|
int mindist = std::max( aAccuracy + GetPenSize() / 2, MINIMUM_SELECTION_DISTANCE );
|
||||||
int dist = KiROUND( GetLineLength( aPosRef, DefaultTransform.TransformCoordinate( m_Pos ) ) );
|
int dist = KiROUND( GetLineLength( aPosRef, DefaultTransform.TransformCoordinate( m_Pos ) ) );
|
||||||
|
|
||||||
if( abs( dist - m_Radius ) <= mindist )
|
if( abs( dist - GetRadius() ) <= mindist )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -99,8 +98,11 @@ int LIB_CIRCLE::compare( const LIB_ITEM& aOther ) const
|
||||||
if( m_Pos.y != tmp->m_Pos.y )
|
if( m_Pos.y != tmp->m_Pos.y )
|
||||||
return m_Pos.y - tmp->m_Pos.y;
|
return m_Pos.y - tmp->m_Pos.y;
|
||||||
|
|
||||||
if( m_Radius != tmp->m_Radius )
|
if( m_EndPos.x != tmp->m_EndPos.x )
|
||||||
return m_Radius - tmp->m_Radius;
|
return m_EndPos.x - tmp->m_EndPos.x;
|
||||||
|
|
||||||
|
if( m_EndPos.y != tmp->m_EndPos.y )
|
||||||
|
return m_EndPos.y - tmp->m_EndPos.y;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -109,19 +111,20 @@ int LIB_CIRCLE::compare( const LIB_ITEM& aOther ) const
|
||||||
void LIB_CIRCLE::SetOffset( const wxPoint& aOffset )
|
void LIB_CIRCLE::SetOffset( const wxPoint& aOffset )
|
||||||
{
|
{
|
||||||
m_Pos += aOffset;
|
m_Pos += aOffset;
|
||||||
|
m_EndPos += aOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LIB_CIRCLE::Inside( EDA_RECT& aRect ) const
|
bool LIB_CIRCLE::Inside( EDA_RECT& aRect ) const
|
||||||
{
|
{
|
||||||
wxPoint center(m_Pos.x, -m_Pos.y);
|
wxPoint center(m_Pos.x, -m_Pos.y);
|
||||||
return aRect.IntersectsCircle( center, m_Radius );
|
return aRect.IntersectsCircle( center, GetRadius() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_CIRCLE::Move( const wxPoint& aPosition )
|
void LIB_CIRCLE::Move( const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
m_Pos = aPosition;
|
SetOffset( aPosition - m_Pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,7 +160,7 @@ void LIB_CIRCLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
||||||
if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
|
if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
|
||||||
{
|
{
|
||||||
aPlotter->SetColor( GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
|
aPlotter->SetColor( GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
|
||||||
aPlotter->Circle( pos, m_Radius * 2, FILLED_WITH_BG_BODYCOLOR, 0 );
|
aPlotter->Circle( pos, GetRadius() * 2, FILLED_WITH_BG_BODYCOLOR, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
|
bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
|
||||||
|
@ -167,7 +170,7 @@ void LIB_CIRCLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
||||||
{
|
{
|
||||||
pen_size = std::max( 0, pen_size );
|
pen_size = std::max( 0, pen_size );
|
||||||
aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
|
aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
|
||||||
aPlotter->Circle( pos, m_Radius * 2, already_filled ? NO_FILL : m_Fill, GetPenSize() );
|
aPlotter->Circle( pos, GetRadius() * 2, already_filled ? NO_FILL : m_Fill, pen_size );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,20 +198,21 @@ void LIB_CIRCLE::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint&
|
||||||
EDA_RECT* const clipbox = aPanel? aPanel->GetClipBox() : NULL;
|
EDA_RECT* const clipbox = aPanel? aPanel->GetClipBox() : NULL;
|
||||||
|
|
||||||
if( fill == FILLED_WITH_BG_BODYCOLOR )
|
if( fill == FILLED_WITH_BG_BODYCOLOR )
|
||||||
GRFilledCircle( clipbox, aDC, pos1.x, pos1.y, m_Radius, GetPenSize(), bgColor, bgColor );
|
GRFilledCircle( clipbox, aDC, pos1.x, pos1.y, GetRadius(), GetPenSize(), bgColor, bgColor );
|
||||||
else if( fill == FILLED_SHAPE )
|
else if( fill == FILLED_SHAPE )
|
||||||
GRFilledCircle( clipbox, aDC, pos1.x, pos1.y, m_Radius, 0, color, color );
|
GRFilledCircle( clipbox, aDC, pos1.x, pos1.y, GetRadius(), 0, color, color );
|
||||||
else
|
else
|
||||||
GRCircle( clipbox, aDC, pos1.x, pos1.y, m_Radius, GetPenSize(), color );
|
GRCircle( clipbox, aDC, pos1.x, pos1.y, GetRadius(), GetPenSize(), color );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const EDA_RECT LIB_CIRCLE::GetBoundingBox() const
|
const EDA_RECT LIB_CIRCLE::GetBoundingBox() const
|
||||||
{
|
{
|
||||||
EDA_RECT rect;
|
EDA_RECT rect;
|
||||||
|
int radius = GetRadius();
|
||||||
|
|
||||||
rect.SetOrigin( m_Pos.x - m_Radius, m_Pos.y - m_Radius );
|
rect.SetOrigin( m_Pos.x - radius, m_Pos.y - radius );
|
||||||
rect.SetEnd( m_Pos.x + m_Radius, m_Pos.y + m_Radius );
|
rect.SetEnd( m_Pos.x + radius, m_Pos.y + radius );
|
||||||
rect.Inflate( ( GetPenSize()+1 ) / 2 );
|
rect.Inflate( ( GetPenSize()+1 ) / 2 );
|
||||||
|
|
||||||
rect.RevertYAxis();
|
rect.RevertYAxis();
|
||||||
|
@ -228,7 +232,7 @@ void LIB_CIRCLE::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList )
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
|
||||||
|
|
||||||
msg = MessageTextFromValue( aUnits, m_Radius, true );
|
msg = MessageTextFromValue( aUnits, GetRadius(), true );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Radius" ), msg, RED ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "Radius" ), msg, RED ) );
|
||||||
|
|
||||||
msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
|
msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
|
||||||
|
@ -243,7 +247,7 @@ wxString LIB_CIRCLE::GetSelectMenuText( EDA_UNITS_T aUnits ) const
|
||||||
return wxString::Format( _( "Circle center (%s, %s), radius %s" ),
|
return wxString::Format( _( "Circle center (%s, %s), radius %s" ),
|
||||||
MessageTextFromValue( aUnits, m_Pos.x ),
|
MessageTextFromValue( aUnits, m_Pos.x ),
|
||||||
MessageTextFromValue( aUnits, m_Pos.y ),
|
MessageTextFromValue( aUnits, m_Pos.y ),
|
||||||
MessageTextFromValue( aUnits, m_Radius ) );
|
MessageTextFromValue( aUnits, GetRadius() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -271,11 +275,11 @@ void LIB_CIRCLE::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
|
||||||
|
|
||||||
void LIB_CIRCLE::CalcEdit( const wxPoint& aPosition )
|
void LIB_CIRCLE::CalcEdit( const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
if( IsNew() || IsResized() )
|
if( IsNew() )
|
||||||
{
|
{
|
||||||
m_Radius = KiROUND( GetLineLength( m_Pos, aPosition ) );
|
SetEnd( aPosition );
|
||||||
}
|
}
|
||||||
else
|
else if( IsMoving() )
|
||||||
{
|
{
|
||||||
Move( m_initialPos + aPosition - m_initialCursorPos );
|
Move( m_initialPos + aPosition - m_initialCursorPos );
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
|
|
||||||
class LIB_CIRCLE : public LIB_ITEM
|
class LIB_CIRCLE : public LIB_ITEM
|
||||||
{
|
{
|
||||||
int m_Radius;
|
|
||||||
wxPoint m_Pos; // Position or centre (Arc and Circle) or start point (segments).
|
wxPoint m_Pos; // Position or centre (Arc and Circle) or start point (segments).
|
||||||
|
wxPoint m_EndPos; // A point on the circumference of the circle.
|
||||||
int m_Width; // Line width.
|
int m_Width; // Line width.
|
||||||
|
|
||||||
void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, void* aData,
|
void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, void* aData,
|
||||||
|
@ -78,6 +78,9 @@ public:
|
||||||
|
|
||||||
wxPoint GetPosition() const override { return m_Pos; }
|
wxPoint GetPosition() const override { return m_Pos; }
|
||||||
|
|
||||||
|
void SetEnd( const wxPoint& aPosition ) { m_EndPos = aPosition; }
|
||||||
|
wxPoint GetEnd() const { return m_EndPos; }
|
||||||
|
|
||||||
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
||||||
void MirrorVertical( const wxPoint& aCenter ) override;
|
void MirrorVertical( const wxPoint& aCenter ) override;
|
||||||
|
|
||||||
|
@ -89,8 +92,8 @@ public:
|
||||||
int GetWidth() const override { return m_Width; }
|
int GetWidth() const override { return m_Width; }
|
||||||
void SetWidth( int aWidth ) override { m_Width = aWidth; }
|
void SetWidth( int aWidth ) override { m_Width = aWidth; }
|
||||||
|
|
||||||
void SetRadius( int aRadius ) { m_Radius = aRadius; }
|
void SetRadius( int aRadius ) { m_EndPos = wxPoint( m_Pos.x + aRadius, m_Pos.y ); }
|
||||||
int GetRadius() const { return m_Radius; }
|
int GetRadius() const { return KiROUND( GetLineLength( m_EndPos, m_Pos ) ); }
|
||||||
|
|
||||||
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
|
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
|
||||||
|
|
||||||
|
|
|
@ -411,47 +411,22 @@ wxString LIB_FIELD::GetName( bool aTranslate ) const
|
||||||
|
|
||||||
switch( m_id )
|
switch( m_id )
|
||||||
{
|
{
|
||||||
case REFERENCE:
|
case REFERENCE: return aTranslate ? _( "Reference" ) : wxT( "Reference" );
|
||||||
if( aTranslate )
|
case VALUE: return aTranslate ? _( "Value" ) : wxT( "Value" );
|
||||||
name = _( "Reference" );
|
case FOOTPRINT: return aTranslate ? _( "Footprint" ) : wxT( "Footprint" );
|
||||||
else
|
case DATASHEET: return aTranslate ? _( "Datasheet" ) : wxT( "Datasheet" );
|
||||||
name = wxT( "Reference" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VALUE:
|
|
||||||
if( aTranslate )
|
|
||||||
name = _( "Value" );
|
|
||||||
else
|
|
||||||
name = wxT( "Value" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FOOTPRINT:
|
|
||||||
if( aTranslate )
|
|
||||||
name = _( "Footprint" );
|
|
||||||
else
|
|
||||||
name = wxT( "Footprint" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DATASHEET:
|
|
||||||
if( aTranslate )
|
|
||||||
name = _( "Datasheet" );
|
|
||||||
else
|
|
||||||
name = wxT( "Datasheet" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if( m_name.IsEmpty() )
|
if( m_name.IsEmpty() )
|
||||||
{
|
{
|
||||||
if( aTranslate )
|
return aTranslate ? wxString::Format( _( "Field%d" ), m_id )
|
||||||
name.Printf( _( "Field%d" ), m_id );
|
: wxString::Format( wxT( "Field%d" ), m_id );
|
||||||
else
|
|
||||||
name.Printf( wxT( "Field%d" ), m_id );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
name = m_name;
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,6 @@ public:
|
||||||
|
|
||||||
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
||||||
void MirrorVertical( const wxPoint& aCenter ) override;
|
void MirrorVertical( const wxPoint& aCenter ) override;
|
||||||
|
|
||||||
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
|
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
|
||||||
|
|
||||||
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
||||||
|
|
|
@ -1712,13 +1712,7 @@ void LIB_PIN::Show( int nestLevel, std::ostream& os ) const
|
||||||
|
|
||||||
void LIB_PIN::CalcEdit( const wxPoint& aPosition )
|
void LIB_PIN::CalcEdit( const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
DBG(printf("m_Flags %x\n", m_Flags );)
|
if( IsMoving() )
|
||||||
|
|
||||||
if( IsNew() )
|
|
||||||
{
|
|
||||||
SetPosition( aPosition );
|
|
||||||
}
|
|
||||||
else if( IsMoving() )
|
|
||||||
{
|
{
|
||||||
DBG(printf("MOVEPIN\n");)
|
DBG(printf("MOVEPIN\n");)
|
||||||
Move( aPosition );
|
Move( aPosition );
|
||||||
|
|
|
@ -350,12 +350,8 @@ public:
|
||||||
* and of type POWER_IN.
|
* and of type POWER_IN.
|
||||||
*/
|
*/
|
||||||
bool IsPowerConnection() const {
|
bool IsPowerConnection() const {
|
||||||
|
return GetType() == PIN_POWER_IN && ( !IsVisible() || (LIB_PART*) GetParent()->IsPower() );
|
||||||
return (
|
}
|
||||||
( !IsVisible() && GetType() == PIN_POWER_IN )
|
|
||||||
||
|
|
||||||
( (LIB_PART*)GetParent()->IsPower() && GetType() == PIN_POWER_IN )
|
|
||||||
) ; }
|
|
||||||
|
|
||||||
int GetPenSize() const override;
|
int GetPenSize() const override;
|
||||||
|
|
||||||
|
@ -444,16 +440,13 @@ public:
|
||||||
void SetPinPosition( wxPoint aPosition );
|
void SetPinPosition( wxPoint aPosition );
|
||||||
|
|
||||||
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
||||||
|
|
||||||
void MirrorVertical( const wxPoint& aCenter ) override;
|
void MirrorVertical( const wxPoint& aCenter ) override;
|
||||||
|
|
||||||
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
|
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
|
||||||
|
|
||||||
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
||||||
const TRANSFORM& aTransform ) override;
|
const TRANSFORM& aTransform ) override;
|
||||||
|
|
||||||
int GetWidth() const override { return m_width; }
|
int GetWidth() const override { return m_width; }
|
||||||
|
|
||||||
void SetWidth( int aWidth ) override;
|
void SetWidth( int aWidth ) override;
|
||||||
|
|
||||||
BITMAP_DEF GetMenuImage() const override;
|
BITMAP_DEF GetMenuImage() const override;
|
||||||
|
|
|
@ -171,9 +171,35 @@ void LIB_POLYLINE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_POLYLINE::AddPoint( const wxPoint& point )
|
void LIB_POLYLINE::AddPoint( const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
m_PolyPoints.push_back( point );
|
m_PolyPoints.push_back( aPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_POLYLINE::AddCorner( const wxPoint& aPosition )
|
||||||
|
{
|
||||||
|
int currentMinDistance = INT_MAX;
|
||||||
|
int closestLineStart = 0;
|
||||||
|
|
||||||
|
for( int i = 0; i < m_PolyPoints.size() - 1; ++i )
|
||||||
|
{
|
||||||
|
int distance = (int) DistanceLinePoint( m_PolyPoints[i], m_PolyPoints[i + 1], aPosition );
|
||||||
|
|
||||||
|
if( distance < currentMinDistance )
|
||||||
|
{
|
||||||
|
currentMinDistance = distance;
|
||||||
|
closestLineStart = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_PolyPoints.insert( m_PolyPoints.begin() + closestLineStart, aPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_POLYLINE::RemoveCorner( int aIdx )
|
||||||
|
{
|
||||||
|
m_PolyPoints.erase( m_PolyPoints.begin() + aIdx );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
return _( "PolyLine" );
|
return _( "PolyLine" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearPoints() { m_PolyPoints.clear(); }
|
||||||
void Reserve( size_t aPointCount ) { m_PolyPoints.reserve( aPointCount ); }
|
void Reserve( size_t aPointCount ) { m_PolyPoints.reserve( aPointCount ); }
|
||||||
void AddPoint( const wxPoint& aPoint );
|
void AddPoint( const wxPoint& aPoint );
|
||||||
|
|
||||||
|
@ -69,6 +70,9 @@ public:
|
||||||
*/
|
*/
|
||||||
void DeleteSegment( const wxPoint aPosition );
|
void DeleteSegment( const wxPoint aPosition );
|
||||||
|
|
||||||
|
void AddCorner( const wxPoint& aPosition );
|
||||||
|
void RemoveCorner( int aIdx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of corners
|
* @return the number of corners
|
||||||
*/
|
*/
|
||||||
|
@ -98,7 +102,6 @@ public:
|
||||||
|
|
||||||
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
||||||
void MirrorVertical( const wxPoint& aCenter ) override;
|
void MirrorVertical( const wxPoint& aCenter ) override;
|
||||||
|
|
||||||
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
|
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
|
||||||
|
|
||||||
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
||||||
|
|
|
@ -285,23 +285,6 @@ void LIB_RECTANGLE::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
|
||||||
{
|
{
|
||||||
m_Pos = m_End = aPosition;
|
m_Pos = m_End = aPosition;
|
||||||
}
|
}
|
||||||
else if( aEditMode == IS_RESIZED )
|
|
||||||
{
|
|
||||||
m_isStartPointSelected = abs( m_Pos.x - aPosition.x ) < MINIMUM_SELECTION_DISTANCE
|
|
||||||
|| abs( m_Pos.y - aPosition.y ) < MINIMUM_SELECTION_DISTANCE;
|
|
||||||
|
|
||||||
if( m_isStartPointSelected )
|
|
||||||
{
|
|
||||||
m_isWidthLocked = abs( m_Pos.x - aPosition.x ) >= MINIMUM_SELECTION_DISTANCE;
|
|
||||||
m_isHeightLocked = abs( m_Pos.y - aPosition.y ) >= MINIMUM_SELECTION_DISTANCE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_isWidthLocked = abs( m_End.x - aPosition.x ) >= MINIMUM_SELECTION_DISTANCE;
|
|
||||||
m_isHeightLocked = abs( m_End.y - aPosition.y ) >= MINIMUM_SELECTION_DISTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if( aEditMode == IS_MOVED )
|
else if( aEditMode == IS_MOVED )
|
||||||
{
|
{
|
||||||
m_initialPos = m_Pos;
|
m_initialPos = m_Pos;
|
||||||
|
@ -325,30 +308,6 @@ void LIB_RECTANGLE::CalcEdit( const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
m_End = aPosition;
|
m_End = aPosition;
|
||||||
}
|
}
|
||||||
else if( IsResized() )
|
|
||||||
{
|
|
||||||
if( m_isHeightLocked )
|
|
||||||
{
|
|
||||||
if( m_isStartPointSelected )
|
|
||||||
m_Pos.x = aPosition.x;
|
|
||||||
else
|
|
||||||
m_End.x = aPosition.x;
|
|
||||||
}
|
|
||||||
else if( m_isWidthLocked )
|
|
||||||
{
|
|
||||||
if( m_isStartPointSelected )
|
|
||||||
m_Pos.y = aPosition.y;
|
|
||||||
else
|
|
||||||
m_End.y = aPosition.y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( m_isStartPointSelected )
|
|
||||||
m_Pos = aPosition;
|
|
||||||
else
|
|
||||||
m_End = aPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( IsMoving() )
|
else if( IsMoving() )
|
||||||
{
|
{
|
||||||
Move( m_initialPos + aPosition - m_initialCursorPos );
|
Move( m_initialPos + aPosition - m_initialCursorPos );
|
||||||
|
|
|
@ -84,20 +84,16 @@ public:
|
||||||
wxPoint GetPosition() const override { return m_Pos; }
|
wxPoint GetPosition() const override { return m_Pos; }
|
||||||
|
|
||||||
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
void MirrorHorizontal( const wxPoint& aCenter ) override;
|
||||||
|
|
||||||
void MirrorVertical( const wxPoint& aCenter ) override;
|
void MirrorVertical( const wxPoint& aCenter ) override;
|
||||||
|
|
||||||
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
|
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
|
||||||
|
|
||||||
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
|
||||||
const TRANSFORM& aTransform ) override;
|
const TRANSFORM& aTransform ) override;
|
||||||
|
|
||||||
int GetWidth() const override { return m_Width; }
|
int GetWidth() const override { return m_Width; }
|
||||||
|
|
||||||
void SetWidth( int aWidth ) override { m_Width = aWidth; }
|
void SetWidth( int aWidth ) override { m_Width = aWidth; }
|
||||||
|
|
||||||
void SetEnd( const wxPoint& aEnd ) { m_End = aEnd; }
|
void SetEnd( const wxPoint& aEnd ) { m_End = aEnd; }
|
||||||
|
|
||||||
wxPoint GetEnd() const { return m_End; }
|
wxPoint GetEnd() const { return m_End; }
|
||||||
|
|
||||||
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
|
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
|
||||||
|
|
|
@ -341,7 +341,6 @@ BITMAP_DEF LIB_TEXT::GetMenuImage() const
|
||||||
|
|
||||||
void LIB_TEXT::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
|
void LIB_TEXT::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
|
||||||
{
|
{
|
||||||
// JEY TODO: this should all move to modern toolset....
|
|
||||||
LIB_ITEM::BeginEdit( aEditMode, aPosition );
|
LIB_ITEM::BeginEdit( aEditMode, aPosition );
|
||||||
|
|
||||||
if( aEditMode == IS_MOVED )
|
if( aEditMode == IS_MOVED )
|
||||||
|
@ -358,7 +357,6 @@ void LIB_TEXT::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
|
||||||
|
|
||||||
void LIB_TEXT::EndEdit( const wxPoint& aPosition )
|
void LIB_TEXT::EndEdit( const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
// JEY TODO: this should all move to modern toolset....
|
|
||||||
LIB_ITEM::EndEdit( aPosition );
|
LIB_ITEM::EndEdit( aPosition );
|
||||||
|
|
||||||
m_rotate = false;
|
m_rotate = false;
|
||||||
|
@ -368,7 +366,6 @@ void LIB_TEXT::EndEdit( const wxPoint& aPosition )
|
||||||
|
|
||||||
void LIB_TEXT::CalcEdit( const wxPoint& aPosition )
|
void LIB_TEXT::CalcEdit( const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
// JEY TODO: this should all move to modern toolset....
|
|
||||||
DBG(printf("textCalcEdit %d %d\n", aPosition.x, aPosition.y );)
|
DBG(printf("textCalcEdit %d %d\n", aPosition.x, aPosition.y );)
|
||||||
|
|
||||||
if( m_rotate )
|
if( m_rotate )
|
||||||
|
|
|
@ -1,588 +0,0 @@
|
||||||
/*
|
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
|
||||||
* Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
|
|
||||||
* Copyright (C) 2004-2017 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file block_libedit.cpp
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fctsys.h>
|
|
||||||
#include <gr_basic.h>
|
|
||||||
#include <sch_draw_panel.h>
|
|
||||||
#include <confirm.h>
|
|
||||||
|
|
||||||
#include <general.h>
|
|
||||||
#include <class_library.h>
|
|
||||||
#include <lib_edit_frame.h>
|
|
||||||
|
|
||||||
#include <preview_items/selection_area.h>
|
|
||||||
#include <sch_view.h>
|
|
||||||
#include <view/view_group.h>
|
|
||||||
|
|
||||||
static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
|
|
||||||
bool aErase );
|
|
||||||
|
|
||||||
|
|
||||||
int LIB_EDIT_FRAME::BlockSelectItems( LIB_PART* aPart, BLOCK_SELECTOR* aBlock, int aUnit, int aConvert, bool aSyncPinEdit )
|
|
||||||
{
|
|
||||||
int itemCount = 0;
|
|
||||||
|
|
||||||
for( LIB_ITEM& item : aPart->GetDrawItems() )
|
|
||||||
{
|
|
||||||
item.ClearFlags( SELECTED );
|
|
||||||
|
|
||||||
if( ( item.GetUnit() && item.GetUnit() != aUnit )
|
|
||||||
|| ( item.GetConvert() && item.GetConvert() != aConvert ) )
|
|
||||||
{
|
|
||||||
if( item.Type() != LIB_PIN_T )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Specific rules for pins:
|
|
||||||
// - do not select pins in other units when synchronized pin edit mode is disabled
|
|
||||||
// - do not select pins in other units when units are not interchangeable
|
|
||||||
// - in other cases verify if the pin belongs to the requested unit
|
|
||||||
if( !aSyncPinEdit || aPart->UnitsLocked()
|
|
||||||
|| ( item.GetConvert() && item.GetConvert() != aConvert ) )
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item.Inside( *aBlock ) )
|
|
||||||
{
|
|
||||||
auto picker = ITEM_PICKER( &item );
|
|
||||||
aBlock->PushItem( picker );
|
|
||||||
item.SetFlags( SELECTED );
|
|
||||||
itemCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::BlockClearSelectedItems( LIB_PART* aPart, BLOCK_SELECTOR* aBlock )
|
|
||||||
{
|
|
||||||
for( LIB_ITEM& item : aPart->GetDrawItems() )
|
|
||||||
{
|
|
||||||
item.ClearFlags();
|
|
||||||
}
|
|
||||||
aBlock->ClearItemsList();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::BlockMoveSelectedItems( const wxPoint& aOffset, LIB_PART* aPart, BLOCK_SELECTOR* aBlock )
|
|
||||||
{
|
|
||||||
for( LIB_ITEM& item : aPart->GetDrawItems() )
|
|
||||||
{
|
|
||||||
if( !item.IsSelected() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
item.SetOffset( aOffset );
|
|
||||||
item.ClearFlags();
|
|
||||||
}
|
|
||||||
|
|
||||||
// view update
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::BlockDeleteSelectedItems( LIB_PART* aPart, BLOCK_SELECTOR* aBlock )
|
|
||||||
{
|
|
||||||
LIB_ITEMS_CONTAINER::ITERATOR item = aPart->GetDrawItems().begin();
|
|
||||||
|
|
||||||
// We *do not* remove the 2 mandatory fields: reference and value
|
|
||||||
// so skip them (do not remove) if they are flagged selected.
|
|
||||||
// Skip also not visible items.
|
|
||||||
// But I think fields must not be deleted by a block delete command or other global command
|
|
||||||
// because they are not really graphic items
|
|
||||||
while( item != aPart->GetDrawItems().end() )
|
|
||||||
{
|
|
||||||
if( item->Type() == LIB_FIELD_T )
|
|
||||||
{
|
|
||||||
item->ClearFlags( SELECTED );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !item->IsSelected() )
|
|
||||||
++item;
|
|
||||||
else
|
|
||||||
item = aPart->GetDrawItems().erase( item );
|
|
||||||
}
|
|
||||||
|
|
||||||
// view update
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::BlockCopySelectedItems( const wxPoint& aOffset, LIB_PART* aPart, BLOCK_SELECTOR* aBlock )
|
|
||||||
{
|
|
||||||
PICKED_ITEMS_LIST& aItemsList = aBlock->GetItems();
|
|
||||||
LIB_ITEM* oldItem;
|
|
||||||
LIB_ITEM* newItem;
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
|
|
||||||
{
|
|
||||||
oldItem = static_cast<LIB_ITEM*>( aItemsList.GetPickedItem( ii ) );
|
|
||||||
|
|
||||||
// We *do not* copy fields because they are unique for the whole component
|
|
||||||
// so skip them (do not duplicate) if they are flagged selected.
|
|
||||||
if( oldItem->Type() == LIB_FIELD_T )
|
|
||||||
oldItem->ClearFlags( SELECTED );
|
|
||||||
|
|
||||||
if( !oldItem->IsSelected() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
newItem = (LIB_ITEM*) oldItem->Clone();
|
|
||||||
newItem->SetFlags( SELECTED );
|
|
||||||
oldItem->ClearFlags( SELECTED );
|
|
||||||
|
|
||||||
newItem->SetOffset( aBlock->GetMoveVector() );
|
|
||||||
|
|
||||||
aItemsList.SetPickedItem( newItem, ii );
|
|
||||||
aItemsList.SetPickedItemStatus( UR_NEW, ii );
|
|
||||||
|
|
||||||
aPart->GetDrawItems().push_back( newItem );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int LIB_EDIT_FRAME::BlockCommand( EDA_KEY key )
|
|
||||||
{
|
|
||||||
int cmd = BLOCK_IDLE;
|
|
||||||
|
|
||||||
switch( key )
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
cmd = key & 0xFF;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EDA_KEY_C( 0xffffffff ): // -1
|
|
||||||
// Historically, -1 has been used as a key, which can cause bit flag
|
|
||||||
// clashes with unaware code. On debug builds, catch any old code that
|
|
||||||
// might still be doing this. TODO: remove if sure all this old code is gone.
|
|
||||||
wxFAIL_MSG( "negative EDA_KEY value should be converted to GR_KEY_INVALID" );
|
|
||||||
// fall through on release builds
|
|
||||||
|
|
||||||
case GR_KEY_INVALID:
|
|
||||||
cmd = BLOCK_PRESELECT_MOVE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_KEY_NONE:
|
|
||||||
cmd = BLOCK_MOVE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_KB_SHIFT:
|
|
||||||
cmd = BLOCK_DUPLICATE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_KB_ALT:
|
|
||||||
cmd = BLOCK_ROTATE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_KB_SHIFTCTRL:
|
|
||||||
cmd = BLOCK_DELETE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_KB_CTRL:
|
|
||||||
cmd = BLOCK_MIRROR_Y;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MOUSE_MIDDLE:
|
|
||||||
cmd = BLOCK_ZOOM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
|
||||||
{
|
|
||||||
int ItemCount = 0;
|
|
||||||
bool nextCmd = false;
|
|
||||||
BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
|
|
||||||
wxPoint pt;
|
|
||||||
|
|
||||||
auto panel =static_cast<SCH_DRAW_PANEL*>(m_canvas);
|
|
||||||
auto view = panel->GetView();
|
|
||||||
auto area = view->GetSelectionArea();
|
|
||||||
|
|
||||||
auto start = area->GetOrigin();
|
|
||||||
auto end = area->GetEnd();
|
|
||||||
|
|
||||||
block->SetOrigin( wxPoint( start.x, start.y ) );
|
|
||||||
block->SetEnd( wxPoint( end.x, end.y ) );
|
|
||||||
|
|
||||||
view->ShowSelectionArea( false );
|
|
||||||
view->ClearHiddenFlags();
|
|
||||||
|
|
||||||
if( block->GetCount() )
|
|
||||||
{
|
|
||||||
BLOCK_STATE_T state = block->GetState();
|
|
||||||
BLOCK_COMMAND_T command = block->GetCommand();
|
|
||||||
|
|
||||||
m_canvas->CallEndMouseCapture( aDC );
|
|
||||||
|
|
||||||
block->SetState( state );
|
|
||||||
block->SetCommand( command );
|
|
||||||
m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand );
|
|
||||||
|
|
||||||
if( block->GetCommand() != BLOCK_ABORT
|
|
||||||
&& block->GetCommand() != BLOCK_DUPLICATE
|
|
||||||
&& block->GetCommand() != BLOCK_COPY
|
|
||||||
&& block->GetCommand() != BLOCK_CUT
|
|
||||||
&& block->GetCommand() != BLOCK_DELETE )
|
|
||||||
{
|
|
||||||
SetCrossHairPosition( block->GetEnd() );
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_canvas->IsMouseCaptured() )
|
|
||||||
{
|
|
||||||
switch( block->GetCommand() )
|
|
||||||
{
|
|
||||||
case BLOCK_IDLE:
|
|
||||||
DisplayError( this, wxT( "Error in HandleBlockPLace" ) );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_DRAG: // Drag
|
|
||||||
case BLOCK_DRAG_ITEM:
|
|
||||||
case BLOCK_MOVE: // Move
|
|
||||||
case BLOCK_DUPLICATE: // Duplicate
|
|
||||||
if( GetCurPart() )
|
|
||||||
ItemCount = BlockSelectItems( GetCurPart(), block, m_unit, m_convert, m_syncPinEdit );
|
|
||||||
|
|
||||||
if( ItemCount )
|
|
||||||
{
|
|
||||||
nextCmd = true;
|
|
||||||
block->SetState( STATE_BLOCK_MOVE );
|
|
||||||
|
|
||||||
if( block->GetCommand() == BLOCK_DUPLICATE )
|
|
||||||
{
|
|
||||||
if( block->AppendUndo() )
|
|
||||||
; // UR_LIBEDIT saves entire state, so no need to append anything more
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SaveCopyInUndoList( GetCurPart(), UR_LIBEDIT );
|
|
||||||
block->SetAppendUndo();
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockCopySelectedItems( pt, GetCurPart(), block );
|
|
||||||
block->SetLastCursorPosition( GetCrossHairPosition( true ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
|
|
||||||
m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
|
|
||||||
m_canvas->SetMouseCapture( NULL, NULL );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_COPY: // Save a copy of items in the clipboard buffer
|
|
||||||
case BLOCK_CUT:
|
|
||||||
if( GetCurPart() )
|
|
||||||
ItemCount = BlockSelectItems( GetCurPart(), block, m_unit, m_convert, m_syncPinEdit );
|
|
||||||
|
|
||||||
if( ItemCount )
|
|
||||||
{
|
|
||||||
copySelectedItems();
|
|
||||||
auto cmd = block->GetCommand();
|
|
||||||
|
|
||||||
if( cmd == BLOCK_COPY )
|
|
||||||
{
|
|
||||||
BlockClearSelectedItems( GetCurPart(), block );
|
|
||||||
block->ClearItemsList();
|
|
||||||
}
|
|
||||||
else if( cmd == BLOCK_CUT )
|
|
||||||
{
|
|
||||||
if( block->AppendUndo() )
|
|
||||||
; // UR_LIBEDIT saves entire state, so no need to append anything more
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SaveCopyInUndoList( GetCurPart(), UR_LIBEDIT );
|
|
||||||
block->SetAppendUndo();
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockDeleteSelectedItems( GetCurPart(), block );
|
|
||||||
RebuildView();
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_DELETE: // Delete
|
|
||||||
if( GetCurPart() )
|
|
||||||
ItemCount = BlockSelectItems( GetCurPart(), block, m_unit, m_convert, m_syncPinEdit );
|
|
||||||
|
|
||||||
if( block->AppendUndo() )
|
|
||||||
; // UR_LIBEDIT saves entire state, so no need to append anything more
|
|
||||||
else if( ItemCount )
|
|
||||||
{
|
|
||||||
SaveCopyInUndoList( GetCurPart(), UR_LIBEDIT );
|
|
||||||
block->SetAppendUndo();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( GetCurPart() )
|
|
||||||
{
|
|
||||||
BlockDeleteSelectedItems( GetCurPart(), block );
|
|
||||||
RebuildView();
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_PASTE:
|
|
||||||
case BLOCK_ROTATE:
|
|
||||||
case BLOCK_MIRROR_X:
|
|
||||||
case BLOCK_MIRROR_Y:
|
|
||||||
case BLOCK_FLIP:
|
|
||||||
wxFAIL; // should not happen
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_ZOOM: // Window Zoom
|
|
||||||
Window_Zoom( *block );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_ABORT:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_SELECT_ITEMS_ONLY:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_PRESELECT_MOVE: // not used in LibEdit
|
|
||||||
case BLOCK_DUPLICATE_AND_INCREMENT: // not used in Eeschema
|
|
||||||
case BLOCK_MOVE_EXACT: // not used in Eeschema
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( block->GetCommand() == BLOCK_ABORT )
|
|
||||||
{
|
|
||||||
GetScreen()->ClearDrawingState();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !nextCmd )
|
|
||||||
{
|
|
||||||
if( block->GetCommand() != BLOCK_SELECT_ITEMS_ONLY && GetCurPart() )
|
|
||||||
BlockClearSelectedItems( GetCurPart(), block );
|
|
||||||
|
|
||||||
GetScreen()->ClearBlockCommand();
|
|
||||||
GetScreen()->SetCurItem( NULL );
|
|
||||||
m_canvas->EndMouseCapture( GetToolId(), GetGalCanvas()->GetCurrentCursor(), wxEmptyString,
|
|
||||||
false );
|
|
||||||
}
|
|
||||||
|
|
||||||
view->ShowSelectionArea( false );
|
|
||||||
view->ShowPreview( nextCmd );
|
|
||||||
|
|
||||||
return nextCmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
|
|
||||||
{
|
|
||||||
BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
|
|
||||||
wxPoint pt;
|
|
||||||
|
|
||||||
if( !m_canvas->IsMouseCaptured() )
|
|
||||||
{
|
|
||||||
DisplayError( this, wxT( "HandleBlockPLace : m_mouseCaptureCallback = NULL" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
block->SetState( STATE_BLOCK_STOP );
|
|
||||||
|
|
||||||
switch( block->GetCommand() )
|
|
||||||
{
|
|
||||||
case BLOCK_IDLE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_DRAG: // Drag
|
|
||||||
case BLOCK_DRAG_ITEM:
|
|
||||||
case BLOCK_MOVE: // Move
|
|
||||||
case BLOCK_DUPLICATE: // Duplicate
|
|
||||||
if( GetCurPart() && !block->AppendUndo() )
|
|
||||||
SaveCopyInUndoList( GetCurPart() );
|
|
||||||
|
|
||||||
pt = block->GetMoveVector();
|
|
||||||
|
|
||||||
if( GetCurPart() )
|
|
||||||
BlockMoveSelectedItems( pt, GetCurPart(), block );
|
|
||||||
|
|
||||||
block->ClearItemsList();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_PASTE: // Paste (recopy the last block saved)
|
|
||||||
if( GetCurPart() )
|
|
||||||
SaveCopyInUndoList( GetCurPart() );
|
|
||||||
|
|
||||||
pt = block->GetMoveVector();
|
|
||||||
|
|
||||||
pasteClipboard( pt );
|
|
||||||
|
|
||||||
block->ClearItemsList();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLOCK_ZOOM: // Handled by HandleBlockEnd
|
|
||||||
case BLOCK_DELETE:
|
|
||||||
case BLOCK_COPY:
|
|
||||||
case BLOCK_ABORT:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RebuildView();
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
|
|
||||||
block->SetState( STATE_NO_BLOCK );
|
|
||||||
block->SetCommand( BLOCK_IDLE );
|
|
||||||
GetScreen()->SetCurItem( NULL );
|
|
||||||
m_canvas->EndMouseCapture( GetToolId(), GetGalCanvas()->GetCurrentCursor(), wxEmptyString, false );
|
|
||||||
|
|
||||||
GetCanvas()->GetView()->ClearPreview();
|
|
||||||
GetCanvas()->GetView()->ClearHiddenFlags();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::InitBlockPasteInfos()
|
|
||||||
{
|
|
||||||
BLOCK_SELECTOR& block = GetScreen()->m_BlockLocate;
|
|
||||||
|
|
||||||
// Copy the clipboard contents to the screen block selector
|
|
||||||
// (only the copy, the new instances will be appended to the part once the items are placed)
|
|
||||||
block.GetItems().CopyList( m_clipboard.GetItems() );
|
|
||||||
|
|
||||||
// Reparent block items and set their current unit & DeMorgan variant
|
|
||||||
for( size_t i = 0; i < m_clipboard.GetItems().GetCount(); ++i )
|
|
||||||
{
|
|
||||||
LIB_ITEM* item = dynamic_cast<LIB_ITEM*>( m_clipboard.GetItem( i ) );
|
|
||||||
|
|
||||||
if( item )
|
|
||||||
{
|
|
||||||
item->SetParent( GetCurPart() );
|
|
||||||
|
|
||||||
item->SetUnit( m_unit );
|
|
||||||
item->SetConvert( m_convert );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the paste reference point
|
|
||||||
block.SetLastCursorPosition( m_clipboard.GetLastCursorPosition() );
|
|
||||||
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::copySelectedItems()
|
|
||||||
{
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
if( !part )
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_clipboard.ClearListAndDeleteItems(); // delete previous saved list, if exists
|
|
||||||
m_clipboard.SetLastCursorPosition( GetScreen()->m_BlockLocate.GetEnd() ); // store the reference point
|
|
||||||
|
|
||||||
for( LIB_ITEM& item : part->GetDrawItems() )
|
|
||||||
{
|
|
||||||
// We *do not* copy fields because they are unique for the whole component
|
|
||||||
// so skip them (do not duplicate) if they are flagged selected.
|
|
||||||
if( item.Type() == LIB_FIELD_T )
|
|
||||||
item.ClearFlags( SELECTED );
|
|
||||||
|
|
||||||
if( !item.IsSelected() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Do not clear the 'selected' flag. It is required to have items drawn when they are pasted.
|
|
||||||
LIB_ITEM* copy = (LIB_ITEM*) item.Clone();
|
|
||||||
copy->SetFlags( UR_TRANSIENT );
|
|
||||||
ITEM_PICKER picker( copy, UR_NEW );
|
|
||||||
m_clipboard.PushItem( picker );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::pasteClipboard( const wxPoint& aOffset )
|
|
||||||
{
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
if( !part || m_clipboard.GetCount() == 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
for( unsigned int i = 0; i < m_clipboard.GetCount(); i++ )
|
|
||||||
{
|
|
||||||
// Append a copy to the current part, so the clipboard buffer might be pasted multiple times
|
|
||||||
LIB_ITEM* item = (LIB_ITEM*) m_clipboard.GetItem( i )->Clone();
|
|
||||||
item->SetParent( part );
|
|
||||||
item->SetSelected();
|
|
||||||
item->SetUnit( GetUnit() );
|
|
||||||
part->AddDrawItem( item );
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockMoveSelectedItems( aOffset, GetCurPart(), &GetScreen()->m_BlockLocate );
|
|
||||||
RebuildView();
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Traces the outline of the search block structures
|
|
||||||
* The entire block follows the cursor
|
|
||||||
*/
|
|
||||||
void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
|
|
||||||
bool aErase )
|
|
||||||
{
|
|
||||||
SCH_DRAW_PANEL* panel =static_cast<SCH_DRAW_PANEL*>( aPanel );
|
|
||||||
LIB_EDIT_FRAME* frame = (LIB_EDIT_FRAME*) aPanel->GetParent();
|
|
||||||
KIGFX::SCH_VIEW* view = panel->GetView();
|
|
||||||
KIGFX::VIEW_GROUP* preview = view->GetPreview();
|
|
||||||
|
|
||||||
BASE_SCREEN* screen = aPanel->GetScreen();
|
|
||||||
BLOCK_SELECTOR* block = &screen->m_BlockLocate;
|
|
||||||
LIB_PART* component = frame->GetCurPart();
|
|
||||||
|
|
||||||
if( component == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
block->SetMoveVector( frame->GetCrossHairPosition( true ) - block->GetLastCursorPosition() );
|
|
||||||
|
|
||||||
preview->Clear();
|
|
||||||
view->SetVisible( preview, true );
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < block->GetCount(); ii++ )
|
|
||||||
{
|
|
||||||
LIB_ITEM* libItem = (LIB_ITEM*) block->GetItem( ii );
|
|
||||||
LIB_ITEM* copy = static_cast<LIB_ITEM*>( libItem->Clone() );
|
|
||||||
|
|
||||||
copy->Move( copy->GetPosition() + block->GetMoveVector() );
|
|
||||||
copy->SetFlags( IS_MOVED );
|
|
||||||
preview->Add( copy );
|
|
||||||
|
|
||||||
view->Hide( libItem );
|
|
||||||
}
|
|
||||||
|
|
||||||
view->Update( preview );
|
|
||||||
}
|
|
|
@ -67,14 +67,16 @@
|
||||||
#include <tool/zoom_tool.h>
|
#include <tool/zoom_tool.h>
|
||||||
#include <tools/sch_actions.h>
|
#include <tools/sch_actions.h>
|
||||||
#include <tools/sch_selection_tool.h>
|
#include <tools/sch_selection_tool.h>
|
||||||
#include <tools/sch_picker_tool.h>
|
#include <tools/picker_tool.h>
|
||||||
#include <tools/sch_inspection_tool.h>
|
#include <tools/inspection_tool.h>
|
||||||
#include <tools/lib_pin_tool.h>
|
#include <tools/lib_pin_tool.h>
|
||||||
|
#include <tools/lib_edit_tool.h>
|
||||||
|
#include <tools/lib_move_tool.h>
|
||||||
#include <tools/lib_drawing_tools.h>
|
#include <tools/lib_drawing_tools.h>
|
||||||
|
#include <tools/point_editor.h>
|
||||||
#include <sch_view.h>
|
#include <sch_view.h>
|
||||||
#include <sch_painter.h>
|
#include <sch_painter.h>
|
||||||
|
|
||||||
LIB_ITEM* LIB_EDIT_FRAME:: m_lastDrawItem = NULL;
|
|
||||||
|
|
||||||
bool LIB_EDIT_FRAME:: m_showDeMorgan = false;
|
bool LIB_EDIT_FRAME:: m_showDeMorgan = false;
|
||||||
int LIB_EDIT_FRAME:: g_LastTextSize = -1;
|
int LIB_EDIT_FRAME:: g_LastTextSize = -1;
|
||||||
|
@ -127,7 +129,7 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnOpenPinTable )
|
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnOpenPinTable )
|
||||||
EVT_TOOL( ID_ADD_PART_TO_SCHEMATIC, LIB_EDIT_FRAME::OnAddPartToSchematic )
|
EVT_TOOL( ID_ADD_PART_TO_SCHEMATIC, LIB_EDIT_FRAME::OnAddPartToSchematic )
|
||||||
|
|
||||||
EVT_COMBOBOX( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnSelectPart )
|
EVT_COMBOBOX( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnSelectUnit )
|
||||||
|
|
||||||
// Right vertical toolbar.
|
// Right vertical toolbar.
|
||||||
EVT_TOOL( ID_NO_TOOL_SELECTED, LIB_EDIT_FRAME::OnSelectTool )
|
EVT_TOOL( ID_NO_TOOL_SELECTED, LIB_EDIT_FRAME::OnSelectTool )
|
||||||
|
@ -152,15 +154,9 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
|
|
||||||
EVT_MENU( wxID_PREFERENCES, LIB_EDIT_FRAME::OnPreferencesOptions )
|
EVT_MENU( wxID_PREFERENCES, LIB_EDIT_FRAME::OnPreferencesOptions )
|
||||||
|
|
||||||
// Multiple item selection context menu commands.
|
|
||||||
EVT_MENU_RANGE( ID_SELECT_ITEM_START, ID_SELECT_ITEM_END, LIB_EDIT_FRAME::OnSelectItem )
|
|
||||||
|
|
||||||
EVT_MENU( ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST, LIB_EDIT_FRAME::Process_Config )
|
EVT_MENU( ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST, LIB_EDIT_FRAME::Process_Config )
|
||||||
|
|
||||||
// Context menu events and commands.
|
// Context menu events and commands.
|
||||||
EVT_MENU( ID_LIBEDIT_EDIT_PIN, LIB_EDIT_FRAME::OnEditPin )
|
|
||||||
EVT_MENU( ID_LIBEDIT_ROTATE_ITEM, LIB_EDIT_FRAME::OnRotate )
|
|
||||||
|
|
||||||
EVT_MENU_RANGE( ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
|
EVT_MENU_RANGE( ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
|
||||||
ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT,
|
ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT,
|
||||||
LIB_EDIT_FRAME::Process_Special_Functions )
|
LIB_EDIT_FRAME::Process_Special_Functions )
|
||||||
|
@ -168,9 +164,6 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
|
EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
|
||||||
LIB_EDIT_FRAME::Process_Special_Functions )
|
LIB_EDIT_FRAME::Process_Special_Functions )
|
||||||
|
|
||||||
EVT_MENU_RANGE( ID_LIBEDIT_MIRROR_X, ID_LIBEDIT_ORIENT_NORMAL,
|
|
||||||
LIB_EDIT_FRAME::OnOrient )
|
|
||||||
|
|
||||||
// Update user interface elements.
|
// Update user interface elements.
|
||||||
EVT_UPDATE_UI( wxID_PASTE, LIB_EDIT_FRAME::OnUpdatePaste )
|
EVT_UPDATE_UI( wxID_PASTE, LIB_EDIT_FRAME::OnUpdatePaste )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_EXPORT_PART, LIB_EDIT_FRAME::OnUpdateHavePart )
|
EVT_UPDATE_UI( ID_LIBEDIT_EXPORT_PART, LIB_EDIT_FRAME::OnUpdateHavePart )
|
||||||
|
@ -213,7 +206,6 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
m_FrameSize = ConvertDialogToPixels( wxSize( 500, 350 ) ); // default in case of no prefs
|
m_FrameSize = ConvertDialogToPixels( wxSize( 500, 350 ) ); // default in case of no prefs
|
||||||
|
|
||||||
m_my_part = NULL;
|
m_my_part = NULL;
|
||||||
m_tempCopyComponent = NULL;
|
|
||||||
m_treePane = nullptr;
|
m_treePane = nullptr;
|
||||||
m_libMgr = nullptr;
|
m_libMgr = nullptr;
|
||||||
m_unit = 1;
|
m_unit = 1;
|
||||||
|
@ -314,10 +306,6 @@ LIB_EDIT_FRAME::~LIB_EDIT_FRAME()
|
||||||
// current screen is destroyed in EDA_DRAW_FRAME
|
// current screen is destroyed in EDA_DRAW_FRAME
|
||||||
SetScreen( m_dummyScreen );
|
SetScreen( m_dummyScreen );
|
||||||
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
SetDrawItem( m_lastDrawItem );
|
|
||||||
|
|
||||||
delete m_tempCopyComponent;
|
|
||||||
delete m_libMgr;
|
delete m_libMgr;
|
||||||
delete m_my_part;
|
delete m_my_part;
|
||||||
}
|
}
|
||||||
|
@ -336,15 +324,17 @@ void LIB_EDIT_FRAME::setupTools()
|
||||||
m_toolManager->RegisterTool( new COMMON_TOOLS );
|
m_toolManager->RegisterTool( new COMMON_TOOLS );
|
||||||
m_toolManager->RegisterTool( new ZOOM_TOOL );
|
m_toolManager->RegisterTool( new ZOOM_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_SELECTION_TOOL );
|
m_toolManager->RegisterTool( new SCH_SELECTION_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_PICKER_TOOL );
|
m_toolManager->RegisterTool( new PICKER_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_INSPECTION_TOOL );
|
m_toolManager->RegisterTool( new INSPECTION_TOOL );
|
||||||
m_toolManager->RegisterTool( new LIB_PIN_TOOL );
|
m_toolManager->RegisterTool( new LIB_PIN_TOOL );
|
||||||
m_toolManager->RegisterTool( new LIB_DRAWING_TOOLS );
|
m_toolManager->RegisterTool( new LIB_DRAWING_TOOLS );
|
||||||
|
m_toolManager->RegisterTool( new POINT_EDITOR );
|
||||||
|
m_toolManager->RegisterTool( new LIB_MOVE_TOOL );
|
||||||
|
m_toolManager->RegisterTool( new LIB_EDIT_TOOL );
|
||||||
m_toolManager->InitTools();
|
m_toolManager->InitTools();
|
||||||
|
|
||||||
// Run the selection tool, it is supposed to be always active
|
// Run the selection tool, it is supposed to be always active
|
||||||
// JEY TODO: not ready for modern toolset event processing yet....
|
m_toolManager->InvokeTool( "eeschema.InteractiveSelection" );
|
||||||
//m_toolManager->InvokeTool( "eeschema.InteractiveSelection" );
|
|
||||||
|
|
||||||
GetCanvas()->SetEventDispatcher( m_toolDispatcher );
|
GetCanvas()->SetEventDispatcher( m_toolDispatcher );
|
||||||
}
|
}
|
||||||
|
@ -530,15 +520,21 @@ void LIB_EDIT_FRAME::OnUpdatePaste( wxUpdateUIEvent& event )
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnUpdateUndo( wxUpdateUIEvent& event )
|
void LIB_EDIT_FRAME::OnUpdateUndo( wxUpdateUIEvent& event )
|
||||||
{
|
{
|
||||||
event.Enable( GetCurPart() && GetScreen() &&
|
SCH_SELECTION_TOOL* selTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
|
||||||
GetScreen()->GetUndoCommandCount() != 0 && !IsEditingDrawItem() );
|
|
||||||
|
event.Enable( GetCurPart() && GetScreen()
|
||||||
|
&& GetScreen()->GetUndoCommandCount() != 0
|
||||||
|
&& SCH_CONDITIONS::Idle( selTool->GetSelection() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnUpdateRedo( wxUpdateUIEvent& event )
|
void LIB_EDIT_FRAME::OnUpdateRedo( wxUpdateUIEvent& event )
|
||||||
{
|
{
|
||||||
event.Enable( GetCurPart() && GetScreen() &&
|
SCH_SELECTION_TOOL* selTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
|
||||||
GetScreen()->GetRedoCommandCount() != 0 && !IsEditingDrawItem() );
|
|
||||||
|
event.Enable( GetCurPart() && GetScreen()
|
||||||
|
&& GetScreen()->GetRedoCommandCount() != 0
|
||||||
|
&& SCH_CONDITIONS::Idle( selTool->GetSelection() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -594,7 +590,7 @@ void LIB_EDIT_FRAME::OnUpdateDeMorganConvert( wxUpdateUIEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnSelectPart( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::OnSelectUnit( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
int i = event.GetSelection();
|
int i = event.GetSelection();
|
||||||
|
|
||||||
|
@ -604,7 +600,6 @@ void LIB_EDIT_FRAME::OnSelectPart( wxCommandEvent& event )
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor() );
|
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor() );
|
||||||
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
m_unit = i + 1;
|
m_unit = i + 1;
|
||||||
|
|
||||||
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
|
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
|
||||||
|
@ -664,238 +659,16 @@ void LIB_EDIT_FRAME::OnSelectBodyStyle( wxCommandEvent& event )
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
int id = event.GetId();
|
switch( event.GetId() )
|
||||||
wxPoint pos;
|
|
||||||
SCH_SCREEN* screen = GetScreen();
|
|
||||||
BLOCK_SELECTOR& block = screen->m_BlockLocate;
|
|
||||||
LIB_ITEM* item = screen->GetCurLibItem();
|
|
||||||
|
|
||||||
m_canvas->SetIgnoreMouseEvents( true );
|
|
||||||
|
|
||||||
wxGetMousePosition( &pos.x, &pos.y );
|
|
||||||
pos.y += 20;
|
|
||||||
|
|
||||||
switch( id ) // Stop placement commands before handling new command.
|
|
||||||
{
|
{
|
||||||
case wxID_COPY:
|
|
||||||
case ID_POPUP_COPY_BLOCK:
|
|
||||||
case wxID_CUT:
|
|
||||||
case ID_POPUP_CUT_BLOCK:
|
|
||||||
case ID_LIBEDIT_EDIT_PIN:
|
|
||||||
case ID_POPUP_LIBEDIT_BODY_EDIT_ITEM:
|
|
||||||
case ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM:
|
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
|
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
|
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
|
|
||||||
case ID_POPUP_ZOOM_BLOCK:
|
|
||||||
case ID_POPUP_DELETE_BLOCK:
|
|
||||||
case ID_POPUP_DUPLICATE_BLOCK:
|
|
||||||
case ID_POPUP_SELECT_ITEMS_BLOCK:
|
|
||||||
case ID_POPUP_MIRROR_X_BLOCK:
|
|
||||||
case ID_POPUP_MIRROR_Y_BLOCK:
|
|
||||||
case ID_POPUP_ROTATE_BLOCK:
|
|
||||||
case ID_POPUP_PLACE_BLOCK:
|
|
||||||
case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_CANCEL_EDITING:
|
|
||||||
if( m_canvas->IsMouseCaptured() )
|
|
||||||
m_canvas->EndMouseCapture();
|
|
||||||
else
|
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_DELETE_ITEM:
|
|
||||||
m_canvas->EndMouseCapture();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor(),
|
|
||||||
wxEmptyString );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( id )
|
|
||||||
{
|
|
||||||
case ID_POPUP_LIBEDIT_CANCEL_EDITING:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_LIBEDIT_SYNC_PIN_EDIT:
|
case ID_LIBEDIT_SYNC_PIN_EDIT:
|
||||||
m_syncPinEdit = m_mainToolBar->GetToolToggled( ID_LIBEDIT_SYNC_PIN_EDIT );
|
m_syncPinEdit = m_mainToolBar->GetToolToggled( ID_LIBEDIT_SYNC_PIN_EDIT );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_BODY_EDIT_ITEM:
|
|
||||||
if( item )
|
|
||||||
{
|
|
||||||
m_canvas->CrossHairOff( );
|
|
||||||
|
|
||||||
switch( item->Type() )
|
|
||||||
{
|
|
||||||
case LIB_ARC_T:
|
|
||||||
case LIB_CIRCLE_T:
|
|
||||||
case LIB_RECTANGLE_T:
|
|
||||||
case LIB_POLYLINE_T:
|
|
||||||
EditGraphicSymbol( nullptr, item );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_TEXT_T:
|
|
||||||
EditSymbolText( nullptr, item );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_canvas->CrossHairOn( );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT:
|
|
||||||
{
|
|
||||||
// Delete the last created segment, while creating a polyline draw item
|
|
||||||
if( item == NULL )
|
|
||||||
break;
|
|
||||||
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
static_cast<LIB_POLYLINE*>( item )->DeleteSegment( GetCrossHairPosition( true ) );
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_DELETE_ITEM:
|
|
||||||
if( item )
|
|
||||||
deleteItem( nullptr, item );
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST:
|
|
||||||
if( item == NULL )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( item->Type() == LIB_PIN_T )
|
|
||||||
StartMovePin( item );
|
|
||||||
else
|
|
||||||
StartMoveDrawSymbol( nullptr, item );
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_MODIFY_ITEM:
|
|
||||||
if( item == NULL )
|
|
||||||
break;
|
|
||||||
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
if( item->Type() == LIB_RECTANGLE_T
|
|
||||||
|| item->Type() == LIB_CIRCLE_T
|
|
||||||
|| item->Type() == LIB_POLYLINE_T
|
|
||||||
|| item->Type() == LIB_ARC_T )
|
|
||||||
{
|
|
||||||
StartModifyDrawSymbol( nullptr, item );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM:
|
|
||||||
if( item == NULL )
|
|
||||||
break;
|
|
||||||
|
|
||||||
m_canvas->CrossHairOff( nullptr );
|
|
||||||
|
|
||||||
if( item->Type() == LIB_FIELD_T )
|
|
||||||
EditField( (LIB_FIELD*) item );
|
|
||||||
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
m_canvas->CrossHairOn( );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
|
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
|
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
|
|
||||||
{
|
|
||||||
if( !item || item->Type() != LIB_PIN_T )
|
|
||||||
break;
|
|
||||||
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
SaveCopyInUndoList( part );
|
|
||||||
|
|
||||||
GlobalSetPins( (LIB_PIN*) item, id );
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_ZOOM_BLOCK:
|
|
||||||
m_canvas->SetAutoPanRequest( false );
|
|
||||||
block.SetCommand( BLOCK_ZOOM );
|
|
||||||
HandleBlockEnd( nullptr );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_DELETE_BLOCK:
|
|
||||||
m_canvas->SetAutoPanRequest( false );
|
|
||||||
block.SetCommand( BLOCK_DELETE );
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
HandleBlockEnd( nullptr );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_DUPLICATE_BLOCK:
|
|
||||||
m_canvas->SetAutoPanRequest( false );
|
|
||||||
block.SetCommand( BLOCK_DUPLICATE );
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
HandleBlockEnd( nullptr );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_SELECT_ITEMS_BLOCK:
|
|
||||||
m_canvas->SetAutoPanRequest( false );
|
|
||||||
block.SetCommand( BLOCK_SELECT_ITEMS_ONLY );
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
HandleBlockEnd( nullptr );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_MIRROR_X_BLOCK:
|
|
||||||
case ID_POPUP_MIRROR_Y_BLOCK:
|
|
||||||
OnOrient( event );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_ROTATE_BLOCK:
|
|
||||||
OnRotate( event );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_PLACE_BLOCK:
|
|
||||||
m_canvas->SetAutoPanRequest( false );
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
HandleBlockPlace( nullptr );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxID_COPY:
|
|
||||||
case ID_POPUP_COPY_BLOCK:
|
|
||||||
block.SetCommand( BLOCK_COPY );
|
|
||||||
block.SetMessageBlock( this );
|
|
||||||
HandleBlockEnd( nullptr );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxID_PASTE:
|
|
||||||
case ID_POPUP_PASTE_BLOCK:
|
|
||||||
HandleBlockBegin( nullptr, BLOCK_PASTE, GetCrossHairPosition() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxID_CUT:
|
|
||||||
case ID_POPUP_CUT_BLOCK:
|
|
||||||
if( block.GetCommand() != BLOCK_MOVE )
|
|
||||||
break;
|
|
||||||
|
|
||||||
block.SetCommand( BLOCK_CUT );
|
|
||||||
block.SetMessageBlock( this );
|
|
||||||
HandleBlockEnd( nullptr );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( "LIB_EDIT_FRAME::Process_Special_Functions error" );
|
wxFAIL_MSG( "LIB_EDIT_FRAME::Process_Special_Functions error" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_canvas->SetIgnoreMouseEvents( false );
|
|
||||||
|
|
||||||
if( GetToolId() == ID_NO_TOOL_SELECTED )
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -971,53 +744,6 @@ void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::TempCopyComponent()
|
|
||||||
{
|
|
||||||
delete m_tempCopyComponent;
|
|
||||||
|
|
||||||
if( LIB_PART* part = GetCurPart() )
|
|
||||||
// clone it and own the clone.
|
|
||||||
m_tempCopyComponent = new LIB_PART( *part );
|
|
||||||
else
|
|
||||||
// clear it, there was no CurPart
|
|
||||||
m_tempCopyComponent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::RestoreComponent()
|
|
||||||
{
|
|
||||||
if( m_tempCopyComponent )
|
|
||||||
{
|
|
||||||
// transfer ownership to CurPart
|
|
||||||
SetCurPart( m_tempCopyComponent );
|
|
||||||
m_tempCopyComponent = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::ClearTempCopyComponent()
|
|
||||||
{
|
|
||||||
delete m_tempCopyComponent;
|
|
||||||
m_tempCopyComponent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::EditSymbolText( wxDC* DC, LIB_ITEM* DrawItem )
|
|
||||||
{
|
|
||||||
if ( ( DrawItem == NULL ) || ( DrawItem->Type() != LIB_TEXT_T ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
DIALOG_LIB_EDIT_TEXT dlg( this, (LIB_TEXT*) DrawItem );
|
|
||||||
|
|
||||||
if( dlg.ShowModal() != wxID_OK )
|
|
||||||
return;
|
|
||||||
|
|
||||||
GetCanvas()->GetView()->Update( DrawItem );
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
bool partLocked = GetCurPart()->UnitsLocked();
|
bool partLocked = GetCurPart()->UnitsLocked();
|
||||||
|
@ -1027,9 +753,6 @@ void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor() );
|
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor() );
|
||||||
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
if( GetDrawItem() && GetDrawItem()->Type() == LIB_FIELD_T )
|
|
||||||
SetDrawItem( nullptr ); // selected LIB_FIELD might be deleted
|
|
||||||
|
|
||||||
DIALOG_EDIT_COMPONENT_IN_LIBRARY dlg( this, GetCurPart() );
|
DIALOG_EDIT_COMPONENT_IN_LIBRARY dlg( this, GetCurPart() );
|
||||||
|
|
||||||
// This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
|
// This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
|
||||||
|
@ -1075,57 +798,22 @@ void LIB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
int id = aEvent.GetId();
|
int id = aEvent.GetId();
|
||||||
|
|
||||||
if( GetToolId() == ID_NO_TOOL_SELECTED || GetToolId() == ID_ZOOM_SELECTION )
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
|
|
||||||
// Stop the current command and deselect the current tool.
|
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor() );
|
|
||||||
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
switch( id )
|
|
||||||
{
|
|
||||||
case ID_NO_TOOL_SELECTED:
|
|
||||||
case ID_ZOOM_SELECTION:
|
|
||||||
case ID_LIBEDIT_PIN_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_TEXT_BUTT:
|
|
||||||
case ID_LIBEDIT_ANCHOR_ITEM_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_RECT_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_CIRCLE_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_ARC_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_LINE_BUTT:
|
|
||||||
// moved to modern toolset
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
// since legacy tools don't activate themsleves, we have to deactivate any modern
|
|
||||||
// tools that might be running until all the legacy tools are moved over....
|
|
||||||
m_toolManager->DeactivateTool();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( id )
|
switch( id )
|
||||||
{
|
{
|
||||||
case ID_LIBEDIT_IMPORT_BODY_BUTT:
|
case ID_LIBEDIT_IMPORT_BODY_BUTT:
|
||||||
|
m_toolManager->DeactivateTool();
|
||||||
SetToolID( id, GetGalCanvas()->GetDefaultCursor(), _( "Import" ) );
|
SetToolID( id, GetGalCanvas()->GetDefaultCursor(), _( "Import" ) );
|
||||||
LoadOneSymbol();
|
LoadOneSymbol();
|
||||||
SetNoToolSelected();
|
SetNoToolSelected();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_LIBEDIT_EXPORT_BODY_BUTT:
|
case ID_LIBEDIT_EXPORT_BODY_BUTT:
|
||||||
|
m_toolManager->DeactivateTool();
|
||||||
SetToolID( id, GetGalCanvas()->GetDefaultCursor(), _( "Export" ) );
|
SetToolID( id, GetGalCanvas()->GetDefaultCursor(), _( "Export" ) );
|
||||||
SaveOneSymbol();
|
SaveOneSymbol();
|
||||||
SetNoToolSelected();
|
SetNoToolSelected();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_LIBEDIT_DELETE_ITEM_BUTT:
|
|
||||||
if( !part )
|
|
||||||
{
|
|
||||||
wxBell();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1134,218 +822,6 @@ void LIB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
|
|
||||||
{
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
BLOCK_SELECTOR& block = GetScreen()->m_BlockLocate;
|
|
||||||
LIB_ITEM* item = GetDrawItem();
|
|
||||||
|
|
||||||
// Allows block rotate operation on hot key.
|
|
||||||
if( block.GetState() != STATE_NO_BLOCK )
|
|
||||||
{
|
|
||||||
// Compute the rotation center and put it on grid:
|
|
||||||
wxPoint rotationPoint = block.Centre();
|
|
||||||
rotationPoint = GetNearestGridPosition( rotationPoint );
|
|
||||||
|
|
||||||
// The Y axis orientation is bottom to top for symbol items.
|
|
||||||
// so change the Y coord value of the rotation center
|
|
||||||
rotationPoint.y = -rotationPoint.y;
|
|
||||||
|
|
||||||
if( block.AppendUndo() )
|
|
||||||
; // UR_LIBEDIT saves entire state, so no need to append anything more
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SaveCopyInUndoList( part, UR_LIBEDIT );
|
|
||||||
block.SetAppendUndo();
|
|
||||||
}
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < block.GetCount(); ii++ )
|
|
||||||
{
|
|
||||||
item = static_cast<LIB_ITEM*>( block.GetItem( ii ) );
|
|
||||||
item->Rotate( rotationPoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
GetCanvas()->CallMouseCapture( nullptr, wxDefaultPosition, false );
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
}
|
|
||||||
else if( item )
|
|
||||||
{
|
|
||||||
wxPoint rotationPoint = item->GetPosition();
|
|
||||||
|
|
||||||
if( !item->InEditMode() )
|
|
||||||
SaveCopyInUndoList( part, UR_LIBEDIT );
|
|
||||||
|
|
||||||
item->Rotate( rotationPoint );
|
|
||||||
|
|
||||||
if( item->InEditMode() )
|
|
||||||
GetCanvas()->CallMouseCapture( nullptr, wxDefaultPosition, false );
|
|
||||||
else
|
|
||||||
GetCanvas()->GetView()->Update( item );
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
|
|
||||||
if( !item->InEditMode() )
|
|
||||||
item->ClearFlags();
|
|
||||||
|
|
||||||
if( GetToolId() == ID_NO_TOOL_SELECTED )
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
|
|
||||||
{
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
BLOCK_SELECTOR& block = GetScreen()->m_BlockLocate;
|
|
||||||
LIB_ITEM* item = GetDrawItem();
|
|
||||||
|
|
||||||
// Allows block rotate operation on hot key.
|
|
||||||
if( block.GetState() != STATE_NO_BLOCK )
|
|
||||||
{
|
|
||||||
// Compute the mirror center and put it on grid.
|
|
||||||
wxPoint mirrorPoint = block.Centre();
|
|
||||||
mirrorPoint = GetNearestGridPosition( mirrorPoint );
|
|
||||||
|
|
||||||
// The Y axis orientation is bottom to top for symbol items.
|
|
||||||
// so change the Y coord value of the rotation center
|
|
||||||
mirrorPoint.y = -mirrorPoint.y;
|
|
||||||
|
|
||||||
if( block.AppendUndo() )
|
|
||||||
; // UR_LIBEDIT saves entire state, so no need to append anything more
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SaveCopyInUndoList( part, UR_LIBEDIT );
|
|
||||||
block.SetAppendUndo();
|
|
||||||
}
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < block.GetCount(); ii++ )
|
|
||||||
{
|
|
||||||
item = static_cast<LIB_ITEM*>( block.GetItem( ii ) );
|
|
||||||
|
|
||||||
if( aEvent.GetId() == ID_LIBEDIT_MIRROR_Y || aEvent.GetId() == ID_POPUP_MIRROR_Y_BLOCK )
|
|
||||||
item->MirrorHorizontal( mirrorPoint );
|
|
||||||
else
|
|
||||||
item->MirrorVertical( mirrorPoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_canvas->CallMouseCapture( nullptr, wxDefaultPosition, false );
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
}
|
|
||||||
else if( item )
|
|
||||||
{
|
|
||||||
wxPoint mirrorPoint = item->GetPosition();
|
|
||||||
mirrorPoint.y = -mirrorPoint.y;
|
|
||||||
|
|
||||||
if( !item->InEditMode() )
|
|
||||||
SaveCopyInUndoList( part, UR_LIBEDIT );
|
|
||||||
|
|
||||||
if( aEvent.GetId() == ID_LIBEDIT_MIRROR_Y || aEvent.GetId() == ID_POPUP_MIRROR_Y_BLOCK )
|
|
||||||
item->MirrorHorizontal( mirrorPoint );
|
|
||||||
else
|
|
||||||
item->MirrorVertical( mirrorPoint );
|
|
||||||
|
|
||||||
if( item->InEditMode() )
|
|
||||||
m_canvas->CallMouseCapture( nullptr, wxDefaultPosition, false );
|
|
||||||
else
|
|
||||||
GetCanvas()->GetView()->Update( item );
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
|
|
||||||
if( !item->InEditMode() )
|
|
||||||
item->ClearFlags();
|
|
||||||
|
|
||||||
if( GetToolId() == ID_NO_TOOL_SELECTED )
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LIB_ITEM* LIB_EDIT_FRAME::LocateItemUsingCursor( const wxPoint& aPos, const KICAD_T aFilter[] )
|
|
||||||
{
|
|
||||||
SCH_SELECTION_TOOL* selTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
bool cancelled = false;
|
|
||||||
wxPoint gridPos;
|
|
||||||
|
|
||||||
if( !part )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
|
||||||
|
|
||||||
EDA_ITEM* item = selTool->SelectPoint( aPos, aFilter, &cancelled );
|
|
||||||
|
|
||||||
// If the user aborted the clarification context menu, don't show it again at the
|
|
||||||
// grid position.
|
|
||||||
if( !item && !cancelled )
|
|
||||||
{
|
|
||||||
gridPos = GetNearestGridPosition( aPos );
|
|
||||||
|
|
||||||
if( aPos != gridPos )
|
|
||||||
item = selTool->SelectPoint( gridPos, aFilter );
|
|
||||||
}
|
|
||||||
|
|
||||||
return (LIB_ITEM*) item;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::deleteItem( wxDC* aDC, LIB_ITEM* aItem )
|
|
||||||
{
|
|
||||||
if( !aItem )
|
|
||||||
return;
|
|
||||||
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
|
||||||
m_canvas->CrossHairOff( aDC );
|
|
||||||
|
|
||||||
SaveCopyInUndoList( part );
|
|
||||||
|
|
||||||
if( aItem->Type() == LIB_PIN_T )
|
|
||||||
{
|
|
||||||
LIB_PIN* pin = static_cast<LIB_PIN*>( aItem );
|
|
||||||
wxPoint pos = pin->GetPosition();
|
|
||||||
|
|
||||||
part->RemoveDrawItem( (LIB_ITEM*) pin, m_canvas, aDC );
|
|
||||||
|
|
||||||
// when pin editing is synchronized, all pins of the same body style are removed:
|
|
||||||
if( SynchronizePins() )
|
|
||||||
{
|
|
||||||
int curr_convert = pin->GetConvert();
|
|
||||||
LIB_PIN* next_pin = part->GetNextPin();
|
|
||||||
|
|
||||||
while( next_pin != NULL )
|
|
||||||
{
|
|
||||||
pin = next_pin;
|
|
||||||
next_pin = part->GetNextPin( pin );
|
|
||||||
|
|
||||||
if( pin->GetPosition() != pos )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( pin->GetConvert() != curr_convert )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
part->RemoveDrawItem( pin );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( m_canvas->IsMouseCaptured() )
|
|
||||||
m_canvas->CallEndMouseCapture( aDC );
|
|
||||||
else
|
|
||||||
part->RemoveDrawItem( aItem, m_canvas, aDC );
|
|
||||||
}
|
|
||||||
|
|
||||||
SetDrawItem( NULL );
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
OnModify();
|
|
||||||
m_canvas->CrossHairOn( aDC );
|
|
||||||
|
|
||||||
RebuildView();
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnModify()
|
void LIB_EDIT_FRAME::OnModify()
|
||||||
{
|
{
|
||||||
GetScreen()->SetModify();
|
GetScreen()->SetModify();
|
||||||
|
@ -1355,26 +831,10 @@ void LIB_EDIT_FRAME::OnModify()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnSelectItem( wxCommandEvent& aEvent )
|
|
||||||
{
|
|
||||||
int id = aEvent.GetId();
|
|
||||||
int index = id - ID_SELECT_ITEM_START;
|
|
||||||
|
|
||||||
if( (id >= ID_SELECT_ITEM_START && id <= ID_SELECT_ITEM_END)
|
|
||||||
&& (index >= 0 && index < m_collectedItems.GetCount()) )
|
|
||||||
{
|
|
||||||
EDA_ITEM* item = m_collectedItems[index];
|
|
||||||
m_canvas->SetAbortRequest( false );
|
|
||||||
SetDrawItem( (LIB_ITEM*) item );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnOpenPinTable( wxCommandEvent& aEvent )
|
void LIB_EDIT_FRAME::OnOpenPinTable( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
LIB_PART* part = GetCurPart();
|
LIB_PART* part = GetCurPart();
|
||||||
|
|
||||||
SetDrawItem( nullptr );
|
|
||||||
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
SaveCopyInUndoList( part );
|
SaveCopyInUndoList( part );
|
||||||
|
@ -1651,8 +1111,6 @@ void LIB_EDIT_FRAME::emptyScreen()
|
||||||
{
|
{
|
||||||
SetCurLib( wxEmptyString );
|
SetCurLib( wxEmptyString );
|
||||||
SetCurPart( nullptr );
|
SetCurPart( nullptr );
|
||||||
m_lastDrawItem = nullptr;
|
|
||||||
SetDrawItem( NULL );
|
|
||||||
SetScreen( m_dummyScreen );
|
SetScreen( m_dummyScreen );
|
||||||
m_dummyScreen->ClearUndoRedoList();
|
m_dummyScreen->ClearUndoRedoList();
|
||||||
Zoom_Automatique( false );
|
Zoom_Automatique( false );
|
||||||
|
|
|
@ -51,7 +51,6 @@ class LIB_MANAGER;
|
||||||
class LIB_EDIT_FRAME : public SCH_BASE_FRAME
|
class LIB_EDIT_FRAME : public SCH_BASE_FRAME
|
||||||
{
|
{
|
||||||
LIB_PART* m_my_part; ///< a part I own, it is not in any library, but a copy could be.
|
LIB_PART* m_my_part; ///< a part I own, it is not in any library, but a copy could be.
|
||||||
LIB_PART* m_tempCopyComponent; ///< temp copy of a part during edit, I own it here.
|
|
||||||
SCH_COLLECTOR m_collectedItems; ///< Used for hit testing.
|
SCH_COLLECTOR m_collectedItems; ///< Used for hit testing.
|
||||||
wxComboBox* m_partSelectBox; ///< a Box to select a part to edit (if any)
|
wxComboBox* m_partSelectBox; ///< a Box to select a part to edit (if any)
|
||||||
SYMBOL_TREE_PANE* m_treePane; ///< component search tree widget
|
SYMBOL_TREE_PANE* m_treePane; ///< component search tree widget
|
||||||
|
@ -83,8 +82,6 @@ class LIB_EDIT_FRAME : public SCH_BASE_FRAME
|
||||||
*/
|
*/
|
||||||
bool m_showPinElectricalTypeName;
|
bool m_showPinElectricalTypeName;
|
||||||
|
|
||||||
static LIB_ITEM* m_lastDrawItem;
|
|
||||||
|
|
||||||
// The unit number to edit and show
|
// The unit number to edit and show
|
||||||
int m_unit;
|
int m_unit;
|
||||||
|
|
||||||
|
@ -151,10 +148,7 @@ public:
|
||||||
*
|
*
|
||||||
* This is a LIB_PART that I own, it is at best a copy of one in a library.
|
* This is a LIB_PART that I own, it is at best a copy of one in a library.
|
||||||
*/
|
*/
|
||||||
LIB_PART* GetCurPart() const
|
LIB_PART* GetCurPart() const { return m_my_part; }
|
||||||
{
|
|
||||||
return m_my_part;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take ownership of aPart and notes that it is the one currently being edited.
|
* Take ownership of aPart and notes that it is the one currently being edited.
|
||||||
|
@ -289,7 +283,7 @@ public:
|
||||||
void OnCopyCutPart( wxCommandEvent& aEvent );
|
void OnCopyCutPart( wxCommandEvent& aEvent );
|
||||||
void OnPasteDuplicatePart( wxCommandEvent& aEvent );
|
void OnPasteDuplicatePart( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
void OnSelectPart( wxCommandEvent& event );
|
void OnSelectUnit( wxCommandEvent& event );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From Option toolbar: option to show the electrical pin type name
|
* From Option toolbar: option to show the electrical pin type name
|
||||||
|
@ -308,8 +302,6 @@ public:
|
||||||
void OnViewEntryDoc( wxCommandEvent& event );
|
void OnViewEntryDoc( wxCommandEvent& event );
|
||||||
void OnCheckComponent( wxCommandEvent& event );
|
void OnCheckComponent( wxCommandEvent& event );
|
||||||
void OnSelectBodyStyle( wxCommandEvent& event );
|
void OnSelectBodyStyle( wxCommandEvent& event );
|
||||||
void OnEditPin( wxCommandEvent& event );
|
|
||||||
void OnSelectItem( wxCommandEvent& aEvent );
|
|
||||||
|
|
||||||
void OnOpenPinTable( wxCommandEvent& aEvent );
|
void OnOpenPinTable( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
@ -329,6 +321,7 @@ public:
|
||||||
void OnUpdateElectricalType( wxUpdateUIEvent& aEvent );
|
void OnUpdateElectricalType( wxUpdateUIEvent& aEvent );
|
||||||
void OnUpdateSearchTreeTool( wxUpdateUIEvent& aEvent );
|
void OnUpdateSearchTreeTool( wxUpdateUIEvent& aEvent );
|
||||||
|
|
||||||
|
void UpdateAfterRename( LIB_PART* aPart, const wxString& aOldName, const wxString& aNewName );
|
||||||
void RebuildSymbolUnitsList();
|
void RebuildSymbolUnitsList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -353,10 +346,8 @@ public:
|
||||||
void ReCreateHToolbar() override;
|
void ReCreateHToolbar() override;
|
||||||
void ReCreateVToolbar() override;
|
void ReCreateVToolbar() override;
|
||||||
void ReCreateOptToolbar();
|
void ReCreateOptToolbar();
|
||||||
void OnLeftClick( wxDC* DC, const wxPoint& MousePos ) override;
|
bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) override { return true; }
|
||||||
bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) override;
|
|
||||||
double BestZoom() override; // Returns the best zoom
|
double BestZoom() override; // Returns the best zoom
|
||||||
void OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) override;
|
|
||||||
|
|
||||||
///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
|
///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
|
||||||
EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const override;
|
EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const override;
|
||||||
|
@ -383,53 +374,20 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be called after a schematic change in order to set the "modify" flag of the
|
* Must be called after a schematic change in order to set the "modify" flag of the
|
||||||
* current screen.
|
* current symbol.
|
||||||
*/
|
*/
|
||||||
void OnModify();
|
void OnModify() override;
|
||||||
|
|
||||||
int GetUnit() { return m_unit; }
|
int GetUnit() { return m_unit; }
|
||||||
|
|
||||||
int GetConvert() { return m_convert; }
|
int GetConvert() { return m_convert; }
|
||||||
|
|
||||||
LIB_ITEM* GetLastDrawItem() { return m_lastDrawItem; }
|
|
||||||
void SetLastDrawItem( LIB_ITEM* drawItem ) { m_lastDrawItem = drawItem; }
|
|
||||||
|
|
||||||
LIB_ITEM* GetDrawItem() const { return GetScreen()->GetCurLibItem(); }
|
|
||||||
void SetDrawItem( LIB_ITEM* drawItem ) { GetScreen()->SetCurLibItem( drawItem ); }
|
|
||||||
|
|
||||||
bool GetShowDeMorgan() { return m_showDeMorgan; }
|
bool GetShowDeMorgan() { return m_showDeMorgan; }
|
||||||
void SetShowDeMorgan( bool show ) { m_showDeMorgan = show; }
|
void SetShowDeMorgan( bool show ) { m_showDeMorgan = show; }
|
||||||
|
|
||||||
bool GetShowElectricalType() { return m_showPinElectricalTypeName; }
|
bool GetShowElectricalType() { return m_showPinElectricalTypeName; }
|
||||||
void SetShowElectricalType( bool aShow ) { m_showPinElectricalTypeName = aShow; }
|
void SetShowElectricalType( bool aShow ) { m_showPinElectricalTypeName = aShow; }
|
||||||
|
|
||||||
FILL_T GetFillStyle() { return g_LastFillStyle; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a temporary copy of the current edited component.
|
|
||||||
*
|
|
||||||
* Used to prepare an undo and/or abort command before editing the symbol.
|
|
||||||
*/
|
|
||||||
void TempCopyComponent();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restore the current edited component from its temporary copy.
|
|
||||||
* Used to abort a command
|
|
||||||
*/
|
|
||||||
void RestoreComponent();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the temporary copy of the current component.
|
|
||||||
*/
|
|
||||||
LIB_PART* GetTempCopyComponent() { return m_tempCopyComponent; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete temporary copy of the current component and clear pointer
|
|
||||||
*/
|
|
||||||
void ClearTempCopyComponent();
|
|
||||||
|
|
||||||
bool IsEditingDrawItem() { return GetDrawItem() && GetDrawItem()->InEditMode(); }
|
|
||||||
|
|
||||||
void ClearMsgPanel() override { DisplayCmpDoc(); }
|
void ClearMsgPanel() override { DisplayCmpDoc(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -503,24 +461,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void DisplayCmpDoc();
|
void DisplayCmpDoc();
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotates the current item.
|
|
||||||
*/
|
|
||||||
void OnRotate( wxCommandEvent& aEvent );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the ID_LIBEDIT_MIRROR_X and ID_LIBEDIT_MIRROR_Y events.
|
|
||||||
*/
|
|
||||||
void OnOrient( wxCommandEvent& aEvent );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the currently selected draw item.
|
|
||||||
*
|
|
||||||
* @param aDC The device context to draw upon when removing item.
|
|
||||||
* @param aItem The item to delete
|
|
||||||
*/
|
|
||||||
void deleteItem( wxDC* aDC, LIB_ITEM* aItem );
|
|
||||||
|
|
||||||
// General editing
|
// General editing
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -531,6 +471,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void SaveCopyInUndoList( EDA_ITEM* ItemToCopy, UNDO_REDO_T undoType = UR_LIBEDIT );
|
void SaveCopyInUndoList( EDA_ITEM* ItemToCopy, UNDO_REDO_T undoType = UR_LIBEDIT );
|
||||||
|
|
||||||
|
void RollbackPartFromUndo();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void GetComponentFromUndoList( wxCommandEvent& event );
|
void GetComponentFromUndoList( wxCommandEvent& event );
|
||||||
void GetComponentFromRedoList( wxCommandEvent& event );
|
void GetComponentFromRedoList( wxCommandEvent& event );
|
||||||
|
@ -549,10 +491,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void CreateImagePins( LIB_PIN* aPin );
|
void CreateImagePins( LIB_PIN* aPin );
|
||||||
|
|
||||||
// Editing graphic items
|
|
||||||
void StartMoveDrawSymbol( wxDC* DC, LIB_ITEM* aItem );
|
|
||||||
void StartModifyDrawSymbol( wxDC* DC, LIB_ITEM* aItem ); //<! Modify the item, adjust size etc.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a component symbol file (*.sym ) and add graphic items to the current component.
|
* Read a component symbol file (*.sym ) and add graphic items to the current component.
|
||||||
*
|
*
|
||||||
|
@ -568,12 +506,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void SaveOneSymbol();
|
void SaveOneSymbol();
|
||||||
|
|
||||||
void EditGraphicSymbol( wxDC* DC, LIB_ITEM* DrawItem );
|
|
||||||
void EditSymbolText( wxDC* DC, LIB_ITEM* DrawItem );
|
|
||||||
LIB_ITEM* LocateItemUsingCursor( const wxPoint& aPos,
|
|
||||||
const KICAD_T aFilter[] = SCH_COLLECTOR::LibItems );
|
|
||||||
void EditField( LIB_FIELD* Field );
|
|
||||||
|
|
||||||
void refreshSchematic();
|
void refreshSchematic();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -587,51 +519,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool LoadComponentAndSelectLib( const LIB_ID& aLibId, int aUnit, int aConvert );
|
bool LoadComponentAndSelectLib( const LIB_ID& aLibId, int aUnit, int aConvert );
|
||||||
|
|
||||||
/* Block commands: */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the block command (BLOCK_MOVE, BLOCK_DUPLICATE...) corresponding to
|
|
||||||
* the \a aKey (ALT, SHIFT ALT ..)
|
|
||||||
*/
|
|
||||||
virtual int BlockCommand( EDA_KEY aKey ) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the block place command.
|
|
||||||
*/
|
|
||||||
virtual void HandleBlockPlace( wxDC* DC ) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a block end command.
|
|
||||||
*
|
|
||||||
* @return If command finished (zoom, delete ...) false is returned otherwise true
|
|
||||||
* is returned indicating more processing is required.
|
|
||||||
*/
|
|
||||||
virtual bool HandleBlockEnd( wxDC* DC ) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Place at cursor location the pin currently moved (i.e. pin pointed by m_drawItem)
|
|
||||||
* (and the linked pins, if any)
|
|
||||||
*/
|
|
||||||
void PlacePin();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param aMasterPin is the "template" pin
|
|
||||||
* @param aId is a param to select what should be mofified:
|
|
||||||
* - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
|
|
||||||
* Change pins text name size
|
|
||||||
* - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
|
|
||||||
* Change pins text num size
|
|
||||||
* - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
|
|
||||||
* Change pins length.
|
|
||||||
*
|
|
||||||
* If aMasterPin is selected ( .m_flag == IS_SELECTED ),
|
|
||||||
* only the other selected pins are modified
|
|
||||||
*/
|
|
||||||
void GlobalSetPins( LIB_PIN* aMasterPin, int aId );
|
|
||||||
|
|
||||||
// Automatic placement of pins
|
|
||||||
void RepeatPinItem( wxDC* DC, LIB_PIN* Pin );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an image (screenshot) of the current symbol.
|
* Creates an image (screenshot) of the current symbol.
|
||||||
*
|
*
|
||||||
|
@ -687,30 +574,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void HardRedraw() override;
|
void HardRedraw() override;
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks all draw objects of part to see if they are with block.
|
|
||||||
*
|
|
||||||
* Use this method to mark draw objects as selected during block
|
|
||||||
* functions.
|
|
||||||
*
|
|
||||||
* @param aRect - The bounding rectangle to test in draw items are inside.
|
|
||||||
* @param aUnit - The current unit number to test against.
|
|
||||||
* @param aConvert - Are the draw items being selected a conversion.
|
|
||||||
* @param aSyncPinEdit - Enable pin selection in other units.
|
|
||||||
* @return The number of draw objects found inside the block select
|
|
||||||
* rectangle.
|
|
||||||
*/
|
|
||||||
int BlockSelectItems( LIB_PART* aPart, BLOCK_SELECTOR* aBlock, int aUnit, int aConvert, bool aSyncPinEdit );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears all the draw items marked by a block select.
|
|
||||||
*/
|
|
||||||
void BlockClearSelectedItems( LIB_PART* aPart, BLOCK_SELECTOR* aBlock );
|
|
||||||
|
|
||||||
void BlockMoveSelectedItems( const wxPoint& aOffset, LIB_PART* aPart, BLOCK_SELECTOR* aBlock );
|
|
||||||
void BlockDeleteSelectedItems( LIB_PART* aPart, BLOCK_SELECTOR* aBlock );
|
|
||||||
void BlockCopySelectedItems( const wxPoint& aOffset, LIB_PART* aPart, BLOCK_SELECTOR* aBlock );
|
|
||||||
|
|
||||||
void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
|
void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -762,8 +625,6 @@ private:
|
||||||
///> Renames LIB_PART aliases to avoid conflicts before adding a component to a library
|
///> Renames LIB_PART aliases to avoid conflicts before adding a component to a library
|
||||||
void fixDuplicateAliases( LIB_PART* aPart, const wxString& aLibrary );
|
void fixDuplicateAliases( LIB_PART* aPart, const wxString& aLibrary );
|
||||||
|
|
||||||
void InitBlockPasteInfos() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies items selected in the current part to the internal clipboard.
|
* Copies items selected in the current part to the internal clipboard.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
wxString msg;
|
wxString msg;
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
wxString libName = getTargetLib();
|
wxString libName = getTargetLib();
|
||||||
|
|
||||||
if( !m_libMgr->LibraryExists( libName ) )
|
if( !m_libMgr->LibraryExists( libName ) )
|
||||||
|
@ -183,8 +182,6 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mruPath = fn.GetPath();
|
m_mruPath = fn.GetPath();
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
SetDrawItem( NULL );
|
|
||||||
|
|
||||||
msg.Printf( _( "Symbol \"%s\" saved in library \"%s\"" ), part->GetName(), fn.GetFullPath() );
|
msg.Printf( _( "Symbol \"%s\" saved in library \"%s\"" ), part->GetName(), fn.GetFullPath() );
|
||||||
SetStatusText( msg );
|
SetStatusText( msg );
|
||||||
|
|
|
@ -103,6 +103,12 @@ bool LIB_EDIT_FRAME::saveCurrentPart()
|
||||||
|
|
||||||
bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( const LIB_ID& aLibId, int aUnit, int aConvert )
|
bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( const LIB_ID& aLibId, int aUnit, int aConvert )
|
||||||
{
|
{
|
||||||
|
if( GetCurPart() && GetCurPart()->GetLibId() == aLibId
|
||||||
|
&& GetUnit() == aUnit && GetConvert() == aConvert )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if( GetScreen()->IsModify() && GetCurPart() )
|
if( GetScreen()->IsModify() && GetCurPart() )
|
||||||
{
|
{
|
||||||
if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
|
if( !HandleUnsavedChanges( this, _( "The current symbol has been modified. Save changes?" ),
|
||||||
|
@ -278,7 +284,6 @@ void LIB_EDIT_FRAME::OnSaveAll( wxCommandEvent& event )
|
||||||
void LIB_EDIT_FRAME::OnCreateNewPart( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::OnCreateNewPart( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor() );
|
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor() );
|
||||||
SetDrawItem( NULL );
|
|
||||||
wxString lib = getTargetLib();
|
wxString lib = getTargetLib();
|
||||||
|
|
||||||
if( !m_libMgr->LibraryExists( lib ) )
|
if( !m_libMgr->LibraryExists( lib ) )
|
||||||
|
@ -497,6 +502,33 @@ void LIB_EDIT_FRAME::savePartAs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::UpdateAfterRename( LIB_PART* aPart, const wxString& aOldName,
|
||||||
|
const wxString& aNewName )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
wxString lib = GetCurLib();
|
||||||
|
|
||||||
|
// Test the current library for name conflicts
|
||||||
|
if( !lib.empty() && m_libMgr->PartExists( aNewName, lib ) )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "The name '%s' conflicts with an existing entry in the library '%s'." ),
|
||||||
|
aNewName,
|
||||||
|
lib );
|
||||||
|
|
||||||
|
DisplayErrorMessage( this, msg );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveCopyInUndoList( aPart, UR_LIB_RENAME );
|
||||||
|
aPart->SetName( aNewName );
|
||||||
|
|
||||||
|
m_libMgr->UpdatePartAfterRename( aPart, aOldName, lib );
|
||||||
|
|
||||||
|
// Reselect the renamed part
|
||||||
|
m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, aNewName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnRemovePart( wxCommandEvent& aEvent )
|
void LIB_EDIT_FRAME::OnRemovePart( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
LIB_ID libId = getTargetLibId();
|
LIB_ID libId = getTargetLibId();
|
||||||
|
@ -701,9 +733,6 @@ void LIB_EDIT_FRAME::loadPart( const wxString& aAlias, const wxString& aLibrary,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_lastDrawItem = nullptr;
|
|
||||||
SetDrawItem( NULL );
|
|
||||||
|
|
||||||
// Optimize default edit options for this symbol
|
// Optimize default edit options for this symbol
|
||||||
// Usually if units are locked, graphic items are specific to each unit
|
// Usually if units are locked, graphic items are specific to each unit
|
||||||
// and if units are interchangeable, graphic items are common to units
|
// and if units are interchangeable, graphic items are common to units
|
||||||
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
|
||||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
|
||||||
* Copyright (C) 1992-2013 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file libedit_onleftclick.cpp
|
|
||||||
* @brief Eeschema library editor event handler for a mouse left button single or double click.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fctsys.h>
|
|
||||||
#include <sch_draw_panel.h>
|
|
||||||
#include <eeschema_id.h>
|
|
||||||
#include <msgpanel.h>
|
|
||||||
|
|
||||||
#include <general.h>
|
|
||||||
#include <lib_edit_frame.h>
|
|
||||||
#include <class_libentry.h>
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& aPosition )
|
|
||||||
{
|
|
||||||
LIB_ITEM* item = GetDrawItem();
|
|
||||||
bool item_in_edit = item && item->InEditMode();
|
|
||||||
bool no_item_edited = !item_in_edit;
|
|
||||||
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
if( !part ) // No component loaded !
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( ( GetToolId() == ID_NO_TOOL_SELECTED ) && no_item_edited )
|
|
||||||
item = LocateItemUsingCursor( aPosition );
|
|
||||||
|
|
||||||
switch( GetToolId() )
|
|
||||||
{
|
|
||||||
case ID_ZOOM_SELECTION:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_NO_TOOL_SELECTED:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_LIBEDIT_DELETE_ITEM_BUTT:
|
|
||||||
item = LocateItemUsingCursor( aPosition );
|
|
||||||
|
|
||||||
if( item )
|
|
||||||
deleteItem( DC, item );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_LIBEDIT_BODY_TEXT_BUTT:
|
|
||||||
case ID_LIBEDIT_ANCHOR_ITEM_BUTT:
|
|
||||||
case ID_LIBEDIT_PIN_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_LINE_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_ARC_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_CIRCLE_BUTT:
|
|
||||||
case ID_LIBEDIT_BODY_RECT_BUTT:
|
|
||||||
// Moved to modern toolset
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
wxFAIL_MSG( wxString::Format( wxT( "Unhandled command ID %d" ), GetToolId() ) );
|
|
||||||
SetNoToolSelected();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called on a double click:
|
|
||||||
* If an editable item (field, pin, graphic):
|
|
||||||
* Call the suitable dialog editor.
|
|
||||||
*/
|
|
||||||
void LIB_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& aPosition )
|
|
||||||
{
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
LIB_ITEM* item = GetDrawItem();
|
|
||||||
|
|
||||||
if( !part )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( !item || !item->InEditMode() )
|
|
||||||
{ // We can locate an item
|
|
||||||
item = LocateItemUsingCursor( aPosition, SCH_COLLECTOR::LibItems );
|
|
||||||
|
|
||||||
if( item == NULL )
|
|
||||||
{
|
|
||||||
// The user canceled the disambiguation menu
|
|
||||||
if( m_canvas->GetAbortRequest() )
|
|
||||||
m_canvas->SetAbortRequest( false );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If there is only a random double-click, we allow the use to edit the part
|
|
||||||
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
|
|
||||||
|
|
||||||
cmd.SetId( ID_LIBEDIT_GET_FRAME_EDIT_PART );
|
|
||||||
GetEventHandler()->ProcessEvent( cmd );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item )
|
|
||||||
SetMsgPanel( item );
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_canvas->SetIgnoreMouseEvents( true );
|
|
||||||
bool not_edited = !item->InEditMode();
|
|
||||||
|
|
||||||
switch( item->Type() )
|
|
||||||
{
|
|
||||||
case LIB_PIN_T:
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
SetDrawItem( item );
|
|
||||||
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
|
|
||||||
|
|
||||||
cmd.SetId( ID_LIBEDIT_EDIT_PIN );
|
|
||||||
GetEventHandler()->ProcessEvent( cmd );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_ARC_T:
|
|
||||||
case LIB_CIRCLE_T:
|
|
||||||
case LIB_RECTANGLE_T:
|
|
||||||
case LIB_POLYLINE_T:
|
|
||||||
if( not_edited )
|
|
||||||
EditGraphicSymbol( DC, item );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_TEXT_T:
|
|
||||||
if( not_edited )
|
|
||||||
EditSymbolText( DC, item );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_FIELD_T:
|
|
||||||
if( not_edited )
|
|
||||||
EditField( (LIB_FIELD*) item );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
wxFAIL_MSG( wxT( "Unhandled item <" ) + item->GetClass() + wxT( ">" ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
|
||||||
m_canvas->SetIgnoreMouseEvents( false );
|
|
||||||
}
|
|
|
@ -1,245 +1,6 @@
|
||||||
/**
|
|
||||||
* @file libedit_onrightclick.cpp
|
|
||||||
* @brief Library editor: create the pop menus when clicking on mouse right button
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004-2014 KiCad Developers, see change_log.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 <fctsys.h>
|
|
||||||
#include <confirm.h>
|
|
||||||
#include <eeschema_id.h>
|
|
||||||
#include <hotkeys.h>
|
|
||||||
#include <sch_draw_panel.h>
|
|
||||||
#include <sch_screen.h>
|
|
||||||
#include <msgpanel.h>
|
|
||||||
|
|
||||||
#include <general.h>
|
|
||||||
#include <lib_edit_frame.h>
|
|
||||||
#include <class_libentry.h>
|
|
||||||
#include <lib_pin.h>
|
|
||||||
#include <lib_polyline.h>
|
|
||||||
#include <menus_helpers.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* functions to add commands and submenus depending on the item */
|
|
||||||
static void AddMenusForBlock( wxMenu* PopMenu, LIB_EDIT_FRAME* frame );
|
|
||||||
static void AddMenusForPin( wxMenu* PopMenu, LIB_PIN* Pin, LIB_EDIT_FRAME* frame );
|
|
||||||
|
|
||||||
|
|
||||||
bool LIB_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
|
|
||||||
{
|
|
||||||
LIB_ITEM* item = GetDrawItem();
|
|
||||||
bool blockActive = GetScreen()->IsBlockActive();
|
|
||||||
wxString msg;
|
|
||||||
|
|
||||||
if( blockActive )
|
|
||||||
{
|
|
||||||
AddMenusForBlock( PopMenu, this );
|
|
||||||
PopMenu->AppendSeparator();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
if( !part )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// If Command in progress, put menu "cancel"
|
|
||||||
if( item && item->InEditMode() )
|
|
||||||
{
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_CANCEL_EDITING, _( "Cancel" ),
|
|
||||||
KiBitmap( cancel_xpm ) );
|
|
||||||
PopMenu->AppendSeparator();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item = LocateItemUsingCursor( aPosition );
|
|
||||||
|
|
||||||
// If the clarify item selection context menu is aborted, don't show the context menu.
|
|
||||||
if( item == NULL && m_canvas->GetAbortRequest() )
|
|
||||||
{
|
|
||||||
m_canvas->SetAbortRequest( false );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( GetToolId() != ID_NO_TOOL_SELECTED )
|
|
||||||
{
|
|
||||||
// If a tool is active, put menu "end tool"
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_CANCEL_EDITING, _( "End Tool" ),
|
|
||||||
KiBitmap( cursor_xpm ) );
|
|
||||||
PopMenu->AppendSeparator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item )
|
|
||||||
{
|
|
||||||
MSG_PANEL_ITEMS items;
|
|
||||||
item->GetMsgPanelInfo( m_UserUnits, items );
|
|
||||||
SetMsgPanel( items );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( GetToolId() == ID_NO_TOOL_SELECTED )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "&Paste" ), g_Libedit_Hotkeys_Descr, HK_EDIT_PASTE );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_PASTE_BLOCK, msg, _( "Pastes copied item(s)" ),
|
|
||||||
KiBitmap( paste_xpm ) );
|
|
||||||
PopMenu->AppendSeparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetDrawItem( item );
|
|
||||||
bool not_edited = !item->InEditMode();
|
|
||||||
|
|
||||||
switch( item->Type() )
|
|
||||||
{
|
|
||||||
case LIB_PIN_T:
|
|
||||||
AddMenusForPin( PopMenu, (LIB_PIN*) item, this );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_ARC_T:
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Move" ), g_Libedit_Hotkeys_Descr,
|
|
||||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
|
|
||||||
KiBitmap( move_xpm ) );
|
|
||||||
msg = AddHotkeyName( _( "Drag Arc Edge" ), g_Libedit_Hotkeys_Descr, HK_DRAG );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM, msg, KiBitmap( move_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Edit Arc Options" ), g_Libedit_Hotkeys_Descr, HK_EDIT );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg, KiBitmap( options_arc_xpm ) );
|
|
||||||
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Delete" ), g_Libedit_Hotkeys_Descr, HK_DELETE );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg, KiBitmap( delete_xpm ) );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_CIRCLE_T:
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Move" ), g_Libedit_Hotkeys_Descr,
|
|
||||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
|
|
||||||
KiBitmap( move_xpm ) );
|
|
||||||
msg = AddHotkeyName( _( "Drag Circle Outline" ), g_Libedit_Hotkeys_Descr, HK_DRAG );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM, msg,
|
|
||||||
KiBitmap( move_rectangle_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Edit Circle Options..." ), g_Libedit_Hotkeys_Descr, HK_EDIT );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg,
|
|
||||||
KiBitmap( options_circle_xpm ) );
|
|
||||||
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Delete" ), g_Libedit_Hotkeys_Descr, HK_DELETE );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg,
|
|
||||||
KiBitmap( delete_circle_xpm ) );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_RECTANGLE_T:
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Move Rectangle" ), g_Libedit_Hotkeys_Descr,
|
|
||||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
|
|
||||||
KiBitmap( move_rectangle_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Edit Rectangle Options..." ), g_Libedit_Hotkeys_Descr, HK_EDIT );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg,
|
|
||||||
KiBitmap( options_rectangle_xpm ) );
|
|
||||||
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Drag Rectangle Edge" ), g_Libedit_Hotkeys_Descr, HK_DRAG );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM, msg,
|
|
||||||
KiBitmap( move_rectangle_xpm ) );
|
|
||||||
msg = AddHotkeyName( _( "Delete" ), g_Libedit_Hotkeys_Descr, HK_DELETE );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg,
|
|
||||||
KiBitmap( delete_rectangle_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LIB_TEXT_T:
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Move" ), g_Libedit_Hotkeys_Descr,
|
|
||||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
|
|
||||||
KiBitmap( move_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Edit..." ), g_Libedit_Hotkeys_Descr, HK_EDIT );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Rotate Clockwise" ), g_Libedit_Hotkeys_Descr, HK_ROTATE );
|
|
||||||
AddMenuItem( PopMenu, ID_LIBEDIT_ROTATE_ITEM, msg, KiBitmap( rotate_cw_xpm ) );
|
|
||||||
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Delete" ), g_Libedit_Hotkeys_Descr, HK_DELETE );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg, KiBitmap( delete_xpm ) );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
case LIB_POLYLINE_T:
|
case LIB_POLYLINE_T:
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Move" ), g_Libedit_Hotkeys_Descr,
|
|
||||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
|
|
||||||
KiBitmap( move_xpm ) );
|
|
||||||
msg = AddHotkeyName( _( "Drag Edge Point" ), g_Libedit_Hotkeys_Descr, HK_DRAG );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM, msg, KiBitmap( move_exactly_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item->IsNew() )
|
|
||||||
{
|
|
||||||
// AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_END_CREATE_ITEM, _( "Line End" ),
|
|
||||||
// KiBitmap( checked_ok_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Edit Line Options..." ), g_Libedit_Hotkeys_Descr, HK_EDIT );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg,
|
|
||||||
KiBitmap( options_segment_xpm ) );
|
|
||||||
|
|
||||||
if( not_edited )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Delete" ), g_Libedit_Hotkeys_Descr, HK_DELETE );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg,
|
|
||||||
KiBitmap( delete_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item->IsNew() )
|
if( item->IsNew() )
|
||||||
{
|
{
|
||||||
if( ( (LIB_POLYLINE*) item )->GetCornerCount() > 2 )
|
if( ( (LIB_POLYLINE*) item )->GetCornerCount() > 2 )
|
||||||
|
@ -252,122 +13,17 @@ bool LIB_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIB_FIELD_T:
|
//===============================================
|
||||||
if( not_edited )
|
|
||||||
|
case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT:
|
||||||
{
|
{
|
||||||
msg = AddHotkeyName( _( "Move" ), g_Libedit_Hotkeys_Descr,
|
// Delete the last created segment, while creating a polyline draw item
|
||||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
if( item == NULL )
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
|
break;
|
||||||
KiBitmap( move_xpm ) );
|
|
||||||
|
m_canvas->MoveCursorToCrossHair();
|
||||||
|
static_cast<LIB_POLYLINE*>( item )->DeleteSegment( GetCrossHairPosition( true ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Rotate Clockwise" ), g_Libedit_Hotkeys_Descr, HK_ROTATE );
|
|
||||||
AddMenuItem( PopMenu, ID_LIBEDIT_ROTATE_ITEM, msg, KiBitmap( rotate_cw_xpm ) );
|
|
||||||
msg = AddHotkeyName( _( "Edit..." ), g_Libedit_Hotkeys_Descr, HK_EDIT );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
|
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
wxFAIL_MSG( wxString::Format( wxT( "Unknown library item type %d" ),
|
|
||||||
item->Type() ) );
|
|
||||||
SetDrawItem( NULL );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PopMenu->AppendSeparator();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddMenusForPin( wxMenu* PopMenu, LIB_PIN* Pin, LIB_EDIT_FRAME* frame )
|
|
||||||
{
|
|
||||||
bool selected = Pin->IsSelected();
|
|
||||||
bool not_in_move = !Pin->IsMoving();
|
|
||||||
wxString msg;
|
|
||||||
|
|
||||||
if( not_in_move )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Move" ), g_Libedit_Hotkeys_Descr,
|
|
||||||
HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg, KiBitmap( move_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Edit..." ), g_Libedit_Hotkeys_Descr, HK_EDIT);
|
|
||||||
AddMenuItem( PopMenu, ID_LIBEDIT_EDIT_PIN, msg, KiBitmap( edit_xpm ) );
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Rotate Clockwise" ), g_Libedit_Hotkeys_Descr, HK_ROTATE );
|
|
||||||
AddMenuItem( PopMenu, ID_LIBEDIT_ROTATE_ITEM, msg, KiBitmap( rotate_cw_xpm ) );
|
|
||||||
|
|
||||||
if( not_in_move )
|
|
||||||
{
|
|
||||||
msg = AddHotkeyName( _( "Delete" ), g_Libedit_Hotkeys_Descr, HK_DELETE );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg, KiBitmap( delete_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
wxMenu* global_pin_change = new wxMenu;
|
|
||||||
AddMenuItem( PopMenu, global_pin_change,
|
|
||||||
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
|
|
||||||
_( "Global" ), KiBitmap( pin_to_xpm ) );
|
|
||||||
AddMenuItem( global_pin_change,
|
|
||||||
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM,
|
|
||||||
selected ? _( "Push Pin Size to Selected Pin" ) :
|
|
||||||
_( "Push Pin Size to Others" ), KiBitmap( pin_size_to_xpm ) );
|
|
||||||
AddMenuItem( global_pin_change,
|
|
||||||
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM,
|
|
||||||
selected ? _( "Push Pin Name Size to Selected Pin" ) :
|
|
||||||
_( "Push Pin Name Size to Others" ), KiBitmap( pin_name_to_xpm ) );
|
|
||||||
AddMenuItem( global_pin_change,
|
|
||||||
ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM,
|
|
||||||
selected ? _( "Push Pin Num Size to Selected Pin" ) :
|
|
||||||
_( "Push Pin Num Size to Others" ), KiBitmap( pin_number_to_xpm ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Add menu commands for block */
|
|
||||||
|
|
||||||
void AddMenusForBlock( wxMenu* PopMenu, LIB_EDIT_FRAME* frame )
|
|
||||||
{
|
|
||||||
wxString msg;
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_CANCEL_EDITING, _( "Cancel Block" ),
|
|
||||||
KiBitmap( cancel_xpm ) );
|
|
||||||
|
|
||||||
if( frame->GetScreen()->m_BlockLocate.GetCommand() == BLOCK_MOVE )
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_ZOOM_BLOCK,
|
|
||||||
_( "Zoom Block" ),
|
|
||||||
KiBitmap( zoom_area_xpm ) );
|
|
||||||
|
|
||||||
PopMenu->AppendSeparator();
|
|
||||||
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_PLACE_BLOCK, _( "Place Block" ), KiBitmap( checked_ok_xpm ) );
|
|
||||||
|
|
||||||
if( frame->GetScreen()->m_BlockLocate.GetCommand() == BLOCK_MOVE )
|
|
||||||
{
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_SELECT_ITEMS_BLOCK, _( "Select Items" ),
|
|
||||||
KiBitmap( green_xpm ) );
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Cut Block" ), g_Schematic_Hotkeys_Descr, HK_EDIT_CUT );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_CUT_BLOCK, msg, KiBitmap( cut_xpm ) );
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Copy Block" ), g_Schematic_Hotkeys_Descr, HK_EDIT_COPY );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_COPY_BLOCK, msg,
|
|
||||||
KiBitmap( copy_xpm ) );
|
|
||||||
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_DUPLICATE_BLOCK, _( "Duplicate Block" ),
|
|
||||||
KiBitmap( duplicate_xpm ) );
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Mirror Block Around Horizontal(X) Axis" ), g_Libedit_Hotkeys_Descr, HK_MIRROR_X );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_MIRROR_X_BLOCK, msg,
|
|
||||||
KiBitmap( mirror_v_xpm ) );
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Mirror Block Around Vertical(Y) Axis" ), g_Libedit_Hotkeys_Descr, HK_MIRROR_Y );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_MIRROR_Y_BLOCK, msg,
|
|
||||||
KiBitmap( mirror_h_xpm ) );
|
|
||||||
|
|
||||||
msg = AddHotkeyName( _( "Rotate Counterclockwise" ), g_Libedit_Hotkeys_Descr, HK_ROTATE );
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_ROTATE_BLOCK, msg,
|
|
||||||
KiBitmap( rotate_ccw_xpm ) );
|
|
||||||
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_DELETE_BLOCK, _( "Delete Block" ),
|
|
||||||
KiBitmap( delete_xpm ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -92,7 +92,6 @@ void LIB_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& event )
|
||||||
m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, part->GetName() ) );
|
m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, part->GetName() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDrawItem( NULL );
|
|
||||||
RebuildSymbolUnitsList();
|
RebuildSymbolUnitsList();
|
||||||
SetShowDeMorgan( part->HasConversion() );
|
SetShowDeMorgan( part->HasConversion() );
|
||||||
updateTitle();
|
updateTitle();
|
||||||
|
@ -142,7 +141,6 @@ void LIB_EDIT_FRAME::GetComponentFromUndoList( wxCommandEvent& event )
|
||||||
m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, part->GetName() ) );
|
m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, part->GetName() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDrawItem( NULL );
|
|
||||||
RebuildSymbolUnitsList();
|
RebuildSymbolUnitsList();
|
||||||
SetShowDeMorgan( part->HasConversion() );
|
SetShowDeMorgan( part->HasConversion() );
|
||||||
updateTitle();
|
updateTitle();
|
||||||
|
@ -151,3 +149,23 @@ void LIB_EDIT_FRAME::GetComponentFromUndoList( wxCommandEvent& event )
|
||||||
GetCanvas()->Refresh();
|
GetCanvas()->Refresh();
|
||||||
OnModify();
|
OnModify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::RollbackPartFromUndo()
|
||||||
|
{
|
||||||
|
m_toolManager->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
|
// Load the last undo entry
|
||||||
|
PICKED_ITEMS_LIST* undoCommand = GetScreen()->PopCommandFromUndoList();
|
||||||
|
ITEM_PICKER undoWrapper = undoCommand->PopItem();
|
||||||
|
delete undoCommand;
|
||||||
|
LIB_PART* part = (LIB_PART*) undoWrapper.GetItem();
|
||||||
|
part->ClearFlags( UR_TRANSIENT );
|
||||||
|
SetCurPart( part );
|
||||||
|
|
||||||
|
RebuildSymbolUnitsList();
|
||||||
|
SetShowDeMorgan( part->HasConversion() );
|
||||||
|
|
||||||
|
RebuildView();
|
||||||
|
GetCanvas()->Refresh();
|
||||||
|
}
|
|
@ -39,66 +39,3 @@
|
||||||
#include <widgets/lib_tree.h>
|
#include <widgets/lib_tree.h>
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
|
|
||||||
{
|
|
||||||
wxString newFieldValue;
|
|
||||||
wxString caption;
|
|
||||||
|
|
||||||
if( aField == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
LIB_PART* parent = aField->GetParent();
|
|
||||||
wxCHECK( parent, /* void */ );
|
|
||||||
|
|
||||||
// Editing the component value field is equivalent to creating a new component based
|
|
||||||
// on the current component. Set the dialog message to inform the user.
|
|
||||||
if( aField->GetId() == VALUE )
|
|
||||||
caption = _( "Edit Component Name" );
|
|
||||||
else
|
|
||||||
caption.Printf( _( "Edit %s Field" ), GetChars( aField->GetName() ) );
|
|
||||||
|
|
||||||
DIALOG_LIB_EDIT_ONE_FIELD dlg( this, caption, aField );
|
|
||||||
|
|
||||||
// The dialog may invoke a kiway player for footprint fields
|
|
||||||
// so we must use a quasimodal dialog.
|
|
||||||
if( dlg.ShowQuasiModal() != wxID_OK )
|
|
||||||
return;
|
|
||||||
|
|
||||||
newFieldValue = LIB_ID::FixIllegalChars( dlg.GetText(), LIB_ID::ID_SCH );
|
|
||||||
wxString oldFieldValue = aField->GetFullText( m_unit );
|
|
||||||
bool renamed = aField->GetId() == VALUE && newFieldValue != oldFieldValue;
|
|
||||||
|
|
||||||
if( renamed )
|
|
||||||
{
|
|
||||||
wxString msg;
|
|
||||||
wxString lib = GetCurLib();
|
|
||||||
|
|
||||||
// Test the current library for name conflicts
|
|
||||||
if( !lib.empty() && m_libMgr->PartExists( newFieldValue, lib ) )
|
|
||||||
{
|
|
||||||
msg.Printf( _(
|
|
||||||
"The name \"%s\" conflicts with an existing entry in the symbol library \"%s\"." ),
|
|
||||||
newFieldValue, lib );
|
|
||||||
|
|
||||||
DisplayErrorMessage( this, msg );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveCopyInUndoList( parent, UR_LIB_RENAME );
|
|
||||||
parent->SetName( newFieldValue );
|
|
||||||
|
|
||||||
m_libMgr->UpdatePartAfterRename( parent, oldFieldValue, lib );
|
|
||||||
|
|
||||||
// Reselect the renamed part
|
|
||||||
m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, newFieldValue ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !aField->InEditMode() && !renamed )
|
|
||||||
SaveCopyInUndoList( parent );
|
|
||||||
|
|
||||||
dlg.UpdateField( aField );
|
|
||||||
|
|
||||||
GetCanvas()->GetView()->Update( aField );
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
/*
|
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
|
||||||
* Copyright (C) 2009-2017 Wayne Stambaugh <stambaughw@verizon.net>
|
|
||||||
* Copyright (C) 2004-2017 KiCad Developers, see change_log.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file symbdraw.cpp
|
|
||||||
* @brief Create, move .. graphic shapes used to build and draw a symbol (lines, arcs ..)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fctsys.h>
|
|
||||||
#include <sch_draw_panel.h>
|
|
||||||
#include <confirm.h>
|
|
||||||
#include <base_units.h>
|
|
||||||
#include <msgpanel.h>
|
|
||||||
|
|
||||||
#include <eeschema_id.h>
|
|
||||||
#include <lib_edit_frame.h>
|
|
||||||
#include <class_libentry.h>
|
|
||||||
#include <lib_arc.h>
|
|
||||||
#include <lib_circle.h>
|
|
||||||
#include <lib_polyline.h>
|
|
||||||
#include <lib_rectangle.h>
|
|
||||||
#include <lib_text.h>
|
|
||||||
|
|
||||||
#include <sch_view.h>
|
|
||||||
#include <dialogs/dialog_lib_edit_draw_item.h>
|
|
||||||
|
|
||||||
|
|
||||||
static void RedrawWhileMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
|
|
||||||
bool aErase );
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::EditGraphicSymbol( wxDC* DC, LIB_ITEM* DrawItem )
|
|
||||||
{
|
|
||||||
if( DrawItem == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem );
|
|
||||||
|
|
||||||
if( dialog.ShowModal() == wxID_CANCEL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Init default values (used to create a new draw item)
|
|
||||||
g_LastLineWidth = dialog.GetWidth();
|
|
||||||
m_DrawSpecificConvert = !dialog.GetApplyToAllConversions();
|
|
||||||
m_DrawSpecificUnit = !dialog.GetApplyToAllUnits();
|
|
||||||
|
|
||||||
// Save copy for undo if not in edit (edit command already handle the save copy)
|
|
||||||
if( !DrawItem->InEditMode() )
|
|
||||||
SaveCopyInUndoList( DrawItem->GetParent() );
|
|
||||||
|
|
||||||
if( m_DrawSpecificUnit )
|
|
||||||
DrawItem->SetUnit( GetUnit() );
|
|
||||||
else
|
|
||||||
DrawItem->SetUnit( 0 );
|
|
||||||
|
|
||||||
if( m_DrawSpecificConvert )
|
|
||||||
DrawItem->SetConvert( GetConvert() );
|
|
||||||
else
|
|
||||||
DrawItem->SetConvert( 0 );
|
|
||||||
|
|
||||||
if( DrawItem->IsFillable() )
|
|
||||||
DrawItem->SetFillMode( (FILL_T) dialog.GetFillStyle() );
|
|
||||||
|
|
||||||
DrawItem->SetWidth( g_LastLineWidth );
|
|
||||||
|
|
||||||
GetCanvas()->GetView()->Update( DrawItem );
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify( );
|
|
||||||
|
|
||||||
MSG_PANEL_ITEMS items;
|
|
||||||
DrawItem->GetMsgPanelInfo( m_UserUnits, items );
|
|
||||||
SetMsgPanel( items );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void AbortSymbolTraceOn( EDA_DRAW_PANEL* aPanel, wxDC* DC )
|
|
||||||
{
|
|
||||||
LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent();
|
|
||||||
LIB_ITEM* item = parent->GetDrawItem();
|
|
||||||
|
|
||||||
if( item == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool newItem = item->IsNew();
|
|
||||||
item->EndEdit( parent->GetCrossHairPosition( true ) );
|
|
||||||
|
|
||||||
if( newItem )
|
|
||||||
delete item;
|
|
||||||
else
|
|
||||||
parent->RestoreComponent();
|
|
||||||
|
|
||||||
parent->SetDrawItem( NULL );
|
|
||||||
|
|
||||||
auto view = static_cast<SCH_DRAW_PANEL*>(aPanel)->GetView();
|
|
||||||
view->ClearPreview();
|
|
||||||
view->ShowPreview( false );
|
|
||||||
view->ClearHiddenFlags();
|
|
||||||
parent->RebuildView();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Redraw the graphic shape while moving
|
|
||||||
*/
|
|
||||||
static void RedrawWhileMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
|
|
||||||
bool aErase )
|
|
||||||
{
|
|
||||||
LIB_ITEM* item = ( (LIB_EDIT_FRAME*) aPanel->GetParent() )->GetDrawItem();
|
|
||||||
|
|
||||||
if( item == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto view = static_cast<SCH_DRAW_PANEL*>(aPanel)->GetView();
|
|
||||||
auto p = aPanel->GetParent()->GetCrossHairPosition( true );
|
|
||||||
|
|
||||||
item->CalcEdit( p );
|
|
||||||
|
|
||||||
view->Hide( item );
|
|
||||||
view->ClearPreview();
|
|
||||||
view->AddToPreview( item->Clone() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::StartMoveDrawSymbol( wxDC* DC, LIB_ITEM* aItem )
|
|
||||||
{
|
|
||||||
if( aItem == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
SetCursor( wxCURSOR_HAND );
|
|
||||||
|
|
||||||
GetGalCanvas()->GetView()->Hide ( aItem );
|
|
||||||
|
|
||||||
TempCopyComponent();
|
|
||||||
|
|
||||||
// For fields only, move the anchor point of the field
|
|
||||||
// to the cursor position to allow user to see the text justification
|
|
||||||
if( aItem->Type() == LIB_FIELD_T )
|
|
||||||
aItem->BeginEdit( IS_MOVED, aItem->GetPosition() );
|
|
||||||
else
|
|
||||||
aItem->BeginEdit( IS_MOVED, GetCrossHairPosition( true ) );
|
|
||||||
|
|
||||||
m_canvas->SetMouseCapture( RedrawWhileMovingCursor, AbortSymbolTraceOn );
|
|
||||||
m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::StartModifyDrawSymbol( wxDC* DC, LIB_ITEM* aItem )
|
|
||||||
{
|
|
||||||
if( aItem == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
DBG(printf("startmdifyraw\n");)
|
|
||||||
|
|
||||||
TempCopyComponent();
|
|
||||||
aItem->BeginEdit( IS_RESIZED, GetCrossHairPosition( true ) );
|
|
||||||
m_canvas->SetMouseCapture( RedrawWhileMovingCursor, AbortSymbolTraceOn );
|
|
||||||
m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
|
|
||||||
}
|
|
|
@ -38,13 +38,16 @@
|
||||||
#include <properties.h>
|
#include <properties.h>
|
||||||
#include <view/view.h>
|
#include <view/view.h>
|
||||||
#include <dialogs/dialog_display_info_HTML_base.h>
|
#include <dialogs/dialog_display_info_HTML_base.h>
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <tools/sch_selection_tool.h>
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::LoadOneSymbol()
|
void LIB_EDIT_FRAME::LoadOneSymbol()
|
||||||
{
|
{
|
||||||
LIB_PART* part = GetCurPart();
|
SCH_SELECTION_TOOL* selTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
|
||||||
|
LIB_PART* part = GetCurPart();
|
||||||
|
|
||||||
// Exit if no library entry is selected or a command is in progress.
|
// Exit if no library entry is selected or a command is in progress.
|
||||||
if( !part || ( GetDrawItem() && GetDrawItem()->GetEditFlags() ) )
|
if( !part || !SCH_CONDITIONS::Idle( selTool->GetSelection() ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PROJECT& prj = Prj();
|
PROJECT& prj = Prj();
|
||||||
|
|
|
@ -324,6 +324,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void SyncView();
|
void SyncView();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must be called after a model change in order to set the "modify" flag and
|
||||||
|
* do other frame-specific processing.
|
||||||
|
*/
|
||||||
|
virtual void OnModify() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,55 +34,7 @@
|
||||||
|
|
||||||
|
|
||||||
const KICAD_T SCH_COLLECTOR::AllItems[] = {
|
const KICAD_T SCH_COLLECTOR::AllItems[] = {
|
||||||
SCH_MARKER_T,
|
SCH_LOCATE_ANY_T,
|
||||||
SCH_JUNCTION_T,
|
|
||||||
SCH_NO_CONNECT_T,
|
|
||||||
SCH_BUS_BUS_ENTRY_T,
|
|
||||||
SCH_BUS_WIRE_ENTRY_T,
|
|
||||||
SCH_LINE_T,
|
|
||||||
SCH_BITMAP_T,
|
|
||||||
SCH_TEXT_T,
|
|
||||||
SCH_LABEL_T,
|
|
||||||
SCH_GLOBAL_LABEL_T,
|
|
||||||
SCH_HIER_LABEL_T,
|
|
||||||
SCH_FIELD_T,
|
|
||||||
SCH_COMPONENT_T,
|
|
||||||
SCH_PIN_T,
|
|
||||||
SCH_SHEET_PIN_T,
|
|
||||||
SCH_SHEET_T,
|
|
||||||
EOT
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const KICAD_T SCH_COLLECTOR::LibItems[] = {
|
|
||||||
LIB_ARC_T,
|
|
||||||
LIB_CIRCLE_T,
|
|
||||||
LIB_TEXT_T,
|
|
||||||
LIB_RECTANGLE_T,
|
|
||||||
LIB_POLYLINE_T,
|
|
||||||
LIB_BEZIER_T,
|
|
||||||
LIB_PIN_T,
|
|
||||||
LIB_FIELD_T,
|
|
||||||
EOT
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const KICAD_T SCH_COLLECTOR::AllItemsButPins[] = {
|
|
||||||
SCH_MARKER_T,
|
|
||||||
SCH_JUNCTION_T,
|
|
||||||
SCH_NO_CONNECT_T,
|
|
||||||
SCH_BUS_BUS_ENTRY_T,
|
|
||||||
SCH_BUS_WIRE_ENTRY_T,
|
|
||||||
SCH_LINE_T,
|
|
||||||
SCH_BITMAP_T,
|
|
||||||
SCH_TEXT_T,
|
|
||||||
SCH_LABEL_T,
|
|
||||||
SCH_GLOBAL_LABEL_T,
|
|
||||||
SCH_HIER_LABEL_T,
|
|
||||||
SCH_FIELD_T,
|
|
||||||
SCH_COMPONENT_T,
|
|
||||||
SCH_SHEET_PIN_T,
|
|
||||||
SCH_SHEET_T,
|
|
||||||
EOT
|
EOT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,7 +91,13 @@ const KICAD_T SCH_COLLECTOR::SheetsAndSheetLabels[] = {
|
||||||
|
|
||||||
SEARCH_RESULT SCH_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData )
|
SEARCH_RESULT SCH_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData )
|
||||||
{
|
{
|
||||||
if( m_Unit || m_Convert )
|
if( aItem->Type() == LIB_PIN_T )
|
||||||
|
{
|
||||||
|
// Special selection rules apply to pins of different units when edited in
|
||||||
|
// synchronized pins mode. Leave it to SCH_SELECTION_TOOL::isSelectable() to
|
||||||
|
// decide what to do with them.
|
||||||
|
}
|
||||||
|
else if( m_Unit || m_Convert )
|
||||||
{
|
{
|
||||||
LIB_ITEM* lib_item = dynamic_cast<LIB_ITEM*>( aItem );
|
LIB_ITEM* lib_item = dynamic_cast<LIB_ITEM*>( aItem );
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,8 @@ class SCH_COLLECTOR : public COLLECTOR
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const KICAD_T AllItems[];
|
static const KICAD_T AllItems[];
|
||||||
static const KICAD_T LibItems[];
|
|
||||||
static const KICAD_T EditableItems[];
|
static const KICAD_T EditableItems[];
|
||||||
static const KICAD_T RotatableItems[];
|
static const KICAD_T RotatableItems[];
|
||||||
static const KICAD_T AllItemsButPins[];
|
|
||||||
static const KICAD_T ComponentsOnly[];
|
static const KICAD_T ComponentsOnly[];
|
||||||
static const KICAD_T SheetsOnly[];
|
static const KICAD_T SheetsOnly[];
|
||||||
static const KICAD_T SheetsAndSheetLabels[];
|
static const KICAD_T SheetsAndSheetLabels[];
|
||||||
|
|
|
@ -1611,53 +1611,53 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR aInspector, void* aTestData,
|
||||||
for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
|
for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
|
||||||
{
|
{
|
||||||
// If caller wants to inspect component type or and component children types.
|
// If caller wants to inspect component type or and component children types.
|
||||||
if( stype == Type() )
|
if( stype == SCH_LOCATE_ANY_T || stype == Type() )
|
||||||
{
|
{
|
||||||
if( SEARCH_QUIT == aInspector( this, aTestData ) )
|
if( SEARCH_QUIT == aInspector( this, aTestData ) )
|
||||||
return SEARCH_QUIT;
|
return SEARCH_QUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( stype )
|
if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T )
|
||||||
{
|
{
|
||||||
case SCH_FIELD_T:
|
|
||||||
// Test the bounding boxes of fields if they are visible and not empty.
|
// Test the bounding boxes of fields if they are visible and not empty.
|
||||||
for( int ii = 0; ii < GetFieldCount(); ii++ )
|
for( int ii = 0; ii < GetFieldCount(); ii++ )
|
||||||
{
|
{
|
||||||
if( SEARCH_QUIT == aInspector( GetField( ii ), (void*) this ) )
|
if( SEARCH_QUIT == aInspector( GetField( ii ), (void*) this ) )
|
||||||
return SEARCH_QUIT;
|
return SEARCH_QUIT;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
|
||||||
case SCH_FIELD_LOCATE_REFERENCE_T:
|
if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_LOCATE_REFERENCE_T )
|
||||||
|
{
|
||||||
if( SEARCH_QUIT == aInspector( GetField( REFERENCE ), (void*) this ) )
|
if( SEARCH_QUIT == aInspector( GetField( REFERENCE ), (void*) this ) )
|
||||||
return SEARCH_QUIT;
|
return SEARCH_QUIT;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case SCH_FIELD_LOCATE_VALUE_T:
|
if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_LOCATE_VALUE_T )
|
||||||
|
{
|
||||||
if( SEARCH_QUIT == aInspector( GetField( VALUE ), (void*) this ) )
|
if( SEARCH_QUIT == aInspector( GetField( VALUE ), (void*) this ) )
|
||||||
return SEARCH_QUIT;
|
return SEARCH_QUIT;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case SCH_FIELD_LOCATE_FOOTPRINT_T:
|
if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_LOCATE_FOOTPRINT_T )
|
||||||
|
{
|
||||||
if( SEARCH_QUIT == aInspector( GetField( FOOTPRINT ), (void*) this ) )
|
if( SEARCH_QUIT == aInspector( GetField( FOOTPRINT ), (void*) this ) )
|
||||||
return SEARCH_QUIT;
|
return SEARCH_QUIT;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case SCH_FIELD_LOCATE_DATASHEET_T:
|
if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_LOCATE_DATASHEET_T )
|
||||||
|
{
|
||||||
if( SEARCH_QUIT == aInspector( GetField( DATASHEET ), (void*) this ) )
|
if( SEARCH_QUIT == aInspector( GetField( DATASHEET ), (void*) this ) )
|
||||||
return SEARCH_QUIT;
|
return SEARCH_QUIT;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case SCH_PIN_T:
|
if( stype == SCH_LOCATE_ANY_T || stype == SCH_PIN_T )
|
||||||
|
{
|
||||||
for( SCH_PIN& pin : m_pins )
|
for( SCH_PIN& pin : m_pins )
|
||||||
{
|
{
|
||||||
if( SEARCH_QUIT == aInspector( &pin, (void*) this ) )
|
if( SEARCH_QUIT == aInspector( &pin, (void*) this ) )
|
||||||
return SEARCH_QUIT;
|
return SEARCH_QUIT;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
#include <pgm_base.h>
|
#include <pgm_base.h>
|
||||||
#include <tools/sch_actions.h> // JEY TODO: temp LibEdit requirement
|
#include <tools/sch_actions.h>
|
||||||
#include <tools/sch_selection_tool.h> // JEY TODO: temp LibEdit requirement
|
#include <tools/sch_selection_tool.h>
|
||||||
|
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
@ -84,17 +84,6 @@ SCH_DRAW_PANEL::SCH_DRAW_PANEL( wxWindow* aParentWindow, wxWindowID aWindowId,
|
||||||
// on updated viewport data.
|
// on updated viewport data.
|
||||||
m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this );
|
m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this );
|
||||||
|
|
||||||
const wxEventType events[] =
|
|
||||||
{
|
|
||||||
wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK,
|
|
||||||
wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK,
|
|
||||||
wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK,
|
|
||||||
wxEVT_MOTION, wxEVT_MOUSEWHEEL,
|
|
||||||
};
|
|
||||||
|
|
||||||
for( auto e : events )
|
|
||||||
Connect( e, wxMouseEventHandler( SCH_DRAW_PANEL::OnMouseEvent ), NULL, this );
|
|
||||||
|
|
||||||
Connect( wxEVT_CHAR, wxKeyEventHandler( SCH_DRAW_PANEL::OnKeyEvent ), NULL, this );
|
Connect( wxEVT_CHAR, wxKeyEventHandler( SCH_DRAW_PANEL::OnKeyEvent ), NULL, this );
|
||||||
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( SCH_DRAW_PANEL::OnCharHook ), NULL, this );
|
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( SCH_DRAW_PANEL::OnCharHook ), NULL, this );
|
||||||
|
|
||||||
|
@ -102,7 +91,6 @@ SCH_DRAW_PANEL::SCH_DRAW_PANEL( wxWindow* aParentWindow, wxWindowID aWindowId,
|
||||||
Pgm().CommonSettings()->Read( ENBL_ZOOM_NO_CENTER_KEY, &m_enableZoomNoCenter, false );
|
Pgm().CommonSettings()->Read( ENBL_ZOOM_NO_CENTER_KEY, &m_enableZoomNoCenter, false );
|
||||||
Pgm().CommonSettings()->Read( ENBL_AUTO_PAN_KEY, &m_enableAutoPan, true );
|
Pgm().CommonSettings()->Read( ENBL_AUTO_PAN_KEY, &m_enableAutoPan, true );
|
||||||
|
|
||||||
m_canStartBlock = -1; // Command block can start if >= 0
|
|
||||||
m_abortRequest = false;
|
m_abortRequest = false;
|
||||||
m_ignoreMouseEvents = false;
|
m_ignoreMouseEvents = false;
|
||||||
// Be sure a mouse release button event will be ignored when creating the canvas
|
// Be sure a mouse release button event will be ignored when creating the canvas
|
||||||
|
@ -258,318 +246,6 @@ EDA_DRAW_FRAME* SCH_DRAW_PANEL::GetParent() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event )
|
|
||||||
{
|
|
||||||
int localbutt = 0;
|
|
||||||
BASE_SCREEN* screen = GetScreen();
|
|
||||||
auto controls = GetViewControls();
|
|
||||||
auto vmp = VECTOR2I( controls->GetMousePosition() );
|
|
||||||
wxPoint mousePos ( vmp.x, vmp.y );
|
|
||||||
|
|
||||||
event.Skip();
|
|
||||||
|
|
||||||
if( !screen )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// JEY TODO: this whole routine can go once libEdit is moved over to modern toolset
|
|
||||||
if( dynamic_cast<SCH_EDIT_FRAME*>( m_parent ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Adjust value to filter mouse displacement before consider the drag
|
|
||||||
* mouse is really a drag command, not just a movement while click
|
|
||||||
*/
|
|
||||||
#define MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND 5
|
|
||||||
|
|
||||||
if( event.Leaving() )
|
|
||||||
m_canStartBlock = -1;
|
|
||||||
|
|
||||||
if( !IsMouseCaptured() && !controls->GetSettings().m_cursorCaptured )
|
|
||||||
SetAutoPanRequest( false );
|
|
||||||
|
|
||||||
if( GetParent()->IsActive() )
|
|
||||||
SetFocus();
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( !event.IsButton() && !event.Moving() && !event.Dragging() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( event.RightUp() )
|
|
||||||
{
|
|
||||||
OnRightClick( event );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_ignoreMouseEvents )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( event.LeftDown() )
|
|
||||||
localbutt = GR_M_LEFT_DOWN;
|
|
||||||
|
|
||||||
if( event.ButtonDClick( 1 ) )
|
|
||||||
localbutt = GR_M_LEFT_DOWN | GR_M_DCLICK;
|
|
||||||
|
|
||||||
if( event.MiddleDown() )
|
|
||||||
localbutt = GR_M_MIDDLE_DOWN;
|
|
||||||
|
|
||||||
// Compute the cursor position in drawing (logical) units.
|
|
||||||
//GetParent()->SetMousePosition( event.GetLogicalPosition( DC ) );
|
|
||||||
|
|
||||||
int kbstat = 0;
|
|
||||||
|
|
||||||
if( event.ShiftDown() )
|
|
||||||
kbstat |= GR_KB_SHIFT;
|
|
||||||
|
|
||||||
if( event.ControlDown() )
|
|
||||||
kbstat |= GR_KB_CTRL;
|
|
||||||
|
|
||||||
if( event.AltDown() )
|
|
||||||
kbstat |= GR_KB_ALT;
|
|
||||||
|
|
||||||
// Calling Double Click and Click functions :
|
|
||||||
if( localbutt == (int) ( GR_M_LEFT_DOWN | GR_M_DCLICK ) )
|
|
||||||
{
|
|
||||||
GetParent()->OnLeftDClick( nullptr, mousePos );
|
|
||||||
|
|
||||||
// inhibit a response to the mouse left button release,
|
|
||||||
// because we have a double click, and we do not want a new
|
|
||||||
// OnLeftClick command at end of this Double Click
|
|
||||||
m_ignoreNextLeftButtonRelease = true;
|
|
||||||
}
|
|
||||||
else if( event.LeftUp() )
|
|
||||||
{
|
|
||||||
// A block command is in progress: a left up is the end of block
|
|
||||||
// or this is the end of a double click, already seen
|
|
||||||
// Note also m_ignoreNextLeftButtonRelease can be set by
|
|
||||||
// the call to OnLeftClick(), so do not change it after calling OnLeftClick
|
|
||||||
bool ignoreEvt = m_ignoreNextLeftButtonRelease;
|
|
||||||
m_ignoreNextLeftButtonRelease = false;
|
|
||||||
|
|
||||||
if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK && !ignoreEvt )
|
|
||||||
GetParent()->OnLeftClick( nullptr, mousePos );
|
|
||||||
|
|
||||||
}
|
|
||||||
else if( !event.LeftIsDown() )
|
|
||||||
{
|
|
||||||
/* be sure there is a response to a left button release command
|
|
||||||
* even when a LeftUp event is not seen. This happens when a
|
|
||||||
* double click opens a dialog box, and the release mouse button
|
|
||||||
* is made when the dialog box is opened.
|
|
||||||
*/
|
|
||||||
m_ignoreNextLeftButtonRelease = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( event.ButtonDown( wxMOUSE_BTN_MIDDLE ) )
|
|
||||||
{
|
|
||||||
m_PanStartCenter = GetParent()->GetScrollCenterPosition();
|
|
||||||
m_PanStartEventPosition = event.GetPosition();
|
|
||||||
|
|
||||||
CrossHairOff( );
|
|
||||||
SetCurrentCursor( wxCURSOR_SIZING );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( event.ButtonUp( wxMOUSE_BTN_MIDDLE ) )
|
|
||||||
{
|
|
||||||
CrossHairOn();
|
|
||||||
SetDefaultCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( event.MiddleIsDown() )
|
|
||||||
{
|
|
||||||
// already managed by EDA_DRAW_PANEL_GAL mouse event handler.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calling the general function on mouse changes (and pseudo key commands)
|
|
||||||
GetParent()->GeneralControl( nullptr, mousePos );
|
|
||||||
|
|
||||||
/*******************************/
|
|
||||||
/* Control of block commands : */
|
|
||||||
/*******************************/
|
|
||||||
|
|
||||||
// Command block can't start if mouse is dragging a new panel
|
|
||||||
static SCH_DRAW_PANEL* lastPanel;
|
|
||||||
if( lastPanel != this )
|
|
||||||
{
|
|
||||||
m_minDragEventCount = 0;
|
|
||||||
m_canStartBlock = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A new command block can start after a release buttons
|
|
||||||
* and if the drag is enough
|
|
||||||
* This is to avoid a false start block when a dialog box is dismissed,
|
|
||||||
* or when changing panels in hierarchy navigation
|
|
||||||
* or when clicking while and moving mouse
|
|
||||||
*/
|
|
||||||
if( !event.LeftIsDown() && !event.MiddleIsDown() )
|
|
||||||
{
|
|
||||||
m_minDragEventCount = 0;
|
|
||||||
m_canStartBlock = 0;
|
|
||||||
|
|
||||||
/* Remember the last cursor position when a drag mouse starts
|
|
||||||
* this is the last position ** before ** clicking a button
|
|
||||||
* this is useful to start a block command from the point where the
|
|
||||||
* mouse was clicked first
|
|
||||||
* (a filter creates a delay for the real block command start, and
|
|
||||||
* we must remember this point)
|
|
||||||
*/
|
|
||||||
m_CursorStartPos = GetParent()->GetCrossHairPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_enableBlockCommands && !(localbutt & GR_M_DCLICK) )
|
|
||||||
{
|
|
||||||
if( !screen->IsBlockActive() )
|
|
||||||
{
|
|
||||||
screen->m_BlockLocate.SetOrigin( m_CursorStartPos );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( event.LeftDown() )
|
|
||||||
{
|
|
||||||
if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
|
|
||||||
{
|
|
||||||
SetAutoPanRequest( false );
|
|
||||||
GetParent()->HandleBlockPlace( nullptr );
|
|
||||||
m_ignoreNextLeftButtonRelease = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( ( m_canStartBlock >= 0 ) && event.LeftIsDown() && !IsMouseCaptured() )
|
|
||||||
{
|
|
||||||
// Mouse is dragging: if no block in progress, start a block command.
|
|
||||||
if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK )
|
|
||||||
{
|
|
||||||
// Start a block command
|
|
||||||
int cmd_type = kbstat;
|
|
||||||
|
|
||||||
// A block command is started if the drag is enough. A small
|
|
||||||
// drag is ignored (it is certainly a little mouse move when
|
|
||||||
// clicking) not really a drag mouse
|
|
||||||
if( m_minDragEventCount < MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND )
|
|
||||||
m_minDragEventCount++;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto cmd = (GetParent()->GetToolId() == ID_ZOOM_SELECTION) ? BLOCK_ZOOM : 0;
|
|
||||||
|
|
||||||
DBG(printf("start block\n");)
|
|
||||||
|
|
||||||
if( !GetParent()->HandleBlockBegin( nullptr, cmd_type, m_CursorStartPos, cmd ) )
|
|
||||||
{
|
|
||||||
// should not occur: error
|
|
||||||
GetParent()->DisplayToolMsg(
|
|
||||||
wxT( "EDA_DRAW_PANEL::OnMouseEvent() Block Error" ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetAutoPanRequest( true );
|
|
||||||
SetCursor( wxCURSOR_SIZING );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( event.ButtonUp( wxMOUSE_BTN_LEFT ) )
|
|
||||||
{
|
|
||||||
/* Release the mouse button: end of block.
|
|
||||||
* The command can finish (DELETE) or have a next command (MOVE,
|
|
||||||
* COPY). However the block command is canceled if the block
|
|
||||||
* size is small because a block command filtering is already
|
|
||||||
* made, this case happens, but only when the on grid cursor has
|
|
||||||
* not moved.
|
|
||||||
*/
|
|
||||||
#define BLOCK_MINSIZE_LIMIT 1
|
|
||||||
bool BlockIsSmall =
|
|
||||||
( std::abs( screen->m_BlockLocate.GetWidth() ) < BLOCK_MINSIZE_LIMIT )
|
|
||||||
&& ( std::abs( screen->m_BlockLocate.GetHeight() ) < BLOCK_MINSIZE_LIMIT );
|
|
||||||
|
|
||||||
if( (screen->m_BlockLocate.GetState() != STATE_NO_BLOCK) && BlockIsSmall )
|
|
||||||
{
|
|
||||||
if( m_endMouseCaptureCallback )
|
|
||||||
{
|
|
||||||
m_endMouseCaptureCallback( this, nullptr );
|
|
||||||
SetAutoPanRequest( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
//SetCursor( (wxStockCursor) m_currentCursor );
|
|
||||||
}
|
|
||||||
else if( screen->m_BlockLocate.GetState() == STATE_BLOCK_END )
|
|
||||||
{
|
|
||||||
SetAutoPanRequest( false );
|
|
||||||
GetParent()->HandleBlockEnd( nullptr );
|
|
||||||
//SetCursor( (wxStockCursor) m_currentCursor );
|
|
||||||
if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
|
|
||||||
{
|
|
||||||
SetAutoPanRequest( true );
|
|
||||||
SetCursor( wxCURSOR_HAND );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// End of block command on a double click
|
|
||||||
// To avoid an unwanted block move command if the mouse is moved while double clicking
|
|
||||||
if( localbutt == (int) ( GR_M_LEFT_DOWN | GR_M_DCLICK ) )
|
|
||||||
{
|
|
||||||
if( !screen->IsBlockActive() && IsMouseCaptured() )
|
|
||||||
m_endMouseCaptureCallback( this, nullptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
lastPanel = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SCH_DRAW_PANEL::OnRightClick( wxMouseEvent& event )
|
|
||||||
{
|
|
||||||
auto controls = GetViewControls();
|
|
||||||
auto vmp = controls->GetMousePosition();
|
|
||||||
wxPoint mouseWorldPos ( (int) vmp.x, (int) vmp.y );
|
|
||||||
|
|
||||||
wxMenu MasterMenu;
|
|
||||||
|
|
||||||
if( !GetParent()->OnRightClick( mouseWorldPos, &MasterMenu ) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
GetParent()->AddMenuZoomAndGrid( &MasterMenu );
|
|
||||||
|
|
||||||
m_ignoreMouseEvents = true;
|
|
||||||
PopupMenu( &MasterMenu, event.GetPosition() );
|
|
||||||
m_ignoreMouseEvents = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SCH_DRAW_PANEL::CallMouseCapture( wxDC* aDC, const wxPoint& aPosition, bool aErase )
|
|
||||||
{
|
|
||||||
wxCHECK_RET( m_mouseCaptureCallback != NULL, wxT( "Mouse capture callback not set." ) );
|
|
||||||
|
|
||||||
m_mouseCaptureCallback( this, aDC, aPosition, aErase );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SCH_DRAW_PANEL::CallEndMouseCapture( wxDC* aDC )
|
|
||||||
{
|
|
||||||
// CallEndMouseCapture is sometimes called with m_endMouseCaptureCallback == NULL
|
|
||||||
// for instance after an ABORT in block paste.
|
|
||||||
if( m_endMouseCaptureCallback )
|
|
||||||
m_endMouseCaptureCallback( this, aDC );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SCH_DRAW_PANEL::EndMouseCapture( int id, int cursor, const wxString& title,
|
|
||||||
bool aCallEndFunc )
|
|
||||||
{
|
|
||||||
if( m_mouseCaptureCallback && m_endMouseCaptureCallback && aCallEndFunc )
|
|
||||||
m_endMouseCaptureCallback( this, nullptr );
|
|
||||||
|
|
||||||
m_mouseCaptureCallback = NULL;
|
|
||||||
m_endMouseCaptureCallback = NULL;
|
|
||||||
SetAutoPanRequest( false );
|
|
||||||
|
|
||||||
if( id != -1 && cursor != -1 )
|
|
||||||
{
|
|
||||||
//wxASSERT( cursor > wxCURSOR_NONE && cursor < wxCURSOR_MAX );
|
|
||||||
GetParent()->SetToolID( id, cursor, title );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SCH_DRAW_PANEL::CrossHairOff( wxDC* DC )
|
void SCH_DRAW_PANEL::CrossHairOff( wxDC* DC )
|
||||||
{
|
{
|
||||||
m_viewControls->ShowCursor( false );
|
m_viewControls->ShowCursor( false );
|
||||||
|
@ -605,26 +281,18 @@ void SCH_DRAW_PANEL::OnKeyEvent( wxKeyEvent& event )
|
||||||
int localkey = event.GetKeyCode();
|
int localkey = event.GetKeyCode();
|
||||||
bool keyWasHandled = false;
|
bool keyWasHandled = false;
|
||||||
|
|
||||||
switch( localkey )
|
if( localkey == WXK_ESCAPE )
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WXK_ESCAPE:
|
|
||||||
m_abortRequest = true;
|
m_abortRequest = true;
|
||||||
|
|
||||||
if( IsMouseCaptured() )
|
SCH_SELECTION_TOOL* selTool = GetParent()->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||||
EndMouseCapture();
|
|
||||||
|
if( SCH_CONDITIONS::Idle( selTool->GetSelection() ) )
|
||||||
|
GetParent()->GetToolManager()->RunAction( SCH_ACTIONS::selectionActivate, true );
|
||||||
else
|
else
|
||||||
{
|
GetParent()->GetToolManager()->RunAction( ACTIONS::cancelInteractive, true );
|
||||||
if( SCH_CONDITIONS::Idle( GetParent()->GetToolManager()->GetTool<SCH_SELECTION_TOOL>()->GetSelection() ) )
|
|
||||||
GetParent()->GetToolManager()->RunAction( SCH_ACTIONS::selectionActivate, true );
|
|
||||||
else
|
|
||||||
GetParent()->GetToolManager()->RunAction( ACTIONS::cancelInteractive, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
keyWasHandled = true; // The key is captured: the key event will be not skipped
|
keyWasHandled = true; // The key is captured: the key event will be not skipped
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normalize keys code to easily handle keys from Ctrl+A to Ctrl+Z
|
/* Normalize keys code to easily handle keys from Ctrl+A to Ctrl+Z
|
||||||
|
|
|
@ -41,8 +41,6 @@ public:
|
||||||
void DisplaySheet( const SCH_SCREEN *aScreen );
|
void DisplaySheet( const SCH_SCREEN *aScreen );
|
||||||
|
|
||||||
bool SwitchBackend( GAL_TYPE aGalType ) override;
|
bool SwitchBackend( GAL_TYPE aGalType ) override;
|
||||||
void OnMouseEvent( wxMouseEvent& event );
|
|
||||||
bool OnRightClick( wxMouseEvent& event );
|
|
||||||
void OnKeyEvent( wxKeyEvent& event );
|
void OnKeyEvent( wxKeyEvent& event );
|
||||||
void OnCharHook( wxKeyEvent& event );
|
void OnCharHook( wxKeyEvent& event );
|
||||||
|
|
||||||
|
@ -54,12 +52,6 @@ public:
|
||||||
BASE_SCREEN* GetScreen() override;
|
BASE_SCREEN* GetScreen() override;
|
||||||
virtual EDA_DRAW_FRAME* GetParent() const override;
|
virtual EDA_DRAW_FRAME* GetParent() const override;
|
||||||
|
|
||||||
virtual void CallMouseCapture( wxDC* aDC, const wxPoint& aPosition, bool aErase ) override;
|
|
||||||
virtual void CallEndMouseCapture( wxDC* aDC ) override;
|
|
||||||
virtual void EndMouseCapture( int aId = -1, int aCursorId = -1,
|
|
||||||
const wxString& aTitle = wxEmptyString,
|
|
||||||
bool aCallEndFunc = true ) override;
|
|
||||||
|
|
||||||
virtual void CrossHairOff( wxDC* DC=nullptr ) override;
|
virtual void CrossHairOff( wxDC* DC=nullptr ) override;
|
||||||
|
|
||||||
// Show the cross hair.
|
// Show the cross hair.
|
||||||
|
|
|
@ -60,12 +60,13 @@
|
||||||
#include <tool/zoom_tool.h>
|
#include <tool/zoom_tool.h>
|
||||||
#include <tools/sch_actions.h>
|
#include <tools/sch_actions.h>
|
||||||
#include <tools/sch_selection_tool.h>
|
#include <tools/sch_selection_tool.h>
|
||||||
#include <tools/sch_picker_tool.h>
|
#include <tools/picker_tool.h>
|
||||||
|
#include <tools/point_editor.h>
|
||||||
#include <tools/sch_drawing_tools.h>
|
#include <tools/sch_drawing_tools.h>
|
||||||
#include <tools/sch_wire_bus_tool.h>
|
#include <tools/sch_wire_bus_tool.h>
|
||||||
#include <tools/sch_move_tool.h>
|
#include <tools/sch_move_tool.h>
|
||||||
#include <tools/sch_edit_tool.h>
|
#include <tools/sch_edit_tool.h>
|
||||||
#include <tools/sch_inspection_tool.h>
|
#include <tools/inspection_tool.h>
|
||||||
#include <tools/sch_editor_control.h>
|
#include <tools/sch_editor_control.h>
|
||||||
#include <build_version.h>
|
#include <build_version.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
@ -428,13 +429,14 @@ void SCH_EDIT_FRAME::setupTools()
|
||||||
m_toolManager->RegisterTool( new COMMON_TOOLS );
|
m_toolManager->RegisterTool( new COMMON_TOOLS );
|
||||||
m_toolManager->RegisterTool( new ZOOM_TOOL );
|
m_toolManager->RegisterTool( new ZOOM_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_SELECTION_TOOL );
|
m_toolManager->RegisterTool( new SCH_SELECTION_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_PICKER_TOOL );
|
m_toolManager->RegisterTool( new PICKER_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_DRAWING_TOOLS );
|
m_toolManager->RegisterTool( new SCH_DRAWING_TOOLS );
|
||||||
m_toolManager->RegisterTool( new SCH_WIRE_BUS_TOOL );
|
m_toolManager->RegisterTool( new SCH_WIRE_BUS_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_MOVE_TOOL );
|
m_toolManager->RegisterTool( new SCH_MOVE_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_EDIT_TOOL );
|
m_toolManager->RegisterTool( new SCH_EDIT_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_INSPECTION_TOOL );
|
m_toolManager->RegisterTool( new INSPECTION_TOOL );
|
||||||
m_toolManager->RegisterTool( new SCH_EDITOR_CONTROL );
|
m_toolManager->RegisterTool( new SCH_EDITOR_CONTROL );
|
||||||
|
m_toolManager->RegisterTool( new POINT_EDITOR );
|
||||||
m_toolManager->InitTools();
|
m_toolManager->InitTools();
|
||||||
|
|
||||||
// Run the selection tool, it is supposed to be always active
|
// Run the selection tool, it is supposed to be always active
|
||||||
|
|
|
@ -347,9 +347,9 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be called after a schematic change in order to set the "modify" flag of the
|
* Must be called after a schematic change in order to set the "modify" flag of the
|
||||||
* current screen* and update the date in frame reference.
|
* current screen and update the date in frame reference.
|
||||||
*/
|
*/
|
||||||
void OnModify();
|
void OnModify() override;
|
||||||
|
|
||||||
virtual wxString GetScreenDesc() const override;
|
virtual wxString GetScreenDesc() const override;
|
||||||
|
|
||||||
|
@ -1070,32 +1070,6 @@ private:
|
||||||
void GetSchematicFromUndoList( wxCommandEvent& event );
|
void GetSchematicFromUndoList( wxCommandEvent& event );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Initialize the parameters used by the block paste command.
|
|
||||||
*/
|
|
||||||
void InitBlockPasteInfos() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call after HandleBlockEnd, when a block command needs to be executed after the block
|
|
||||||
* is moved to its new place.
|
|
||||||
*
|
|
||||||
* Parameters must be initialized in GetScreen()->m_BlockLocate
|
|
||||||
*/
|
|
||||||
virtual void HandleBlockPlace( wxDC* DC ) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the "end" of a block command,
|
|
||||||
* i.e. is called at the end of the definition of the area of a block.
|
|
||||||
* depending on the current block command, this command is executed
|
|
||||||
* or parameters are initialized to prepare a call to HandleBlockPlace
|
|
||||||
* in GetScreen()->m_BlockLocate
|
|
||||||
*
|
|
||||||
* @param aDC is a device context to draw on.
|
|
||||||
* @return false if no item selected, or command finished,
|
|
||||||
* true if some items found and HandleBlockPlace must be called later
|
|
||||||
*/
|
|
||||||
virtual bool HandleBlockEnd( wxDC* aDC ) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone \a aItem and owns that clone in this container.
|
* Clone \a aItem and owns that clone in this container.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -73,6 +73,8 @@ public:
|
||||||
return true;
|
return true;
|
||||||
else if ( *p == SCH_LINE_LOCATE_BUS_T && m_Layer == LAYER_BUS )
|
else if ( *p == SCH_LINE_LOCATE_BUS_T && m_Layer == LAYER_BUS )
|
||||||
return true;
|
return true;
|
||||||
|
else if ( *p == SCH_LINE_LOCATE_GRAPHIC_LINE_T && m_Layer == LAYER_NOTES )
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -181,23 +181,6 @@ public:
|
||||||
--m_modification_sync;
|
--m_modification_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the currently selected SCH_ITEM, overriding BASE_SCREEN::GetCurItem().
|
|
||||||
*
|
|
||||||
* @return SCH_ITEM* - the one selected, or NULL.
|
|
||||||
*/
|
|
||||||
// JEY TODO: these should go away: if the selection contains one item then it's the curItem...
|
|
||||||
SCH_ITEM* GetCurItem() const { return (SCH_ITEM*) BASE_SCREEN::GetCurItem(); }
|
|
||||||
LIB_ITEM* GetCurLibItem() const { return (LIB_ITEM*) BASE_SCREEN::GetCurItem(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the currently selected object, m_CurrentItem.
|
|
||||||
*
|
|
||||||
* @param aItem Any object derived from SCH_ITEM
|
|
||||||
*/
|
|
||||||
void SetCurItem( SCH_ITEM* aItem ) { BASE_SCREEN::SetCurItem( (EDA_ITEM*) aItem ); }
|
|
||||||
void SetCurLibItem( LIB_ITEM* aItem ) { BASE_SCREEN::SetCurItem( (EDA_ITEM*) aItem ); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all draw items and clears the project settings.
|
* Delete all draw items and clears the project settings.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -797,12 +797,13 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICA
|
||||||
for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
|
for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
|
||||||
{
|
{
|
||||||
// If caller wants to inspect my type
|
// If caller wants to inspect my type
|
||||||
if( stype == Type() )
|
if( stype == SCH_LOCATE_ANY_T || stype == Type() )
|
||||||
{
|
{
|
||||||
if( SEARCH_QUIT == aInspector( this, NULL ) )
|
if( SEARCH_QUIT == aInspector( this, NULL ) )
|
||||||
return SEARCH_QUIT;
|
return SEARCH_QUIT;
|
||||||
}
|
}
|
||||||
else if( stype == SCH_SHEET_PIN_T )
|
|
||||||
|
if( stype == SCH_LOCATE_ANY_T || stype == SCH_SHEET_PIN_T )
|
||||||
{
|
{
|
||||||
// Test the sheet labels.
|
// Test the sheet labels.
|
||||||
for( size_t i = 0; i < m_pins.size(); i++ )
|
for( size_t i = 0; i < m_pins.size(); i++ )
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tools/sch_actions.h>
|
#include <tools/sch_actions.h>
|
||||||
#include <tools/sch_inspection_tool.h>
|
#include <tools/inspection_tool.h>
|
||||||
#include <tools/sch_selection_tool.h>
|
#include <tools/sch_selection_tool.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
#include <sch_component.h>
|
#include <sch_component.h>
|
||||||
|
@ -49,7 +49,7 @@ TOOL_ACTION SCH_ACTIONS::showMarkerInfo( "eeschema.InspectionTool.showMarkerInfo
|
||||||
info_xpm );
|
info_xpm );
|
||||||
|
|
||||||
|
|
||||||
SCH_INSPECTION_TOOL::SCH_INSPECTION_TOOL()
|
INSPECTION_TOOL::INSPECTION_TOOL()
|
||||||
: TOOL_INTERACTIVE( "eeschema.InspectionTool" ),
|
: TOOL_INTERACTIVE( "eeschema.InspectionTool" ),
|
||||||
m_selectionTool( nullptr ),
|
m_selectionTool( nullptr ),
|
||||||
m_view( nullptr ),
|
m_view( nullptr ),
|
||||||
|
@ -59,7 +59,7 @@ SCH_INSPECTION_TOOL::SCH_INSPECTION_TOOL()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_INSPECTION_TOOL::Init()
|
bool INSPECTION_TOOL::Init()
|
||||||
{
|
{
|
||||||
m_frame = getEditFrame<SCH_BASE_FRAME>();
|
m_frame = getEditFrame<SCH_BASE_FRAME>();
|
||||||
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||||
|
@ -80,7 +80,7 @@ bool SCH_INSPECTION_TOOL::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_INSPECTION_TOOL::Reset( RESET_REASON aReason )
|
void INSPECTION_TOOL::Reset( RESET_REASON aReason )
|
||||||
{
|
{
|
||||||
m_view = static_cast<KIGFX::SCH_VIEW*>( getView() );
|
m_view = static_cast<KIGFX::SCH_VIEW*>( getView() );
|
||||||
m_controls = getViewControls();
|
m_controls = getViewControls();
|
||||||
|
@ -88,7 +88,7 @@ void SCH_INSPECTION_TOOL::Reset( RESET_REASON aReason )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
|
int INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection( SCH_COLLECTOR::ComponentsOnly );
|
SELECTION& selection = m_selectionTool->RequestSelection( SCH_COLLECTOR::ComponentsOnly );
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ int SCH_INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_INSPECTION_TOOL::ShowMarkerInfo( const TOOL_EVENT& aEvent )
|
int INSPECTION_TOOL::ShowMarkerInfo( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
SELECTION& selection = m_selectionTool->GetSelection();
|
SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ int SCH_INSPECTION_TOOL::ShowMarkerInfo( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_INSPECTION_TOOL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
int INSPECTION_TOOL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||||
SELECTION& selection = selTool->GetSelection();
|
SELECTION& selection = selTool->GetSelection();
|
||||||
|
@ -143,14 +143,14 @@ int SCH_INSPECTION_TOOL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_INSPECTION_TOOL::setTransitions()
|
void INSPECTION_TOOL::setTransitions()
|
||||||
{
|
{
|
||||||
Go( &SCH_INSPECTION_TOOL::ShowDatasheet, SCH_ACTIONS::showDatasheet.MakeEvent() );
|
Go( &INSPECTION_TOOL::ShowDatasheet, SCH_ACTIONS::showDatasheet.MakeEvent() );
|
||||||
Go( &SCH_INSPECTION_TOOL::ShowMarkerInfo, SCH_ACTIONS::showMarkerInfo.MakeEvent() );
|
Go( &INSPECTION_TOOL::ShowMarkerInfo, SCH_ACTIONS::showMarkerInfo.MakeEvent() );
|
||||||
|
|
||||||
Go( &SCH_INSPECTION_TOOL::UpdateMessagePanel, EVENTS::SelectedEvent );
|
Go( &INSPECTION_TOOL::UpdateMessagePanel, EVENTS::SelectedEvent );
|
||||||
Go( &SCH_INSPECTION_TOOL::UpdateMessagePanel, EVENTS::UnselectedEvent );
|
Go( &INSPECTION_TOOL::UpdateMessagePanel, EVENTS::UnselectedEvent );
|
||||||
Go( &SCH_INSPECTION_TOOL::UpdateMessagePanel, EVENTS::ClearedEvent );
|
Go( &INSPECTION_TOOL::UpdateMessagePanel, EVENTS::ClearedEvent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,11 @@ class SCH_SELECTION_TOOL;
|
||||||
class SCH_EDIT_FRAME;
|
class SCH_EDIT_FRAME;
|
||||||
|
|
||||||
|
|
||||||
class SCH_INSPECTION_TOOL : public TOOL_INTERACTIVE
|
class INSPECTION_TOOL : public TOOL_INTERACTIVE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SCH_INSPECTION_TOOL();
|
INSPECTION_TOOL();
|
||||||
~SCH_INSPECTION_TOOL() {}
|
~INSPECTION_TOOL() {}
|
||||||
|
|
||||||
/// @copydoc TOOL_INTERACTIVE::Init()
|
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||||
bool Init() override;
|
bool Init() override;
|
|
@ -87,6 +87,9 @@ TOOL_ACTION SCH_ACTIONS::finishDrawing( "libedit.InteractiveDrawing.finishDrawin
|
||||||
checked_ok_xpm, AF_NONE );
|
checked_ok_xpm, AF_NONE );
|
||||||
|
|
||||||
|
|
||||||
|
static void* g_lastPinWeakPtr;
|
||||||
|
|
||||||
|
|
||||||
LIB_DRAWING_TOOLS::LIB_DRAWING_TOOLS() :
|
LIB_DRAWING_TOOLS::LIB_DRAWING_TOOLS() :
|
||||||
TOOL_INTERACTIVE( "libedit.InteractiveDrawing" ),
|
TOOL_INTERACTIVE( "libedit.InteractiveDrawing" ),
|
||||||
m_selectionTool( nullptr ),
|
m_selectionTool( nullptr ),
|
||||||
|
@ -153,8 +156,9 @@ int LIB_DRAWING_TOOLS::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int LIB_DRAWING_TOOLS::doTwoClickPlace( KICAD_T aType )
|
int LIB_DRAWING_TOOLS::doTwoClickPlace( KICAD_T aType )
|
||||||
{
|
{
|
||||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
LIB_PIN_TOOL* pinTool = aType == LIB_PIN_T ? m_toolMgr->GetTool<LIB_PIN_TOOL>() : nullptr;
|
||||||
EDA_ITEM* item = nullptr;
|
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||||
|
EDA_ITEM* item = nullptr;
|
||||||
|
|
||||||
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
m_controls->ShowCursor( true );
|
m_controls->ShowCursor( true );
|
||||||
|
@ -198,9 +202,8 @@ int LIB_DRAWING_TOOLS::doTwoClickPlace( KICAD_T aType )
|
||||||
{
|
{
|
||||||
case LIB_PIN_T:
|
case LIB_PIN_T:
|
||||||
{
|
{
|
||||||
LIB_PIN_TOOL* pinTool = m_toolMgr->GetTool<LIB_PIN_TOOL>();
|
|
||||||
|
|
||||||
item = pinTool->CreatePin( wxPoint( cursorPos.x, -cursorPos.y), part );
|
item = pinTool->CreatePin( wxPoint( cursorPos.x, -cursorPos.y), part );
|
||||||
|
g_lastPinWeakPtr = item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LIB_TEXT_T:
|
case LIB_TEXT_T:
|
||||||
|
@ -219,7 +222,6 @@ int LIB_DRAWING_TOOLS::doTwoClickPlace( KICAD_T aType )
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( "doTwoClickPlace(): unknown type" );
|
wxFAIL_MSG( "doTwoClickPlace(): unknown type" );
|
||||||
}
|
}
|
||||||
|
@ -245,10 +247,19 @@ int LIB_DRAWING_TOOLS::doTwoClickPlace( KICAD_T aType )
|
||||||
{
|
{
|
||||||
m_frame->SaveCopyInUndoList( part );
|
m_frame->SaveCopyInUndoList( part );
|
||||||
|
|
||||||
part->AddDrawItem( (LIB_ITEM*) item );
|
switch( item->Type() )
|
||||||
item->ClearFlags( item->GetEditFlags() );
|
{
|
||||||
|
case LIB_PIN_T:
|
||||||
|
pinTool->PlacePin( (LIB_PIN*) item );
|
||||||
|
break;
|
||||||
|
case LIB_TEXT_T:
|
||||||
|
part->AddDrawItem( (LIB_TEXT*) item );
|
||||||
|
item->ClearFlags( item->GetEditFlags() );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( "doTwoClickPlace(): unknown type" );
|
||||||
|
}
|
||||||
|
|
||||||
m_frame->SetDrawItem( nullptr );
|
|
||||||
item = nullptr;
|
item = nullptr;
|
||||||
m_view->ClearPreview();
|
m_view->ClearPreview();
|
||||||
|
|
||||||
|
@ -272,7 +283,7 @@ int LIB_DRAWING_TOOLS::doTwoClickPlace( KICAD_T aType )
|
||||||
m_view->AddToPreview( item->Clone() );
|
m_view->AddToPreview( item->Clone() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable autopanning and cursor capture only when there is a module to be placed
|
// Enable autopanning and cursor capture only when there is an item to be placed
|
||||||
m_controls->SetAutoPan( !!item );
|
m_controls->SetAutoPan( !!item );
|
||||||
m_controls->CaptureCursor( !!item );
|
m_controls->CaptureCursor( !!item );
|
||||||
}
|
}
|
||||||
|
@ -355,7 +366,7 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
||||||
|| evt->IsDblClick( BUT_LEFT )
|
|| evt->IsDblClick( BUT_LEFT )
|
||||||
|| evt->IsAction( &SCH_ACTIONS::finishDrawing ) ) )
|
|| evt->IsAction( &SCH_ACTIONS::finishDrawing ) ) )
|
||||||
{
|
{
|
||||||
if( evt->IsDblClick()
|
if( evt->IsDblClick( BUT_LEFT )
|
||||||
|| evt->IsAction( &SCH_ACTIONS::finishDrawing )
|
|| evt->IsAction( &SCH_ACTIONS::finishDrawing )
|
||||||
|| !item->ContinueEdit( wxPoint( cursorPos.x, -cursorPos.y ) ) )
|
|| !item->ContinueEdit( wxPoint( cursorPos.x, -cursorPos.y ) ) )
|
||||||
{
|
{
|
||||||
|
@ -381,9 +392,7 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
else if( evt->IsDblClick( BUT_LEFT ) && !item )
|
else if( evt->IsDblClick( BUT_LEFT ) && !item )
|
||||||
{
|
{
|
||||||
// JEY TODO: handle edit action...
|
m_toolMgr->RunAction( SCH_ACTIONS::properties, true );
|
||||||
// This will need to be a RunAction() as the user might have double-clicked
|
|
||||||
// a text or pin or something
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( evt->IsClick( BUT_RIGHT ) )
|
else if( evt->IsClick( BUT_RIGHT ) )
|
||||||
|
@ -456,6 +465,37 @@ int LIB_DRAWING_TOOLS::PlaceAnchor( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_DRAWING_TOOLS::RepeatDrawItem( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
LIB_PIN_TOOL* pinTool = m_toolMgr->GetTool<LIB_PIN_TOOL>();
|
||||||
|
LIB_PART* part = m_frame->GetCurPart();
|
||||||
|
LIB_PIN* sourcePin = nullptr;
|
||||||
|
|
||||||
|
if( !part )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// See if we have a pin matching our weak ptr
|
||||||
|
for( LIB_PIN* test = part->GetNextPin(); test; test = part->GetNextPin( test ) )
|
||||||
|
{
|
||||||
|
if( (void*) test == g_lastPinWeakPtr )
|
||||||
|
sourcePin = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sourcePin )
|
||||||
|
{
|
||||||
|
LIB_PIN* pin = pinTool->RepeatPin( sourcePin );
|
||||||
|
g_lastPinWeakPtr = pin;
|
||||||
|
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
|
if( pin )
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, pin );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_DRAWING_TOOLS::setTransitions()
|
void LIB_DRAWING_TOOLS::setTransitions()
|
||||||
{
|
{
|
||||||
Go( &LIB_DRAWING_TOOLS::PlacePin, SCH_ACTIONS::placeSymbolPin.MakeEvent() );
|
Go( &LIB_DRAWING_TOOLS::PlacePin, SCH_ACTIONS::placeSymbolPin.MakeEvent() );
|
||||||
|
@ -465,4 +505,5 @@ void LIB_DRAWING_TOOLS::setTransitions()
|
||||||
Go( &LIB_DRAWING_TOOLS::DrawShape, SCH_ACTIONS::drawSymbolArc.MakeEvent() );
|
Go( &LIB_DRAWING_TOOLS::DrawShape, SCH_ACTIONS::drawSymbolArc.MakeEvent() );
|
||||||
Go( &LIB_DRAWING_TOOLS::DrawShape, SCH_ACTIONS::drawSymbolLines.MakeEvent() );
|
Go( &LIB_DRAWING_TOOLS::DrawShape, SCH_ACTIONS::drawSymbolLines.MakeEvent() );
|
||||||
Go( &LIB_DRAWING_TOOLS::PlaceAnchor, SCH_ACTIONS::placeSymbolAnchor.MakeEvent() );
|
Go( &LIB_DRAWING_TOOLS::PlaceAnchor, SCH_ACTIONS::placeSymbolAnchor.MakeEvent() );
|
||||||
|
Go( &LIB_DRAWING_TOOLS::RepeatDrawItem, SCH_ACTIONS::repeatDrawItem.MakeEvent() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ public:
|
||||||
int DrawShape( const TOOL_EVENT& aEvent );
|
int DrawShape( const TOOL_EVENT& aEvent );
|
||||||
int PlaceAnchor( const TOOL_EVENT& aEvent );
|
int PlaceAnchor( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
int RepeatDrawItem( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int doTwoClickPlace( KICAD_T aType );
|
int doTwoClickPlace( KICAD_T aType );
|
||||||
|
|
|
@ -0,0 +1,609 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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 <tool/tool_manager.h>
|
||||||
|
#include <tools/sch_selection_tool.h>
|
||||||
|
#include <tools/picker_tool.h>
|
||||||
|
#include <tools/lib_pin_tool.h>
|
||||||
|
#include <tools/lib_drawing_tools.h>
|
||||||
|
#include <tools/lib_move_tool.h>
|
||||||
|
#include <sch_actions.h>
|
||||||
|
#include <hotkeys.h>
|
||||||
|
#include <bitmaps.h>
|
||||||
|
#include <confirm.h>
|
||||||
|
#include <base_struct.h>
|
||||||
|
#include <sch_view.h>
|
||||||
|
#include <lib_edit_frame.h>
|
||||||
|
#include <eeschema_id.h>
|
||||||
|
#include <dialogs/dialog_lib_edit_draw_item.h>
|
||||||
|
#include <dialogs/dialog_lib_edit_text.h>
|
||||||
|
#include <dialogs/dialog_edit_one_field.h>
|
||||||
|
#include <sch_legacy_plugin.h>
|
||||||
|
#include "lib_edit_tool.h"
|
||||||
|
|
||||||
|
LIB_EDIT_TOOL::LIB_EDIT_TOOL() :
|
||||||
|
TOOL_INTERACTIVE( "libedit.InteractiveEdit" ),
|
||||||
|
m_selectionTool( nullptr ),
|
||||||
|
m_frame( nullptr ),
|
||||||
|
m_menu( *this )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_EDIT_TOOL::~LIB_EDIT_TOOL()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_EDIT_TOOL::Init()
|
||||||
|
{
|
||||||
|
m_frame = getEditFrame<LIB_EDIT_FRAME>();
|
||||||
|
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||||
|
LIB_DRAWING_TOOLS* drawingTools = m_toolMgr->GetTool<LIB_DRAWING_TOOLS>();
|
||||||
|
LIB_MOVE_TOOL* moveTool = m_toolMgr->GetTool<LIB_MOVE_TOOL>();
|
||||||
|
|
||||||
|
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
|
||||||
|
wxASSERT_MSG( drawingTools, "libedit.InteractiveDrawing tool is not available" );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add edit actions to the move tool menu
|
||||||
|
//
|
||||||
|
if( moveTool )
|
||||||
|
{
|
||||||
|
CONDITIONAL_MENU& moveMenu = moveTool->GetToolMenu().GetMenu();
|
||||||
|
|
||||||
|
moveMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty );
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::rotateCCW, SCH_CONDITIONS::NotEmpty );
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::rotateCW, SCH_CONDITIONS::NotEmpty );
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::mirrorX, SCH_CONDITIONS::NotEmpty );
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::mirrorY, SCH_CONDITIONS::NotEmpty );
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::duplicate, SCH_CONDITIONS::NotEmpty );
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::doDelete, SCH_CONDITIONS::NotEmpty );
|
||||||
|
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::properties, SCH_CONDITIONS::Count( 1 ) );
|
||||||
|
|
||||||
|
moveMenu.AddSeparator( SCH_CONDITIONS::IdleSelection );
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::cut, SCH_CONDITIONS::IdleSelection );
|
||||||
|
moveMenu.AddItem( SCH_ACTIONS::copy, SCH_CONDITIONS::IdleSelection );
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add editing actions to the drawing tool menu
|
||||||
|
//
|
||||||
|
CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
|
||||||
|
|
||||||
|
drawMenu.AddSeparator( SCH_CONDITIONS::NotEmpty, 200 );
|
||||||
|
drawMenu.AddItem( SCH_ACTIONS::rotateCCW, SCH_CONDITIONS::IdleSelection, 200 );
|
||||||
|
drawMenu.AddItem( SCH_ACTIONS::rotateCW, SCH_CONDITIONS::IdleSelection, 200 );
|
||||||
|
drawMenu.AddItem( SCH_ACTIONS::mirrorX, SCH_CONDITIONS::IdleSelection, 200 );
|
||||||
|
drawMenu.AddItem( SCH_ACTIONS::mirrorY, SCH_CONDITIONS::IdleSelection, 200 );
|
||||||
|
|
||||||
|
drawMenu.AddItem( SCH_ACTIONS::properties, SCH_CONDITIONS::Count( 1 ), 200 );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add editing actions to the selection tool menu
|
||||||
|
//
|
||||||
|
CONDITIONAL_MENU& selToolMenu = m_selectionTool->GetToolMenu().GetMenu();
|
||||||
|
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::rotateCCW, SCH_CONDITIONS::NotEmpty, 200 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::rotateCW, SCH_CONDITIONS::NotEmpty, 200 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::mirrorX, SCH_CONDITIONS::NotEmpty, 200 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::mirrorY, SCH_CONDITIONS::NotEmpty, 200 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::duplicate, SCH_CONDITIONS::NotEmpty, 200 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::doDelete, SCH_CONDITIONS::NotEmpty, 200 );
|
||||||
|
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::properties, SCH_CONDITIONS::Count( 1 ), 200 );
|
||||||
|
|
||||||
|
selToolMenu.AddSeparator( SCH_CONDITIONS::Idle, 200 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::cut, SCH_CONDITIONS::IdleSelection, 200 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::copy, SCH_CONDITIONS::IdleSelection, 200 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::paste, SCH_CONDITIONS::Idle, 200 );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_TOOL::Reset( RESET_REASON aReason )
|
||||||
|
{
|
||||||
|
if( aReason == MODEL_RELOAD )
|
||||||
|
{
|
||||||
|
// Init variables used by every drawing tool
|
||||||
|
m_frame = getEditFrame<LIB_EDIT_FRAME>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
SELECTION& selection = m_selectionTool->RequestSelection();
|
||||||
|
|
||||||
|
if( selection.GetSize() == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wxPoint rotPoint;
|
||||||
|
bool ccw = ( aEvent.Matches( SCH_ACTIONS::rotateCCW.MakeEvent() ) );
|
||||||
|
LIB_ITEM* item = static_cast<LIB_ITEM*>( selection.Front() );
|
||||||
|
|
||||||
|
if( !item->IsMoving() )
|
||||||
|
m_frame->SaveCopyInUndoList( m_frame->GetCurPart() );
|
||||||
|
|
||||||
|
if( selection.GetSize() == 1 )
|
||||||
|
rotPoint = item->GetPosition();
|
||||||
|
else
|
||||||
|
rotPoint = m_frame->GetNearestGridPosition( mapCoords( selection.GetCenter() ) );
|
||||||
|
|
||||||
|
for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
|
||||||
|
{
|
||||||
|
item = static_cast<LIB_ITEM*>( selection.GetItem( ii ) );
|
||||||
|
item->Rotate( rotPoint, ccw );
|
||||||
|
m_frame->RefreshItem( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
|
if( !item->IsMoving() )
|
||||||
|
{
|
||||||
|
if( selection.IsHover() )
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
|
m_frame->OnModify();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
SELECTION& selection = m_selectionTool->RequestSelection();
|
||||||
|
|
||||||
|
if( selection.GetSize() == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wxPoint mirrorPoint;
|
||||||
|
bool xAxis = ( aEvent.Matches( SCH_ACTIONS::mirrorX.MakeEvent() ) );
|
||||||
|
LIB_ITEM* item = static_cast<LIB_ITEM*>( selection.Front() );
|
||||||
|
|
||||||
|
if( !item->IsMoving() )
|
||||||
|
m_frame->SaveCopyInUndoList( m_frame->GetCurPart() );
|
||||||
|
|
||||||
|
if( selection.GetSize() == 1 )
|
||||||
|
mirrorPoint = item->GetPosition();
|
||||||
|
else
|
||||||
|
mirrorPoint = m_frame->GetNearestGridPosition( mapCoords( selection.GetCenter() ) );
|
||||||
|
|
||||||
|
for( unsigned ii = 0; ii < selection.GetSize(); ii++ )
|
||||||
|
{
|
||||||
|
item = static_cast<LIB_ITEM*>( selection.GetItem( ii ) );
|
||||||
|
|
||||||
|
if( xAxis )
|
||||||
|
item->MirrorVertical( mirrorPoint );
|
||||||
|
else
|
||||||
|
item->MirrorHorizontal( mirrorPoint );
|
||||||
|
|
||||||
|
m_frame->RefreshItem( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
|
if( !item->IsMoving() )
|
||||||
|
{
|
||||||
|
if( selection.IsHover() )
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
|
m_frame->OnModify();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static KICAD_T nonFields[] =
|
||||||
|
{
|
||||||
|
LIB_PART_T,
|
||||||
|
LIB_ALIAS_T,
|
||||||
|
LIB_ARC_T,
|
||||||
|
LIB_CIRCLE_T,
|
||||||
|
LIB_TEXT_T,
|
||||||
|
LIB_RECTANGLE_T,
|
||||||
|
LIB_POLYLINE_T,
|
||||||
|
LIB_BEZIER_T,
|
||||||
|
LIB_PIN_T,
|
||||||
|
EOT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
LIB_PART* part = m_frame->GetCurPart();
|
||||||
|
SELECTION& selection = m_selectionTool->RequestSelection( nonFields );
|
||||||
|
|
||||||
|
if( selection.GetSize() == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Doing a duplicate of a new object doesn't really make any sense; we'd just end
|
||||||
|
// up dragging around a stack of objects...
|
||||||
|
if( selection.Front()->IsNew() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( !selection.Front()->IsMoving() )
|
||||||
|
m_frame->SaveCopyInUndoList( m_frame->GetCurPart() );
|
||||||
|
|
||||||
|
EDA_ITEMS newItems;
|
||||||
|
|
||||||
|
for( unsigned ii = 0; ii < selection.GetSize(); ++ii )
|
||||||
|
{
|
||||||
|
LIB_ITEM* oldItem = static_cast<LIB_ITEM*>( selection.GetItem( ii ) );
|
||||||
|
LIB_ITEM* newItem = (LIB_ITEM*) oldItem->Clone();
|
||||||
|
newItem->SetFlags( IS_NEW );
|
||||||
|
newItems.push_back( newItem );
|
||||||
|
|
||||||
|
part->GetDrawItems().push_back( newItem );
|
||||||
|
getView()->Add( newItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::addItemsToSel, true, &newItems );
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::move, true );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
LIB_PART* part = m_frame->GetCurPart();
|
||||||
|
auto items = m_selectionTool->RequestSelection( nonFields ).GetItems();
|
||||||
|
|
||||||
|
if( items.empty() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Don't leave a freed pointer in the selection
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
|
m_frame->SaveCopyInUndoList( part );
|
||||||
|
|
||||||
|
for( EDA_ITEM* item : items )
|
||||||
|
{
|
||||||
|
if( item->Type() == LIB_PIN_T )
|
||||||
|
{
|
||||||
|
LIB_PIN* pin = static_cast<LIB_PIN*>( item );
|
||||||
|
wxPoint pos = pin->GetPosition();
|
||||||
|
|
||||||
|
part->RemoveDrawItem( pin );
|
||||||
|
|
||||||
|
// when pin editing is synchronized, all pins of the same body style are removed:
|
||||||
|
if( m_frame->SynchronizePins() )
|
||||||
|
{
|
||||||
|
int curr_convert = pin->GetConvert();
|
||||||
|
LIB_PIN* next_pin = part->GetNextPin();
|
||||||
|
|
||||||
|
while( next_pin != NULL )
|
||||||
|
{
|
||||||
|
pin = next_pin;
|
||||||
|
next_pin = part->GetNextPin( pin );
|
||||||
|
|
||||||
|
if( pin->GetPosition() != pos )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( pin->GetConvert() != curr_convert )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
part->RemoveDrawItem( pin );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
part->RemoveDrawItem( (LIB_ITEM*) item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_frame->RebuildView();
|
||||||
|
m_frame->OnModify();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool deleteItem( SCH_BASE_FRAME* aFrame, const VECTOR2D& aPosition )
|
||||||
|
{
|
||||||
|
SCH_SELECTION_TOOL* selectionTool = aFrame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||||
|
wxCHECK( selectionTool, false );
|
||||||
|
|
||||||
|
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
|
EDA_ITEM* item = selectionTool->SelectPoint( aPosition );
|
||||||
|
|
||||||
|
if( item )
|
||||||
|
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::doDelete, true );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
Activate();
|
||||||
|
|
||||||
|
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||||
|
wxCHECK( picker, 0 );
|
||||||
|
|
||||||
|
m_frame->SetToolID( ID_LIBEDIT_DELETE_ITEM_BUTT, wxCURSOR_BULLSEYE, _( "Delete item" ) );
|
||||||
|
picker->SetClickHandler( std::bind( deleteItem, m_frame, std::placeholders::_1 ) );
|
||||||
|
picker->Activate();
|
||||||
|
Wait();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
SELECTION& selection = m_selectionTool->RequestSelection();
|
||||||
|
|
||||||
|
if( selection.Empty() )
|
||||||
|
{
|
||||||
|
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
|
||||||
|
|
||||||
|
cmd.SetId( ID_LIBEDIT_GET_FRAME_EDIT_PART );
|
||||||
|
m_frame->GetEventHandler()->ProcessEvent( cmd );
|
||||||
|
}
|
||||||
|
else if( selection.Size() == 1 )
|
||||||
|
{
|
||||||
|
LIB_ITEM* item = (LIB_ITEM*) selection.Front();
|
||||||
|
|
||||||
|
// Save copy for undo if not in edit (edit command already handle the save copy)
|
||||||
|
if( !item->InEditMode() )
|
||||||
|
m_frame->SaveCopyInUndoList( item->GetParent() );
|
||||||
|
|
||||||
|
switch( item->Type() )
|
||||||
|
{
|
||||||
|
case LIB_PIN_T:
|
||||||
|
{
|
||||||
|
LIB_PIN_TOOL* pinTool = m_toolMgr->GetTool<LIB_PIN_TOOL>();
|
||||||
|
|
||||||
|
if( pinTool )
|
||||||
|
pinTool->EditPinProperties( (LIB_PIN*) item );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LIB_ARC_T:
|
||||||
|
case LIB_CIRCLE_T:
|
||||||
|
case LIB_RECTANGLE_T:
|
||||||
|
case LIB_POLYLINE_T:
|
||||||
|
editGraphicProperties( item );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIB_TEXT_T:
|
||||||
|
editTextProperties( item );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIB_FIELD_T:
|
||||||
|
editFieldProperties( (LIB_FIELD*) item );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( wxT( "Unhandled item <" ) + item->GetClass() + wxT( ">" ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_TOOL::editGraphicProperties( LIB_ITEM* aItem )
|
||||||
|
{
|
||||||
|
if( aItem == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
DIALOG_LIB_EDIT_DRAW_ITEM dialog( m_frame, aItem );
|
||||||
|
|
||||||
|
if( dialog.ShowModal() != wxID_OK )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( aItem->IsFillable() )
|
||||||
|
aItem->SetFillMode( (FILL_T) dialog.GetFillStyle() );
|
||||||
|
|
||||||
|
aItem->SetWidth( dialog.GetWidth() );
|
||||||
|
|
||||||
|
m_frame->GetCanvas()->GetView()->Update( aItem );
|
||||||
|
m_frame->GetCanvas()->Refresh();
|
||||||
|
m_frame->OnModify( );
|
||||||
|
|
||||||
|
m_frame->g_LastLineWidth = dialog.GetWidth();
|
||||||
|
m_frame->m_DrawSpecificConvert = !dialog.GetApplyToAllConversions();
|
||||||
|
m_frame->m_DrawSpecificUnit = !dialog.GetApplyToAllUnits();
|
||||||
|
|
||||||
|
MSG_PANEL_ITEMS items;
|
||||||
|
aItem->GetMsgPanelInfo( m_frame->GetUserUnits(), items );
|
||||||
|
m_frame->SetMsgPanel( items );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_TOOL::editTextProperties( LIB_ITEM* aItem )
|
||||||
|
{
|
||||||
|
if ( ( aItem == NULL ) || ( aItem->Type() != LIB_TEXT_T ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
DIALOG_LIB_EDIT_TEXT dlg( m_frame, (LIB_TEXT*) aItem );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() != wxID_OK )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_frame->GetCanvas()->GetView()->Update( aItem );
|
||||||
|
m_frame->GetCanvas()->Refresh();
|
||||||
|
m_frame->OnModify( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_TOOL::editFieldProperties( LIB_FIELD* aField )
|
||||||
|
{
|
||||||
|
if( aField == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxString caption;
|
||||||
|
LIB_PART* parent = aField->GetParent();
|
||||||
|
wxCHECK( parent, /* void */ );
|
||||||
|
|
||||||
|
// Editing the component value field is equivalent to creating a new component based
|
||||||
|
// on the current component. Set the dialog message to inform the user.
|
||||||
|
if( aField->GetId() == VALUE )
|
||||||
|
caption = _( "Edit Component Name" );
|
||||||
|
else
|
||||||
|
caption.Printf( _( "Edit %s Field" ), GetChars( aField->GetName() ) );
|
||||||
|
|
||||||
|
DIALOG_LIB_EDIT_ONE_FIELD dlg( m_frame, caption, aField );
|
||||||
|
|
||||||
|
// The dialog may invoke a kiway player for footprint fields
|
||||||
|
// so we must use a quasimodal dialog.
|
||||||
|
if( dlg.ShowQuasiModal() != wxID_OK )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxString newFieldValue = LIB_ID::FixIllegalChars( dlg.GetText(), LIB_ID::ID_SCH );
|
||||||
|
wxString oldFieldValue = aField->GetFullText( m_frame->GetUnit() );
|
||||||
|
bool renamed = aField->GetId() == VALUE && newFieldValue != oldFieldValue;
|
||||||
|
|
||||||
|
if( renamed )
|
||||||
|
m_frame->UpdateAfterRename( parent, oldFieldValue, newFieldValue );
|
||||||
|
|
||||||
|
dlg.UpdateField( aField );
|
||||||
|
|
||||||
|
m_frame->GetCanvas()->GetView()->Update( aField );
|
||||||
|
m_frame->GetCanvas()->Refresh();
|
||||||
|
m_frame->OnModify( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::Cut( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
int retVal = Copy( aEvent );
|
||||||
|
|
||||||
|
if( retVal == 0 )
|
||||||
|
retVal = DoDelete( aEvent );
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::Copy( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
LIB_PART* part = m_frame->GetCurPart();
|
||||||
|
SELECTION& selection = m_selectionTool->RequestSelection( nonFields );
|
||||||
|
|
||||||
|
if( !part || !selection.GetSize() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for( LIB_ITEM& item : part->GetDrawItems() )
|
||||||
|
{
|
||||||
|
if( item.Type() == LIB_FIELD_T )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wxASSERT( ( item.GetFlags() & STRUCT_DELETED ) == 0 );
|
||||||
|
|
||||||
|
if( !item.IsSelected() )
|
||||||
|
item.SetFlags( STRUCT_DELETED );
|
||||||
|
}
|
||||||
|
|
||||||
|
LIB_PART* partCopy = new LIB_PART( *part );
|
||||||
|
|
||||||
|
STRING_FORMATTER formatter;
|
||||||
|
SCH_LEGACY_PLUGIN::FormatPart( partCopy, formatter );
|
||||||
|
|
||||||
|
delete partCopy;
|
||||||
|
|
||||||
|
for( LIB_ITEM& item : part->GetDrawItems() )
|
||||||
|
item.ClearFlags( STRUCT_DELETED );
|
||||||
|
|
||||||
|
if( m_toolMgr->SaveClipboard( formatter.GetString() ) )
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
LIB_PART* part = m_frame->GetCurPart();
|
||||||
|
|
||||||
|
if( !part )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::string text = m_toolMgr->GetClipboard();
|
||||||
|
STRING_LINE_READER reader( text, "Clipboard" );
|
||||||
|
LIB_PART* newPart;
|
||||||
|
EDA_ITEMS newItems;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reader.ReadLine();
|
||||||
|
newPart = SCH_LEGACY_PLUGIN::ParsePart( reader );
|
||||||
|
}
|
||||||
|
catch( IO_ERROR& e )
|
||||||
|
{
|
||||||
|
wxLogError( wxString::Format( "Malformed clipboard: %s" ), GetChars( e.What() ) );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( LIB_ITEM& item : newPart->GetDrawItems() )
|
||||||
|
{
|
||||||
|
if( item.Type() == LIB_FIELD_T )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
|
||||||
|
newItem->SetFlags( IS_NEW );
|
||||||
|
newItems.push_back( newItem );
|
||||||
|
|
||||||
|
part->GetDrawItems().push_back( newItem );
|
||||||
|
getView()->Add( newItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
delete newPart;
|
||||||
|
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::addItemsToSel, true, &newItems );
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::move, true );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_TOOL::setTransitions()
|
||||||
|
{
|
||||||
|
Go( &LIB_EDIT_TOOL::Duplicate, SCH_ACTIONS::duplicate.MakeEvent() );
|
||||||
|
Go( &LIB_EDIT_TOOL::Rotate, SCH_ACTIONS::rotateCW.MakeEvent() );
|
||||||
|
Go( &LIB_EDIT_TOOL::Rotate, SCH_ACTIONS::rotateCCW.MakeEvent() );
|
||||||
|
Go( &LIB_EDIT_TOOL::Mirror, SCH_ACTIONS::mirrorX.MakeEvent() );
|
||||||
|
Go( &LIB_EDIT_TOOL::Mirror, SCH_ACTIONS::mirrorY.MakeEvent() );
|
||||||
|
Go( &LIB_EDIT_TOOL::DoDelete, SCH_ACTIONS::doDelete.MakeEvent() );
|
||||||
|
Go( &LIB_EDIT_TOOL::DeleteItemCursor, SCH_ACTIONS::deleteItemCursor.MakeEvent() );
|
||||||
|
|
||||||
|
Go( &LIB_EDIT_TOOL::Properties, SCH_ACTIONS::properties.MakeEvent() );
|
||||||
|
|
||||||
|
Go( &LIB_EDIT_TOOL::Cut, SCH_ACTIONS::cut.MakeEvent() );
|
||||||
|
Go( &LIB_EDIT_TOOL::Copy, SCH_ACTIONS::copy.MakeEvent() );
|
||||||
|
Go( &LIB_EDIT_TOOL::Paste, SCH_ACTIONS::paste.MakeEvent() );
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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 KICAD_LIB_EDIT_TOOL_H
|
||||||
|
#define KICAD_LIB_EDIT_TOOL_H
|
||||||
|
|
||||||
|
#include <tool/tool_interactive.h>
|
||||||
|
#include <tool/tool_menu.h>
|
||||||
|
#include <sch_base_frame.h>
|
||||||
|
|
||||||
|
|
||||||
|
class LIB_EDIT_FRAME;
|
||||||
|
class SCH_SELECTION_TOOL;
|
||||||
|
|
||||||
|
|
||||||
|
class LIB_EDIT_TOOL : public TOOL_INTERACTIVE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LIB_EDIT_TOOL();
|
||||||
|
~LIB_EDIT_TOOL();
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||||
|
bool Init() override;
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Reset()
|
||||||
|
void Reset( RESET_REASON aReason ) override;
|
||||||
|
|
||||||
|
///> Get the SCH_DRAWING_TOOL top-level context menu
|
||||||
|
inline TOOL_MENU& GetToolMenu() { return m_menu; }
|
||||||
|
|
||||||
|
int Rotate( const TOOL_EVENT& aEvent );
|
||||||
|
int Mirror( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
int Duplicate( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
int Properties( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
int Cut( const TOOL_EVENT& aEvent );
|
||||||
|
int Copy( const TOOL_EVENT& aEvent );
|
||||||
|
int Paste( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function DoDelete()
|
||||||
|
*
|
||||||
|
* Deletes the selected items, or the item under the cursor.
|
||||||
|
*/
|
||||||
|
int DoDelete( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Runs the deletion tool.
|
||||||
|
int DeleteItemCursor( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void editGraphicProperties( LIB_ITEM* aItem );
|
||||||
|
void editTextProperties( LIB_ITEM* aItem );
|
||||||
|
void editFieldProperties( LIB_FIELD* aField );
|
||||||
|
|
||||||
|
///> Sets up handlers for various events.
|
||||||
|
void setTransitions() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SCH_SELECTION_TOOL* m_selectionTool;
|
||||||
|
LIB_EDIT_FRAME* m_frame;
|
||||||
|
|
||||||
|
/// Menu model displayed by the tool.
|
||||||
|
TOOL_MENU m_menu;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //KICAD_LIB_EDIT_TOOL_H
|
|
@ -0,0 +1,346 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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 <tool/tool_manager.h>
|
||||||
|
#include <tools/sch_selection_tool.h>
|
||||||
|
#include <sch_actions.h>
|
||||||
|
#include <hotkeys.h>
|
||||||
|
#include <view/view.h>
|
||||||
|
#include <bitmaps.h>
|
||||||
|
#include <base_struct.h>
|
||||||
|
#include <lib_edit_frame.h>
|
||||||
|
#include <eeschema_id.h>
|
||||||
|
#include "lib_move_tool.h"
|
||||||
|
#include "lib_pin_tool.h"
|
||||||
|
|
||||||
|
|
||||||
|
LIB_MOVE_TOOL::LIB_MOVE_TOOL() :
|
||||||
|
TOOL_INTERACTIVE( "libedit.InteractiveMove" ),
|
||||||
|
m_selectionTool( nullptr ),
|
||||||
|
m_controls( nullptr ),
|
||||||
|
m_frame( nullptr ),
|
||||||
|
m_menu( *this ),
|
||||||
|
m_moveInProgress( false ),
|
||||||
|
m_moveOffset( 0, 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_MOVE_TOOL::~LIB_MOVE_TOOL()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MOVE_TOOL::Init()
|
||||||
|
{
|
||||||
|
m_frame = getEditFrame<LIB_EDIT_FRAME>();
|
||||||
|
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||||
|
|
||||||
|
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build the tool menu
|
||||||
|
//
|
||||||
|
CONDITIONAL_MENU& ctxMenu = m_menu.GetMenu();
|
||||||
|
|
||||||
|
ctxMenu.AddItem( ACTIONS::cancelInteractive, SCH_CONDITIONS::ShowAlways, 1 );
|
||||||
|
|
||||||
|
ctxMenu.AddSeparator( SCH_CONDITIONS::ShowAlways, 1000 );
|
||||||
|
m_menu.AddStandardSubMenus( m_frame );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add move actions to the selection tool menu
|
||||||
|
//
|
||||||
|
CONDITIONAL_MENU& selToolMenu = m_selectionTool->GetToolMenu().GetMenu();
|
||||||
|
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::move, SCH_CONDITIONS::Idle, 150 );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MOVE_TOOL::Reset( RESET_REASON aReason )
|
||||||
|
{
|
||||||
|
if( aReason == MODEL_RELOAD )
|
||||||
|
{
|
||||||
|
m_moveInProgress = false;
|
||||||
|
m_moveOffset = { 0, 0 };
|
||||||
|
|
||||||
|
// Init variables used by every drawing tool
|
||||||
|
m_controls = getViewControls();
|
||||||
|
m_frame = getEditFrame<LIB_EDIT_FRAME>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
|
|
||||||
|
controls->SetSnapping( true );
|
||||||
|
VECTOR2I originalCursorPos = controls->GetCursorPosition();
|
||||||
|
|
||||||
|
// Be sure that there is at least one item that we can move. If there's no selection try
|
||||||
|
// looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection).
|
||||||
|
SELECTION& selection = m_selectionTool->RequestSelection();
|
||||||
|
bool unselect = selection.IsHover();
|
||||||
|
|
||||||
|
if( selection.Empty() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
m_frame->SetToolID( ID_SCH_MOVE, wxCURSOR_DEFAULT, _( "Move Items" ) );
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
controls->ShowCursor( true );
|
||||||
|
controls->SetAutoPan( true );
|
||||||
|
|
||||||
|
bool restore_state = false;
|
||||||
|
bool chain_commands = false;
|
||||||
|
OPT_TOOL_EVENT evt = aEvent;
|
||||||
|
VECTOR2I prevPos;
|
||||||
|
|
||||||
|
if( !selection.Front()->IsNew() )
|
||||||
|
m_frame->SaveCopyInUndoList( m_frame->GetCurPart() );
|
||||||
|
|
||||||
|
// Main loop: keep receiving events
|
||||||
|
do
|
||||||
|
{
|
||||||
|
controls->SetSnapping( !evt->Modifier( MD_ALT ) );
|
||||||
|
|
||||||
|
if( evt->IsAction( &SCH_ACTIONS::move ) || evt->IsMotion() || evt->IsDrag( BUT_LEFT )
|
||||||
|
|| evt->IsAction( &SCH_ACTIONS::refreshPreview ) )
|
||||||
|
{
|
||||||
|
if( !m_moveInProgress ) // Prepare to start moving/dragging
|
||||||
|
{
|
||||||
|
// Pick up any synchronized pins
|
||||||
|
//
|
||||||
|
if( selection.GetSize() == 1 && selection.Front()->Type() == LIB_PIN_T
|
||||||
|
&& m_frame->SynchronizePins() )
|
||||||
|
{
|
||||||
|
LIB_PIN* cur_pin = (LIB_PIN*) selection.Front();
|
||||||
|
LIB_PART* part = m_frame->GetCurPart();
|
||||||
|
|
||||||
|
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
||||||
|
{
|
||||||
|
if( pin->GetPosition() == cur_pin->GetPosition()
|
||||||
|
&& pin->GetOrientation() == cur_pin->GetOrientation()
|
||||||
|
&& pin->GetConvert() == cur_pin->GetConvert() )
|
||||||
|
{
|
||||||
|
m_selectionTool->AddItemToSel( pin, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply any initial offset in case we're coming from a previous command.
|
||||||
|
//
|
||||||
|
for( EDA_ITEM* item : selection )
|
||||||
|
moveItem( item, m_moveOffset );
|
||||||
|
|
||||||
|
// Set up the starting position and move/drag offset
|
||||||
|
//
|
||||||
|
m_cursor = controls->GetCursorPosition();
|
||||||
|
|
||||||
|
if( selection.HasReferencePoint() )
|
||||||
|
{
|
||||||
|
VECTOR2I delta = m_cursor - selection.GetReferencePoint();
|
||||||
|
|
||||||
|
// Drag items to the current cursor position
|
||||||
|
for( EDA_ITEM* item : selection )
|
||||||
|
{
|
||||||
|
// Don't double move pins, fields, etc.
|
||||||
|
if( item->GetParent() && item->GetParent()->IsSelected() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
moveItem( item, delta );
|
||||||
|
getView()->Update( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
selection.SetReferencePoint( m_cursor );
|
||||||
|
}
|
||||||
|
else if( selection.Size() == 1 )
|
||||||
|
{
|
||||||
|
// Set the current cursor position to the first dragged item origin,
|
||||||
|
// so the movement vector can be computed later
|
||||||
|
updateModificationPoint( selection );
|
||||||
|
m_cursor = originalCursorPos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updateModificationPoint( selection );
|
||||||
|
}
|
||||||
|
|
||||||
|
controls->SetCursorPosition( m_cursor, false );
|
||||||
|
|
||||||
|
prevPos = m_cursor;
|
||||||
|
controls->SetAutoPan( true );
|
||||||
|
m_moveInProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Follow the mouse
|
||||||
|
//
|
||||||
|
m_cursor = controls->GetCursorPosition();
|
||||||
|
VECTOR2I delta( m_cursor - prevPos );
|
||||||
|
selection.SetReferencePoint( m_cursor );
|
||||||
|
|
||||||
|
m_moveOffset += delta;
|
||||||
|
prevPos = m_cursor;
|
||||||
|
|
||||||
|
for( EDA_ITEM* item : selection )
|
||||||
|
{
|
||||||
|
moveItem( item, delta );
|
||||||
|
getView()->Update( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
m_frame->UpdateMsgPanel();
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Handle cancel
|
||||||
|
//
|
||||||
|
else if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) )
|
||||||
|
{
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
|
if( m_moveInProgress )
|
||||||
|
restore_state = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Handle TOOL_ACTION special cases
|
||||||
|
//
|
||||||
|
else if( evt->Action() == TA_UNDO_REDO_PRE )
|
||||||
|
{
|
||||||
|
unselect = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( evt->Category() == TC_COMMAND )
|
||||||
|
{
|
||||||
|
if( evt->IsAction( &SCH_ACTIONS::doDelete ) )
|
||||||
|
{
|
||||||
|
// Exit on a remove operation; there is no further processing for removed items.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( evt->IsAction( &SCH_ACTIONS::duplicate ) )
|
||||||
|
{
|
||||||
|
if( selection.Front()->IsNew() )
|
||||||
|
{
|
||||||
|
// This doesn't really make sense; we'll just end up dragging a stack of
|
||||||
|
// objects so Duplicate() is going to ignore this and we'll just carry on.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move original back and exit. The duplicate will run in its own loop.
|
||||||
|
restore_state = true;
|
||||||
|
unselect = false;
|
||||||
|
chain_commands = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Handle context menu
|
||||||
|
//
|
||||||
|
else if( evt->IsClick( BUT_RIGHT ) )
|
||||||
|
{
|
||||||
|
m_menu.ShowContextMenu( selection );
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Handle drop
|
||||||
|
//
|
||||||
|
else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
if( selection.GetSize() == 1 && selection.Front()->Type() == LIB_PIN_T )
|
||||||
|
{
|
||||||
|
LIB_PIN_TOOL* pinTool = m_toolMgr->GetTool<LIB_PIN_TOOL>();
|
||||||
|
|
||||||
|
if( !pinTool->PlacePin( (LIB_PIN*) selection.Front() ) )
|
||||||
|
restore_state = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break; // Finish
|
||||||
|
}
|
||||||
|
|
||||||
|
} while( ( evt = Wait() ) ); //Should be assignment not equality test
|
||||||
|
|
||||||
|
controls->ForceCursorPosition( false );
|
||||||
|
controls->ShowCursor( false );
|
||||||
|
controls->SetSnapping( false );
|
||||||
|
controls->SetAutoPan( false );
|
||||||
|
|
||||||
|
if( !chain_commands )
|
||||||
|
m_moveOffset = { 0, 0 };
|
||||||
|
|
||||||
|
m_moveInProgress = false;
|
||||||
|
m_frame->SetNoToolSelected();
|
||||||
|
|
||||||
|
selection.ClearReferencePoint();
|
||||||
|
|
||||||
|
for( auto item : selection )
|
||||||
|
item->ClearFlags( item->GetEditFlags() );
|
||||||
|
|
||||||
|
if( unselect )
|
||||||
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
|
|
||||||
|
if( restore_state )
|
||||||
|
m_frame->RollbackPartFromUndo();
|
||||||
|
else
|
||||||
|
m_frame->OnModify();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MOVE_TOOL::moveItem( EDA_ITEM* aItem, VECTOR2I aDelta )
|
||||||
|
{
|
||||||
|
static_cast<LIB_ITEM*>( aItem )->Move( mapCoords( aDelta ) );
|
||||||
|
aItem->SetFlags( IS_MOVED );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MOVE_TOOL::updateModificationPoint( SELECTION& aSelection )
|
||||||
|
{
|
||||||
|
if( m_moveInProgress && aSelection.HasReferencePoint() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// When there is only one item selected, the reference point is its position...
|
||||||
|
if( aSelection.Size() == 1 )
|
||||||
|
{
|
||||||
|
LIB_ITEM* item = static_cast<LIB_ITEM*>( aSelection.Front() );
|
||||||
|
aSelection.SetReferencePoint( item->GetPosition() );
|
||||||
|
}
|
||||||
|
// ...otherwise modify items with regard to the grid-snapped cursor position
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cursor = getViewControls()->GetCursorPosition( true );
|
||||||
|
aSelection.SetReferencePoint( m_cursor );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MOVE_TOOL::setTransitions()
|
||||||
|
{
|
||||||
|
Go( &LIB_MOVE_TOOL::Main, SCH_ACTIONS::move.MakeEvent() );
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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 KICAD_LIB_MOVE_TOOL_H
|
||||||
|
#define KICAD_LIB_MOVE_TOOL_H
|
||||||
|
|
||||||
|
#include <tool/tool_interactive.h>
|
||||||
|
#include <tool/tool_menu.h>
|
||||||
|
#include <sch_base_frame.h>
|
||||||
|
|
||||||
|
|
||||||
|
class LIB_EDIT_FRAME;
|
||||||
|
class SCH_SELECTION_TOOL;
|
||||||
|
|
||||||
|
|
||||||
|
class LIB_MOVE_TOOL : public TOOL_INTERACTIVE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LIB_MOVE_TOOL();
|
||||||
|
~LIB_MOVE_TOOL();
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||||
|
bool Init() override;
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Reset()
|
||||||
|
void Reset( RESET_REASON aReason ) override;
|
||||||
|
|
||||||
|
///> Get the SCH_DRAWING_TOOL top-level context menu
|
||||||
|
inline TOOL_MENU& GetToolMenu() { return m_menu; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Main()
|
||||||
|
*
|
||||||
|
* Runs an interactive move of the selected items, or the item under the cursor.
|
||||||
|
*/
|
||||||
|
int Main( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void moveItem( EDA_ITEM* aItem, VECTOR2I aDelta );
|
||||||
|
|
||||||
|
///> Returns the right modification point (e.g. for rotation), depending on the number of
|
||||||
|
///> selected items.
|
||||||
|
bool updateModificationPoint( SELECTION& aSelection );
|
||||||
|
|
||||||
|
///> Sets up handlers for various events.
|
||||||
|
void setTransitions() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SCH_SELECTION_TOOL* m_selectionTool;
|
||||||
|
KIGFX::VIEW_CONTROLS* m_controls;
|
||||||
|
LIB_EDIT_FRAME* m_frame;
|
||||||
|
|
||||||
|
/// Menu model displayed by the tool.
|
||||||
|
TOOL_MENU m_menu;
|
||||||
|
|
||||||
|
///> Flag determining if anything is being dragged right now
|
||||||
|
bool m_moveInProgress;
|
||||||
|
|
||||||
|
///> Used for chaining commands
|
||||||
|
VECTOR2I m_moveOffset;
|
||||||
|
|
||||||
|
///> Last cursor position (needed for getModificationPoint() to avoid changes
|
||||||
|
///> of edit reference point).
|
||||||
|
VECTOR2I m_cursor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //KICAD_LIB_MOVE_TOOL_H
|
|
@ -26,12 +26,26 @@
|
||||||
#include <lib_edit_frame.h>
|
#include <lib_edit_frame.h>
|
||||||
#include <eeschema_id.h>
|
#include <eeschema_id.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
|
#include <sch_actions.h>
|
||||||
#include <sch_view.h>
|
#include <sch_view.h>
|
||||||
#include <dialogs/dialog_display_info_HTML_base.h>
|
#include <dialogs/dialog_display_info_HTML_base.h>
|
||||||
#include <dialogs/dialog_lib_edit_pin.h>
|
#include <dialogs/dialog_lib_edit_pin.h>
|
||||||
#include "lib_pin_tool.h"
|
#include "lib_pin_tool.h"
|
||||||
|
|
||||||
|
|
||||||
|
TOOL_ACTION SCH_ACTIONS::pushPinLength( "libedit.PinEditing.pushPinLength",
|
||||||
|
AS_GLOBAL, 0, _( "Push Pin Length" ), _( "Copy pin length to other pins in symbol" ),
|
||||||
|
pin_size_to_xpm );
|
||||||
|
|
||||||
|
TOOL_ACTION SCH_ACTIONS::pushPinNameSize( "libedit.PinEditing.pushPinNameSize",
|
||||||
|
AS_GLOBAL, 0, _( "Push Pin Name Size" ), _( "Copy pin name size to other pins in symbol" ),
|
||||||
|
pin_size_to_xpm );
|
||||||
|
|
||||||
|
TOOL_ACTION SCH_ACTIONS::pushPinNumSize( "libedit.PinEditing.pushPinNumSize",
|
||||||
|
AS_GLOBAL, 0, _( "Push Pin Number Size" ), _( "Copy pin number size to other pins in symbol" ),
|
||||||
|
pin_size_to_xpm );
|
||||||
|
|
||||||
|
|
||||||
static ELECTRICAL_PINTYPE g_LastPinType = PIN_INPUT;
|
static ELECTRICAL_PINTYPE g_LastPinType = PIN_INPUT;
|
||||||
static int g_LastPinOrient = PIN_RIGHT;
|
static int g_LastPinOrient = PIN_RIGHT;
|
||||||
static GRAPHIC_PINSHAPE g_LastPinShape = PINSHAPE_LINE;
|
static GRAPHIC_PINSHAPE g_LastPinShape = PINSHAPE_LINE;
|
||||||
|
@ -92,6 +106,15 @@ bool LIB_PIN_TOOL::Init()
|
||||||
|
|
||||||
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
|
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
|
||||||
|
|
||||||
|
auto singlePinCondition = SCH_CONDITIONS::Count( 1 ) && SCH_CONDITIONS::OnlyType( LIB_PIN_T );
|
||||||
|
|
||||||
|
CONDITIONAL_MENU& selToolMenu = m_selectionTool->GetToolMenu().GetMenu();
|
||||||
|
|
||||||
|
selToolMenu.AddSeparator( singlePinCondition, 400 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::pushPinLength, singlePinCondition, 400 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::pushPinNameSize, singlePinCondition, 400 );
|
||||||
|
selToolMenu.AddItem( SCH_ACTIONS::pushPinNumSize, singlePinCondition, 400 );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,170 +129,95 @@ void LIB_PIN_TOOL::Reset( RESET_REASON aReason )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnEditPin( wxCommandEvent& event )
|
bool LIB_PIN_TOOL::EditPinProperties( LIB_PIN* aPin )
|
||||||
{
|
{
|
||||||
if( GetDrawItem() == NULL || GetDrawItem()->Type() != LIB_PIN_T )
|
aPin->EnableEditMode( true, !m_frame->SynchronizePins() );
|
||||||
return;
|
|
||||||
|
|
||||||
STATUS_FLAGS item_flags = GetDrawItem()->GetFlags(); // save flags to restore them after editing
|
DIALOG_LIB_EDIT_PIN dlg( m_frame, aPin );
|
||||||
LIB_PIN* pin = (LIB_PIN*) GetDrawItem();
|
|
||||||
|
|
||||||
pin->EnableEditMode( true, !SynchronizePins() );
|
|
||||||
|
|
||||||
DIALOG_LIB_EDIT_PIN dlg( this, pin );
|
|
||||||
|
|
||||||
if( dlg.ShowModal() == wxID_CANCEL )
|
if( dlg.ShowModal() == wxID_CANCEL )
|
||||||
{
|
{
|
||||||
if( pin->IsNew() )
|
return false;
|
||||||
{
|
|
||||||
pin->SetFlags( IS_CANCELLED );
|
|
||||||
m_canvas->EndMouseCapture();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pin->IsModified() || pin->IsNew() )
|
m_frame->RefreshItem( aPin );
|
||||||
{
|
m_frame->OnModify( );
|
||||||
GetCanvas()->GetView()->Update( pin );
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify( );
|
|
||||||
|
|
||||||
MSG_PANEL_ITEMS items;
|
MSG_PANEL_ITEMS items;
|
||||||
pin->GetMsgPanelInfo( m_UserUnits, items );
|
aPin->GetMsgPanelInfo( m_frame->GetUserUnits(), items );
|
||||||
SetMsgPanel( items );
|
m_frame->SetMsgPanel( items );
|
||||||
}
|
|
||||||
|
|
||||||
pin->EnableEditMode( false );
|
aPin->EnableEditMode( false );
|
||||||
|
|
||||||
// Restore pin flags, that can be changed by the dialog editor
|
|
||||||
pin->ClearFlags();
|
|
||||||
pin->SetFlags( item_flags );
|
|
||||||
|
|
||||||
// Save the pin properties to use for the next new pin.
|
// Save the pin properties to use for the next new pin.
|
||||||
g_LastPinNameSize = pin->GetNameTextSize();
|
g_LastPinNameSize = aPin->GetNameTextSize();
|
||||||
g_LastPinNumSize = pin->GetNumberTextSize();
|
g_LastPinNumSize = aPin->GetNumberTextSize();
|
||||||
g_LastPinOrient = pin->GetOrientation();
|
g_LastPinOrient = aPin->GetOrientation();
|
||||||
g_LastPinLength = pin->GetLength();
|
g_LastPinLength = aPin->GetLength();
|
||||||
g_LastPinShape = pin->GetShape();
|
g_LastPinShape = aPin->GetShape();
|
||||||
g_LastPinType = pin->GetType();
|
g_LastPinType = aPin->GetType();
|
||||||
g_LastPinCommonConvert = pin->GetConvert() == 0;
|
g_LastPinCommonConvert = aPin->GetConvert() == 0;
|
||||||
g_LastPinCommonUnit = pin->GetUnit() == 0;
|
g_LastPinCommonUnit = aPin->GetUnit() == 0;
|
||||||
g_LastPinVisible = pin->IsVisible();
|
g_LastPinVisible = aPin->IsVisible();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
bool LIB_PIN_TOOL::PlacePin( LIB_PIN* aPin )
|
||||||
* Clean up after aborting a move pin command.
|
|
||||||
*/
|
|
||||||
static void AbortPinMove( EDA_DRAW_PANEL* aPanel, wxDC* DC )
|
|
||||||
{
|
{
|
||||||
LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent();
|
LIB_PART* part = m_frame->GetCurPart();
|
||||||
auto panel = static_cast<SCH_DRAW_PANEL*>( aPanel );
|
bool ask_for_pin = true; // Test for another pin in same position in other units
|
||||||
|
|
||||||
if( parent == NULL )
|
for( LIB_PIN* test = part->GetNextPin(); test; test = part->GetNextPin( test ) )
|
||||||
return;
|
|
||||||
|
|
||||||
LIB_PIN* pin = (LIB_PIN*) parent->GetDrawItem();
|
|
||||||
|
|
||||||
if( pin == NULL || pin->Type() != LIB_PIN_T )
|
|
||||||
return;
|
|
||||||
|
|
||||||
pin->ClearFlags();
|
|
||||||
|
|
||||||
if( pin->IsNew() )
|
|
||||||
delete pin;
|
|
||||||
else
|
|
||||||
parent->RestoreComponent();
|
|
||||||
|
|
||||||
panel->GetView()->ClearPreview();
|
|
||||||
panel->GetView()->ClearHiddenFlags();
|
|
||||||
|
|
||||||
// clear edit flags
|
|
||||||
parent->SetDrawItem( NULL );
|
|
||||||
parent->SetLastDrawItem( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Managed cursor callback for placing component pins.
|
|
||||||
*/
|
|
||||||
void LIB_EDIT_FRAME::PlacePin()
|
|
||||||
{
|
|
||||||
LIB_PIN* cur_pin = (LIB_PIN*) GetDrawItem();
|
|
||||||
|
|
||||||
DBG(printf("PlacePin!\n");)
|
|
||||||
|
|
||||||
// Some tests
|
|
||||||
if( !cur_pin || cur_pin->Type() != LIB_PIN_T )
|
|
||||||
{
|
{
|
||||||
wxMessageBox( wxT( "LIB_EDIT_FRAME::PlacePin() error" ) );
|
if( test == aPin || aPin->GetPosition() != test->GetPosition() || test->GetEditFlags() )
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxPoint newpos;
|
|
||||||
newpos = GetCrossHairPosition( true );
|
|
||||||
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
// Test for another pin in same new position in other units:
|
|
||||||
bool ask_for_pin = true;
|
|
||||||
|
|
||||||
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
|
||||||
{
|
|
||||||
if( pin == cur_pin || newpos != pin->GetPosition() || pin->GetEditFlags() )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// test for same body style
|
// test for same body style
|
||||||
if( pin->GetConvert() && pin->GetConvert() != cur_pin->GetConvert() )
|
if( test->GetConvert() && test->GetConvert() != aPin->GetConvert() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( ask_for_pin && SynchronizePins() )
|
if( ask_for_pin && m_frame->SynchronizePins() )
|
||||||
{
|
{
|
||||||
m_canvas->SetIgnoreMouseEvents( true );
|
m_frame->GetCanvas()->SetIgnoreMouseEvents( true );
|
||||||
wxString msg;
|
wxString msg;
|
||||||
msg.Printf( _( "This position is already occupied by another pin, in unit %d." ),
|
msg.Printf( _( "This position is already occupied by another pin, in unit %d." ),
|
||||||
pin->GetUnit() );
|
test->GetUnit() );
|
||||||
|
|
||||||
KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
|
KIDIALOG dlg( m_frame, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
|
||||||
dlg.SetOKLabel( _( "Create Pin Anyway" ) );
|
dlg.SetOKLabel( _( "Create Pin Anyway" ) );
|
||||||
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
|
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
|
||||||
|
|
||||||
bool status = dlg.ShowModal() == wxID_OK;
|
bool status = dlg.ShowModal() == wxID_OK;
|
||||||
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
m_frame->GetCanvas()->MoveCursorToCrossHair();
|
||||||
m_canvas->SetIgnoreMouseEvents( false );
|
m_frame->GetCanvas()->SetIgnoreMouseEvents( false );
|
||||||
|
|
||||||
if( !status )
|
if( !status )
|
||||||
{
|
{
|
||||||
RebuildView();
|
if( aPin->IsNew() )
|
||||||
return;
|
delete aPin;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
ask_for_pin = false;
|
ask_for_pin = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Undo from GetTempCopyComponent() if exists ( i.e. after a pin move)
|
if( aPin->IsNew() )
|
||||||
// or from m_component (pin add ...)
|
|
||||||
if( GetTempCopyComponent() )
|
|
||||||
SaveCopyInUndoList( GetTempCopyComponent() );
|
|
||||||
else
|
|
||||||
SaveCopyInUndoList( part );
|
|
||||||
|
|
||||||
m_canvas->SetMouseCapture( NULL, NULL );
|
|
||||||
cur_pin->Move( newpos );
|
|
||||||
|
|
||||||
if( cur_pin->IsNew() )
|
|
||||||
{
|
{
|
||||||
g_LastPinOrient = cur_pin->GetOrientation();
|
g_LastPinOrient = aPin->GetOrientation();
|
||||||
g_LastPinType = cur_pin->GetType();
|
g_LastPinType = aPin->GetType();
|
||||||
g_LastPinShape = cur_pin->GetShape();
|
g_LastPinShape = aPin->GetShape();
|
||||||
|
|
||||||
if( SynchronizePins() )
|
if( m_frame->SynchronizePins() )
|
||||||
CreateImagePins( cur_pin );
|
CreateImagePins( aPin );
|
||||||
|
|
||||||
m_lastDrawItem = cur_pin;
|
part->AddDrawItem( aPin );
|
||||||
part->AddDrawItem( GetDrawItem() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put linked pins in new position, and clear flags
|
// Put linked pins in new position, and clear flags
|
||||||
|
@ -278,82 +226,14 @@ void LIB_EDIT_FRAME::PlacePin()
|
||||||
if( pin->GetEditFlags() == 0 )
|
if( pin->GetEditFlags() == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pin->Move( cur_pin->GetPosition() );
|
pin->Move( aPin->GetPosition() );
|
||||||
pin->ClearFlags();
|
pin->ClearFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDrawItem( NULL );
|
m_frame->RebuildView();
|
||||||
|
m_frame->OnModify();
|
||||||
|
|
||||||
RebuildView();
|
return true;
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Move pin to the current mouse position. This function is called by the
|
|
||||||
* cursor management code. */
|
|
||||||
static void DrawMovePin( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
|
|
||||||
bool aErase )
|
|
||||||
{
|
|
||||||
LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent();
|
|
||||||
|
|
||||||
if( parent == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
LIB_PIN* cur_pin = (LIB_PIN*) parent->GetDrawItem();
|
|
||||||
|
|
||||||
if( cur_pin == NULL || cur_pin->Type() != LIB_PIN_T )
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto p = aPanel->GetParent()->GetCrossHairPosition( true );
|
|
||||||
|
|
||||||
// Redraw pin in new position
|
|
||||||
cur_pin->Move(p);
|
|
||||||
|
|
||||||
KIGFX::SCH_VIEW* view = parent->GetCanvas()->GetView();
|
|
||||||
|
|
||||||
view->Hide( cur_pin );
|
|
||||||
view->ClearPreview();
|
|
||||||
view->AddToPreview( cur_pin->Clone() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::StartMovePin( LIB_ITEM* aItem )
|
|
||||||
{
|
|
||||||
LIB_PIN* cur_pin = (LIB_PIN*) aItem;
|
|
||||||
|
|
||||||
TempCopyComponent();
|
|
||||||
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
// Clear pin flags and mark pins for moving. All pins having the same location
|
|
||||||
// orientation, and body style are flagged.
|
|
||||||
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
|
||||||
{
|
|
||||||
pin->ClearFlags();
|
|
||||||
|
|
||||||
if( !SynchronizePins() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( pin == cur_pin )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( pin->GetPosition() == cur_pin->GetPosition() &&
|
|
||||||
pin->GetOrientation() == cur_pin->GetOrientation() &&
|
|
||||||
pin->GetConvert() == cur_pin->GetConvert() )
|
|
||||||
{
|
|
||||||
pin->SetFlags( IS_LINKED | IS_MOVED );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_pin->SetFlags( IS_LINKED | IS_MOVED );
|
|
||||||
|
|
||||||
MSG_PANEL_ITEMS items;
|
|
||||||
|
|
||||||
cur_pin->GetMsgPanelInfo( m_UserUnits, items );
|
|
||||||
SetMsgPanel( items );
|
|
||||||
|
|
||||||
m_canvas->SetMouseCapture( DrawMovePin, AbortPinMove );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -383,10 +263,7 @@ LIB_PIN* LIB_PIN_TOOL::CreatePin( const VECTOR2I& aPosition, LIB_PART* aPart )
|
||||||
pin->SetUnit( g_LastPinCommonUnit ? 0 : m_frame->GetUnit() );
|
pin->SetUnit( g_LastPinCommonUnit ? 0 : m_frame->GetUnit() );
|
||||||
pin->SetVisible( g_LastPinVisible );
|
pin->SetVisible( g_LastPinVisible );
|
||||||
|
|
||||||
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
|
if( !EditPinProperties( pin ) )
|
||||||
m_frame->OnEditPin( cmd );
|
|
||||||
|
|
||||||
if( pin->GetFlags() & IS_CANCELLED )
|
|
||||||
{
|
{
|
||||||
delete pin;
|
delete pin;
|
||||||
pin = nullptr;
|
pin = nullptr;
|
||||||
|
@ -396,14 +273,14 @@ LIB_PIN* LIB_PIN_TOOL::CreatePin( const VECTOR2I& aPosition, LIB_PART* aPart )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::CreateImagePins( LIB_PIN* aPin )
|
void LIB_PIN_TOOL::CreateImagePins( LIB_PIN* aPin )
|
||||||
{
|
{
|
||||||
int ii;
|
int ii;
|
||||||
LIB_PIN* newPin;
|
LIB_PIN* newPin;
|
||||||
|
|
||||||
// if "synchronize pins editing" option is off, do not create any similar pin for other
|
// if "synchronize pins editing" option is off, do not create any similar pin for other
|
||||||
// units and/or shapes: each unit is edited regardless other units or body
|
// units and/or shapes: each unit is edited regardless other units or body
|
||||||
if( !SynchronizePins() )
|
if( !m_frame->SynchronizePins() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( aPin->GetUnit() == 0 ) // Pin common to all units: no need to create similar pins.
|
if( aPin->GetUnit() == 0 ) // Pin common to all units: no need to create similar pins.
|
||||||
|
@ -434,127 +311,80 @@ void LIB_EDIT_FRAME::CreateImagePins( LIB_PIN* aPin )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* aMasterPin is the "template" pin
|
int LIB_PIN_TOOL::PushPinProperties( const TOOL_EVENT& aEvent )
|
||||||
* aId is a param to select what should be mofified:
|
|
||||||
* - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
|
|
||||||
* Change pins text name size
|
|
||||||
* - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
|
|
||||||
* Change pins text num size
|
|
||||||
* - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
|
|
||||||
* Change pins length.
|
|
||||||
*
|
|
||||||
* If aMasterPin is selected ( .m_flag == IS_SELECTED ),
|
|
||||||
* only the other selected pins are modified
|
|
||||||
*/
|
|
||||||
void LIB_EDIT_FRAME::GlobalSetPins( LIB_PIN* aMasterPin, int aId )
|
|
||||||
|
|
||||||
{
|
{
|
||||||
LIB_PART* part = GetCurPart();
|
LIB_PART* part = m_frame->GetCurPart();
|
||||||
|
SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
|
LIB_PIN* sourcePin = dynamic_cast<LIB_PIN*>( selection.Front() );
|
||||||
|
|
||||||
if( !part || !aMasterPin )
|
if( !sourcePin )
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if( aMasterPin->Type() != LIB_PIN_T )
|
m_frame->SaveCopyInUndoList( part );
|
||||||
return;
|
|
||||||
|
|
||||||
bool selected = aMasterPin->IsSelected();
|
|
||||||
|
|
||||||
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
||||||
{
|
{
|
||||||
if( pin->GetConvert() && pin->GetConvert() != m_convert )
|
if( pin->GetConvert() && pin->GetConvert() != m_frame->GetConvert() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Is it the "selected mode" ?
|
if( pin == sourcePin )
|
||||||
if( selected && !pin->IsSelected() )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch( aId )
|
if( aEvent.IsAction( &SCH_ACTIONS::pushPinLength ) )
|
||||||
{
|
pin->SetLength( sourcePin->GetLength() );
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
|
else if( aEvent.IsAction( &SCH_ACTIONS::pushPinNameSize ) )
|
||||||
pin->SetNumberTextSize( aMasterPin->GetNumberTextSize() );
|
pin->SetNameTextSize( sourcePin->GetNameTextSize() );
|
||||||
break;
|
else if( aEvent.IsAction( &SCH_ACTIONS::pushPinNumSize ) )
|
||||||
|
pin->SetNumberTextSize( sourcePin->GetNumberTextSize() );
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
|
|
||||||
pin->SetNameTextSize( aMasterPin->GetNameTextSize() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
|
|
||||||
pin->SetLength( aMasterPin->GetLength() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the flag IS_CHANGED, which was set by previous changes (if any)
|
|
||||||
// but not used here.
|
|
||||||
pin->ClearFlags( IS_CHANGED );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now changes are made, call OnModify() to validate thes changes and set
|
m_frame->RebuildView();
|
||||||
// the global change for UI
|
m_frame->OnModify();
|
||||||
RebuildView();
|
|
||||||
GetCanvas()->Refresh();
|
return 0;
|
||||||
OnModify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create a new pin based on the previous pin with an incremented pin number.
|
// Create a new pin based on the previous pin with an incremented pin number.
|
||||||
void LIB_EDIT_FRAME::RepeatPinItem( wxDC* DC, LIB_PIN* SourcePin )
|
LIB_PIN* LIB_PIN_TOOL::RepeatPin( const LIB_PIN* aSourcePin )
|
||||||
{
|
{
|
||||||
wxString msg;
|
LIB_PIN* pin = (LIB_PIN*) aSourcePin->Clone();
|
||||||
|
wxPoint step;
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
if( !part || !SourcePin || SourcePin->Type() != LIB_PIN_T )
|
|
||||||
return;
|
|
||||||
|
|
||||||
LIB_PIN* pin = (LIB_PIN*) SourcePin->Clone();
|
|
||||||
|
|
||||||
pin->ClearFlags();
|
pin->ClearFlags();
|
||||||
pin->SetFlags( IS_NEW );
|
pin->SetFlags( IS_NEW );
|
||||||
wxPoint step;
|
|
||||||
|
|
||||||
switch( pin->GetOrientation() )
|
switch( pin->GetOrientation() )
|
||||||
{
|
{
|
||||||
case PIN_UP: step.x = GetRepeatPinStep(); break;
|
case PIN_UP: step.x = m_frame->GetRepeatPinStep(); break;
|
||||||
case PIN_DOWN: step.x = GetRepeatPinStep(); break;
|
case PIN_DOWN: step.x = m_frame->GetRepeatPinStep(); break;
|
||||||
case PIN_LEFT: step.y = -GetRepeatPinStep(); break;
|
case PIN_LEFT: step.y = -m_frame->GetRepeatPinStep(); break;
|
||||||
case PIN_RIGHT: step.y = -GetRepeatPinStep(); break;
|
case PIN_RIGHT: step.y = -m_frame->GetRepeatPinStep(); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pin->Move( pin->GetPosition() + step );
|
pin->SetOffset( step );
|
||||||
|
|
||||||
wxString nextName = pin->GetName();
|
wxString nextName = pin->GetName();
|
||||||
IncrementLabelMember( nextName, GetRepeatDeltaLabel() );
|
IncrementLabelMember( nextName, m_frame->GetRepeatDeltaLabel() );
|
||||||
pin->SetName( nextName );
|
pin->SetName( nextName );
|
||||||
|
|
||||||
msg = pin->GetNumber();
|
wxString nextNumber = pin->GetNumber();
|
||||||
IncrementLabelMember( msg, GetRepeatDeltaLabel() );
|
IncrementLabelMember( nextNumber, m_frame->GetRepeatDeltaLabel() );
|
||||||
pin->SetNumber( msg );
|
pin->SetNumber( nextNumber );
|
||||||
|
|
||||||
SetDrawItem( pin );
|
if( m_frame->SynchronizePins() )
|
||||||
|
|
||||||
if( SynchronizePins() )
|
|
||||||
pin->SetFlags( IS_LINKED );
|
pin->SetFlags( IS_LINKED );
|
||||||
|
|
||||||
wxPoint savepos = GetCrossHairPosition();
|
PlacePin( pin );
|
||||||
m_canvas->CrossHairOff( DC );
|
|
||||||
|
|
||||||
SetCrossHairPosition( wxPoint( pin->GetPosition().x, -pin->GetPosition().y ) );
|
return pin;
|
||||||
|
|
||||||
// Add this new pin in list, and creates pins for others parts if needed
|
|
||||||
SetDrawItem( pin );
|
|
||||||
ClearTempCopyComponent();
|
|
||||||
PlacePin();
|
|
||||||
m_lastDrawItem = pin;
|
|
||||||
|
|
||||||
SetCrossHairPosition( savepos );
|
|
||||||
m_canvas->CrossHairOn( DC );
|
|
||||||
|
|
||||||
MSG_PANEL_ITEMS items;
|
|
||||||
pin->GetMsgPanelInfo( m_UserUnits, items );
|
|
||||||
SetMsgPanel( items );
|
|
||||||
|
|
||||||
RebuildView();
|
|
||||||
GetCanvas()->Refresh();
|
|
||||||
OnModify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_PIN_TOOL::setTransitions()
|
||||||
|
{
|
||||||
|
Go( &LIB_PIN_TOOL::PushPinProperties, SCH_ACTIONS::pushPinLength.MakeEvent() );
|
||||||
|
Go( &LIB_PIN_TOOL::PushPinProperties, SCH_ACTIONS::pushPinNameSize.MakeEvent() );
|
||||||
|
Go( &LIB_PIN_TOOL::PushPinProperties, SCH_ACTIONS::pushPinNumSize.MakeEvent() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,17 @@ public:
|
||||||
void Reset( RESET_REASON aReason ) override;
|
void Reset( RESET_REASON aReason ) override;
|
||||||
|
|
||||||
LIB_PIN* CreatePin( const VECTOR2I& aPosition, LIB_PART* aPart );
|
LIB_PIN* CreatePin( const VECTOR2I& aPosition, LIB_PART* aPart );
|
||||||
|
LIB_PIN* RepeatPin( const LIB_PIN* aSourcePin );
|
||||||
|
|
||||||
|
bool PlacePin( LIB_PIN* aPin );
|
||||||
|
void CreateImagePins( LIB_PIN* aPin );
|
||||||
|
|
||||||
|
bool EditPinProperties( LIB_PIN* aPin );
|
||||||
|
int PushPinProperties( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///> Sets up handlers for various events.
|
///> Sets up handlers for various events.
|
||||||
void setTransitions() override { }
|
void setTransitions() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SCH_SELECTION_TOOL* m_selectionTool;
|
SCH_SELECTION_TOOL* m_selectionTool;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sch_picker_tool.h>
|
#include <picker_tool.h>
|
||||||
#include <sch_actions.h>
|
#include <sch_actions.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
|
@ -30,14 +30,14 @@
|
||||||
TOOL_ACTION SCH_ACTIONS::pickerTool( "eeschema.Picker", AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE );
|
TOOL_ACTION SCH_ACTIONS::pickerTool( "eeschema.Picker", AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE );
|
||||||
|
|
||||||
|
|
||||||
SCH_PICKER_TOOL::SCH_PICKER_TOOL()
|
PICKER_TOOL::PICKER_TOOL()
|
||||||
: TOOL_INTERACTIVE( "eeschema.Picker" )
|
: TOOL_INTERACTIVE( "eeschema.Picker" )
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
int PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
int finalize_state = WAIT_CANCEL;
|
int finalize_state = WAIT_CANCEL;
|
||||||
|
@ -62,7 +62,7 @@ int SCH_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
{
|
{
|
||||||
std::cerr << "SCH_PICKER_TOOL click handler error: " << e.what() << std::endl;
|
std::cerr << "PICKER_TOOL click handler error: " << e.what() << std::endl;
|
||||||
finalize_state = EXCEPTION_CANCEL;
|
finalize_state = EXCEPTION_CANCEL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ int SCH_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
{
|
{
|
||||||
std::cerr << "SCH_PICKER_TOOL cancel handler error: " << e.what() << std::endl;
|
std::cerr << "PICKER_TOOL cancel handler error: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ int SCH_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
{
|
{
|
||||||
std::cerr << "SCH_PICKER_TOOL finalize handler error: " << e.what() << std::endl;
|
std::cerr << "PICKER_TOOL finalize handler error: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,13 +130,13 @@ int SCH_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_PICKER_TOOL::setTransitions()
|
void PICKER_TOOL::setTransitions()
|
||||||
{
|
{
|
||||||
Go( &SCH_PICKER_TOOL::Main, SCH_ACTIONS::pickerTool.MakeEvent() );
|
Go( &PICKER_TOOL::Main, SCH_ACTIONS::pickerTool.MakeEvent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_PICKER_TOOL::reset()
|
void PICKER_TOOL::reset()
|
||||||
{
|
{
|
||||||
m_cursorCapture = false;
|
m_cursorCapture = false;
|
||||||
m_autoPanning = false;
|
m_autoPanning = false;
|
||||||
|
@ -148,7 +148,7 @@ void SCH_PICKER_TOOL::reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_PICKER_TOOL::setControls()
|
void PICKER_TOOL::setControls()
|
||||||
{
|
{
|
||||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
|
|
|
@ -29,11 +29,11 @@
|
||||||
#include <tool/tool_interactive.h>
|
#include <tool/tool_interactive.h>
|
||||||
|
|
||||||
|
|
||||||
class SCH_PICKER_TOOL : public TOOL_INTERACTIVE
|
class PICKER_TOOL : public TOOL_INTERACTIVE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SCH_PICKER_TOOL();
|
PICKER_TOOL();
|
||||||
~SCH_PICKER_TOOL() {}
|
~PICKER_TOOL() {}
|
||||||
|
|
||||||
///> Event handler types.
|
///> Event handler types.
|
||||||
typedef std::function<bool(const VECTOR2D&)> CLICK_HANDLER;
|
typedef std::function<bool(const VECTOR2D&)> CLICK_HANDLER;
|
|
@ -0,0 +1,782 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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 <functional>
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
#include "point_editor.h"
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <view/view_controls.h>
|
||||||
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
#include <geometry/seg.h>
|
||||||
|
#include <confirm.h>
|
||||||
|
|
||||||
|
#include <tools/sch_actions.h>
|
||||||
|
#include <tools/sch_selection_tool.h>
|
||||||
|
#include <bitmaps.h>
|
||||||
|
#include <status_popup.h>
|
||||||
|
#include <sch_edit_frame.h>
|
||||||
|
#include <sch_line.h>
|
||||||
|
#include <sch_sheet.h>
|
||||||
|
#include <lib_edit_frame.h>
|
||||||
|
#include <lib_arc.h>
|
||||||
|
#include <lib_circle.h>
|
||||||
|
#include <lib_rectangle.h>
|
||||||
|
#include <lib_polyline.h>
|
||||||
|
#include <widgets/progress_reporter.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Point editor
|
||||||
|
TOOL_ACTION SCH_ACTIONS::pointEditorAddCorner( "eeschema.PointEditor.addCorner",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
_( "Create Corner" ), _( "Create a corner" ), add_corner_xpm );
|
||||||
|
|
||||||
|
TOOL_ACTION SCH_ACTIONS::pointEditorRemoveCorner( "eeschema.PointEditor.removeCorner",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
_( "Remove Corner" ), _( "Remove corner" ), delete_xpm );
|
||||||
|
|
||||||
|
|
||||||
|
// Few constants to avoid using bare numbers for point indices
|
||||||
|
enum ARC_POINTS
|
||||||
|
{
|
||||||
|
ARC_CENTER, ARC_START, ARC_END
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CIRCLE_POINTS
|
||||||
|
{
|
||||||
|
CIRC_CENTER, CIRC_END
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RECTANGLE_POINTS
|
||||||
|
{
|
||||||
|
RECT_TOPLEFT, RECT_TOPRIGHT, RECT_BOTLEFT, RECT_BOTRIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LINE_POINTS
|
||||||
|
{
|
||||||
|
LINE_START, LINE_END
|
||||||
|
};
|
||||||
|
|
||||||
|
class EDIT_POINTS_FACTORY
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<EDIT_POINTS> Make( EDA_ITEM* aItem, SCH_BASE_FRAME* frame )
|
||||||
|
{
|
||||||
|
std::shared_ptr<EDIT_POINTS> points = std::make_shared<EDIT_POINTS>( aItem );
|
||||||
|
|
||||||
|
if( !aItem )
|
||||||
|
return points;
|
||||||
|
|
||||||
|
// Generate list of edit points based on the item type
|
||||||
|
switch( aItem->Type() )
|
||||||
|
{
|
||||||
|
case LIB_ARC_T:
|
||||||
|
{
|
||||||
|
LIB_ARC* arc = (LIB_ARC*) aItem;
|
||||||
|
|
||||||
|
points->AddPoint( mapCoords( arc->GetPosition() ) );
|
||||||
|
points->AddPoint( mapCoords( arc->GetStart() ) );
|
||||||
|
points->AddPoint( mapCoords( arc->GetEnd() ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LIB_CIRCLE_T:
|
||||||
|
{
|
||||||
|
LIB_CIRCLE* circle = (LIB_CIRCLE*) aItem;
|
||||||
|
|
||||||
|
points->AddPoint( mapCoords( circle->GetPosition() ) );
|
||||||
|
points->AddPoint( mapCoords( circle->GetEnd() ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LIB_POLYLINE_T:
|
||||||
|
{
|
||||||
|
LIB_POLYLINE* lines = (LIB_POLYLINE*) aItem;
|
||||||
|
const std::vector<wxPoint>& pts = lines->GetPolyPoints();
|
||||||
|
|
||||||
|
for( wxPoint pt : pts )
|
||||||
|
points->AddPoint( mapCoords( pt ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LIB_RECTANGLE_T:
|
||||||
|
{
|
||||||
|
LIB_RECTANGLE* rect = (LIB_RECTANGLE*) aItem;
|
||||||
|
wxPoint topLeft = rect->GetPosition();
|
||||||
|
wxPoint botRight = rect->GetEnd();
|
||||||
|
|
||||||
|
points->AddPoint( mapCoords( topLeft ) );
|
||||||
|
points->AddPoint( mapCoords( botRight.x, topLeft.y ) );
|
||||||
|
points->AddPoint( mapCoords( topLeft.x, botRight.y ) );
|
||||||
|
points->AddPoint( mapCoords( botRight ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SCH_SHEET_T:
|
||||||
|
{
|
||||||
|
SCH_SHEET* sheet = (SCH_SHEET*) aItem;
|
||||||
|
wxPoint topLeft = sheet->GetPosition();
|
||||||
|
wxPoint botRight = sheet->GetPosition() + sheet->GetSize();
|
||||||
|
|
||||||
|
points->AddPoint( (wxPoint) topLeft );
|
||||||
|
points->AddPoint( wxPoint( botRight.x, topLeft.y ) );
|
||||||
|
points->AddPoint( wxPoint( topLeft.x, botRight.y ) );
|
||||||
|
points->AddPoint( (wxPoint) botRight );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SCH_LINE_T:
|
||||||
|
{
|
||||||
|
SCH_LINE* line = (SCH_LINE*) aItem;
|
||||||
|
SCH_LINE* connectedStart = nullptr;
|
||||||
|
SCH_LINE* connectedEnd = nullptr;
|
||||||
|
|
||||||
|
for( SCH_ITEM* test = frame->GetScreen()->GetDrawItems(); test; test = test->Next() )
|
||||||
|
{
|
||||||
|
if( test->Type() != SCH_LINE_T || test->GetLayer() != LAYER_NOTES )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( test == aItem )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SCH_LINE* testLine = (SCH_LINE*) test;
|
||||||
|
testLine->ClearFlags( STARTPOINT | ENDPOINT );
|
||||||
|
|
||||||
|
if( testLine->GetStartPoint() == line->GetStartPoint() )
|
||||||
|
{
|
||||||
|
connectedStart = testLine;
|
||||||
|
testLine->SetFlags( STARTPOINT );
|
||||||
|
}
|
||||||
|
else if( testLine->GetEndPoint() == line->GetStartPoint() )
|
||||||
|
{
|
||||||
|
connectedStart = testLine;
|
||||||
|
testLine->SetFlags( ENDPOINT );
|
||||||
|
}
|
||||||
|
else if( testLine->GetStartPoint() == line->GetEndPoint() )
|
||||||
|
{
|
||||||
|
connectedEnd = testLine;
|
||||||
|
testLine->SetFlags( STARTPOINT );
|
||||||
|
}
|
||||||
|
else if( testLine->GetEndPoint() == line->GetEndPoint() )
|
||||||
|
{
|
||||||
|
connectedEnd = testLine;
|
||||||
|
testLine->SetFlags( ENDPOINT );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
points->AddPoint( line->GetStartPoint(), connectedStart );
|
||||||
|
points->AddPoint( line->GetEndPoint(), connectedEnd );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
points.reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
EDIT_POINTS_FACTORY() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
POINT_EDITOR::POINT_EDITOR() :
|
||||||
|
TOOL_INTERACTIVE( "eeschema.PointEditor" ),
|
||||||
|
m_frame( nullptr ),
|
||||||
|
m_selectionTool( nullptr ),
|
||||||
|
m_editedPoint( nullptr )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::Reset( RESET_REASON aReason )
|
||||||
|
{
|
||||||
|
m_editPoints.reset();
|
||||||
|
getViewControls()->SetAutoPan( false );
|
||||||
|
m_frame = getEditFrame<SCH_BASE_FRAME>();
|
||||||
|
m_isLibEdit = dynamic_cast<LIB_EDIT_FRAME*>( m_frame ) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool POINT_EDITOR::Init()
|
||||||
|
{
|
||||||
|
m_frame = getEditFrame<SCH_BASE_FRAME>();
|
||||||
|
m_isLibEdit = dynamic_cast<LIB_EDIT_FRAME*>( m_frame ) != nullptr;
|
||||||
|
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||||
|
|
||||||
|
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
|
||||||
|
|
||||||
|
auto& menu = m_selectionTool->GetToolMenu().GetMenu();
|
||||||
|
menu.AddItem( SCH_ACTIONS::pointEditorAddCorner,
|
||||||
|
std::bind( &POINT_EDITOR::addCornerCondition, this, _1 ) );
|
||||||
|
menu.AddItem( SCH_ACTIONS::pointEditorRemoveCorner,
|
||||||
|
std::bind( &POINT_EDITOR::removeCornerCondition, this, _1 ) );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::updateEditedPoint( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
EDIT_POINT* point = m_editedPoint;
|
||||||
|
|
||||||
|
if( aEvent.IsMotion() )
|
||||||
|
{
|
||||||
|
point = m_editPoints->FindPoint( aEvent.Position(), getView() );
|
||||||
|
}
|
||||||
|
else if( aEvent.IsDrag( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
point = m_editPoints->FindPoint( aEvent.DragOrigin(), getView() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_editedPoint != point )
|
||||||
|
setEditedPoint( point );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
static KICAD_T pointTypes[] = { LIB_ARC_T, LIB_CIRCLE_T, LIB_POLYLINE_T, LIB_RECTANGLE_T,
|
||||||
|
SCH_SHEET_T, SCH_LINE_LOCATE_GRAPHIC_LINE_T, EOT };
|
||||||
|
|
||||||
|
if( !m_selectionTool )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
|
|
||||||
|
if( selection.Size() != 1 || !selection.Front()->IsType( pointTypes ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
|
||||||
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
|
KIGFX::VIEW* view = getView();
|
||||||
|
int savedToolID = m_frame->GetToolId();
|
||||||
|
wxString savedToolMsg = m_frame->GetToolMsg();
|
||||||
|
EDA_ITEM* item = (EDA_ITEM*) selection.Front();
|
||||||
|
|
||||||
|
controls->ShowCursor( true );
|
||||||
|
|
||||||
|
m_editPoints = EDIT_POINTS_FACTORY::Make( item, m_frame );
|
||||||
|
|
||||||
|
if( !m_editPoints )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
view->Add( m_editPoints.get() );
|
||||||
|
setEditedPoint( nullptr );
|
||||||
|
bool inDrag = false;
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
// Main loop: keep receiving events
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
if( !m_editPoints
|
||||||
|
|| evt->Matches( EVENTS::ClearedEvent )
|
||||||
|
|| evt->Matches( EVENTS::UnselectedEvent )
|
||||||
|
|| evt->Matches( EVENTS::SelectedEvent ) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !inDrag )
|
||||||
|
updateEditedPoint( *evt );
|
||||||
|
|
||||||
|
if( evt->IsDrag( BUT_LEFT ) && m_editedPoint )
|
||||||
|
{
|
||||||
|
m_frame->SetToolID( ID_DRAG_POINT, -1, _( "Drag Point" ) );
|
||||||
|
|
||||||
|
if( !inDrag )
|
||||||
|
{
|
||||||
|
saveItemsToUndo();
|
||||||
|
controls->ForceCursorPosition( false );
|
||||||
|
inDrag = true;
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_editedPoint->SetPosition( controls->GetCursorPosition( !evt->Modifier( MD_ALT ) ) );
|
||||||
|
|
||||||
|
updateItem();
|
||||||
|
updatePoints();
|
||||||
|
|
||||||
|
view->Redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->IsMouseUp( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
controls->SetAutoPan( false );
|
||||||
|
m_frame->SetToolID( savedToolID, -1, savedToolMsg );
|
||||||
|
|
||||||
|
inDrag = false;
|
||||||
|
|
||||||
|
m_toolMgr->PassEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->IsCancel() )
|
||||||
|
{
|
||||||
|
if( inDrag ) // Restore the last change
|
||||||
|
{
|
||||||
|
rollbackFromUndo();
|
||||||
|
modified = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_frame->SetToolID( savedToolID, -1, savedToolMsg );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_toolMgr->PassEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
controls->SetAutoPan( inDrag );
|
||||||
|
controls->CaptureCursor( inDrag );
|
||||||
|
}
|
||||||
|
|
||||||
|
controls->SetAutoPan( false );
|
||||||
|
controls->CaptureCursor( false );
|
||||||
|
m_frame->SetToolID( savedToolID, -1, savedToolMsg );
|
||||||
|
|
||||||
|
if( m_editPoints )
|
||||||
|
{
|
||||||
|
view->Remove( m_editPoints.get() );
|
||||||
|
|
||||||
|
if( modified )
|
||||||
|
m_frame->OnModify();
|
||||||
|
|
||||||
|
m_editPoints.reset();
|
||||||
|
m_frame->GetCanvas()->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pinEditedCorner( int editedPointIndex, int minWidth, int minHeight, VECTOR2I& topLeft,
|
||||||
|
VECTOR2I& topRight, VECTOR2I& botLeft, VECTOR2I& botRight )
|
||||||
|
{
|
||||||
|
switch( editedPointIndex )
|
||||||
|
{
|
||||||
|
case RECT_TOPLEFT:
|
||||||
|
// pin edited point within opposite corner
|
||||||
|
topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
|
||||||
|
topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
|
||||||
|
|
||||||
|
// push edited point edges to adjacent corners
|
||||||
|
topRight.y = topLeft.y;
|
||||||
|
botLeft.x = topLeft.x;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_TOPRIGHT:
|
||||||
|
// pin edited point within opposite corner
|
||||||
|
topRight.x = std::max( topRight.x, botLeft.x + minWidth );
|
||||||
|
topRight.y = std::min( topRight.y, botLeft.y - minHeight );
|
||||||
|
|
||||||
|
// push edited point edges to adjacent corners
|
||||||
|
topLeft.y = topRight.y;
|
||||||
|
botRight.x = topRight.x;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_BOTLEFT:
|
||||||
|
// pin edited point within opposite corner
|
||||||
|
botLeft.x = std::min( botLeft.x, topRight.x - minWidth );
|
||||||
|
botLeft.y = std::max( botLeft.y, topRight.y + minHeight );
|
||||||
|
|
||||||
|
// push edited point edges to adjacent corners
|
||||||
|
botRight.y = botLeft.y;
|
||||||
|
topLeft.x = botLeft.x;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_BOTRIGHT:
|
||||||
|
// pin edited point within opposite corner
|
||||||
|
botRight.x = std::max( botRight.x, topLeft.x + minWidth );
|
||||||
|
botRight.y = std::max( botRight.y, topLeft.y + minHeight );
|
||||||
|
|
||||||
|
// push edited point edges to adjacent corners
|
||||||
|
botLeft.y = botRight.y;
|
||||||
|
topRight.x = botRight.x;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::updateItem() const
|
||||||
|
{
|
||||||
|
EDA_ITEM* item = m_editPoints->GetParent();
|
||||||
|
|
||||||
|
if( !item )
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch( item->Type() )
|
||||||
|
{
|
||||||
|
case LIB_ARC_T:
|
||||||
|
{
|
||||||
|
LIB_ARC* arc = (LIB_ARC*) item;
|
||||||
|
|
||||||
|
arc->SetPosition( mapCoords( m_editPoints->Point( ARC_CENTER ).GetPosition() ) );
|
||||||
|
arc->SetStart( mapCoords( m_editPoints->Point( ARC_START ).GetPosition() ) );
|
||||||
|
arc->SetEnd( mapCoords( m_editPoints->Point( ARC_END ).GetPosition() ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LIB_CIRCLE_T:
|
||||||
|
{
|
||||||
|
LIB_CIRCLE* circle = (LIB_CIRCLE*) item;
|
||||||
|
|
||||||
|
circle->SetPosition( mapCoords( m_editPoints->Point( CIRC_CENTER ).GetPosition() ) );
|
||||||
|
circle->SetEnd( mapCoords( m_editPoints->Point( CIRC_END ).GetPosition() ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LIB_POLYLINE_T:
|
||||||
|
{
|
||||||
|
LIB_POLYLINE* lines = (LIB_POLYLINE*) item;
|
||||||
|
|
||||||
|
lines->ClearPoints();
|
||||||
|
|
||||||
|
for( int i = 0; i < m_editPoints->PointsSize(); ++i )
|
||||||
|
lines->AddPoint( mapCoords( m_editPoints->Point( i ).GetPosition() ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LIB_RECTANGLE_T:
|
||||||
|
{
|
||||||
|
LIB_RECTANGLE* rect = (LIB_RECTANGLE*) item;
|
||||||
|
VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
|
||||||
|
VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
|
||||||
|
VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
|
||||||
|
VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
|
||||||
|
|
||||||
|
pinEditedCorner( getEditedPointIndex(), Mils2iu( 1 ), Mils2iu( 1 ),
|
||||||
|
topLeft, topRight, botLeft, botRight );
|
||||||
|
|
||||||
|
rect->SetPosition( (wxPoint) topLeft );
|
||||||
|
rect->SetEnd( (wxPoint) botRight );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCH_SHEET_T:
|
||||||
|
{
|
||||||
|
SCH_SHEET* sheet = (SCH_SHEET*) item;
|
||||||
|
VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
|
||||||
|
VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
|
||||||
|
VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
|
||||||
|
VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
|
||||||
|
|
||||||
|
pinEditedCorner( getEditedPointIndex(), sheet->GetMinWidth(), sheet->GetMinHeight(),
|
||||||
|
topLeft, topRight, botLeft, botRight );
|
||||||
|
|
||||||
|
sheet->SetPosition( (wxPoint) topLeft );
|
||||||
|
sheet->SetSize( wxSize( botRight.x - topLeft.x, botRight.y - topLeft.y ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCH_LINE_T:
|
||||||
|
{
|
||||||
|
SCH_LINE* line = (SCH_LINE*) item;
|
||||||
|
|
||||||
|
line->SetStartPoint( (wxPoint) m_editPoints->Point( LINE_START ).GetPosition() );
|
||||||
|
line->SetEndPoint( (wxPoint) m_editPoints->Point( LINE_END ).GetPosition() );
|
||||||
|
|
||||||
|
SCH_LINE* connection = (SCH_LINE*) ( m_editPoints->Point( LINE_START ).GetConnection() );
|
||||||
|
|
||||||
|
if( connection )
|
||||||
|
{
|
||||||
|
if( ( connection->GetFlags() & STARTPOINT ) != 0 )
|
||||||
|
connection->SetStartPoint( line->GetPosition() );
|
||||||
|
else if( ( connection->GetFlags() & ENDPOINT ) != 0 )
|
||||||
|
connection->SetEndPoint( line->GetPosition() );
|
||||||
|
|
||||||
|
getView()->Update( connection, KIGFX::GEOMETRY );
|
||||||
|
}
|
||||||
|
|
||||||
|
connection = (SCH_LINE*) ( m_editPoints->Point( LINE_END ).GetConnection() );
|
||||||
|
|
||||||
|
if( connection )
|
||||||
|
{
|
||||||
|
if( ( connection->GetFlags() & STARTPOINT ) != 0 )
|
||||||
|
connection->SetStartPoint( line->GetEndPoint() );
|
||||||
|
else if( ( connection->GetFlags() & ENDPOINT ) != 0 )
|
||||||
|
connection->SetEndPoint( line->GetEndPoint() );
|
||||||
|
|
||||||
|
getView()->Update( connection, KIGFX::GEOMETRY );
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
getView()->Update( item, KIGFX::GEOMETRY );
|
||||||
|
m_frame->SetMsgPanel( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::updatePoints()
|
||||||
|
{
|
||||||
|
if( !m_editPoints )
|
||||||
|
return;
|
||||||
|
|
||||||
|
EDA_ITEM* item = m_editPoints->GetParent();
|
||||||
|
|
||||||
|
if( !item )
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch( item->Type() )
|
||||||
|
{
|
||||||
|
case LIB_ARC_T:
|
||||||
|
{
|
||||||
|
LIB_ARC* arc = (LIB_ARC*) item;
|
||||||
|
|
||||||
|
m_editPoints->Point( ARC_CENTER ).SetPosition( mapCoords( arc->GetPosition() ) );
|
||||||
|
m_editPoints->Point( ARC_START ).SetPosition( mapCoords( arc->GetStart() ) );
|
||||||
|
m_editPoints->Point( ARC_END ).SetPosition( mapCoords( arc->GetEnd() ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LIB_CIRCLE_T:
|
||||||
|
{
|
||||||
|
LIB_CIRCLE* circle = (LIB_CIRCLE*) item;
|
||||||
|
|
||||||
|
m_editPoints->Point( CIRC_CENTER ).SetPosition( mapCoords( circle->GetPosition() ) );
|
||||||
|
m_editPoints->Point( CIRC_END ).SetPosition( mapCoords( circle->GetEnd() ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LIB_POLYLINE_T:
|
||||||
|
{
|
||||||
|
LIB_POLYLINE* lines = (LIB_POLYLINE*) item;
|
||||||
|
const std::vector<wxPoint>& pts = lines->GetPolyPoints();
|
||||||
|
|
||||||
|
if( m_editPoints->PointsSize() != (unsigned) pts.size() )
|
||||||
|
{
|
||||||
|
getView()->Remove( m_editPoints.get() );
|
||||||
|
m_editedPoint = nullptr;
|
||||||
|
m_editPoints = EDIT_POINTS_FACTORY::Make( item, m_frame );
|
||||||
|
getView()->Add(m_editPoints.get() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( unsigned i = 0; i < pts.size(); i++ )
|
||||||
|
m_editPoints->Point( i ).SetPosition( mapCoords( pts[i] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LIB_RECTANGLE_T:
|
||||||
|
{
|
||||||
|
LIB_RECTANGLE* rect = (LIB_RECTANGLE*) item;
|
||||||
|
wxPoint topLeft = rect->GetPosition();
|
||||||
|
wxPoint botRight = rect->GetEnd();
|
||||||
|
|
||||||
|
m_editPoints->Point( RECT_TOPLEFT ).SetPosition( mapCoords( topLeft ) );
|
||||||
|
m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( mapCoords( botRight.x, topLeft.y ) );
|
||||||
|
m_editPoints->Point( RECT_BOTLEFT ).SetPosition( mapCoords( topLeft.x, botRight.y ) );
|
||||||
|
m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( mapCoords( botRight ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCH_SHEET_T:
|
||||||
|
{
|
||||||
|
SCH_SHEET* sheet = (SCH_SHEET*) item;
|
||||||
|
wxPoint topLeft = sheet->GetPosition();
|
||||||
|
wxPoint botRight = sheet->GetPosition() + sheet->GetSize();
|
||||||
|
|
||||||
|
m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft );
|
||||||
|
m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( botRight.x, topLeft.y );
|
||||||
|
m_editPoints->Point( RECT_BOTLEFT ).SetPosition( topLeft.x, botRight.y );
|
||||||
|
m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCH_LINE_T:
|
||||||
|
{
|
||||||
|
SCH_LINE* line = (SCH_LINE*) item;
|
||||||
|
|
||||||
|
m_editPoints->Point( LINE_START ).SetPosition( line->GetStartPoint() );
|
||||||
|
m_editPoints->Point( LINE_END ).SetPosition( line->GetEndPoint() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
getView()->Update( m_editPoints.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::setEditedPoint( EDIT_POINT* aPoint )
|
||||||
|
{
|
||||||
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
|
|
||||||
|
if( aPoint )
|
||||||
|
{
|
||||||
|
controls->ForceCursorPosition( true, aPoint->GetPosition() );
|
||||||
|
controls->ShowCursor( true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controls->ShowCursor( false );
|
||||||
|
controls->ForceCursorPosition( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_editedPoint = aPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool POINT_EDITOR::removeCornerCondition( const SELECTION& )
|
||||||
|
{
|
||||||
|
if( !m_editPoints || !m_editedPoint )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LIB_POLYLINE* polyLine = dynamic_cast<LIB_POLYLINE*>( m_editPoints->GetParent() );
|
||||||
|
|
||||||
|
if( !polyLine || polyLine->GetCornerCount() < 3 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const std::vector<wxPoint>& pts = polyLine->GetPolyPoints();
|
||||||
|
|
||||||
|
for( int i = 0; i < polyLine->GetCornerCount(); ++i )
|
||||||
|
{
|
||||||
|
if( pts[i] == mapCoords( m_editedPoint->GetPosition() ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool POINT_EDITOR::addCornerCondition( const SELECTION& )
|
||||||
|
{
|
||||||
|
if( !m_editPoints || !m_editedPoint )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LIB_POLYLINE* polyLine = dynamic_cast<LIB_POLYLINE*>( m_editPoints->GetParent() );
|
||||||
|
|
||||||
|
if( !polyLine )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
|
||||||
|
double threshold = getView()->ToWorld( EDIT_POINT::POINT_SIZE );
|
||||||
|
|
||||||
|
return polyLine->HitTest( mapCoords( cursorPos ), (int) threshold );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
if( !m_editPoints )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
LIB_POLYLINE* polyLine = dynamic_cast<LIB_POLYLINE*>( m_editPoints->GetParent() );
|
||||||
|
|
||||||
|
if( !polyLine )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) );
|
||||||
|
polyLine->AddCorner( mapCoords( cursorPos ) );
|
||||||
|
|
||||||
|
m_frame->RefreshItem( polyLine );
|
||||||
|
updatePoints();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int POINT_EDITOR::removeCorner( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
if( !m_editPoints || !m_editedPoint )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
LIB_POLYLINE* polyLine = dynamic_cast<LIB_POLYLINE*>( m_editPoints->GetParent() );
|
||||||
|
|
||||||
|
if( !polyLine || polyLine->GetCornerCount() < 3 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
polyLine->RemoveCorner( getEditedPointIndex() );
|
||||||
|
|
||||||
|
m_frame->RefreshItem( polyLine );
|
||||||
|
updatePoints();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int POINT_EDITOR::modifiedSelection( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
updatePoints();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::saveItemsToUndo()
|
||||||
|
{
|
||||||
|
if( m_isLibEdit )
|
||||||
|
{
|
||||||
|
LIB_EDIT_FRAME* editFrame = static_cast<LIB_EDIT_FRAME*>( m_frame );
|
||||||
|
editFrame->SaveCopyInUndoList( m_editPoints->GetParent()->GetParent() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCH_EDIT_FRAME* editFrame = static_cast<SCH_EDIT_FRAME*>( m_frame );
|
||||||
|
editFrame->SaveCopyInUndoList( (SCH_ITEM*) m_editPoints->GetParent(), UR_CHANGED );
|
||||||
|
|
||||||
|
if( m_editPoints->GetParent()->Type() == SCH_LINE_T )
|
||||||
|
{
|
||||||
|
EDA_ITEM* connection = m_editPoints->Point( LINE_START ).GetConnection();
|
||||||
|
|
||||||
|
if( connection )
|
||||||
|
editFrame->SaveCopyInUndoList( (SCH_ITEM*) connection, UR_CHANGED, true );
|
||||||
|
|
||||||
|
connection = m_editPoints->Point( LINE_END ).GetConnection();
|
||||||
|
|
||||||
|
if( connection )
|
||||||
|
editFrame->SaveCopyInUndoList( (SCH_ITEM*) connection, UR_CHANGED, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::rollbackFromUndo()
|
||||||
|
{
|
||||||
|
if( m_isLibEdit )
|
||||||
|
static_cast<LIB_EDIT_FRAME*>( m_frame )->RollbackPartFromUndo();
|
||||||
|
else
|
||||||
|
static_cast<SCH_EDIT_FRAME*>( m_frame )->RollbackSchematicFromUndo();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::setTransitions()
|
||||||
|
{
|
||||||
|
Go( &POINT_EDITOR::addCorner, SCH_ACTIONS::pointEditorAddCorner.MakeEvent() );
|
||||||
|
Go( &POINT_EDITOR::removeCorner, SCH_ACTIONS::pointEditorRemoveCorner.MakeEvent() );
|
||||||
|
Go( &POINT_EDITOR::modifiedSelection, EVENTS::SelectedItemsModified );
|
||||||
|
Go( &POINT_EDITOR::Main, EVENTS::SelectedEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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 SCH_POINT_EDITOR_H
|
||||||
|
#define SCH_POINT_EDITOR_H
|
||||||
|
|
||||||
|
#include <tool/tool_interactive.h>
|
||||||
|
#include <tool/edit_points.h>
|
||||||
|
#include <tool/selection.h>
|
||||||
|
|
||||||
|
class SCH_SELECTION_TOOL;
|
||||||
|
class SCH_BASE_FRAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SCH_POINT_EDITOR
|
||||||
|
*
|
||||||
|
* Tool that displays edit points allowing to modify items by dragging the points.
|
||||||
|
*/
|
||||||
|
class POINT_EDITOR : public TOOL_INTERACTIVE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
POINT_EDITOR();
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Reset()
|
||||||
|
void Reset( RESET_REASON aReason ) override;
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||||
|
bool Init() override;
|
||||||
|
|
||||||
|
int Main( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Sets up handlers for various events.
|
||||||
|
void setTransitions() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
///> Updates item's points with edit points.
|
||||||
|
void updateItem() const;
|
||||||
|
|
||||||
|
///> Updates edit points with item's points.
|
||||||
|
void updatePoints();
|
||||||
|
|
||||||
|
///> Updates which point is being edited.
|
||||||
|
void updateEditedPoint( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
///> Sets the current point being edited. NULL means none.
|
||||||
|
void setEditedPoint( EDIT_POINT* aPoint );
|
||||||
|
|
||||||
|
///> Returns true if aPoint is the currently modified point.
|
||||||
|
inline bool isModified( const EDIT_POINT& aPoint ) const
|
||||||
|
{
|
||||||
|
return m_editedPoint == &aPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int getEditedPointIndex() const
|
||||||
|
{
|
||||||
|
for( int i = 0; i < m_editPoints->PointsSize(); ++i )
|
||||||
|
{
|
||||||
|
if( m_editedPoint == &m_editPoints->Point( i ) )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool addCornerCondition( const SELECTION& aSelection );
|
||||||
|
bool removeCornerCondition( const SELECTION& aSelection );
|
||||||
|
|
||||||
|
/// TOOL_ACTION handlers
|
||||||
|
int addCorner( const TOOL_EVENT& aEvent );
|
||||||
|
int removeCorner( const TOOL_EVENT& aEvent );
|
||||||
|
int modifiedSelection( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
void saveItemsToUndo();
|
||||||
|
void rollbackFromUndo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SCH_BASE_FRAME* m_frame;
|
||||||
|
SCH_SELECTION_TOOL* m_selectionTool;
|
||||||
|
bool m_isLibEdit;
|
||||||
|
|
||||||
|
///> Currently edited point, NULL if there is none.
|
||||||
|
EDIT_POINT* m_editedPoint;
|
||||||
|
|
||||||
|
///> Currently available edit points.
|
||||||
|
std::shared_ptr<EDIT_POINTS> m_editPoints;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SCH_POINT_EDITOR_H
|
|
@ -234,6 +234,9 @@ OPT<TOOL_EVENT> SCH_ACTIONS::TranslateLegacyId( int aId )
|
||||||
|
|
||||||
case ID_LIBEDIT_BODY_RECT_BUTT:
|
case ID_LIBEDIT_BODY_RECT_BUTT:
|
||||||
return SCH_ACTIONS::drawSymbolRectangle.MakeEvent();
|
return SCH_ACTIONS::drawSymbolRectangle.MakeEvent();
|
||||||
|
|
||||||
|
case ID_LIBEDIT_DELETE_ITEM_BUTT:
|
||||||
|
return SCH_ACTIONS::deleteItemCursor.MakeEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
return OPT<TOOL_EVENT>();
|
return OPT<TOOL_EVENT>();
|
||||||
|
|
|
@ -90,7 +90,6 @@ public:
|
||||||
static TOOL_ACTION placeGlobalLabel;
|
static TOOL_ACTION placeGlobalLabel;
|
||||||
static TOOL_ACTION placeHierarchicalLabel;
|
static TOOL_ACTION placeHierarchicalLabel;
|
||||||
static TOOL_ACTION drawSheet;
|
static TOOL_ACTION drawSheet;
|
||||||
static TOOL_ACTION resizeSheet;
|
|
||||||
static TOOL_ACTION placeSheetPin;
|
static TOOL_ACTION placeSheetPin;
|
||||||
static TOOL_ACTION importSheetPin;
|
static TOOL_ACTION importSheetPin;
|
||||||
static TOOL_ACTION placeSchematicText;
|
static TOOL_ACTION placeSchematicText;
|
||||||
|
@ -142,6 +141,8 @@ public:
|
||||||
static TOOL_ACTION toText;
|
static TOOL_ACTION toText;
|
||||||
static TOOL_ACTION breakWire;
|
static TOOL_ACTION breakWire;
|
||||||
static TOOL_ACTION breakBus;
|
static TOOL_ACTION breakBus;
|
||||||
|
static TOOL_ACTION pointEditorAddCorner;
|
||||||
|
static TOOL_ACTION pointEditorRemoveCorner;
|
||||||
|
|
||||||
/// Inspection
|
/// Inspection
|
||||||
static TOOL_ACTION showDatasheet;
|
static TOOL_ACTION showDatasheet;
|
||||||
|
@ -163,6 +164,9 @@ public:
|
||||||
static TOOL_ACTION deleteItemCursor;
|
static TOOL_ACTION deleteItemCursor;
|
||||||
static TOOL_ACTION refreshPreview;
|
static TOOL_ACTION refreshPreview;
|
||||||
static TOOL_ACTION explicitCrossProbe;
|
static TOOL_ACTION explicitCrossProbe;
|
||||||
|
static TOOL_ACTION pushPinLength;
|
||||||
|
static TOOL_ACTION pushPinNameSize;
|
||||||
|
static TOOL_ACTION pushPinNumSize;
|
||||||
|
|
||||||
// SPICE
|
// SPICE
|
||||||
static TOOL_ACTION simProbe;
|
static TOOL_ACTION simProbe;
|
||||||
|
@ -178,4 +182,26 @@ public:
|
||||||
virtual OPT<TOOL_EVENT> TranslateLegacyId( int aId ) override;
|
virtual OPT<TOOL_EVENT> TranslateLegacyId( int aId ) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// For LibEdit
|
||||||
|
//
|
||||||
|
inline VECTOR2I mapCoords( const wxPoint& aCoord )
|
||||||
|
{
|
||||||
|
return VECTOR2I( aCoord.x, -aCoord.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline wxPoint mapCoords( const VECTOR2I& aCoord )
|
||||||
|
{
|
||||||
|
return wxPoint( aCoord.x, -aCoord.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline wxPoint mapCoords( const int x, const int y )
|
||||||
|
{
|
||||||
|
return wxPoint( x, -y );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -93,10 +93,6 @@ TOOL_ACTION SCH_ACTIONS::drawSheet( "eeschema.InteractiveDrawing.drawSheet",
|
||||||
_( "Add Sheet" ), _( "Add a hierarchical sheet" ),
|
_( "Add Sheet" ), _( "Add a hierarchical sheet" ),
|
||||||
add_hierarchical_subsheet_xpm, AF_ACTIVATE );
|
add_hierarchical_subsheet_xpm, AF_ACTIVATE );
|
||||||
|
|
||||||
TOOL_ACTION SCH_ACTIONS::resizeSheet( "eeschema.InteractiveDrawing.resizeSheet",
|
|
||||||
AS_GLOBAL, 0, _( "Resize Sheet" ), _( "Resize hierarchical sheet" ),
|
|
||||||
resize_sheet_xpm );
|
|
||||||
|
|
||||||
TOOL_ACTION SCH_ACTIONS::placeSheetPin( "eeschema.InteractiveDrawing.placeSheetPin",
|
TOOL_ACTION SCH_ACTIONS::placeSheetPin( "eeschema.InteractiveDrawing.placeSheetPin",
|
||||||
AS_GLOBAL, 0, _( "Add Sheet Pin" ), _( "Add a sheet pin" ),
|
AS_GLOBAL, 0, _( "Add Sheet Pin" ), _( "Add a sheet pin" ),
|
||||||
add_hierar_pin_xpm, AF_ACTIVATE );
|
add_hierar_pin_xpm, AF_ACTIVATE );
|
||||||
|
@ -767,43 +763,10 @@ int SCH_DRAWING_TOOLS::doTwoClickPlace( KICAD_T aType )
|
||||||
int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
m_frame->SetToolID( ID_SHEET_SYMBOL_BUTT, wxCURSOR_PENCIL, _( "Add sheet" ) );
|
m_frame->SetToolID( ID_SHEET_SYMBOL_BUTT, wxCURSOR_PENCIL, _( "Add sheet" ) );
|
||||||
return doDrawSheet( nullptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SCH_DRAWING_TOOLS::ResizeSheet( const TOOL_EVENT& aEvent )
|
|
||||||
{
|
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection( SCH_COLLECTOR::SheetsOnly );
|
|
||||||
|
|
||||||
if( !selection.Empty() )
|
|
||||||
{
|
|
||||||
SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
|
|
||||||
|
|
||||||
m_frame->SetToolID( ID_SCH_RESIZE_SHEET, wxCURSOR_PENCIL, _( "Resize sheet" ) );
|
|
||||||
doDrawSheet( sheet );
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SCH_DRAWING_TOOLS::doDrawSheet( SCH_SHEET *aSheet )
|
|
||||||
{
|
|
||||||
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
m_controls->ShowCursor( true );
|
m_controls->ShowCursor( true );
|
||||||
|
|
||||||
if( aSheet )
|
SCH_SHEET* sheet = nullptr;
|
||||||
{
|
|
||||||
m_frame->SaveCopyInUndoList( aSheet, UR_CHANGED );
|
|
||||||
aSheet->SetFlags( IS_RESIZED );
|
|
||||||
|
|
||||||
m_selectionTool->AddItemToSel( aSheet, true /*quiet mode; should already be selected*/ );
|
|
||||||
m_view->Hide( aSheet );
|
|
||||||
m_view->AddToPreview( aSheet->Clone() );
|
|
||||||
|
|
||||||
m_controls->SetCursorPosition( aSheet->GetResizePosition() );
|
|
||||||
m_controls->SetCrossHairCursorPosition( m_controls->GetCursorPosition() );
|
|
||||||
}
|
|
||||||
|
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
|
@ -817,15 +780,10 @@ int SCH_DRAWING_TOOLS::doDrawSheet( SCH_SHEET *aSheet )
|
||||||
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
|
||||||
m_view->ClearPreview();
|
m_view->ClearPreview();
|
||||||
|
|
||||||
if( m_frame->GetToolId() == ID_SCH_RESIZE_SHEET )
|
if( sheet )
|
||||||
{
|
{
|
||||||
m_frame->RollbackSchematicFromUndo();
|
delete sheet;
|
||||||
// resize sheet is a single-shot command, when we're done we're done
|
sheet = nullptr;
|
||||||
}
|
|
||||||
else if( aSheet )
|
|
||||||
{
|
|
||||||
delete aSheet;
|
|
||||||
aSheet = nullptr;
|
|
||||||
|
|
||||||
if( !evt->IsActivate() )
|
if( !evt->IsActivate() )
|
||||||
continue;
|
continue;
|
||||||
|
@ -834,67 +792,55 @@ int SCH_DRAWING_TOOLS::doDrawSheet( SCH_SHEET *aSheet )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( evt->IsClick( BUT_LEFT ) && !aSheet )
|
else if( evt->IsClick( BUT_LEFT ) && !sheet )
|
||||||
{
|
{
|
||||||
aSheet = new SCH_SHEET( (wxPoint) cursorPos );
|
sheet = new SCH_SHEET( (wxPoint) cursorPos );
|
||||||
aSheet->SetFlags( IS_NEW | IS_RESIZED );
|
sheet->SetFlags( IS_NEW | IS_RESIZED );
|
||||||
aSheet->SetTimeStamp( GetNewTimeStamp() );
|
sheet->SetTimeStamp( GetNewTimeStamp() );
|
||||||
aSheet->SetParent( m_frame->GetScreen() );
|
sheet->SetParent( m_frame->GetScreen() );
|
||||||
aSheet->SetScreen( NULL );
|
sheet->SetScreen( NULL );
|
||||||
sizeSheet( aSheet, cursorPos );
|
sizeSheet( sheet, cursorPos );
|
||||||
|
|
||||||
m_frame->SetRepeatItem( nullptr );
|
m_frame->SetRepeatItem( nullptr );
|
||||||
|
|
||||||
m_selectionTool->AddItemToSel( aSheet );
|
m_selectionTool->AddItemToSel( sheet );
|
||||||
m_view->ClearPreview();
|
m_view->ClearPreview();
|
||||||
m_view->AddToPreview( aSheet->Clone() );
|
m_view->AddToPreview( sheet->Clone() );
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( aSheet && ( evt->IsClick( BUT_LEFT )
|
else if( sheet && ( evt->IsClick( BUT_LEFT )
|
||||||
|| evt->IsAction( &SCH_ACTIONS::finishSheet ) ) )
|
|| evt->IsAction( &SCH_ACTIONS::finishSheet ) ) )
|
||||||
{
|
{
|
||||||
m_view->ClearPreview();
|
m_view->ClearPreview();
|
||||||
|
|
||||||
if( aSheet->IsNew() )
|
if( m_frame->EditSheet( (SCH_SHEET*)sheet, g_CurrentSheet, nullptr ) )
|
||||||
{
|
m_frame->AddItemToScreenAndUndoList( sheet );
|
||||||
if( m_frame->EditSheet( (SCH_SHEET*)aSheet, g_CurrentSheet, nullptr ) )
|
|
||||||
m_frame->AddItemToScreenAndUndoList( aSheet );
|
|
||||||
else
|
|
||||||
delete aSheet;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
delete sheet;
|
||||||
m_view->Hide( aSheet, false );
|
|
||||||
m_frame->RefreshItem( aSheet );
|
|
||||||
m_frame->OnModify();
|
|
||||||
}
|
|
||||||
|
|
||||||
aSheet = nullptr;
|
sheet = nullptr;
|
||||||
|
|
||||||
if( m_frame->GetToolId() == ID_SCH_RESIZE_SHEET )
|
|
||||||
break; // resize sheet is a single-shot command; when we're done we're done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( aSheet && ( evt->IsAction( &SCH_ACTIONS::refreshPreview )
|
else if( sheet && ( evt->IsAction( &SCH_ACTIONS::refreshPreview )
|
||||||
|| evt->IsMotion() ) )
|
|| evt->IsMotion() ) )
|
||||||
{
|
{
|
||||||
sizeSheet( aSheet, cursorPos );
|
sizeSheet( sheet, cursorPos );
|
||||||
m_view->ClearPreview();
|
m_view->ClearPreview();
|
||||||
m_view->AddToPreview( aSheet->Clone() );
|
m_view->AddToPreview( sheet->Clone() );
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( evt->IsClick( BUT_RIGHT ) )
|
else if( evt->IsClick( BUT_RIGHT ) )
|
||||||
{
|
{
|
||||||
// Warp after context menu only if dragging...
|
// Warp after context menu only if dragging...
|
||||||
if( !aSheet )
|
if( !sheet )
|
||||||
m_toolMgr->VetoContextMenuMouseWarp();
|
m_toolMgr->VetoContextMenuMouseWarp();
|
||||||
|
|
||||||
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
|
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable autopanning and cursor capture only when there is a sheet to be placed
|
// Enable autopanning and cursor capture only when there is a sheet to be placed
|
||||||
m_controls->SetAutoPan( !!aSheet );
|
m_controls->SetAutoPan( !!sheet );
|
||||||
m_controls->CaptureCursor( !!aSheet );
|
m_controls->CaptureCursor( !!sheet );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_frame->SetNoToolSelected();
|
m_frame->SetNoToolSelected();
|
||||||
|
@ -908,20 +854,9 @@ void SCH_DRAWING_TOOLS::sizeSheet( SCH_SHEET* aSheet, VECTOR2I aPos )
|
||||||
wxPoint pos = aSheet->GetPosition();
|
wxPoint pos = aSheet->GetPosition();
|
||||||
wxPoint size = (wxPoint) aPos - pos;
|
wxPoint size = (wxPoint) aPos - pos;
|
||||||
|
|
||||||
// If the sheet doesn't have any pins, clamp the minimum size to the defaults.
|
|
||||||
size.x = std::max( size.x, MIN_SHEET_WIDTH );
|
size.x = std::max( size.x, MIN_SHEET_WIDTH );
|
||||||
size.y = std::max( size.y, MIN_SHEET_HEIGHT );
|
size.y = std::max( size.y, MIN_SHEET_HEIGHT );
|
||||||
|
|
||||||
if( aSheet->HasPins() )
|
|
||||||
{
|
|
||||||
int gridSizeX = KiROUND( m_frame->GetScreen()->GetGridSize().x );
|
|
||||||
int gridSizeY = KiROUND( m_frame->GetScreen()->GetGridSize().y );
|
|
||||||
|
|
||||||
// Use the pin positions to clamp the minimum width and height.
|
|
||||||
size.x = std::max( size.x, aSheet->GetMinWidth() + gridSizeX );
|
|
||||||
size.y = std::max( size.y, aSheet->GetMinHeight() + gridSizeY );
|
|
||||||
}
|
|
||||||
|
|
||||||
wxPoint grid = m_frame->GetNearestGridPosition( pos + size );
|
wxPoint grid = m_frame->GetNearestGridPosition( pos + size );
|
||||||
aSheet->Resize( wxSize( grid.x - pos.x, grid.y - pos.y ) );
|
aSheet->Resize( wxSize( grid.x - pos.x, grid.y - pos.y ) );
|
||||||
}
|
}
|
||||||
|
@ -939,7 +874,6 @@ void SCH_DRAWING_TOOLS::setTransitions()
|
||||||
Go( &SCH_DRAWING_TOOLS::PlaceHierarchicalLabel,SCH_ACTIONS::placeHierarchicalLabel.MakeEvent() );
|
Go( &SCH_DRAWING_TOOLS::PlaceHierarchicalLabel,SCH_ACTIONS::placeHierarchicalLabel.MakeEvent() );
|
||||||
Go( &SCH_DRAWING_TOOLS::PlaceGlobalLabel, SCH_ACTIONS::placeGlobalLabel.MakeEvent() );
|
Go( &SCH_DRAWING_TOOLS::PlaceGlobalLabel, SCH_ACTIONS::placeGlobalLabel.MakeEvent() );
|
||||||
Go( &SCH_DRAWING_TOOLS::DrawSheet, SCH_ACTIONS::drawSheet.MakeEvent() );
|
Go( &SCH_DRAWING_TOOLS::DrawSheet, SCH_ACTIONS::drawSheet.MakeEvent() );
|
||||||
Go( &SCH_DRAWING_TOOLS::ResizeSheet, SCH_ACTIONS::resizeSheet.MakeEvent() );
|
|
||||||
Go( &SCH_DRAWING_TOOLS::PlaceSheetPin, SCH_ACTIONS::placeSheetPin.MakeEvent() );
|
Go( &SCH_DRAWING_TOOLS::PlaceSheetPin, SCH_ACTIONS::placeSheetPin.MakeEvent() );
|
||||||
Go( &SCH_DRAWING_TOOLS::ImportSheetPin, SCH_ACTIONS::importSheetPin.MakeEvent() );
|
Go( &SCH_DRAWING_TOOLS::ImportSheetPin, SCH_ACTIONS::importSheetPin.MakeEvent() );
|
||||||
Go( &SCH_DRAWING_TOOLS::PlaceSchematicText, SCH_ACTIONS::placeSchematicText.MakeEvent() );
|
Go( &SCH_DRAWING_TOOLS::PlaceSchematicText, SCH_ACTIONS::placeSchematicText.MakeEvent() );
|
||||||
|
|
|
@ -72,7 +72,6 @@ public:
|
||||||
int PlaceGlobalLabel( const TOOL_EVENT& aEvent );
|
int PlaceGlobalLabel( const TOOL_EVENT& aEvent );
|
||||||
int PlaceHierarchicalLabel( const TOOL_EVENT& aEvent );
|
int PlaceHierarchicalLabel( const TOOL_EVENT& aEvent );
|
||||||
int DrawSheet( const TOOL_EVENT& aEvent );
|
int DrawSheet( const TOOL_EVENT& aEvent );
|
||||||
int ResizeSheet( const TOOL_EVENT& aEvent );
|
|
||||||
int PlaceSheetPin( const TOOL_EVENT& aEvent );
|
int PlaceSheetPin( const TOOL_EVENT& aEvent );
|
||||||
int ImportSheetPin( const TOOL_EVENT& aEvent );
|
int ImportSheetPin( const TOOL_EVENT& aEvent );
|
||||||
int PlaceSchematicText( const TOOL_EVENT& aEvent );
|
int PlaceSchematicText( const TOOL_EVENT& aEvent );
|
||||||
|
@ -87,7 +86,6 @@ private:
|
||||||
|
|
||||||
int doTwoClickPlace( KICAD_T aType );
|
int doTwoClickPlace( KICAD_T aType );
|
||||||
|
|
||||||
int doDrawSheet( SCH_SHEET* aSheet );
|
|
||||||
void sizeSheet( SCH_SHEET* aSheet, VECTOR2I aPos );
|
void sizeSheet( SCH_SHEET* aSheet, VECTOR2I aPos );
|
||||||
|
|
||||||
///> Sets up handlers for various events.
|
///> Sets up handlers for various events.
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <tools/sch_edit_tool.h>
|
#include <tools/sch_edit_tool.h>
|
||||||
#include <tools/sch_selection_tool.h>
|
#include <tools/sch_selection_tool.h>
|
||||||
#include <tools/sch_wire_bus_tool.h>
|
#include <tools/sch_wire_bus_tool.h>
|
||||||
#include <tools/sch_picker_tool.h>
|
#include <tools/picker_tool.h>
|
||||||
#include <tools/sch_move_tool.h>
|
#include <tools/sch_move_tool.h>
|
||||||
#include <sch_actions.h>
|
#include <sch_actions.h>
|
||||||
#include <hotkeys.h>
|
#include <hotkeys.h>
|
||||||
|
@ -242,11 +242,11 @@ bool SCH_EDIT_TOOL::Init()
|
||||||
{
|
{
|
||||||
m_frame = getEditFrame<SCH_EDIT_FRAME>();
|
m_frame = getEditFrame<SCH_EDIT_FRAME>();
|
||||||
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||||
SCH_DRAWING_TOOLS* drawingTool = m_toolMgr->GetTool<SCH_DRAWING_TOOLS>();
|
SCH_DRAWING_TOOLS* drawingTools = m_toolMgr->GetTool<SCH_DRAWING_TOOLS>();
|
||||||
SCH_MOVE_TOOL* moveTool = m_toolMgr->GetTool<SCH_MOVE_TOOL>();
|
SCH_MOVE_TOOL* moveTool = m_toolMgr->GetTool<SCH_MOVE_TOOL>();
|
||||||
|
|
||||||
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
|
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
|
||||||
wxASSERT_MSG( drawingTool, "eeshema.InteractiveDrawing tool is not available" );
|
wxASSERT_MSG( drawingTools, "eeshema.InteractiveDrawing tool is not available" );
|
||||||
|
|
||||||
auto sheetTool = [ this ] ( const SELECTION& aSel ) {
|
auto sheetTool = [ this ] ( const SELECTION& aSel ) {
|
||||||
return ( m_frame->GetToolId() == ID_SHEET_SYMBOL_BUTT );
|
return ( m_frame->GetToolId() == ID_SHEET_SYMBOL_BUTT );
|
||||||
|
@ -380,7 +380,7 @@ bool SCH_EDIT_TOOL::Init()
|
||||||
//
|
//
|
||||||
// Add editing actions to the drawing tool menu
|
// Add editing actions to the drawing tool menu
|
||||||
//
|
//
|
||||||
CONDITIONAL_MENU& drawMenu = drawingTool->GetToolMenu().GetMenu();
|
CONDITIONAL_MENU& drawMenu = drawingTools->GetToolMenu().GetMenu();
|
||||||
|
|
||||||
drawMenu.AddSeparator( SCH_CONDITIONS::NotEmpty, 200 );
|
drawMenu.AddSeparator( SCH_CONDITIONS::NotEmpty, 200 );
|
||||||
drawMenu.AddItem( SCH_ACTIONS::rotateCCW, orientCondition, 200 );
|
drawMenu.AddItem( SCH_ACTIONS::rotateCCW, orientCondition, 200 );
|
||||||
|
@ -395,8 +395,8 @@ bool SCH_EDIT_TOOL::Init()
|
||||||
drawMenu.AddItem( SCH_ACTIONS::convertDeMorgan, SCH_CONDITIONS::SingleDeMorganSymbol, 200 );
|
drawMenu.AddItem( SCH_ACTIONS::convertDeMorgan, SCH_CONDITIONS::SingleDeMorganSymbol, 200 );
|
||||||
|
|
||||||
std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
|
std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
|
||||||
symUnitMenu2->SetTool( drawingTool );
|
symUnitMenu2->SetTool( drawingTools );
|
||||||
drawingTool->GetToolMenu().AddSubMenu( symUnitMenu2 );
|
drawingTools->GetToolMenu().AddSubMenu( symUnitMenu2 );
|
||||||
drawMenu.AddMenu( symUnitMenu2.get(), false, SCH_CONDITIONS::SingleMultiUnitSymbol, 1 );
|
drawMenu.AddMenu( symUnitMenu2.get(), false, SCH_CONDITIONS::SingleMultiUnitSymbol, 1 );
|
||||||
|
|
||||||
drawMenu.AddItem( SCH_ACTIONS::editWithSymbolEditor,
|
drawMenu.AddItem( SCH_ACTIONS::editWithSymbolEditor,
|
||||||
|
@ -409,7 +409,6 @@ bool SCH_EDIT_TOOL::Init()
|
||||||
drawMenu.AddItem( SCH_ACTIONS::toGLabel, anyTextTool && SCH_CONDITIONS::Idle, 200 );
|
drawMenu.AddItem( SCH_ACTIONS::toGLabel, anyTextTool && SCH_CONDITIONS::Idle, 200 );
|
||||||
drawMenu.AddItem( SCH_ACTIONS::toText, anyTextTool && SCH_CONDITIONS::Idle, 200 );
|
drawMenu.AddItem( SCH_ACTIONS::toText, anyTextTool && SCH_CONDITIONS::Idle, 200 );
|
||||||
drawMenu.AddItem( SCH_ACTIONS::cleanupSheetPins, sheetTool && SCH_CONDITIONS::Idle, 200 );
|
drawMenu.AddItem( SCH_ACTIONS::cleanupSheetPins, sheetTool && SCH_CONDITIONS::Idle, 200 );
|
||||||
drawMenu.AddItem( SCH_ACTIONS::resizeSheet, sheetTool && SCH_CONDITIONS::Idle, 200 );
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Add editing actions to the selection tool menu
|
// Add editing actions to the selection tool menu
|
||||||
|
@ -445,7 +444,6 @@ bool SCH_EDIT_TOOL::Init()
|
||||||
selToolMenu.AddItem( SCH_ACTIONS::toGLabel, toGLabelCondition, 200 );
|
selToolMenu.AddItem( SCH_ACTIONS::toGLabel, toGLabelCondition, 200 );
|
||||||
selToolMenu.AddItem( SCH_ACTIONS::toText, toTextlCondition, 200 );
|
selToolMenu.AddItem( SCH_ACTIONS::toText, toTextlCondition, 200 );
|
||||||
selToolMenu.AddItem( SCH_ACTIONS::cleanupSheetPins, singleSheetCondition, 200 );
|
selToolMenu.AddItem( SCH_ACTIONS::cleanupSheetPins, singleSheetCondition, 200 );
|
||||||
selToolMenu.AddItem( SCH_ACTIONS::resizeSheet, singleSheetCondition, 200 );
|
|
||||||
|
|
||||||
selToolMenu.AddSeparator( SCH_CONDITIONS::Idle, 200 );
|
selToolMenu.AddSeparator( SCH_CONDITIONS::Idle, 200 );
|
||||||
selToolMenu.AddItem( SCH_ACTIONS::cut, SCH_CONDITIONS::IdleSelection, 200 );
|
selToolMenu.AddItem( SCH_ACTIONS::cut, SCH_CONDITIONS::IdleSelection, 200 );
|
||||||
|
@ -589,6 +587,8 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
if( !item->IsMoving() )
|
if( !item->IsMoving() )
|
||||||
{
|
{
|
||||||
if( selection.IsHover() )
|
if( selection.IsHover() )
|
||||||
|
@ -730,6 +730,8 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
if( !item->IsMoving() )
|
if( !item->IsMoving() )
|
||||||
{
|
{
|
||||||
if( selection.IsHover() )
|
if( selection.IsHover() )
|
||||||
|
@ -768,7 +770,8 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
||||||
if( selection.GetSize() == 0 )
|
if( selection.GetSize() == 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// This doesn't really make sense; we'll just end up dragging a stack of objects...
|
// Doing a duplicate of a new object doesn't really make any sense; we'd just end
|
||||||
|
// up dragging around a stack of objects...
|
||||||
if( selection.Front()->IsNew() )
|
if( selection.Front()->IsNew() )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -997,10 +1000,10 @@ int SCH_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
SCH_PICKER_TOOL* picker = m_toolMgr->GetTool<SCH_PICKER_TOOL>();
|
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||||
wxCHECK( picker, 0 );
|
wxCHECK( picker, 0 );
|
||||||
|
|
||||||
m_frame->SetToolID( ID_SCHEMATIC_DELETE_ITEM_BUTT, wxCURSOR_BULLSEYE, _( "DoDelete item" ) );
|
m_frame->SetToolID( ID_SCHEMATIC_DELETE_ITEM_BUTT, wxCURSOR_BULLSEYE, _( "Delete item" ) );
|
||||||
picker->SetClickHandler( std::bind( deleteItem, m_frame, std::placeholders::_1 ) );
|
picker->SetClickHandler( std::bind( deleteItem, m_frame, std::placeholders::_1 ) );
|
||||||
picker->Activate();
|
picker->Activate();
|
||||||
Wait();
|
Wait();
|
||||||
|
@ -1129,7 +1132,10 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( doRefresh )
|
if( doRefresh )
|
||||||
|
{
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
m_frame->GetCanvas()->Refresh();
|
m_frame->GetCanvas()->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1179,7 +1185,7 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int SCH_EDIT_TOOL::ChangeShape( const TOOL_EVENT& aEvent )
|
int SCH_EDIT_TOOL::ChangeShape( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
SELECTION selection = m_selectionTool->GetSelection();
|
SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
char shape;
|
char shape;
|
||||||
|
|
||||||
if( aEvent.IsAction( &SCH_ACTIONS::toShapeSlash ) )
|
if( aEvent.IsAction( &SCH_ACTIONS::toShapeSlash ) )
|
||||||
|
@ -1214,9 +1220,9 @@ int SCH_EDIT_TOOL::ChangeShape( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int SCH_EDIT_TOOL::ChangeTextType( const TOOL_EVENT& aEvent )
|
int SCH_EDIT_TOOL::ChangeTextType( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
KICAD_T allTextTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
|
KICAD_T allTextTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
|
||||||
SELECTION selection = m_selectionTool->RequestSelection( allTextTypes );
|
SELECTION& selection = m_selectionTool->RequestSelection( allTextTypes );
|
||||||
KICAD_T convertTo;
|
KICAD_T convertTo;
|
||||||
|
|
||||||
if( aEvent.IsAction( &SCH_ACTIONS::toLabel ) )
|
if( aEvent.IsAction( &SCH_ACTIONS::toLabel ) )
|
||||||
convertTo = SCH_LABEL_T;
|
convertTo = SCH_LABEL_T;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <netlist_object.h>
|
#include <netlist_object.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tools/sch_actions.h>
|
#include <tools/sch_actions.h>
|
||||||
#include <tools/sch_picker_tool.h>
|
#include <tools/picker_tool.h>
|
||||||
#include <tools/sch_editor_control.h>
|
#include <tools/sch_editor_control.h>
|
||||||
#include <tools/sch_selection_tool.h>
|
#include <tools/sch_selection_tool.h>
|
||||||
#include <tools/sch_drawing_tools.h>
|
#include <tools/sch_drawing_tools.h>
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
#include "sch_wire_bus_tool.h"
|
#include "sch_wire_bus_tool.h"
|
||||||
|
|
||||||
TOOL_ACTION SCH_ACTIONS::refreshPreview( "eeschema.EditorControl.refreshPreview",
|
TOOL_ACTION SCH_ACTIONS::refreshPreview( "eeschema.EditorControl.refreshPreview",
|
||||||
AS_GLOBAL, 0, "", "" );
|
AS_GLOBAL, 0, "", "" );
|
||||||
|
|
||||||
TOOL_ACTION SCH_ACTIONS::simProbe( "eeschema.Simulation.probe",
|
TOOL_ACTION SCH_ACTIONS::simProbe( "eeschema.Simulation.probe",
|
||||||
AS_GLOBAL, 0,
|
AS_GLOBAL, 0,
|
||||||
|
@ -260,7 +260,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
SCH_PICKER_TOOL* picker = m_toolMgr->GetTool<SCH_PICKER_TOOL>();
|
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||||
assert( picker );
|
assert( picker );
|
||||||
|
|
||||||
m_frame->SetToolID( ID_SIM_PROBE, wxCURSOR_DEFAULT, _( "Add a simulator probe" ) );
|
m_frame->SetToolID( ID_SIM_PROBE, wxCURSOR_DEFAULT, _( "Add a simulator probe" ) );
|
||||||
|
@ -304,7 +304,7 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
SCH_PICKER_TOOL* picker = m_toolMgr->GetTool<SCH_PICKER_TOOL>();
|
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||||
assert( picker );
|
assert( picker );
|
||||||
|
|
||||||
m_frame->SetToolID( ID_SIM_TUNE, wxCURSOR_DEFAULT, _( "Select a value to be tuned" ) );
|
m_frame->SetToolID( ID_SIM_TUNE, wxCURSOR_DEFAULT, _( "Select a value to be tuned" ) );
|
||||||
|
@ -471,7 +471,7 @@ int SCH_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
SCH_PICKER_TOOL* picker = m_toolMgr->GetTool<SCH_PICKER_TOOL>();
|
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||||
assert( picker );
|
assert( picker );
|
||||||
|
|
||||||
m_frame->SetToolID( ID_HIGHLIGHT_BUTT, wxCURSOR_HAND, _( "Highlight specific net" ) );
|
m_frame->SetToolID( ID_HIGHLIGHT_BUTT, wxCURSOR_HAND, _( "Highlight specific net" ) );
|
||||||
|
|
|
@ -22,11 +22,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tools/sch_edit_tool.h>
|
|
||||||
#include <tools/sch_selection_tool.h>
|
#include <tools/sch_selection_tool.h>
|
||||||
#include <tools/sch_drawing_tools.h>
|
|
||||||
#include <tools/sch_wire_bus_tool.h>
|
#include <tools/sch_wire_bus_tool.h>
|
||||||
#include <tools/sch_picker_tool.h>
|
|
||||||
#include <sch_actions.h>
|
#include <sch_actions.h>
|
||||||
#include <hotkeys.h>
|
#include <hotkeys.h>
|
||||||
#include <bitmaps.h>
|
#include <bitmaps.h>
|
||||||
|
@ -316,6 +313,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
controls->SetCursorPosition( m_cursor, false );
|
controls->SetCursorPosition( m_cursor, false );
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
prevPos = m_cursor;
|
prevPos = m_cursor;
|
||||||
controls->SetAutoPan( true );
|
controls->SetAutoPan( true );
|
||||||
|
@ -339,9 +337,11 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
moveItem( item, delta, m_frame->GetToolId() == ID_SCH_DRAG );
|
moveItem( item, delta, m_frame->GetToolId() == ID_SCH_DRAG );
|
||||||
|
|
||||||
updateView( item );
|
updateView( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
m_frame->UpdateMsgPanel();
|
m_frame->UpdateMsgPanel();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
|
@ -194,6 +194,10 @@ bool SCH_SELECTION_TOOL::Init()
|
||||||
auto sheetSelection = SELECTION_CONDITIONS::Count( 1 )
|
auto sheetSelection = SELECTION_CONDITIONS::Count( 1 )
|
||||||
&& SELECTION_CONDITIONS::OnlyType( SCH_SHEET_T );
|
&& SELECTION_CONDITIONS::OnlyType( SCH_SHEET_T );
|
||||||
|
|
||||||
|
auto libEdit = [this] ( const SELECTION& aSel ) {
|
||||||
|
return m_isLibEdit;
|
||||||
|
};
|
||||||
|
|
||||||
auto belowRootSheetCondition = [] ( const SELECTION& aSel ) {
|
auto belowRootSheetCondition = [] ( const SELECTION& aSel ) {
|
||||||
return g_CurrentSheet->Last() != g_RootSheet;
|
return g_CurrentSheet->Last() != g_RootSheet;
|
||||||
};
|
};
|
||||||
|
@ -202,12 +206,11 @@ bool SCH_SELECTION_TOOL::Init()
|
||||||
|
|
||||||
menu.AddItem( SCH_ACTIONS::enterSheet, sheetSelection && SCH_CONDITIONS::Idle, 1 );
|
menu.AddItem( SCH_ACTIONS::enterSheet, sheetSelection && SCH_CONDITIONS::Idle, 1 );
|
||||||
menu.AddItem( SCH_ACTIONS::explicitCrossProbe, sheetSelection && SCH_CONDITIONS::Idle, 1 );
|
menu.AddItem( SCH_ACTIONS::explicitCrossProbe, sheetSelection && SCH_CONDITIONS::Idle, 1 );
|
||||||
menu.AddItem( SCH_ACTIONS::resizeSheet, sheetSelection && SCH_CONDITIONS::Idle, 1 );
|
|
||||||
menu.AddItem( SCH_ACTIONS::leaveSheet, belowRootSheetCondition, 1 );
|
menu.AddItem( SCH_ACTIONS::leaveSheet, belowRootSheetCondition, 1 );
|
||||||
|
|
||||||
menu.AddSeparator( SCH_CONDITIONS::Empty, 100 );
|
menu.AddSeparator( SCH_CONDITIONS::Empty, 100 );
|
||||||
menu.AddItem( SCH_ACTIONS::startWire, SCH_CONDITIONS::Empty, 100 );
|
menu.AddItem( SCH_ACTIONS::startWire, !libEdit && SCH_CONDITIONS::Empty, 100 );
|
||||||
menu.AddItem( SCH_ACTIONS::startBus, SCH_CONDITIONS::Empty, 100 );
|
menu.AddItem( SCH_ACTIONS::startBus, !libEdit && SCH_CONDITIONS::Empty, 100 );
|
||||||
|
|
||||||
menu.AddSeparator( SCH_WIRE_BUS_TOOL::IsDrawingWire, 100 );
|
menu.AddSeparator( SCH_WIRE_BUS_TOOL::IsDrawingWire, 100 );
|
||||||
menu.AddItem( SCH_ACTIONS::finishWire, SCH_WIRE_BUS_TOOL::IsDrawingWire, 100 );
|
menu.AddItem( SCH_ACTIONS::finishWire, SCH_WIRE_BUS_TOOL::IsDrawingWire, 100 );
|
||||||
|
@ -264,17 +267,6 @@ void SCH_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
||||||
|
|
||||||
int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
// JEY TODO: temp hack for LibEdit legacy selection tool
|
|
||||||
if( m_isLibEdit )
|
|
||||||
{
|
|
||||||
LIB_EDIT_FRAME* libEditFrame = (LIB_EDIT_FRAME*) m_frame;
|
|
||||||
wxCommandEvent selectArrow;
|
|
||||||
selectArrow.SetId( ID_NO_TOOL_SELECTED );
|
|
||||||
libEditFrame->OnSelectTool( selectArrow );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main loop: keep receiving events
|
// Main loop: keep receiving events
|
||||||
while( OPT_TOOL_EVENT evt = Wait() )
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
{
|
{
|
||||||
|
@ -893,6 +885,27 @@ bool SCH_SELECTION_TOOL::selectable( const EDA_ITEM* aItem, bool checkVisibility
|
||||||
case LIB_PART_T: // In libedit we do not want to select the symbol itself.
|
case LIB_PART_T: // In libedit we do not want to select the symbol itself.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case LIB_PIN_T:
|
||||||
|
{
|
||||||
|
LIB_EDIT_FRAME* editFrame = (LIB_EDIT_FRAME*) m_frame;
|
||||||
|
LIB_PIN* pin = (LIB_PIN*) aItem;
|
||||||
|
|
||||||
|
if( ( pin->GetUnit() && pin->GetUnit() != editFrame->GetUnit() )
|
||||||
|
|| ( pin->GetConvert() && pin->GetConvert() != editFrame->GetConvert() ) )
|
||||||
|
{
|
||||||
|
// Specific rules for pins:
|
||||||
|
// - do not select pins in other units when synchronized pin edit mode is disabled
|
||||||
|
// - do not select pins in other units when units are not interchangeable
|
||||||
|
// - in other cases verify if the pin belongs to the requested DeMorgan variant
|
||||||
|
if( !editFrame->SynchronizePins()
|
||||||
|
|| editFrame->GetCurPart()->UnitsLocked()
|
||||||
|
|| ( pin->GetConvert() && pin->GetConvert() != editFrame->GetConvert() ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SCH_MARKER_T: // Always selectable
|
case SCH_MARKER_T: // Always selectable
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -294,8 +294,8 @@ static bool isNewSegment( SCH_ITEM* aItem )
|
||||||
|
|
||||||
bool SCH_WIRE_BUS_TOOL::IsDrawingLine( const SELECTION& aSelection )
|
bool SCH_WIRE_BUS_TOOL::IsDrawingLine( const SELECTION& aSelection )
|
||||||
{
|
{
|
||||||
static KICAD_T wireOrBusTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
|
static KICAD_T graphicLineType[] = { SCH_LINE_LOCATE_GRAPHIC_LINE_T, EOT };
|
||||||
return IsDrawingLineWireOrBus( aSelection ) && !aSelection.Front()->IsType( wireOrBusTypes );
|
return IsDrawingLineWireOrBus( aSelection ) && aSelection.Front()->IsType( graphicLineType );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,7 @@ enum KICAD_T
|
||||||
// Same for picking wires and busses from SCH_LINE_T items
|
// Same for picking wires and busses from SCH_LINE_T items
|
||||||
SCH_LINE_LOCATE_WIRE_T,
|
SCH_LINE_LOCATE_WIRE_T,
|
||||||
SCH_LINE_LOCATE_BUS_T,
|
SCH_LINE_LOCATE_BUS_T,
|
||||||
|
SCH_LINE_LOCATE_GRAPHIC_LINE_T,
|
||||||
|
|
||||||
// matches any type
|
// matches any type
|
||||||
SCH_LOCATE_ANY_T,
|
SCH_LOCATE_ANY_T,
|
||||||
|
|
|
@ -86,6 +86,7 @@ class EDA_DRAW_FRAME : public KIWAY_PLAYER
|
||||||
|
|
||||||
///< Id of active button on the vertical toolbar.
|
///< Id of active button on the vertical toolbar.
|
||||||
int m_toolId;
|
int m_toolId;
|
||||||
|
wxString m_toolMsg;
|
||||||
|
|
||||||
BASE_SCREEN* m_currentScreen; ///< current used SCREEN
|
BASE_SCREEN* m_currentScreen; ///< current used SCREEN
|
||||||
|
|
||||||
|
@ -738,9 +739,10 @@ public:
|
||||||
const wxString &aSheetLayer = wxEmptyString );
|
const wxString &aSheetLayer = wxEmptyString );
|
||||||
|
|
||||||
void DisplayToolMsg( const wxString& msg );
|
void DisplayToolMsg( const wxString& msg );
|
||||||
|
wxString GetToolMsg() { return m_toolMsg; }
|
||||||
virtual void RedrawActiveWindow( wxDC* DC, bool EraseBg ) = 0;
|
virtual void RedrawActiveWindow( wxDC* DC, bool EraseBg ) = 0;
|
||||||
virtual void OnLeftClick( wxDC* DC, const wxPoint& MousePos ) {};
|
virtual void OnLeftClick( wxDC* DC, const wxPoint& MousePos ) {}
|
||||||
virtual void OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) {};
|
virtual void OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) {}
|
||||||
virtual bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) = 0;
|
virtual bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) = 0;
|
||||||
virtual void ToolOnRightClick( wxCommandEvent& event );
|
virtual void ToolOnRightClick( wxCommandEvent& event );
|
||||||
void AdjustScrollBars( const wxPoint& aCenterPosition );
|
void AdjustScrollBars( const wxPoint& aCenterPosition );
|
||||||
|
@ -750,7 +752,7 @@ public:
|
||||||
* In derived classes it can be used to modify parameters like draw area size,
|
* In derived classes it can be used to modify parameters like draw area size,
|
||||||
* and any other local parameter related to the page settings.
|
* and any other local parameter related to the page settings.
|
||||||
*/
|
*/
|
||||||
virtual void OnPageSettingsChange() {};
|
virtual void OnPageSettingsChange() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when activating the frame.
|
* Called when activating the frame.
|
||||||
|
|
|
@ -130,8 +130,7 @@ class EDA_TEXT
|
||||||
public:
|
public:
|
||||||
EDA_TEXT( const wxString& text = wxEmptyString );
|
EDA_TEXT( const wxString& text = wxEmptyString );
|
||||||
|
|
||||||
// Do not create a copy constructor & operator=.
|
EDA_TEXT( const EDA_TEXT& aText );
|
||||||
// The ones generated by the compiler are adequate.
|
|
||||||
|
|
||||||
virtual ~EDA_TEXT();
|
virtual ~EDA_TEXT();
|
||||||
|
|
||||||
|
|
11
include/id.h
11
include/id.h
|
@ -161,23 +161,16 @@ enum main_id
|
||||||
ID_POPUP_CANCEL_CURRENT_COMMAND,
|
ID_POPUP_CANCEL_CURRENT_COMMAND,
|
||||||
ID_POPUP_CLOSE_CURRENT_TOOL,
|
ID_POPUP_CLOSE_CURRENT_TOOL,
|
||||||
|
|
||||||
// JEY TODO: all the block-specific commands are obsolete after LibEdit moves to modern toolset
|
// JEY TODO: all the block-specific commands are obsolete after PCBNew's legacy canvas goes...
|
||||||
ID_POPUP_MOVE_BLOCK,
|
|
||||||
ID_POPUP_MOVE_BLOCK_EXACT,
|
ID_POPUP_MOVE_BLOCK_EXACT,
|
||||||
ID_POPUP_DRAG_BLOCK,
|
|
||||||
ID_POPUP_COPY_BLOCK,
|
|
||||||
ID_POPUP_PASTE_BLOCK,
|
|
||||||
ID_POPUP_CUT_BLOCK,
|
|
||||||
ID_POPUP_DUPLICATE_BLOCK,
|
ID_POPUP_DUPLICATE_BLOCK,
|
||||||
ID_POPUP_ROTATE_BLOCK,
|
ID_POPUP_ROTATE_BLOCK,
|
||||||
ID_POPUP_DELETE_BLOCK,
|
ID_POPUP_DELETE_BLOCK,
|
||||||
ID_POPUP_FLIP_BLOCK,
|
ID_POPUP_FLIP_BLOCK,
|
||||||
ID_POPUP_PLACE_BLOCK,
|
ID_POPUP_PLACE_BLOCK,
|
||||||
ID_POPUP_ZOOM_BLOCK,
|
ID_POPUP_ZOOM_BLOCK,
|
||||||
ID_POPUP_SELECT_ITEMS_BLOCK,
|
|
||||||
ID_POPUP_MIRROR_X_BLOCK,
|
ID_POPUP_MIRROR_X_BLOCK,
|
||||||
ID_POPUP_MIRROR_Y_BLOCK,
|
ID_POPUP_MIRROR_Y_BLOCK,
|
||||||
ID_POPUP_OTHER_COMMANDS,
|
|
||||||
ID_POPUP_GENERAL_END_RANGE, // last number
|
ID_POPUP_GENERAL_END_RANGE, // last number
|
||||||
|
|
||||||
ID_POPUP_ENTER_MENU,
|
ID_POPUP_ENTER_MENU,
|
||||||
|
@ -261,6 +254,8 @@ enum main_id
|
||||||
ID_MOUSE_CLICK,
|
ID_MOUSE_CLICK,
|
||||||
ID_MOUSE_DOUBLECLICK,
|
ID_MOUSE_DOUBLECLICK,
|
||||||
|
|
||||||
|
ID_DRAG_POINT,
|
||||||
|
|
||||||
ID_GET_NETLIST,
|
ID_GET_NETLIST,
|
||||||
ID_OPEN_CMP_TABLE,
|
ID_OPEN_CMP_TABLE,
|
||||||
ID_GET_TOOLS,
|
ID_GET_TOOLS,
|
||||||
|
|
|
@ -117,6 +117,8 @@ public:
|
||||||
const static TOOL_EVENT SelectedEvent;
|
const static TOOL_EVENT SelectedEvent;
|
||||||
const static TOOL_EVENT UnselectedEvent;
|
const static TOOL_EVENT UnselectedEvent;
|
||||||
const static TOOL_EVENT ClearedEvent;
|
const static TOOL_EVENT ClearedEvent;
|
||||||
|
|
||||||
|
const static TOOL_EVENT SelectedItemsModified;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ACTIONS_H
|
#endif // __ACTIONS_H
|
||||||
|
|
|
@ -323,8 +323,6 @@ set( PCBNEW_CLASS_SRCS
|
||||||
zones_test_and_combine_areas.cpp
|
zones_test_and_combine_areas.cpp
|
||||||
|
|
||||||
tools/drawing_tool.cpp
|
tools/drawing_tool.cpp
|
||||||
tools/edit_constraints.cpp
|
|
||||||
tools/edit_points.cpp
|
|
||||||
tools/edit_tool.cpp
|
tools/edit_tool.cpp
|
||||||
tools/grid_helper.cpp
|
tools/grid_helper.cpp
|
||||||
tools/microwave_tool.cpp
|
tools/microwave_tool.cpp
|
||||||
|
|
|
@ -146,10 +146,6 @@ TOOL_ACTION PCB_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_ITEM ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_ITEM ),
|
||||||
_( "Properties..." ), _( "Displays item properties dialog" ), config_xpm );
|
_( "Properties..." ), _( "Displays item properties dialog" ), config_xpm );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::selectionModified( "pcbnew.InteractiveEdit.ModifiedSelection",
|
|
||||||
AS_GLOBAL, 0,
|
|
||||||
"", "", nullptr, AF_NOTIFY );
|
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::measureTool( "pcbnew.InteractiveEdit.measureTool",
|
TOOL_ACTION PCB_ACTIONS::measureTool( "pcbnew.InteractiveEdit.measureTool",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_MEASURE_TOOL ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_MEASURE_TOOL ),
|
||||||
_( "Measuring Tool" ), _( "Interactively measure distance between points" ),
|
_( "Measuring Tool" ), _( "Interactively measure distance between points" ),
|
||||||
|
@ -500,7 +496,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
m_dragging = true;
|
m_dragging = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, false );
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,7 +651,7 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
editFrame->OnEditItemRequest( NULL, item );
|
editFrame->OnEditItemRequest( NULL, item );
|
||||||
|
|
||||||
// Notify other tools of the changes
|
// Notify other tools of the changes
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( selection.IsHover() )
|
if( selection.IsHover() )
|
||||||
|
@ -663,7 +659,7 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
// Notify other tools of the changes -- This updates the visual ratsnest
|
// Notify other tools of the changes -- This updates the visual ratsnest
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -703,7 +699,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||||
if( selection.IsHover() && !m_dragging )
|
if( selection.IsHover() && !m_dragging )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
if( m_dragging )
|
if( m_dragging )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
||||||
|
@ -824,7 +820,7 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||||
if( selection.IsHover() && !m_dragging )
|
if( selection.IsHover() && !m_dragging )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
if( m_dragging )
|
if( m_dragging )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
||||||
|
@ -863,7 +859,7 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
||||||
if( selection.IsHover() && !m_dragging )
|
if( selection.IsHover() && !m_dragging )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
if( m_dragging )
|
if( m_dragging )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
||||||
|
@ -1054,7 +1050,7 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
||||||
if( selection.IsHover() )
|
if( selection.IsHover() )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
if( m_dragging )
|
if( m_dragging )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
||||||
|
|
|
@ -223,7 +223,7 @@ int PAD_TOOL::pastePadProperties( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
commit.Push( _( "Paste Pad Properties" ) );
|
commit.Push( _( "Paste Pad Properties" ) );
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
frame.Refresh();
|
frame.Refresh();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -335,7 +335,7 @@ int PAD_TOOL::pushPadSettings( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
commit.Push( _( "Push Pad Settings" ) );
|
commit.Push( _( "Push Pad Settings" ) );
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
frame.Refresh();
|
frame.Refresh();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -104,9 +104,6 @@ public:
|
||||||
/// Activation of the edit tool
|
/// Activation of the edit tool
|
||||||
static TOOL_ACTION properties;
|
static TOOL_ACTION properties;
|
||||||
|
|
||||||
/// Modified selection notification
|
|
||||||
static TOOL_ACTION selectionModified;
|
|
||||||
|
|
||||||
/// Activation of the exact move tool
|
/// Activation of the exact move tool
|
||||||
static TOOL_ACTION moveExact;
|
static TOOL_ACTION moveExact;
|
||||||
|
|
||||||
|
|
|
@ -239,8 +239,12 @@ private:
|
||||||
|
|
||||||
|
|
||||||
POINT_EDITOR::POINT_EDITOR() :
|
POINT_EDITOR::POINT_EDITOR() :
|
||||||
PCB_TOOL( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_editedPoint( NULL ),
|
PCB_TOOL( "pcbnew.PointEditor" ),
|
||||||
m_original( VECTOR2I( 0, 0 ) ), m_altConstrainer( VECTOR2I( 0, 0 ) ), m_refill( false )
|
m_selectionTool( NULL ),
|
||||||
|
m_editedPoint( NULL ),
|
||||||
|
m_original( VECTOR2I( 0, 0 ) ),
|
||||||
|
m_altConstrainer( VECTOR2I( 0, 0 ) ),
|
||||||
|
m_refill( false )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,13 +265,9 @@ void POINT_EDITOR::Reset( RESET_REASON aReason )
|
||||||
bool POINT_EDITOR::Init()
|
bool POINT_EDITOR::Init()
|
||||||
{
|
{
|
||||||
// Find the selection tool, so they can cooperate
|
// Find the selection tool, so they can cooperate
|
||||||
m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
|
m_selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||||
|
|
||||||
if( !m_selectionTool )
|
wxASSERT_MSG( m_selectionTool, _( "pcbnew.InteractiveSelection tool is not available" ) );
|
||||||
{
|
|
||||||
DisplayError( NULL, _( "pcbnew.InteractiveSelection tool is not available" ) );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& menu = m_selectionTool->GetToolMenu().GetMenu();
|
auto& menu = m_selectionTool->GetToolMenu().GetMenu();
|
||||||
menu.AddItem( PCB_ACTIONS::pointEditorAddCorner, POINT_EDITOR::addCornerCondition );
|
menu.AddItem( PCB_ACTIONS::pointEditorAddCorner, POINT_EDITOR::addCornerCondition );
|
||||||
|
@ -904,7 +904,7 @@ void POINT_EDITOR::setTransitions()
|
||||||
{
|
{
|
||||||
Go( &POINT_EDITOR::addCorner, PCB_ACTIONS::pointEditorAddCorner.MakeEvent() );
|
Go( &POINT_EDITOR::addCorner, PCB_ACTIONS::pointEditorAddCorner.MakeEvent() );
|
||||||
Go( &POINT_EDITOR::removeCorner, PCB_ACTIONS::pointEditorRemoveCorner.MakeEvent() );
|
Go( &POINT_EDITOR::removeCorner, PCB_ACTIONS::pointEditorRemoveCorner.MakeEvent() );
|
||||||
Go( &POINT_EDITOR::modifiedSelection, PCB_ACTIONS::selectionModified.MakeEvent() );
|
Go( &POINT_EDITOR::modifiedSelection, EVENTS::SelectedItemsModified );
|
||||||
Go( &POINT_EDITOR::OnSelectionChange, EVENTS::SelectedEvent );
|
Go( &POINT_EDITOR::OnSelectionChange, EVENTS::SelectedEvent );
|
||||||
Go( &POINT_EDITOR::OnSelectionChange, EVENTS::UnselectedEvent );
|
Go( &POINT_EDITOR::OnSelectionChange, EVENTS::UnselectedEvent );
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#define __POINT_EDITOR_H
|
#define __POINT_EDITOR_H
|
||||||
|
|
||||||
#include <tool/tool_interactive.h>
|
#include <tool/tool_interactive.h>
|
||||||
#include "edit_points.h"
|
#include "tool/edit_points.h"
|
||||||
#include <status_popup.h>
|
#include <status_popup.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -120,12 +120,6 @@ private:
|
||||||
///> Returns a point that should be used as a constrainer for 45 degrees mode.
|
///> Returns a point that should be used as a constrainer for 45 degrees mode.
|
||||||
EDIT_POINT get45DegConstrainer() const;
|
EDIT_POINT get45DegConstrainer() const;
|
||||||
|
|
||||||
///> Adds a new edit point on a zone outline/line.
|
|
||||||
void addCorner( const VECTOR2I& aPoint );
|
|
||||||
|
|
||||||
///> Removes a corner.
|
|
||||||
void removeCorner( EDIT_POINT* aPoint );
|
|
||||||
|
|
||||||
///> Condition to display "Create corner" context menu entry.
|
///> Condition to display "Create corner" context menu entry.
|
||||||
static bool addCornerCondition( const SELECTION& aSelection );
|
static bool addCornerCondition( const SELECTION& aSelection );
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint aPosAnchor, wxPoi
|
||||||
if( m_selection.IsHover() )
|
if( m_selection.IsHover() )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true );
|
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
||||||
canvas()->Refresh();
|
canvas()->Refresh();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -713,7 +713,7 @@ void SELECTION_TOOL::setTransitions()
|
||||||
Go( &SELECTION_TOOL::selectNet, PCB_ACTIONS::selectNet.MakeEvent() );
|
Go( &SELECTION_TOOL::selectNet, PCB_ACTIONS::selectNet.MakeEvent() );
|
||||||
Go( &SELECTION_TOOL::selectSameSheet, PCB_ACTIONS::selectSameSheet.MakeEvent() );
|
Go( &SELECTION_TOOL::selectSameSheet, PCB_ACTIONS::selectSameSheet.MakeEvent() );
|
||||||
Go( &SELECTION_TOOL::selectOnSheetFromEeschema, PCB_ACTIONS::selectOnSheetFromEeschema.MakeEvent() );
|
Go( &SELECTION_TOOL::selectOnSheetFromEeschema, PCB_ACTIONS::selectOnSheetFromEeschema.MakeEvent() );
|
||||||
Go( &SELECTION_TOOL::updateSelection, PCB_ACTIONS::selectionModified.MakeEvent() );
|
Go( &SELECTION_TOOL::updateSelection, EVENTS::SelectedItemsModified );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -267,10 +267,6 @@ TOOL_ACTION PCB_ACTIONS::hideLocalRatsnest( "pcbnew.Control.hideLocalRatsnest",
|
||||||
AS_GLOBAL, 0,
|
AS_GLOBAL, 0,
|
||||||
"", "" );
|
"", "" );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::selectionModified( "pcbnew.InteractiveEdit.ModifiedSelection",
|
|
||||||
AS_GLOBAL, 0,
|
|
||||||
"", "", nullptr, AF_NOTIFY );
|
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
|
TOOL_ACTION PCB_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ),
|
||||||
_( "Flip" ), _( "Flips selected item(s)" ), nullptr );
|
_( "Flip" ), _( "Flips selected item(s)" ), nullptr );
|
||||||
|
|
Loading…
Reference in New Issue