Implement modern tools for LibEdit.

This commit is contained in:
Jeff Young 2019-05-08 19:56:03 +01:00
parent 40f41133b3
commit ea0941cab3
88 changed files with 2679 additions and 3738 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,6 +245,9 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
{ {
auto gal = aView->GetGAL(); auto gal = aView->GetGAL();
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->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
gal->SetIsFill( true ); gal->SetIsFill( true );
gal->SetIsStroke( false ); gal->SetIsStroke( false );

View File

@ -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()
* *
@ -174,6 +188,10 @@ 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 ) );
} }
/** /**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
}; };
@ -542,6 +542,8 @@ bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
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 );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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.
*/ */

View File

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

View File

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

View File

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

View File

@ -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 )
{
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( _( "Rotate Clockwise" ), g_Libedit_Hotkeys_Descr, HK_ROTATE ); case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT:
AddMenuItem( PopMenu, ID_LIBEDIT_ROTATE_ITEM, msg, KiBitmap( rotate_cw_xpm ) ); {
msg = AddHotkeyName( _( "Edit..." ), g_Libedit_Hotkeys_Descr, HK_EDIT ); // Delete the last created segment, while creating a polyline draw item
AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); if( item == NULL )
break; break;
m_canvas->MoveCursorToCrossHair();
default: static_cast<LIB_POLYLINE*>( item )->DeleteSegment( GetCrossHairPosition( true ) );
wxFAIL_MSG( wxString::Format( wxT( "Unknown library item type %d" ), }
item->Type() ) );
SetDrawItem( NULL );
break; break;
} #endif
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 ) );
}
}

View File

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

View File

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

View File

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

View File

@ -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()
{ {
SCH_SELECTION_TOOL* selTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
LIB_PART* part = GetCurPart(); 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();

View File

@ -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:
/** /**

View File

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

View File

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

View File

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

View File

@ -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();
else if( SCH_CONDITIONS::Idle( selTool->GetSelection() ) )
{
if( SCH_CONDITIONS::Idle( GetParent()->GetToolManager()->GetTool<SCH_SELECTION_TOOL>()->GetSelection() ) )
GetParent()->GetToolManager()->RunAction( SCH_ACTIONS::selectionActivate, true ); GetParent()->GetToolManager()->RunAction( SCH_ACTIONS::selectionActivate, true );
else else
GetParent()->GetToolManager()->RunAction( ACTIONS::cancelInteractive, true ); 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

View File

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

View File

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

View File

@ -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.
*/ */

View File

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

View File

@ -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.
*/ */

View File

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

View File

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

View File

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

View File

@ -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,6 +156,7 @@ 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 )
{ {
LIB_PIN_TOOL* pinTool = aType == LIB_PIN_T ? m_toolMgr->GetTool<LIB_PIN_TOOL>() : nullptr;
VECTOR2I cursorPos = m_controls->GetCursorPosition(); VECTOR2I cursorPos = m_controls->GetCursorPosition();
EDA_ITEM* item = nullptr; EDA_ITEM* item = nullptr;
@ -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() )
{
case LIB_PIN_T:
pinTool->PlacePin( (LIB_PIN*) item );
break;
case LIB_TEXT_T:
part->AddDrawItem( (LIB_TEXT*) item );
item->ClearFlags( item->GetEditFlags() ); 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() );
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) m_frame->RebuildView();
// but not used here. m_frame->OnModify();
pin->ClearFlags( IS_CHANGED );
}
// Now changes are made, call OnModify() to validate thes changes and set return 0;
// the global change for UI
RebuildView();
GetCanvas()->Refresh();
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() );
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 else
delete aSheet; delete sheet;
}
else sheet = nullptr;
{
m_view->Hide( aSheet, false );
m_frame->RefreshItem( aSheet );
m_frame->OnModify();
} }
aSheet = nullptr; else if( sheet && ( evt->IsAction( &SCH_ACTIONS::refreshPreview )
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 )
|| 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() );

View File

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

View File

@ -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 ) )
@ -1215,7 +1221,7 @@ 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 ) )

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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