Moved SELECTION_TOOL context menu to a separate class.

This commit is contained in:
Maciej Suminski 2015-04-30 10:46:08 +02:00
parent 9ef9b7b8e1
commit 958046ddb2
8 changed files with 51 additions and 135 deletions

View File

@ -271,6 +271,7 @@ set( PCBNEW_CLASS_SRCS
tools/selection_tool.cpp
tools/selection_area.cpp
tools/selection_conditions.cpp
tools/conditional_menu.cpp
tools/bright_box.cpp
tools/edit_points.cpp
tools/edit_constraints.cpp

View File

@ -79,19 +79,19 @@ bool EDIT_TOOL::Init()
}
// Add context menu entries that are displayed when selection tool is active
m_selectionTool->AddMenuItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveExact, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::createArray, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::rotate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::moveExact, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::createArray, SELECTION_CONDITIONS::NotEmpty );
// Footprint actions
m_selectionTool->AddMenuItem( COMMON_ACTIONS::editFootprintInFpEditor,
SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) &&
SELECTION_CONDITIONS::Count( 1 ) );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::editFootprintInFpEditor,
SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) &&
SELECTION_CONDITIONS::Count( 1 ) );
m_offset.x = 0;
m_offset.y = 0;

View File

@ -74,7 +74,7 @@ bool MODULE_TOOLS::Init()
return false;
}
selectionTool->AddMenuItem( COMMON_ACTIONS::enumeratePads );
selectionTool->GetMenu().AddItem( COMMON_ACTIONS::enumeratePads );
return true;
}

View File

@ -74,8 +74,8 @@ bool PCB_EDITOR_CONTROL::Init()
if( selTool )
{
selTool->AddSubMenu( new ZONE_CONTEXT_MENU, _( "Zones" ),
SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) );
selTool->GetMenu().AddMenu( new ZONE_CONTEXT_MENU, _( "Zones" ),
SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) );
}
return true;

View File

@ -63,8 +63,7 @@ bool PLACEMENT_TOOL::Init()
menu->AppendSeparator();
menu->Add( COMMON_ACTIONS::distributeHorizontally );
menu->Add( COMMON_ACTIONS::distributeVertically );
m_selectionTool->AddSubMenu( menu, _( "Align/distribute" ),
SELECTION_CONDITIONS::MoreThan( 1 ) );
m_selectionTool->GetMenu().AddMenu( menu, _( "Align/distribute" ), SELECTION_CONDITIONS::MoreThan( 1 ) );
return true;
}

View File

@ -210,8 +210,8 @@ bool POINT_EDITOR::Init()
return false;
}
m_selectionTool->AddMenuItem( COMMON_ACTIONS::pointEditorBreakOutline,
POINT_EDITOR::breakOutlineCondition );
m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::pointEditorBreakOutline,
POINT_EDITOR::breakOutlineCondition );
return true;
}

View File

@ -77,28 +77,27 @@ SELECTION_TOOL::SELECTION_TOOL() :
SELECTION_TOOL::~SELECTION_TOOL()
{
delete m_selArea;
delete m_selection.group;
}
bool SELECTION_TOOL::Init()
{
m_selArea = new SELECTION_AREA;
m_selection.group = new KIGFX::VIEW_GROUP;
AddSubMenu( new SELECT_MENU, _( "Select..." ),
m_menu.AddMenu( new SELECT_MENU, _( "Select..." ),
(SELECTION_CONDITION) SELECTION_CONDITIONS::OnlyConnectedItems &&
SELECTION_CONDITIONS::Count( 1 ) );
AddMenuItem( COMMON_ACTIONS::zoomCenter );
AddMenuItem( COMMON_ACTIONS::zoomIn );
AddMenuItem( COMMON_ACTIONS::zoomOut );
AddMenuItem( COMMON_ACTIONS::zoomFitScreen );
m_menu.AddItem( COMMON_ACTIONS::zoomCenter );
m_menu.AddItem( COMMON_ACTIONS::zoomIn );
m_menu.AddItem( COMMON_ACTIONS::zoomOut );
m_menu.AddItem( COMMON_ACTIONS::zoomFitScreen );
AddSubMenu( new ZOOM_MENU( getEditFrame<PCB_BASE_FRAME>() ), "Zoom" );
m_menu.AddMenu( new ZOOM_MENU( getEditFrame<PCB_BASE_FRAME>() ), "Zoom" );
m_menu.AddMenu( new GRID_MENU( getEditFrame<PCB_BASE_FRAME>() ), "Grid" );
AddSubMenu( new GRID_MENU( getEditFrame<PCB_BASE_FRAME>() ), "Grid" );
//m_menu.AddSeparator();
return true;
}
@ -160,7 +159,11 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
if( emptySelection )
selectCursor( evt->Position() );
generateMenu();
CONTEXT_MENU& contextMenu = m_menu.Generate( m_selection );
if( contextMenu.GetMenuItemCount() > 0 )
SetContextMenu( &contextMenu, CMENU_NOW );
m_preliminary = emptySelection;
}
@ -271,25 +274,6 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
}
void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition )
{
assert( aAction.GetId() > 0 ); // Check if action was previously registered in ACTION_MANAGER
m_menu.Add( aAction );
m_menuConditions.push_back( aCondition );
}
void SELECTION_TOOL::AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel,
const SELECTION_CONDITION& aCondition, bool aExpand )
{
std::list<wxMenuItem*> items = m_menu.Add( aMenu, aLabel, aExpand );
for( unsigned int i = 0; i < items.size(); ++i )
m_menuConditions.push_back( aCondition );
}
void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem )
{
if( aItem->IsSelected() )
@ -390,7 +374,8 @@ bool SELECTION_TOOL::selectMultiple()
KIGFX::VIEW* view = getView();
getViewControls()->SetAutoPan( true );
view->Add( m_selArea );
SELECTION_AREA area;
view->Add( &area );
while( OPT_TOOL_EVENT evt = Wait() )
{
@ -406,20 +391,20 @@ bool SELECTION_TOOL::selectMultiple()
clearSelection();
// Start drawing a selection box
m_selArea->SetOrigin( evt->DragOrigin() );
m_selArea->SetEnd( evt->Position() );
m_selArea->ViewSetVisible( true );
m_selArea->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
area.SetOrigin( evt->DragOrigin() );
area.SetEnd( evt->Position() );
area.ViewSetVisible( true );
area.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
if( evt->IsMouseUp( BUT_LEFT ) )
{
// End drawing the selection box
m_selArea->ViewSetVisible( false );
area.ViewSetVisible( false );
// Mark items within the selection box as selected
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
BOX2I selectionBox = m_selArea->ViewBBox();
BOX2I selectionBox = area.ViewBBox();
view->Query( selectionBox, selectedItems ); // Get the list of selected items
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
@ -450,8 +435,8 @@ bool SELECTION_TOOL::selectMultiple()
}
// Stop drawing the selection box
m_selArea->ViewSetVisible( false );
view->Remove( m_selArea );
area.ViewSetVisible( false );
view->Remove( &area );
m_multiple = false; // Multiple selection mode is inactive
getViewControls()->SetAutoPan( false );
@ -1314,42 +1299,6 @@ bool SELECTION_TOOL::SanitizeSelection()
}
void SELECTION_TOOL::generateMenu()
{
// Menu has to be updated before its copy is created. Copying does not preserve subtypes of the
// stored menus, so updating may not work correctly.
m_menu.UpdateAll();
// Create a copy of the master context menu
m_menuCopy = m_menu;
assert( m_menuCopy.GetMenuItemCount() == m_menuConditions.size() );
// Filter out entries that do not comply with the current selection
for( int i = m_menuCopy.GetMenuItemCount() - 1; i >= 0; --i )
{
try
{
if( !m_menuConditions[i]( m_selection ) )
{
wxMenuItem* item = m_menuCopy.FindItemByPosition( i );
m_menuCopy.Destroy( item );
}
}
catch( boost::bad_function_call )
{
// If it is not possible to determine if a menu entry should be
// shown or not - do not let users pick non-existing options
wxMenuItem* item = m_menuCopy.FindItemByPosition( i );
m_menuCopy.Destroy( item );
}
}
if( m_menuCopy.GetMenuItemCount() > 0 )
SetContextMenu( &m_menuCopy, CMENU_NOW );
}
void SELECTION::clear()
{
items.ClearItemsList();

View File

@ -32,6 +32,7 @@
#include <class_undoredo_container.h>
#include "selection_conditions.h"
#include "conditional_menu.h"
class PCB_BASE_FRAME;
class SELECTION_AREA;
@ -122,36 +123,13 @@ public:
*
* Returns the set of currently selected items.
*/
const SELECTION& GetSelection()
inline const SELECTION& GetSelection()
{
// The selected items list has been requested, so it is no longer preliminary
m_preliminary = false;
return m_selection;
}
/**
* Function AddMenuItem()
*
* Adds a menu entry to run a TOOL_ACTION on selected items.
* @param aAction is a menu entry to be added.
* @param aCondition is a condition that has to be fulfilled to enable the menu entry.
*/
void AddMenuItem( const TOOL_ACTION& aAction,
const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways );
/**
* Function AddSubMenu()
*
* Adds a submenu to the selection tool right-click context menu.
* @param aMenu is the submenu to be added.
* @param aLabel is the label of added submenu.
* @param aCondition is a condition that has to be fulfilled to enable the submenu entry.
* @param aExpand determines if the added submenu items should be added as individual items.
*/
void AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel,
const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
bool aExpand = false );
/**
* Function EditModules()
*
@ -159,11 +137,16 @@ public:
* (graphics, pads, etc.), so they can be modified.
* @param aEnabled decides if the mode should be enabled.
*/
void EditModules( bool aEnabled )
inline void EditModules( bool aEnabled )
{
m_editModules = aEnabled;
}
inline CONDITIONAL_MENU& GetMenu()
{
return m_menu;
}
///> Checks if the user has agreed to modify locked items for the given selection.
SELECTION_LOCK_FLAGS CheckLock();
@ -324,19 +307,9 @@ private:
*/
void guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) const;
/**
* Function generateMenu()
* Creates a copy of context menu that is filtered by menu conditions and displayed to
* the user.
*/
void generateMenu();
/// Pointer to the parent frame.
PCB_BASE_FRAME* m_frame;
/// Visual representation of selection box.
SELECTION_AREA* m_selArea;
/// Current state of selection.
SELECTION m_selection;
@ -346,12 +319,6 @@ private:
/// Flag saying if multiple selection mode is active.
bool m_multiple;
/// Right click popup menu (master instance).
CONTEXT_MENU m_menu;
/// Copy of the context menu that is filtered by menu conditions and displayed to the user.
CONTEXT_MENU m_menuCopy;
/// Edit module mode flag.
bool m_editModules;
@ -361,8 +328,8 @@ private:
/// Determines if the selection is preliminary or final.
bool m_preliminary;
/// Conditions for specific context menu entries.
std::deque<SELECTION_CONDITION> m_menuConditions;
/// Menu displayed by the tool.
CONDITIONAL_MENU m_menu;
};
#endif