pcbnew: hooked Tool Framework into the edit panel. Added a sample selection tool (not fully functional).

This commit is contained in:
tomasz. 2013-08-02 16:53:50 +02:00
parent 4c777e92f3
commit 69a44d5f13
14 changed files with 632 additions and 6 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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" ) );
@ -79,7 +81,7 @@ BEGIN_EVENT_TABLE( PCB_BASE_FRAME, EDA_DRAW_FRAME )
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_PADS_SKETCH, PCB_BASE_FRAME::OnUpdatePadDrawMode ) EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_PADS_SKETCH, PCB_BASE_FRAME::OnUpdatePadDrawMode )
EVT_UPDATE_UI( ID_ON_GRID_SELECT, PCB_BASE_FRAME::OnUpdateSelectGrid ) EVT_UPDATE_UI( ID_ON_GRID_SELECT, PCB_BASE_FRAME::OnUpdateSelectGrid )
EVT_UPDATE_UI( ID_ON_ZOOM_SELECT, PCB_BASE_FRAME::OnUpdateSelectZoom ) EVT_UPDATE_UI( ID_ON_ZOOM_SELECT, PCB_BASE_FRAME::OnUpdateSelectZoom )
EVT_UPDATE_UI_RANGE( ID_ZOOM_IN, ID_ZOOM_PAGE, PCB_BASE_FRAME::OnUpdateSelectZoom ) EVT_UPDATE_UI_RANGE( ID_ZOOM_IN, ID_ZOOM_PAGE, PCB_BASE_FRAME::OnUpdateSelectZoom )
END_EVENT_TABLE() END_EVENT_TABLE()
@ -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)

View File

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

View File

@ -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,9 +480,10 @@ 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()
{ {
m_RecordingMacros = -1; m_RecordingMacros = -1;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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