pcbnew: hooked Tool Framework into the edit panel. Added a sample selection tool (not fully functional).
This commit is contained in:
parent
4c777e92f3
commit
69a44d5f13
|
@ -38,6 +38,9 @@
|
||||||
#include <gal/opengl/opengl_gal.h>
|
#include <gal/opengl/opengl_gal.h>
|
||||||
#include <gal/cairo/cairo_gal.h>
|
#include <gal/cairo/cairo_gal.h>
|
||||||
|
|
||||||
|
#include <tool/tool_dispatcher.h>
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
#include <profile.h>
|
#include <profile.h>
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
@ -54,6 +57,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||||
m_currentGal = GAL_TYPE_NONE;
|
m_currentGal = GAL_TYPE_NONE;
|
||||||
m_view = NULL;
|
m_view = NULL;
|
||||||
m_painter = NULL;
|
m_painter = NULL;
|
||||||
|
m_eventDispatcher = NULL;
|
||||||
|
|
||||||
SwitchBackend( aGalType, true );
|
SwitchBackend( aGalType, true );
|
||||||
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
||||||
|
@ -83,6 +87,19 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||||
Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this );
|
Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this );
|
||||||
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this );
|
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this );
|
||||||
|
|
||||||
|
/* Generic events for the Tool Dispatcher */
|
||||||
|
|
||||||
|
Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
Connect( wxEVT_KEY_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
|
||||||
|
|
||||||
m_timeStamp = 0;
|
m_timeStamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,8 +138,8 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool eraseBackground, const wxRect* rect )
|
||||||
|
|
||||||
// Framerate limiter
|
// Framerate limiter
|
||||||
wxLongLong currentTimeStamp = wxGetLocalTimeMillis();
|
wxLongLong currentTimeStamp = wxGetLocalTimeMillis();
|
||||||
if( currentTimeStamp - m_timeStamp < ( 1000 / FPS_LIMIT ) )
|
// if( currentTimeStamp - m_timeStamp < ( 1000 / FPS_LIMIT ) )
|
||||||
return;
|
// return;
|
||||||
m_timeStamp = currentTimeStamp;
|
m_timeStamp = currentTimeStamp;
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
|
@ -131,6 +148,8 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool eraseBackground, const wxRect* rect )
|
||||||
prof_start( &time, false );
|
prof_start( &time, false );
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
|
printf("Refresh!\n");
|
||||||
|
|
||||||
m_gal->BeginDrawing();
|
m_gal->BeginDrawing();
|
||||||
m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
|
m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
|
||||||
m_gal->ClearScreen();
|
m_gal->ClearScreen();
|
||||||
|
@ -193,3 +212,20 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType, bool aUseShaders )
|
||||||
m_currentGal = aGalType;
|
m_currentGal = aGalType;
|
||||||
m_useShaders = aUseShaders;
|
m_useShaders = aUseShaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EDA_DRAW_PANEL_GAL::onEvent( wxEvent& aEvent )
|
||||||
|
{
|
||||||
|
if(!m_eventDispatcher)
|
||||||
|
{
|
||||||
|
aEvent.Skip();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
printf("evType %d\n", aEvent.GetEventType());
|
||||||
|
m_eventDispatcher->DispatchWxEvent(aEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KiGfx::VIEW_CONTROLS* EDA_DRAW_PANEL_GAL::GetViewControls() const
|
||||||
|
{
|
||||||
|
return m_viewControls;
|
||||||
|
}
|
|
@ -36,12 +36,14 @@
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
class BOARD;
|
class BOARD;
|
||||||
|
class TOOL_DISPATCHER;
|
||||||
|
|
||||||
namespace KiGfx
|
namespace KiGfx
|
||||||
{
|
{
|
||||||
class GAL;
|
class GAL;
|
||||||
class VIEW;
|
class VIEW;
|
||||||
class WX_VIEW_CONTROLS;
|
class WX_VIEW_CONTROLS;
|
||||||
|
class VIEW_CONTROLS;
|
||||||
class PAINTER;
|
class PAINTER;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,13 +76,21 @@ public:
|
||||||
KiGfx::GAL* GetGAL() { return m_gal; }
|
KiGfx::GAL* GetGAL() { return m_gal; }
|
||||||
|
|
||||||
void SetView( KiGfx::VIEW* aView ) { m_view = aView; }
|
void SetView( KiGfx::VIEW* aView ) { m_view = aView; }
|
||||||
|
|
||||||
KiGfx::VIEW* GetView() const { return m_view; }
|
KiGfx::VIEW* GetView() const { return m_view; }
|
||||||
|
KiGfx::VIEW_CONTROLS* GetViewControls() const;
|
||||||
|
|
||||||
virtual void Refresh( bool eraseBackground = true, const wxRect* rect = NULL );
|
virtual void Refresh( bool eraseBackground = true, const wxRect* rect = NULL );
|
||||||
|
|
||||||
|
void SetEventDispatcher(TOOL_DISPATCHER *aEventDispatcher)
|
||||||
|
{
|
||||||
|
m_eventDispatcher = aEventDispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
|
void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
|
||||||
void onSize( wxSizeEvent& aEvent );
|
void onSize( wxSizeEvent& aEvent );
|
||||||
|
void onEvent( wxEvent& aEvent );
|
||||||
|
|
||||||
KiGfx::GAL* m_gal; ///< Interface for drawing objects on a 2D-surface
|
KiGfx::GAL* m_gal; ///< Interface for drawing objects on a 2D-surface
|
||||||
KiGfx::VIEW* m_view; ///< Stores view settings (scale, center, etc.)
|
KiGfx::VIEW* m_view; ///< Stores view settings (scale, center, etc.)
|
||||||
|
@ -91,6 +101,7 @@ protected:
|
||||||
GalType m_currentGal; ///< Currently used GAL
|
GalType m_currentGal; ///< Currently used GAL
|
||||||
bool m_useShaders; ///< Are shaders used? (only for OpenGL GAL)
|
bool m_useShaders; ///< Are shaders used? (only for OpenGL GAL)
|
||||||
wxLongLong m_timeStamp;
|
wxLongLong m_timeStamp;
|
||||||
|
TOOL_DISPATCHER* m_eventDispatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,7 +56,8 @@ class ZONE_SETTINGS;
|
||||||
class PCB_PLOT_PARAMS;
|
class PCB_PLOT_PARAMS;
|
||||||
class FP_LIB_TABLE;
|
class FP_LIB_TABLE;
|
||||||
class FPID;
|
class FPID;
|
||||||
|
class TOOL_MANAGER;
|
||||||
|
class TOOL_DISPATCHER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class PCB_BASE_FRAME
|
* class PCB_BASE_FRAME
|
||||||
|
@ -94,6 +95,10 @@ protected:
|
||||||
/// main window.
|
/// main window.
|
||||||
wxAuiToolBar* m_auxiliaryToolBar;
|
wxAuiToolBar* m_auxiliaryToolBar;
|
||||||
|
|
||||||
|
TOOL_MANAGER *m_toolManager;
|
||||||
|
TOOL_DISPATCHER *m_toolDispatcher;
|
||||||
|
|
||||||
|
void setupTools();
|
||||||
void updateGridSelectBox();
|
void updateGridSelectBox();
|
||||||
void updateZoomSelectBox();
|
void updateZoomSelectBox();
|
||||||
virtual void unitsChangeRefresh();
|
virtual void unitsChangeRefresh();
|
||||||
|
|
|
@ -65,7 +65,6 @@ class PARSE_ERROR;
|
||||||
class IO_ERROR;
|
class IO_ERROR;
|
||||||
class FP_LIB_TABLE;
|
class FP_LIB_TABLE;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class PCB_EDIT_FRAME
|
* class PCB_EDIT_FRAME
|
||||||
* the main frame for Pcbnew
|
* the main frame for Pcbnew
|
||||||
|
@ -118,6 +117,8 @@ protected:
|
||||||
bool m_useCmpFileForFpNames; ///< is true, use the .cmp file from CvPcb, else use the netlist
|
bool m_useCmpFileForFpNames; ///< is true, use the .cmp file from CvPcb, else use the netlist
|
||||||
// to know the footprint name of components.
|
// to know the footprint name of components.
|
||||||
|
|
||||||
|
void onGenericCommand( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
// we'll use lower case function names for private member functions.
|
// we'll use lower case function names for private member functions.
|
||||||
void createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu );
|
void createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu );
|
||||||
void createPopUpMenuForFootprints( MODULE* aModule, wxMenu* aPopMenu );
|
void createPopUpMenuForFootprints( MODULE* aModule, wxMenu* aPopMenu );
|
||||||
|
|
|
@ -216,6 +216,10 @@ set(PCBNEW_CLASS_SRCS
|
||||||
zones_polygons_test_connections.cpp
|
zones_polygons_test_connections.cpp
|
||||||
zones_test_and_combine_areas.cpp
|
zones_test_and_combine_areas.cpp
|
||||||
class_footprint_wizard.cpp
|
class_footprint_wizard.cpp
|
||||||
|
|
||||||
|
tools/selection_tool.cpp
|
||||||
|
tools/selection_area.cpp
|
||||||
|
tools/pcb_tools.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PCBNEW_SRCS ${PCBNEW_AUTOROUTER_SRCS} ${PCBNEW_CLASS_SRCS} ${PCBNEW_DIALOGS})
|
set(PCBNEW_SRCS ${PCBNEW_AUTOROUTER_SRCS} ${PCBNEW_CLASS_SRCS} ${PCBNEW_DIALOGS})
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
#include <trigo.h>
|
#include <trigo.h>
|
||||||
#include <pcb_painter.h>
|
#include <pcb_painter.h>
|
||||||
|
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <tool/tool_dispatcher.h>
|
||||||
|
|
||||||
// Configuration entry names.
|
// Configuration entry names.
|
||||||
static const wxString UserGridSizeXEntry( wxT( "PcbUserGrid_X" ) );
|
static const wxString UserGridSizeXEntry( wxT( "PcbUserGrid_X" ) );
|
||||||
|
@ -91,6 +93,8 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
|
||||||
EDA_DRAW_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName )
|
EDA_DRAW_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName )
|
||||||
{
|
{
|
||||||
m_Pcb = NULL;
|
m_Pcb = NULL;
|
||||||
|
m_toolManager = NULL;
|
||||||
|
m_toolDispatcher = NULL;
|
||||||
|
|
||||||
m_DisplayPadFill = true; // How to draw pads
|
m_DisplayPadFill = true; // How to draw pads
|
||||||
m_DisplayViaFill = true; // How to draw vias
|
m_DisplayViaFill = true; // How to draw vias
|
||||||
|
@ -111,6 +115,8 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
|
||||||
m_galCanvas = new EDA_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize,
|
m_galCanvas = new EDA_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize,
|
||||||
EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL );
|
EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL );
|
||||||
|
|
||||||
|
setupTools();
|
||||||
|
|
||||||
m_auxiliaryToolBar = NULL;
|
m_auxiliaryToolBar = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +191,11 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
|
||||||
view->RecacheAllItems( true );
|
view->RecacheAllItems( true );
|
||||||
if( m_galCanvasActive )
|
if( m_galCanvasActive )
|
||||||
m_galCanvas->Refresh();
|
m_galCanvas->Refresh();
|
||||||
|
|
||||||
|
// update the tool manager with the new board and its view.
|
||||||
|
if(m_toolManager)
|
||||||
|
m_toolManager->SetEnvironment( m_Pcb, view, m_galCanvas->GetViewControls(), this);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,6 +807,7 @@ void PCB_BASE_FRAME::LoadSettings()
|
||||||
wxASSERT( i < KiGfx::VIEW::VIEW_MAX_LAYERS );
|
wxASSERT( i < KiGfx::VIEW::VIEW_MAX_LAYERS );
|
||||||
|
|
||||||
view->SetLayerOrder( GalLayerOrder[i], i );
|
view->SetLayerOrder( GalLayerOrder[i], i );
|
||||||
|
view->SetLayerTarget( i, KiGfx::TARGET_NONCACHED );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Netnames are drawn only when scale is sufficient (level of details)
|
// Netnames are drawn only when scale is sufficient (level of details)
|
||||||
|
|
|
@ -298,6 +298,12 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
||||||
_( "Reset text size and width of all module fields to current defaults" ),
|
_( "Reset text size and width of all module fields to current defaults" ),
|
||||||
KiBitmap( reset_text_xpm ) );
|
KiBitmap( reset_text_xpm ) );
|
||||||
|
|
||||||
|
editMenu->AppendSeparator();
|
||||||
|
|
||||||
|
AddMenuItem( editMenu, ID_SELECTION_TOOL,
|
||||||
|
_( "Select Tool" ),
|
||||||
|
_( "Interactive selection and drag&drop tool." ) );
|
||||||
|
|
||||||
/** Create View menu **/
|
/** Create View menu **/
|
||||||
wxMenu* viewMenu = new wxMenu;
|
wxMenu* viewMenu = new wxMenu;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@
|
||||||
#include <view/view.h>
|
#include <view/view.h>
|
||||||
#include <painter.h>
|
#include <painter.h>
|
||||||
|
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <tool/tool_dispatcher.h>
|
||||||
|
|
||||||
#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
|
#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
|
||||||
#include <python_scripting.h>
|
#include <python_scripting.h>
|
||||||
|
@ -116,6 +118,12 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
|
||||||
EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit )
|
EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit )
|
||||||
|
|
||||||
// menu Config
|
// menu Config
|
||||||
|
|
||||||
|
/* Tom's hacks start */
|
||||||
|
EVT_MENU ( ID_SELECTION_TOOL, PCB_EDIT_FRAME::onGenericCommand )
|
||||||
|
EVT_TOOL ( ID_SELECTION_TOOL, PCB_EDIT_FRAME::onGenericCommand )
|
||||||
|
/* Tom's hacks end */
|
||||||
|
|
||||||
EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions )
|
EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions )
|
||||||
EVT_MENU( ID_CONFIG_REQ, PCB_EDIT_FRAME::Process_Config )
|
EVT_MENU( ID_CONFIG_REQ, PCB_EDIT_FRAME::Process_Config )
|
||||||
EVT_MENU( ID_PCB_LIB_TABLE_EDIT, PCB_EDIT_FRAME::Process_Config )
|
EVT_MENU( ID_PCB_LIB_TABLE_EDIT, PCB_EDIT_FRAME::Process_Config )
|
||||||
|
@ -472,8 +480,9 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
|
||||||
DisplayError( this, msg );
|
DisplayError( this, msg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
setupTools();
|
||||||
|
}
|
||||||
|
|
||||||
PCB_EDIT_FRAME::~PCB_EDIT_FRAME()
|
PCB_EDIT_FRAME::~PCB_EDIT_FRAME()
|
||||||
{
|
{
|
||||||
|
|
|
@ -367,6 +367,8 @@ enum pcbnew_ids
|
||||||
ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
|
ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
|
||||||
ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD,
|
ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD,
|
||||||
|
|
||||||
|
ID_SELECTION_TOOL
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PCBNEW_ID_H_
|
#endif // PCBNEW_ID_H_
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 CERN
|
||||||
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <wx/wx.h>
|
||||||
|
#include <wx/event.h>
|
||||||
|
|
||||||
|
#include <wxPcbStruct.h>
|
||||||
|
#include <wxBasePcbFrame.h>
|
||||||
|
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <tool/tool_dispatcher.h>
|
||||||
|
|
||||||
|
#include <class_drawpanel_gal.h>
|
||||||
|
#include <pcbnew_id.h>
|
||||||
|
|
||||||
|
#include "selection_tool.h"
|
||||||
|
|
||||||
|
void PCB_BASE_FRAME::setupTools()
|
||||||
|
{
|
||||||
|
// create the manager and dispatcher. Route draw panel events to the dispatcher.
|
||||||
|
m_toolManager = new TOOL_MANAGER;
|
||||||
|
m_toolDispatcher = new TOOL_DISPATCHER_PCBNEW( m_toolManager, this );
|
||||||
|
m_galCanvas->SetEventDispatcher (m_toolDispatcher);
|
||||||
|
|
||||||
|
// register our selection tool.
|
||||||
|
m_toolManager->RegisterTool(new SELECTION_TOOL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCB_EDIT_FRAME::onGenericCommand(wxCommandEvent &aEvent)
|
||||||
|
{
|
||||||
|
m_toolDispatcher->DispatchWxCommand(aEvent);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 CERN
|
||||||
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <wx/wx.h>
|
||||||
|
|
||||||
|
#include <layers_id_colors_and_visibility.h>
|
||||||
|
|
||||||
|
#include "selection_area.h"
|
||||||
|
|
||||||
|
using namespace KiGfx;
|
||||||
|
|
||||||
|
const BOX2I SELECTION_AREA::ViewBBox() const
|
||||||
|
{
|
||||||
|
BOX2I tmp;
|
||||||
|
tmp.SetOrigin(m_origin);
|
||||||
|
tmp.SetEnd(m_end);
|
||||||
|
tmp.Normalize();
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SELECTION_AREA::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||||
|
{
|
||||||
|
aLayers[0] = SelectionLayer;
|
||||||
|
aCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SELECTION_AREA::ViewDraw( int aLayer, GAL* aGal, const BOX2I& aVisibleArea ) const
|
||||||
|
{
|
||||||
|
VECTOR2D width = m_view->ToWorld( VECTOR2D(1.0, 1.0), false ); // fixme: pixel-sized stroke width setting?
|
||||||
|
aGal->SetLineWidth( width.x );
|
||||||
|
aGal->SetStrokeColor(COLOR4D(1.0, 1.0, 0.4, 1.0));
|
||||||
|
aGal->SetFillColor(COLOR4D(0.3, 0.3, 0.5, 0.3));
|
||||||
|
aGal->SetIsStroke(true);
|
||||||
|
aGal->SetIsFill(true);
|
||||||
|
aGal->SetLayerDepth(100.0);
|
||||||
|
aGal->DrawRectangle(m_origin, m_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
SELECTION_AREA::SELECTION_AREA():
|
||||||
|
EDA_ITEM(NOT_USED) // this item is never added to a BOARD so it needs no type.
|
||||||
|
{}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 CERN
|
||||||
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SELECTION_AREA_H
|
||||||
|
#define __SELECTION_AREA_H
|
||||||
|
|
||||||
|
#include <tool/tool_event.h>
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
|
||||||
|
#include <math/box2.h>
|
||||||
|
|
||||||
|
#include <view/view.h>
|
||||||
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
#include <base_struct.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SELECTION_AREA
|
||||||
|
*
|
||||||
|
* Represents a selection area (currently a rectangle) in a VIEW.
|
||||||
|
*/
|
||||||
|
class SELECTION_AREA : public EDA_ITEM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const int SelectionLayer = 126; // fixme: define globally
|
||||||
|
|
||||||
|
SELECTION_AREA();
|
||||||
|
~SELECTION_AREA() {};
|
||||||
|
|
||||||
|
virtual const BOX2I ViewBBox() const;
|
||||||
|
|
||||||
|
void ViewDraw( int aLayer, KiGfx::GAL* aGal, const BOX2I& aVisibleArea ) const;
|
||||||
|
void ViewGetLayers( int aLayers[], int& aCount ) const;
|
||||||
|
|
||||||
|
void SetOrigin ( VECTOR2I aOrigin )
|
||||||
|
{
|
||||||
|
m_origin = aOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetEnd ( VECTOR2I aEnd )
|
||||||
|
{
|
||||||
|
m_end = aEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Show(int x, std::ostream& st) const
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
VECTOR2I m_origin, m_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,276 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 CERN
|
||||||
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include <class_drawpanel_gal.h>
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <class_board_item.h>
|
||||||
|
#include <class_module.h>
|
||||||
|
|
||||||
|
#include <wxPcbStruct.h>
|
||||||
|
#include <collectors.h>
|
||||||
|
|
||||||
|
#include <tool/context_menu.h>
|
||||||
|
|
||||||
|
#include "selection_tool.h"
|
||||||
|
#include "selection_area.h"
|
||||||
|
|
||||||
|
using namespace KiGfx;
|
||||||
|
using boost::optional;
|
||||||
|
|
||||||
|
|
||||||
|
SELECTION_TOOL::SELECTION_TOOL() :
|
||||||
|
TOOL_INTERACTIVE( "pcbnew.InteractiveSelection" )
|
||||||
|
{
|
||||||
|
m_selArea = new SELECTION_AREA;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SELECTION_TOOL::~SELECTION_TOOL()
|
||||||
|
{
|
||||||
|
if(m_selArea)
|
||||||
|
delete m_selArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SELECTION_TOOL::Reset()
|
||||||
|
{
|
||||||
|
// the tool launches upon reception of activate ("pcbnew.InteractiveSelection")
|
||||||
|
Go(&SELECTION_TOOL::Main, TOOL_EVENT(TC_Command, TA_ActivateTool, GetName())); //"pcbnew.InteractiveSelection"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int SELECTION_TOOL::Main(TOOL_EVENT& aEvent)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Main loop: keep receiving events
|
||||||
|
while(OPT_TOOL_EVENT evt = Wait ())
|
||||||
|
{
|
||||||
|
|
||||||
|
if(evt->IsCancel ())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// single click? Select single object
|
||||||
|
if( evt->IsClick (MB_Left) )
|
||||||
|
selectSingle(evt->Position(), evt->Modifier( MB_ModShift ));
|
||||||
|
|
||||||
|
// drag with LMB? Select multiple objects (or at least draw a selection box)
|
||||||
|
if (evt->IsDrag ( MB_Left ))
|
||||||
|
selectMultiple();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SELECTION_TOOL::toggleSelection ( BOARD_ITEM * aItem, bool aAdditive )
|
||||||
|
{
|
||||||
|
|
||||||
|
if(m_selectedItems.find(aItem) != m_selectedItems.end())
|
||||||
|
{
|
||||||
|
aItem->ViewSetHighlighted(false);
|
||||||
|
m_selectedItems.erase(aItem);
|
||||||
|
} else {
|
||||||
|
if(!aAdditive)
|
||||||
|
clearSelection();
|
||||||
|
aItem->ViewSetHighlighted(true);
|
||||||
|
m_selectedItems.insert(aItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SELECTION_TOOL::clearSelection ()
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(BOARD_ITEM *item, m_selectedItems)
|
||||||
|
{
|
||||||
|
item->ViewSetHighlighted(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_selectedItems.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SELECTION_TOOL::selectSingle( const VECTOR2I &aWhere, bool aAdditive )
|
||||||
|
{
|
||||||
|
BOARD *pcb = getModel<BOARD> (PCB_T);
|
||||||
|
BOARD_ITEM *item;
|
||||||
|
GENERAL_COLLECTORS_GUIDE guide = getEditFrame<PCB_EDIT_FRAME>()->GetCollectorsGuide();
|
||||||
|
GENERAL_COLLECTOR collector;
|
||||||
|
|
||||||
|
collector.Collect(pcb, GENERAL_COLLECTOR::AllBoardItems , wxPoint(aWhere.x, aWhere.y), guide);
|
||||||
|
|
||||||
|
switch (collector.GetCount())
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if(!aAdditive)
|
||||||
|
clearSelection();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
toggleSelection( collector[0], aAdditive );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
item = disambiguationMenu(&collector);
|
||||||
|
if(item)
|
||||||
|
toggleSelection(item, aAdditive );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector )
|
||||||
|
{
|
||||||
|
int count = aCollector->GetPrimaryCount(); // try to use preferred layer
|
||||||
|
if( 0 == count ) count = aCollector->GetCount();
|
||||||
|
|
||||||
|
for( int i = 0; i<count; ++i )
|
||||||
|
{
|
||||||
|
if( (*aCollector)[i]->Type() != PCB_MODULE_T )
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all are modules, now find smallest MODULE
|
||||||
|
|
||||||
|
int minDim = 0x7FFFFFFF;
|
||||||
|
int minNdx = 0;
|
||||||
|
|
||||||
|
for( int i = 0; i<count; ++i )
|
||||||
|
{
|
||||||
|
MODULE* module = (MODULE*) (*aCollector)[i];
|
||||||
|
|
||||||
|
int lx = module->GetBoundingBox().GetWidth();
|
||||||
|
int ly = module->GetBoundingBox().GetHeight();
|
||||||
|
|
||||||
|
int lmin = std::min( lx, ly );
|
||||||
|
|
||||||
|
if( lmin < minDim )
|
||||||
|
{
|
||||||
|
minDim = lmin;
|
||||||
|
minNdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*aCollector)[minNdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SELECTION_TOOL::handleHighlight( const VECTOR2D& aP )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SELECTION_TOOL::selectMultiple()
|
||||||
|
{
|
||||||
|
OPT_TOOL_EVENT evt;
|
||||||
|
VIEW *v = getView();
|
||||||
|
|
||||||
|
v->Add(m_selArea);
|
||||||
|
|
||||||
|
while (evt = Wait())
|
||||||
|
{
|
||||||
|
if(evt->IsCancel())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(evt->IsDrag( MB_Left ))
|
||||||
|
{
|
||||||
|
m_selArea->SetOrigin( evt->DragOrigin() );
|
||||||
|
m_selArea->SetEnd( evt->Position() );
|
||||||
|
m_selArea->ViewSetVisible(true);
|
||||||
|
m_selArea->ViewUpdate(VIEW_ITEM::APPEARANCE | VIEW_ITEM::GEOMETRY);
|
||||||
|
|
||||||
|
|
||||||
|
v->SetLayerVisible( SELECTION_AREA::SelectionLayer );
|
||||||
|
v->SetLayerOrder( SELECTION_AREA::SelectionLayer, 1000);
|
||||||
|
v->SetLayerTarget( SELECTION_AREA::SelectionLayer, TARGET_OVERLAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
if(evt->IsMouseUp( MB_Left ))
|
||||||
|
{
|
||||||
|
m_selArea->ViewSetVisible(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
v->Remove(m_selArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOARD_ITEM *SELECTION_TOOL::disambiguationMenu ( GENERAL_COLLECTOR *aCollector )
|
||||||
|
{
|
||||||
|
CONTEXT_MENU cmenu;
|
||||||
|
OPT_TOOL_EVENT evt ;
|
||||||
|
BOARD_ITEM *current = NULL;
|
||||||
|
|
||||||
|
cmenu.SetTitle( _("Clarify selection"));
|
||||||
|
|
||||||
|
int limit = std::min( 10, aCollector->GetCount() );
|
||||||
|
|
||||||
|
for( int i = 0; i<limit; ++i )
|
||||||
|
{
|
||||||
|
wxString text;
|
||||||
|
BOARD_ITEM *item = (*aCollector) [i];
|
||||||
|
text = item->GetSelectMenuText();
|
||||||
|
cmenu.Add(text, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetContextMenu(&cmenu, CMENU_NOW);
|
||||||
|
|
||||||
|
while (evt = Wait())
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if(evt->Action() == TA_ContextMenuUpdate )
|
||||||
|
{
|
||||||
|
if(current)
|
||||||
|
current->ViewSetHighlighted(false);
|
||||||
|
|
||||||
|
int id = *evt->GetCommandId();
|
||||||
|
if(id >= 0)
|
||||||
|
{
|
||||||
|
current = (*aCollector) [id];
|
||||||
|
current->ViewSetHighlighted(true);
|
||||||
|
} else
|
||||||
|
current = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
} else if(evt->Action() == TA_ContextMenuChoice ) {
|
||||||
|
|
||||||
|
optional<int> id = evt->GetCommandId();
|
||||||
|
|
||||||
|
if(current)
|
||||||
|
current->ViewSetHighlighted(false);
|
||||||
|
|
||||||
|
if(id && (*id >= 0))
|
||||||
|
{
|
||||||
|
current = (*aCollector) [*id];
|
||||||
|
current->ViewSetHighlighted(true);
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 CERN
|
||||||
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SELECTION_TOOL_H
|
||||||
|
#define __SELECTION_TOOL_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
#include <tool/tool_interactive.h>
|
||||||
|
|
||||||
|
class SELECTION_AREA;
|
||||||
|
class BOARD_ITEM;
|
||||||
|
class GENERAL_COLLECTOR;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SELECTION_AREA
|
||||||
|
*
|
||||||
|
* Our sample selection tool: currently supports:
|
||||||
|
* - pick single objects (click LMB)
|
||||||
|
* - add objects to existing selection (Shift+LMB)
|
||||||
|
* - draw selection box (drag LMB)
|
||||||
|
*
|
||||||
|
* WORK IN PROGRESS. CONSIDER AS A DEMO!
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SELECTION_TOOL : public TOOL_INTERACTIVE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SELECTION_TOOL ();
|
||||||
|
~SELECTION_TOOL ();
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
int Main(TOOL_EVENT& aEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void selectSingle( const VECTOR2I &aWhere, bool aAdditive );
|
||||||
|
void selectMultiple ();
|
||||||
|
void handleHighlight( const VECTOR2D& aP );
|
||||||
|
BOARD_ITEM* disambiguationMenu ( GENERAL_COLLECTOR* aItems );
|
||||||
|
BOARD_ITEM* pickSmallestComponent( GENERAL_COLLECTOR* aCollector );
|
||||||
|
void toggleSelection ( BOARD_ITEM * aItem, bool aAdditive );
|
||||||
|
void clearSelection ();
|
||||||
|
|
||||||
|
std::set<BOARD_ITEM *> m_selectedItems;
|
||||||
|
SELECTION_AREA *m_selArea;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue