refactoring: allow to run TOOL_MANAGER and SELECTION_TOOL without a host wxFrame
This commit is contained in:
parent
06f3b35255
commit
781008bfa5
|
@ -233,8 +233,12 @@ int ACTION_MANAGER::processHotKey( TOOL_ACTION* aAction )
|
|||
if( ( hotkey & TOOL_ACTION::LEGACY_HK ) )
|
||||
{
|
||||
hotkey = hotkey & ~TOOL_ACTION::LEGACY_HK; // it leaves only HK_xxx identifier
|
||||
EDA_DRAW_FRAME* frame = static_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetEditFrame() );
|
||||
EDA_HOTKEY* hk_desc = frame->GetHotKeyDescription( hotkey );
|
||||
|
||||
auto frame = dynamic_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetEditFrame() );
|
||||
EDA_HOTKEY* hk_desc = nullptr;
|
||||
|
||||
if( frame )
|
||||
hk_desc = frame->GetHotKeyDescription( hotkey );
|
||||
|
||||
if( hk_desc )
|
||||
{
|
||||
|
|
|
@ -146,7 +146,7 @@ void TOOL_DISPATCHER::ResetState()
|
|||
|
||||
KIGFX::VIEW* TOOL_DISPATCHER::getView()
|
||||
{
|
||||
return static_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetEditFrame() )->GetGalCanvas()->GetView();
|
||||
return m_toolMgr->GetView();
|
||||
}
|
||||
|
||||
|
||||
|
@ -451,7 +451,11 @@ void TOOL_DISPATCHER::updateUI()
|
|||
{
|
||||
// TODO I don't feel it is the right place for updating UI,
|
||||
// but at the moment I cannot think of a better one..
|
||||
EDA_DRAW_FRAME* frame = static_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetEditFrame() );
|
||||
frame->UpdateStatusBar();
|
||||
//frame->UpdateMsgPanel();
|
||||
|
||||
auto frame = dynamic_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetEditFrame() );
|
||||
if( frame )
|
||||
{
|
||||
frame->UpdateStatusBar();
|
||||
//frame->UpdateMsgPanel();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -674,7 +674,14 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent )
|
|||
// Run update handlers on the created copy
|
||||
menu->UpdateAll();
|
||||
m_menuActive = true;
|
||||
GetEditFrame()->PopupMenu( menu.get() );
|
||||
|
||||
auto frame = dynamic_cast<wxFrame*>( m_editFrame );
|
||||
|
||||
if( frame )
|
||||
{
|
||||
frame->PopupMenu( menu.get() );
|
||||
}
|
||||
|
||||
m_menuActive = false;
|
||||
|
||||
m_viewControls->WarpCursor( cursor, true, false );
|
||||
|
@ -739,8 +746,11 @@ bool TOOL_MANAGER::ProcessEvent( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( m_view->IsDirty() )
|
||||
{
|
||||
EDA_DRAW_FRAME* f = static_cast<EDA_DRAW_FRAME*>( GetEditFrame() );
|
||||
f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
|
||||
auto f = dynamic_cast<EDA_DRAW_FRAME*>( GetEditFrame() );
|
||||
if( f )
|
||||
{
|
||||
f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
|
||||
}
|
||||
}
|
||||
|
||||
return hotkey_handled;
|
||||
|
|
|
@ -195,6 +195,16 @@ void PCB_TOOL::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE* aPlacer,
|
|||
view()->Remove( &preview );
|
||||
}
|
||||
|
||||
void PCB_TOOL::Reset( RESET_REASON aReason )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PCB_TOOL::setTransitions()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PCB_DISPLAY_OPTIONS* PCB_TOOL::displayOptions() const
|
||||
{
|
||||
return static_cast<PCB_DISPLAY_OPTIONS*>( frame()->GetDisplayOptions() );
|
||||
|
|
|
@ -79,6 +79,8 @@ public:
|
|||
|
||||
virtual ~PCB_TOOL() {};
|
||||
|
||||
virtual void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
/**
|
||||
* Function SetEditModules()
|
||||
*
|
||||
|
@ -123,6 +125,9 @@ protected:
|
|||
const wxString& aCommitMessage,
|
||||
int aOptions = IPO_ROTATE | IPO_FLIP | IPO_REPEAT );
|
||||
|
||||
virtual void setTransitions() override;
|
||||
|
||||
|
||||
KIGFX::PCB_VIEW* view() const { return static_cast<KIGFX::PCB_VIEW*>( getView() ); }
|
||||
KIGFX::VIEW_CONTROLS* controls() const { return getViewControls(); }
|
||||
PCB_EDIT_FRAME* frame() const { return getEditFrame<PCB_EDIT_FRAME>(); }
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
* Copyright (C) 2017 KiCad Developers, see CHANGELOG.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 <limits>
|
||||
|
||||
#include <functional>
|
||||
using namespace std::placeholders;
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_board_item.h>
|
||||
#include <class_track.h>
|
||||
#include <class_module.h>
|
||||
#include <class_pcb_text.h>
|
||||
#include <class_drawsegment.h>
|
||||
#include <class_zone.h>
|
||||
|
||||
#include <wxPcbStruct.h>
|
||||
|
||||
#include <class_draw_panel_gal.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <view/view_group.h>
|
||||
#include <preview_items/selection_area.h>
|
||||
#include <painter.h>
|
||||
#include <bitmaps.h>
|
||||
#include <hotkeys.h>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <connectivity.h>
|
||||
|
||||
#include "selection_tool.h"
|
||||
#include "pcb_bright_box.h"
|
||||
#include "pcb_actions.h"
|
||||
|
||||
#include "kicad_plugin.h"
|
||||
|
||||
// TODO(JE) Only works for BOARD_ITEM
|
||||
VECTOR2I SELECTION::GetPosition() const
|
||||
{
|
||||
return static_cast<VECTOR2I>( GetBoundingBox().GetPosition() );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I SELECTION::GetCenter() const
|
||||
{
|
||||
return static_cast<VECTOR2I>( GetBoundingBox().Centre() );
|
||||
}
|
||||
|
||||
|
||||
EDA_RECT SELECTION::GetBoundingBox() const
|
||||
{
|
||||
EDA_RECT bbox;
|
||||
|
||||
bbox = Front()->GetBoundingBox();
|
||||
auto i = m_items.begin();
|
||||
++i;
|
||||
|
||||
for( ; i != m_items.end(); ++i )
|
||||
{
|
||||
bbox.Merge( (*i)->GetBoundingBox() );
|
||||
}
|
||||
|
||||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
EDA_ITEM* SELECTION::GetTopLeftItem( bool onlyModules ) const
|
||||
{
|
||||
BOARD_ITEM* topLeftItem = nullptr;
|
||||
BOARD_ITEM* currentItem;
|
||||
|
||||
wxPoint pnt;
|
||||
|
||||
// find the leftmost (smallest x coord) and highest (smallest y with the smallest x) item in the selection
|
||||
for( auto item : m_items )
|
||||
{
|
||||
currentItem = static_cast<BOARD_ITEM*>( item );
|
||||
pnt = currentItem->GetPosition();
|
||||
|
||||
if( ( currentItem->Type() != PCB_MODULE_T ) && onlyModules )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( topLeftItem == nullptr )
|
||||
{
|
||||
topLeftItem = currentItem;
|
||||
}
|
||||
else if( ( pnt.x < topLeftItem->GetPosition().x ) ||
|
||||
( ( topLeftItem->GetPosition().x == pnt.x ) &&
|
||||
( pnt.y < topLeftItem->GetPosition().y ) ) )
|
||||
{
|
||||
topLeftItem = currentItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<EDA_ITEM*>( topLeftItem );
|
||||
}
|
||||
|
||||
|
||||
EDA_ITEM* SELECTION::GetTopLeftModule() const
|
||||
{
|
||||
return GetTopLeftItem( true );
|
||||
}
|
||||
|
||||
|
||||
const BOX2I SELECTION::ViewBBox() const
|
||||
{
|
||||
BOX2I r;
|
||||
r.SetMaximum();
|
||||
return r;
|
||||
EDA_RECT eda_bbox;
|
||||
|
||||
if( Size() == 1 )
|
||||
{
|
||||
eda_bbox = Front()->GetBoundingBox();
|
||||
}
|
||||
else if( Size() > 1 )
|
||||
{
|
||||
eda_bbox = Front()->GetBoundingBox();
|
||||
auto i = m_items.begin();
|
||||
++i;
|
||||
|
||||
for( ; i != m_items.end(); ++i )
|
||||
{
|
||||
eda_bbox.Merge( (*i)->GetBoundingBox() );
|
||||
}
|
||||
}
|
||||
|
||||
return BOX2I( eda_bbox.GetOrigin(), eda_bbox.GetSize() );
|
||||
}
|
||||
|
||||
|
||||
const KIGFX::VIEW_GROUP::ITEMS SELECTION::updateDrawList() const
|
||||
{
|
||||
std::vector<VIEW_ITEM*> items;
|
||||
|
||||
for( auto item : m_items )
|
||||
{
|
||||
items.push_back( item );
|
||||
|
||||
if( item->Type() == PCB_MODULE_T )
|
||||
{
|
||||
MODULE* module = static_cast<MODULE*>( item );
|
||||
module->RunOnChildren( [&] ( BOARD_ITEM* bitem ) { items.push_back( bitem ); } );
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
|
@ -202,7 +202,12 @@ bool SELECTION_TOOL::Init()
|
|||
// only show separator if there is a Select menu to show above it
|
||||
menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 );
|
||||
|
||||
m_menu.AddStandardSubMenus( *getEditFrame<PCB_BASE_FRAME>() );
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
|
||||
if( frame )
|
||||
{
|
||||
m_menu.AddStandardSubMenus( *frame );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -226,8 +231,8 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason )
|
|||
clearSelection();
|
||||
|
||||
// Reinsert the VIEW_GROUP, in case it was removed from the VIEW
|
||||
getView()->Remove( &m_selection );
|
||||
getView()->Add( &m_selection );
|
||||
view()->Remove( &m_selection );
|
||||
view()->Add( &m_selection );
|
||||
}
|
||||
|
||||
|
||||
|
@ -399,7 +404,10 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem )
|
|||
}
|
||||
}
|
||||
|
||||
m_frame->GetGalCanvas()->ForceRefresh();
|
||||
if( m_frame )
|
||||
{
|
||||
m_frame->GetGalCanvas()->ForceRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -574,10 +582,13 @@ bool SELECTION_TOOL::selectMultiple()
|
|||
}
|
||||
}
|
||||
|
||||
if( m_selection.Size() == 1 )
|
||||
m_frame->SetCurItem( static_cast<BOARD_ITEM*>( m_selection.Front() ) );
|
||||
else
|
||||
m_frame->SetCurItem( NULL );
|
||||
if( m_frame )
|
||||
{
|
||||
if( m_selection.Size() == 1 )
|
||||
m_frame->SetCurItem( static_cast<BOARD_ITEM*>( m_selection.Front() ) );
|
||||
else
|
||||
m_frame->SetCurItem( NULL );
|
||||
}
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( !m_selection.Empty() )
|
||||
|
@ -1539,16 +1550,18 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem )
|
|||
m_selection.Add( aItem );
|
||||
selectVisually( aItem );
|
||||
|
||||
|
||||
if( m_selection.Size() == 1 )
|
||||
if( m_frame )
|
||||
{
|
||||
// Set as the current item, so the information about selection is displayed
|
||||
m_frame->SetCurItem( aItem, true );
|
||||
}
|
||||
else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
|
||||
{ // called for every next selected item
|
||||
// If multiple items are selected, do not show the information about the selected item
|
||||
m_frame->SetCurItem( NULL, true );
|
||||
if( m_selection.Size() == 1 )
|
||||
{
|
||||
// Set as the current item, so the information about selection is displayed
|
||||
m_frame->SetCurItem( aItem, true );
|
||||
}
|
||||
else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
|
||||
{ // called for every next selected item
|
||||
// If multiple items are selected, do not show the information about the selected item
|
||||
m_frame->SetCurItem( NULL, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1563,7 +1576,10 @@ void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
|
|||
|
||||
if( m_selection.Empty() )
|
||||
{
|
||||
m_frame->SetCurItem( NULL );
|
||||
if( m_frame )
|
||||
{
|
||||
m_frame->SetCurItem( NULL );
|
||||
}
|
||||
m_locked = true;
|
||||
}
|
||||
}
|
||||
|
@ -1996,121 +2012,6 @@ bool SELECTION_TOOL::SanitizeSelection()
|
|||
}
|
||||
|
||||
|
||||
// TODO(JE) Only works for BOARD_ITEM
|
||||
VECTOR2I SELECTION::GetPosition() const
|
||||
{
|
||||
return static_cast<VECTOR2I>( GetBoundingBox().GetPosition() );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I SELECTION::GetCenter() const
|
||||
{
|
||||
return static_cast<VECTOR2I>( GetBoundingBox().Centre() );
|
||||
}
|
||||
|
||||
|
||||
EDA_RECT SELECTION::GetBoundingBox() const
|
||||
{
|
||||
EDA_RECT bbox;
|
||||
|
||||
bbox = Front()->GetBoundingBox();
|
||||
auto i = m_items.begin();
|
||||
++i;
|
||||
|
||||
for( ; i != m_items.end(); ++i )
|
||||
{
|
||||
bbox.Merge( (*i)->GetBoundingBox() );
|
||||
}
|
||||
|
||||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
EDA_ITEM* SELECTION::GetTopLeftItem( bool onlyModules ) const
|
||||
{
|
||||
BOARD_ITEM* topLeftItem = nullptr;
|
||||
BOARD_ITEM* currentItem;
|
||||
|
||||
wxPoint pnt;
|
||||
|
||||
// find the leftmost (smallest x coord) and highest (smallest y with the smallest x) item in the selection
|
||||
for( auto item : m_items )
|
||||
{
|
||||
currentItem = static_cast<BOARD_ITEM*>( item );
|
||||
pnt = currentItem->GetPosition();
|
||||
|
||||
if( ( currentItem->Type() != PCB_MODULE_T ) && onlyModules )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( topLeftItem == nullptr )
|
||||
{
|
||||
topLeftItem = currentItem;
|
||||
}
|
||||
else if( ( pnt.x < topLeftItem->GetPosition().x ) ||
|
||||
( ( topLeftItem->GetPosition().x == pnt.x ) &&
|
||||
( pnt.y < topLeftItem->GetPosition().y ) ) )
|
||||
{
|
||||
topLeftItem = currentItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<EDA_ITEM*>( topLeftItem );
|
||||
}
|
||||
|
||||
|
||||
EDA_ITEM* SELECTION::GetTopLeftModule() const
|
||||
{
|
||||
return GetTopLeftItem( true );
|
||||
}
|
||||
|
||||
|
||||
const BOX2I SELECTION::ViewBBox() const
|
||||
{
|
||||
EDA_RECT eda_bbox;
|
||||
|
||||
if( Size() == 1 )
|
||||
{
|
||||
eda_bbox = Front()->GetBoundingBox();
|
||||
}
|
||||
else if( Size() > 1 )
|
||||
{
|
||||
eda_bbox = Front()->GetBoundingBox();
|
||||
auto i = m_items.begin();
|
||||
++i;
|
||||
|
||||
for( ; i != m_items.end(); ++i )
|
||||
{
|
||||
eda_bbox.Merge( (*i)->GetBoundingBox() );
|
||||
}
|
||||
}
|
||||
|
||||
return BOX2I( eda_bbox.GetOrigin(), eda_bbox.GetSize() );
|
||||
}
|
||||
|
||||
|
||||
const KIGFX::VIEW_GROUP::ITEMS SELECTION::updateDrawList() const
|
||||
{
|
||||
std::vector<VIEW_ITEM*> items;
|
||||
|
||||
for( auto item : m_items )
|
||||
{
|
||||
items.push_back( item );
|
||||
|
||||
if( item->Type() == PCB_MODULE_T )
|
||||
{
|
||||
MODULE* module = static_cast<MODULE*>( item );
|
||||
module->RunOnChildren( [&] ( BOARD_ITEM* bitem ) { items.push_back( bitem ); } );
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
|
||||
const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
|
||||
const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
|
||||
|
|
Loading…
Reference in New Issue