#include "useless_tool.h"
#include <class_draw_panel_gal.h>
#include <view/view_controls.h>
#include <view/view.h>
#include <tool/tool_manager.h>
#include <board_commit.h>
// For frame ToolID values
#include <pcbnew_id.h>
// For action icons
#include <bitmaps.h>
// Items tool can act on
#include <class_board_item.h>
#include <class_drawsegment.h>
// Access to other PCB actions and tools
#include "pcb_actions.h"
#include "selection_tool.h"
/*
* Tool-specific action definitions
*/
TOOL_ACTION PCB_ACTIONS::uselessMoveItemLeft(
"pcbnew.UselessTool.MoveItemLeft",
AS_GLOBAL, MD_CTRL + MD_SHIFT + int( 'L' ),
_( "Move item left" ), _( "Select and move item left" ) );
TOOL_ACTION PCB_ACTIONS::uselessFixedCircle(
"pcbnew.UselessTool.FixedCircle",
AS_GLOBAL, MD_CTRL + MD_SHIFT + int( 'C' ),
_( "Fixed circle" ), _( "Add a fixed size circle in a fixed place" ),
add_circle_xpm );
/*
* USELESS_TOOL implementation
*/
USELESS_TOOL::USELESS_TOOL() :
PCB_TOOL( "pcbnew.UselessTool" ),
m_menu( *this )
{
}
USELESS_TOOL::~USELESS_TOOL()
{}
void USELESS_TOOL::Reset( RESET_REASON aReason )
{
}
bool USELESS_TOOL::Init()
{
auto& menu = m_menu.GetMenu();
// add our own tool's action
menu.AddItem( PCB_ACTIONS::uselessFixedCircle );
// add the PCB_EDITOR_CONTROL's zone unfill all action
menu.AddItem( PCB_ACTIONS::zoneUnfillAll );
// Add standard zoom and grid tool actions
m_menu.AddStandardSubMenus( *getEditFrame<PCB_BASE_FRAME>() );
return true;
}
void USELESS_TOOL::moveLeftInt()
{
// we will call actions on the selection tool to get the current
// selection. The selection tools will handle item disambiguation
PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
assert( selectionTool );
// call the actions
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
selectionTool->SanitizeSelection();
const SELECTION& selection = selectionTool->GetSelection();
// nothing selected, return to event loop
if( selection.Empty() )
return;
BOARD_COMMIT commit( this );
// iterate BOARD_ITEM* container, moving each item
for( auto item : selection )
{
commit.Modify( item );
item->Move( wxPoint( -5 * IU_PER_MM, 0 ) );
}
// push commit - if selection were empty, this is a no-op
commit.Push( "Move left" );
}
int USELESS_TOOL::moveLeft( const TOOL_EVENT& aEvent )
{
auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
// set tool hint and cursor (actually looks like a crosshair)
frame.SetToolID( ID_NO_TOOL_SELECTED,
wxCURSOR_PENCIL, _( "Select item to move left" ) );
getViewControls()->ShowCursor( true );
Activate();
// handle tool events for as long as the tool is active
while( OPT_TOOL_EVENT evt = Wait() )
{
if( evt->IsCancel() || evt->IsActivate() )
{
// end of interactive tool
break;
}
else if( evt->IsClick( BUT_RIGHT ) )
{
m_menu.ShowContextMenu();
}
else if( evt->IsClick( BUT_LEFT ) )
{
// invoke the main action logic
moveLeftInt();
// keep showing the edit cursor
getViewControls()->ShowCursor( true );
}
}
// reset the PCB frame to how it was we got it
frame.SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
getViewControls()->ShowCursor( false );
// exit action
return 0;
}
int USELESS_TOOL::fixedCircle( const TOOL_EVENT& aEvent )
{
// new circle to add (ideally use a smart pointer)
PCB_SHAPE* circle = new PCB_SHAPE;
// Set the circle attributes
circle->SetShape( S_CIRCLE );
circle->SetWidth( 5 * IU_PER_MM );
circle->SetStart( wxPoint( 50 * IU_PER_MM, 50 * IU_PER_MM ) );
circle->SetEnd( wxPoint( 80 * IU_PER_MM, 80 * IU_PER_MM ) );
circle->SetLayer( LAYER_ID::F_SilkS );
// commit the circle to the BOARD
BOARD_COMMIT commit( this );
commit.Add( circle );
commit.Push( _( "Draw a circle" ) );
return 0;
}
void USELESS_TOOL::setTransitions()
{
Go( &USELESS_TOOL::fixedCircle, PCB_ACTIONS::uselessFixedCircle.MakeEvent() );
Go( &USELESS_TOOL::moveLeft, PCB_ACTIONS::uselessMoveItemLeft.MakeEvent() );
}