Browse Source
pcbnew: hooked Tool Framework into the edit panel. Added a sample selection tool (not fully functional).
pull/1/head
pcbnew: hooked Tool Framework into the edit panel. Added a sample selection tool (not fully functional).
pull/1/head
14 changed files with 632 additions and 6 deletions
-
40common/drawpanel_gal.cpp
-
11include/class_drawpanel_gal.h
-
7include/wxBasePcbFrame.h
-
3include/wxPcbStruct.h
-
4pcbnew/CMakeLists.txt
-
14pcbnew/basepcbframe.cpp
-
6pcbnew/menubar_pcbframe.cpp
-
11pcbnew/pcbframe.cpp
-
2pcbnew/pcbnew_id.h
-
55pcbnew/tools/pcb_tools.cpp
-
62pcbnew/tools/selection_area.cpp
-
76pcbnew/tools/selection_area.h
-
276pcbnew/tools/selection_tool.cpp
-
71pcbnew/tools/selection_tool.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 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue