Commit 958046dd authored by Maciej Suminski's avatar Maciej Suminski

Moved SELECTION_TOOL context menu to a separate class.

parent 9ef9b7b8
...@@ -271,6 +271,7 @@ set( PCBNEW_CLASS_SRCS ...@@ -271,6 +271,7 @@ set( PCBNEW_CLASS_SRCS
tools/selection_tool.cpp tools/selection_tool.cpp
tools/selection_area.cpp tools/selection_area.cpp
tools/selection_conditions.cpp tools/selection_conditions.cpp
tools/conditional_menu.cpp
tools/bright_box.cpp tools/bright_box.cpp
tools/edit_points.cpp tools/edit_points.cpp
tools/edit_constraints.cpp tools/edit_constraints.cpp
......
...@@ -79,17 +79,17 @@ bool EDIT_TOOL::Init() ...@@ -79,17 +79,17 @@ bool EDIT_TOOL::Init()
} }
// Add context menu entries that are displayed when selection tool is active // Add context menu entries that are displayed when selection tool is active
m_selectionTool->AddMenuItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::rotate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveExact, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::moveExact, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::createArray, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::createArray, SELECTION_CONDITIONS::NotEmpty );
// Footprint actions // Footprint actions
m_selectionTool->AddMenuItem( COMMON_ACTIONS::editFootprintInFpEditor, m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::editFootprintInFpEditor,
SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) && SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) &&
SELECTION_CONDITIONS::Count( 1 ) ); SELECTION_CONDITIONS::Count( 1 ) );
......
...@@ -74,7 +74,7 @@ bool MODULE_TOOLS::Init() ...@@ -74,7 +74,7 @@ bool MODULE_TOOLS::Init()
return false; return false;
} }
selectionTool->AddMenuItem( COMMON_ACTIONS::enumeratePads ); selectionTool->GetMenu().AddItem( COMMON_ACTIONS::enumeratePads );
return true; return true;
} }
......
...@@ -74,7 +74,7 @@ bool PCB_EDITOR_CONTROL::Init() ...@@ -74,7 +74,7 @@ bool PCB_EDITOR_CONTROL::Init()
if( selTool ) if( selTool )
{ {
selTool->AddSubMenu( new ZONE_CONTEXT_MENU, _( "Zones" ), selTool->GetMenu().AddMenu( new ZONE_CONTEXT_MENU, _( "Zones" ),
SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) ); SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) );
} }
......
...@@ -63,8 +63,7 @@ bool PLACEMENT_TOOL::Init() ...@@ -63,8 +63,7 @@ bool PLACEMENT_TOOL::Init()
menu->AppendSeparator(); menu->AppendSeparator();
menu->Add( COMMON_ACTIONS::distributeHorizontally ); menu->Add( COMMON_ACTIONS::distributeHorizontally );
menu->Add( COMMON_ACTIONS::distributeVertically ); menu->Add( COMMON_ACTIONS::distributeVertically );
m_selectionTool->AddSubMenu( menu, _( "Align/distribute" ), m_selectionTool->GetMenu().AddMenu( menu, _( "Align/distribute" ), SELECTION_CONDITIONS::MoreThan( 1 ) );
SELECTION_CONDITIONS::MoreThan( 1 ) );
return true; return true;
} }
......
...@@ -210,7 +210,7 @@ bool POINT_EDITOR::Init() ...@@ -210,7 +210,7 @@ bool POINT_EDITOR::Init()
return false; return false;
} }
m_selectionTool->AddMenuItem( COMMON_ACTIONS::pointEditorBreakOutline, m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::pointEditorBreakOutline,
POINT_EDITOR::breakOutlineCondition ); POINT_EDITOR::breakOutlineCondition );
return true; return true;
......
...@@ -77,28 +77,27 @@ SELECTION_TOOL::SELECTION_TOOL() : ...@@ -77,28 +77,27 @@ SELECTION_TOOL::SELECTION_TOOL() :
SELECTION_TOOL::~SELECTION_TOOL() SELECTION_TOOL::~SELECTION_TOOL()
{ {
delete m_selArea;
delete m_selection.group; delete m_selection.group;
} }
bool SELECTION_TOOL::Init() bool SELECTION_TOOL::Init()
{ {
m_selArea = new SELECTION_AREA;
m_selection.group = new KIGFX::VIEW_GROUP; 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_CONDITION) SELECTION_CONDITIONS::OnlyConnectedItems &&
SELECTION_CONDITIONS::Count( 1 ) ); SELECTION_CONDITIONS::Count( 1 ) );
AddMenuItem( COMMON_ACTIONS::zoomCenter ); m_menu.AddItem( COMMON_ACTIONS::zoomCenter );
AddMenuItem( COMMON_ACTIONS::zoomIn ); m_menu.AddItem( COMMON_ACTIONS::zoomIn );
AddMenuItem( COMMON_ACTIONS::zoomOut ); m_menu.AddItem( COMMON_ACTIONS::zoomOut );
AddMenuItem( COMMON_ACTIONS::zoomFitScreen ); 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; return true;
} }
...@@ -160,7 +159,11 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) ...@@ -160,7 +159,11 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
if( emptySelection ) if( emptySelection )
selectCursor( evt->Position() ); selectCursor( evt->Position() );
generateMenu(); CONTEXT_MENU& contextMenu = m_menu.Generate( m_selection );
if( contextMenu.GetMenuItemCount() > 0 )
SetContextMenu( &contextMenu, CMENU_NOW );
m_preliminary = emptySelection; m_preliminary = emptySelection;
} }
...@@ -271,25 +274,6 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) ...@@ -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 ) void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem )
{ {
if( aItem->IsSelected() ) if( aItem->IsSelected() )
...@@ -390,7 +374,8 @@ bool SELECTION_TOOL::selectMultiple() ...@@ -390,7 +374,8 @@ bool SELECTION_TOOL::selectMultiple()
KIGFX::VIEW* view = getView(); KIGFX::VIEW* view = getView();
getViewControls()->SetAutoPan( true ); getViewControls()->SetAutoPan( true );
view->Add( m_selArea ); SELECTION_AREA area;
view->Add( &area );
while( OPT_TOOL_EVENT evt = Wait() ) while( OPT_TOOL_EVENT evt = Wait() )
{ {
...@@ -406,20 +391,20 @@ bool SELECTION_TOOL::selectMultiple() ...@@ -406,20 +391,20 @@ bool SELECTION_TOOL::selectMultiple()
clearSelection(); clearSelection();
// Start drawing a selection box // Start drawing a selection box
m_selArea->SetOrigin( evt->DragOrigin() ); area.SetOrigin( evt->DragOrigin() );
m_selArea->SetEnd( evt->Position() ); area.SetEnd( evt->Position() );
m_selArea->ViewSetVisible( true ); area.ViewSetVisible( true );
m_selArea->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); area.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
} }
if( evt->IsMouseUp( BUT_LEFT ) ) if( evt->IsMouseUp( BUT_LEFT ) )
{ {
// End drawing the selection box // End drawing the selection box
m_selArea->ViewSetVisible( false ); area.ViewSetVisible( false );
// Mark items within the selection box as selected // Mark items within the selection box as selected
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems; 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 view->Query( selectionBox, selectedItems ); // Get the list of selected items
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end; std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
...@@ -450,8 +435,8 @@ bool SELECTION_TOOL::selectMultiple() ...@@ -450,8 +435,8 @@ bool SELECTION_TOOL::selectMultiple()
} }
// Stop drawing the selection box // Stop drawing the selection box
m_selArea->ViewSetVisible( false ); area.ViewSetVisible( false );
view->Remove( m_selArea ); view->Remove( &area );
m_multiple = false; // Multiple selection mode is inactive m_multiple = false; // Multiple selection mode is inactive
getViewControls()->SetAutoPan( false ); getViewControls()->SetAutoPan( false );
...@@ -1314,42 +1299,6 @@ bool SELECTION_TOOL::SanitizeSelection() ...@@ -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() void SELECTION::clear()
{ {
items.ClearItemsList(); items.ClearItemsList();
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <class_undoredo_container.h> #include <class_undoredo_container.h>
#include "selection_conditions.h" #include "selection_conditions.h"
#include "conditional_menu.h"
class PCB_BASE_FRAME; class PCB_BASE_FRAME;
class SELECTION_AREA; class SELECTION_AREA;
...@@ -122,36 +123,13 @@ public: ...@@ -122,36 +123,13 @@ public:
* *
* Returns the set of currently selected items. * 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 // The selected items list has been requested, so it is no longer preliminary
m_preliminary = false; m_preliminary = false;
return m_selection; 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() * Function EditModules()
* *
...@@ -159,11 +137,16 @@ public: ...@@ -159,11 +137,16 @@ public:
* (graphics, pads, etc.), so they can be modified. * (graphics, pads, etc.), so they can be modified.
* @param aEnabled decides if the mode should be enabled. * @param aEnabled decides if the mode should be enabled.
*/ */
void EditModules( bool aEnabled ) inline void EditModules( bool aEnabled )
{ {
m_editModules = 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. ///> Checks if the user has agreed to modify locked items for the given selection.
SELECTION_LOCK_FLAGS CheckLock(); SELECTION_LOCK_FLAGS CheckLock();
...@@ -324,19 +307,9 @@ private: ...@@ -324,19 +307,9 @@ private:
*/ */
void guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) const; 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. /// Pointer to the parent frame.
PCB_BASE_FRAME* m_frame; PCB_BASE_FRAME* m_frame;
/// Visual representation of selection box.
SELECTION_AREA* m_selArea;
/// Current state of selection. /// Current state of selection.
SELECTION m_selection; SELECTION m_selection;
...@@ -346,12 +319,6 @@ private: ...@@ -346,12 +319,6 @@ private:
/// Flag saying if multiple selection mode is active. /// Flag saying if multiple selection mode is active.
bool m_multiple; 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. /// Edit module mode flag.
bool m_editModules; bool m_editModules;
...@@ -361,8 +328,8 @@ private: ...@@ -361,8 +328,8 @@ private:
/// Determines if the selection is preliminary or final. /// Determines if the selection is preliminary or final.
bool m_preliminary; bool m_preliminary;
/// Conditions for specific context menu entries. /// Menu displayed by the tool.
std::deque<SELECTION_CONDITION> m_menuConditions; CONDITIONAL_MENU m_menu;
}; };
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment