Commit 2c03bf41 authored by Maciej Suminski's avatar Maciej Suminski
Browse files

Removed TA_ActivateTool (now tools are invoked by sending TA_Action event,...

Removed TA_ActivateTool (now tools are invoked by sending TA_Action event, with the tool name as string parameter).
Developed TOOL_Action class & added ActionManager. Hot keys registered by tools are processed.
Selection & move tool can be invoked by a hot key.
parent eb784536
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ set(COMMON_SRCS
    tool/tool_dispatcher.cpp
    tool/tool_event.cpp
    tool/tool_interactive.cpp
    tool/action_manager.cpp
    tool/context_menu.cpp

	geometry/seg.cpp
+1 −1
Original line number Diff line number Diff line
@@ -83,9 +83,9 @@ const std::string TOOL_EVENT::Format() const
		{ TA_ViewDirty, "view-dirty" },
		{ TA_ChangeLayer, "change-layer" },
		{ TA_CancelTool, "cancel-tool" },
		{ TA_ActivateTool, "activate-tool" },
		{ TA_ContextMenuUpdate, "context-menu-update" },
		{ TA_ContextMenuChoice, "context-menu-choice" },
		{ TA_Action, "action" },
		{ 0, "" }
	};

+95 −20
Original line number Diff line number Diff line
@@ -82,9 +82,8 @@ struct TOOL_MANAGER::TOOL_STATE


TOOL_MANAGER::TOOL_MANAGER() : 
	m_model( NULL ), m_view( NULL )
    m_actionMgr( this ), m_model( NULL ), m_view( NULL )
{
	
}


@@ -128,38 +127,79 @@ bool TOOL_MANAGER::InvokeTool( TOOL_ID aToolId )
    TOOL_BASE* tool = FindTool( aToolId );

    if( tool && tool->GetType() == TOOL_Interactive )
        return invokeTool( tool );

    return false;
}


bool TOOL_MANAGER::InvokeTool( const std::string& aToolName )
{
        // If the tool is already active, do not invoke it again
        if( m_toolIdIndex[aToolId]->idle == false )
    TOOL_BASE* tool = FindTool( aToolName );

    if( tool && tool->GetType() == TOOL_Interactive )
        return invokeTool( tool );

    return false;
}

        m_toolIdIndex[aToolId]->idle = false;
        static_cast<TOOL_INTERACTIVE*>( tool )->Reset();

        TOOL_EVENT evt( TC_Command, TA_ActivateTool, tool->GetName() );
        ProcessEvent( evt );
bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool )
{
    wxASSERT( aTool != NULL );

        // Save the tool on the front of the processing queue
        m_activeTools.push_front( aToolId );
    TOOL_EVENT evt( TC_Command, TA_Action, aTool->GetName() );
    ProcessEvent( evt );

    return true;
}


bool TOOL_MANAGER::runTool( TOOL_ID aToolId )
{
    TOOL_BASE* tool = FindTool( aToolId );

    if( tool && tool->GetType() == TOOL_Interactive )
        return runTool( tool );

    return false;
}


bool TOOL_MANAGER::InvokeTool( const std::string& aName )
bool TOOL_MANAGER::runTool( const std::string& aToolName )
{
    TOOL_BASE* tool = FindTool( aName );
    TOOL_BASE* tool = FindTool( aToolName );

    if( tool )
        return InvokeTool( tool->GetId() );
    if( tool && tool->GetType() == TOOL_Interactive )
        return runTool( tool );

    return false;
}


bool TOOL_MANAGER::runTool( TOOL_BASE* aTool )
{
    wxASSERT( aTool != NULL );

    if( !isRegistered( aTool ) )
        return false;

    TOOL_STATE* state = m_toolState[aTool];

    // If the tool is already active, do not invoke it again
    if( state->idle == false )
        return false;
    state->idle = false;

    static_cast<TOOL_INTERACTIVE*>( aTool )->Reset();

    // Add the tool on the front of the processing queue (it gets events first)
    m_activeTools.push_front( aTool->GetId() );

    return true;
}


TOOL_BASE* TOOL_MANAGER::FindTool( int aId ) const
{
    std::map<TOOL_ID, TOOL_STATE*>::const_iterator it = m_toolIdIndex.find( aId );
@@ -228,7 +268,8 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
				    finishTool( st );
				}

				// The tool requested to stop propagating event to other tools
				// If the tool did not request to propagate
				// the event to other tools, we should stop it now
				if( !m_passEvent )
				    break;
			}
@@ -269,6 +310,21 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
}


bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent )
{
    BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values )
    {
        if( st->theTool->GetName() == aEvent.m_commandStr )
        {
            runTool( st->theTool );
            return true;
        }
    }

    return false;
}


void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
{
    wxASSERT( m_activeTools.front() == aState->theTool->GetId() );
@@ -286,6 +342,16 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
{
//	wxLogDebug( "event: %s", aEvent.Format().c_str() );

	if( aEvent.Action() == TA_KeyUp )
	{
	    // Check if there is a hotkey associated
	    if( m_actionMgr.RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) )
	        return false;   // hotkey event was handled so it does not go any further
	} else if( aEvent.Category() == TC_Command )        // it may be a tool activation event
	{
	    dispatchActivation( aEvent );
	}

	dispatchInternal( aEvent );

    BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
@@ -359,3 +425,12 @@ void TOOL_MANAGER::SetEnvironment( EDA_ITEM* aModel, KiGfx::VIEW* aView,
	        static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
	}
}


bool TOOL_MANAGER::isActive( TOOL_BASE* aTool )
{
    if( !isRegistered( aTool ) )
        return false;

    return !m_toolState[aTool]->idle;
}
+170 −71
Original line number Diff line number Diff line
/*
 * 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 __TOOL_ACTION_H
#define __TOOL_ACTION_H

@@ -5,12 +29,7 @@
#include <wx/wx.h>

#include <tool/tool_base.h>

///> Scope of tool actions
enum TOOL_ActionScope {
	SCOPE_CONTEXT = 1,  ///> Action belongs to a particular tool (i.e. a part of a pop-up menu)
	SCOPE_GLOBAL		///> Global action (toolbar/main menu event, global shortcut)
};
#include <tool/action_manager.h>

// TOOL_ACTION - represents a single action. For instance:
// - changing layer to top by pressing PgUp
@@ -19,68 +38,148 @@ enum TOOL_ActionScope {
class TOOL_ACTION
{
public:
    TOOL_ACTION( const std::string& aName, TOOL_ActionScope aScope = AS_CONTEXT, int aDefaultHotKey = 0,
                 const wxString& aMenuItem = wxT( "" ), const wxString& aMenuDesc = wxT( "" ) ) :
            m_name( aName ), m_scope( aScope ), m_defaultHotKey( aDefaultHotKey ),
                m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ),
                m_menuDescription( aMenuDesc ), m_id( -1 ), m_actionMgr( NULL )
    {
    }

    ~TOOL_ACTION()
    {
        if( m_actionMgr )
            m_actionMgr->UnregisterAction( this );
    }

    bool operator==( const TOOL_ACTION& aRhs ) const
    {
        return m_id == aRhs.m_id;
    }

    bool operator!=( const TOOL_ACTION& aRhs ) const
    {
        return m_id != aRhs.m_id;
    }

    /**
     * Function GetName()
     * Returns name of the action. It is the same one that is contained in TOOL_EVENT that is
     * sent by activating the TOOL_ACTION.
     *
     * @return Name of the action.
     */
    const std::string& GetName() const
    {
        return m_name;
    }

    /**
     * Function GetId()
     * Returns the unique id of the TOOL_ACTION object. It is valid only after registering the
     * TOOL_ACTION by ACTION_MANAGER.
     *
     * @return The unique identification number. If the number is negative, then it is not valid.
     */
    int GetId() const
    {
        return m_id;
    }

		TOOL_ACTION
		(
			const std::string& name,
			TOOL_ActionScope scope = SCOPE_GLOBAL,
			int aDefaultHotKey = 0,
			const wxString& menuItem = wxT(""), 
			const wxString& menuDesc = wxT("")
		) :
			m_name(name),
			m_scope(scope),
			m_defaultHotKey(aDefaultHotKey),
			m_currentHotKey(aDefaultHotKey),
			m_menuItem(menuItem),
			m_menuDescription(menuDesc) {}

		bool operator == ( const TOOL_ACTION& rhs ) const
    /**
     * Function ChangeHotKey()
     * Assigns a new hot key.
     *
     * @param aNewHotKey is the new hot key.
     */
    void ChangeHotKey( int aNewHotKey )
    {
			return m_id	== rhs.m_id;
        wxASSERT_MSG( false, wxT( "It is not fully implemented yet") );
        // I mean it has to be changed in the ACTION_MANAGER, or change the implementation
        m_currentHotKey = aNewHotKey;
    }

		bool operator != ( const TOOL_ACTION& rhs ) const
    /**
     * Function RestoreHotKey()
     * Changes the assigned hot key to the default one.
     */
    void RestoreHotKey()
    {
			return m_id	!= rhs.m_id;
        wxASSERT_MSG( false, wxT( "It is not fully implemented yet") );
        // I mean it has to be changed in the ACTION_MANAGER, or change the implementation
        m_currentHotKey = m_defaultHotKey;
    }

		bool hasHotKey() const
    /**
     * Function HasHotKey()
     * Checks if the action has a hot key assigned.
     *
     * @return True if there is a hot key assigned, false otherwise.
     *
     */
    bool HasHotKey() const
    {
        return m_currentHotKey > 0;
    }

    /**
     * Function GetEvent()
     * Returns the event associated with the action (ie. the event that will be sent after
     * activating the action).
     *
     * @return The event associated with the action.
     */
    TOOL_EVENT GetEvent() const
    {
        return TOOL_EVENT( TC_Command, TA_Action, m_name, m_scope );
    }

private:
		friend class TOOL_MANAGER;
    friend class ACTION_MANAGER;

    /// Assigns an unique identifier. It is given by an instance of ACTION_MANAGER.
    void setId( int aId )
    {
        m_id = aId;
    }

    /// Assigns ACTION_MANAGER object that handles the TOOL_ACTION.
    void setActionMgr( ACTION_MANAGER* aManager )
    {
        m_actionMgr = aManager;
    }

		// name of the action (convention is: app.[tool.]action.name)
    /// Name of the action (convention is: app.[tool.]action.name)
    std::string m_name;

    /// Scope of the action (ie. the event that is issued after activation).
    TOOL_ActionScope m_scope;
		int m_defaultHotKey;

    /// Default hot key that activates the action.
    const int m_defaultHotKey;

    /// Custom assigned hot key that activates the action.
    int m_currentHotKey;

		// Menu item text
    /// Menu entry text
    wxString m_menuItem;
		// Pop-up help

    /// Pop-up help
    wxString m_menuDescription;

    // Icon for menu entry
    //KiBitmap m_bitmap;

		// Unique ID for fast matching. Assigned by TOOL_MANAGER
    /// Unique ID for fast matching. Assigned by ACTION_MANAGER.
    int m_id;

		// Origin of the action
		TOOL_BASE *m_origin;
    /// Action manager that handles this TOOL_ACTION.
    ACTION_MANAGER* m_actionMgr;

		// Originating UI object
		wxWindow *m_uiOrigin;
};
    /// Origin of the action
//    const TOOL_BASE* m_origin;

    /// Originating UI object
//    wxWindow* m_uiOrigin;
};
#endif
+31 −12
Original line number Diff line number Diff line
@@ -74,15 +74,16 @@ enum TOOL_Actions
	// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from the context menu.
	TA_CancelTool   = 0x2000,

	// Tool activation event. Issued by the GUI upon pressing a button/menu selection.
	TA_ActivateTool = 0x4000,

	// Context menu update. Issued whenever context menu is open and the user hovers the mouse over one of choices.
	// Used in dynamic highligting in disambiguation menu 
	TA_ContextMenuUpdate = 0x8000,
	TA_ContextMenuUpdate = 0x4000,

	// Context menu choice. Sent if the user picked something from the context menu or closed it without selecting anything.
	TA_ContextMenuChoice = 0x10000,
	TA_ContextMenuChoice = 0x8000,

	// Tool action
	TA_Action            = 0x10000,

	TA_Any = 0xffffffff
};

@@ -104,7 +105,15 @@ enum TOOL_Modifiers
    MD_ModifierMask = MD_ModShift | MD_ModCtrl | MD_ModAlt,
};

// Defines when a context menu is opened.
/// Scope of tool actions
enum TOOL_ActionScope
{
    AS_CONTEXT = 1,  ///> Action belongs to a particular tool (i.e. a part of a pop-up menu)
    AS_ACTIVE,       ///> All active tools
    AS_GLOBAL        ///> Global action (toolbar/main menu event, global shortcut)
};

/// Defines when a context menu is opened.
enum CONTEXT_MENU_TRIGGER
{
	CMENU_BUTTON = 0,   // On the right button
@@ -122,16 +131,19 @@ class TOOL_EVENT
public:
    const std::string Format() const;

    TOOL_EVENT( TOOL_EventCategory aCategory = TC_None, TOOL_Actions aAction = TA_None ) :
    TOOL_EVENT( TOOL_EventCategory aCategory = TC_None, TOOL_Actions aAction = TA_None,
                TOOL_ActionScope aScope = AS_GLOBAL ) :
        m_category( aCategory ),
        m_actions( aAction ),
        m_scope( aScope ),
        m_mouseButtons( 0 ),
        m_keyCode( 0 ),
        m_modifiers( 0 ) {}

    TOOL_EVENT( TOOL_EventCategory aCategory, TOOL_Actions aAction, int aExtraParam ) :
    TOOL_EVENT( TOOL_EventCategory aCategory, TOOL_Actions aAction, int aExtraParam, TOOL_ActionScope aScope = AS_GLOBAL ) :
        m_category( aCategory ),
        m_actions( aAction )
        m_actions( aAction ),
        m_scope( aScope )
        {
            if( aCategory == TC_Mouse )
            {
@@ -153,16 +165,16 @@ public:
        }

    TOOL_EVENT( TOOL_EventCategory aCategory, TOOL_Actions aAction,
                const std::string& aExtraParam ) :
                const std::string& aExtraParam, TOOL_ActionScope aScope = AS_GLOBAL ) :
        m_category( aCategory ),
        m_actions( aAction ),
        m_scope( aScope ),
        m_mouseButtons( 0 )
        {
            if( aCategory == TC_Command )
                m_commandStr = aExtraParam;
        }


    TOOL_EventCategory Category() const
    {
        return m_category;
@@ -285,6 +297,7 @@ private:

    TOOL_EventCategory m_category;
    TOOL_Actions m_actions;
    TOOL_ActionScope m_scope;

    VECTOR2D m_mouseDelta;
    VECTOR2D m_mousePos;
@@ -317,6 +330,12 @@ public:
        m_events.push_back( aSingleEvent );
    }

    /**
     * Function Format()
     * Returns information about event in form of a human-readable string.
     *
     * @return Event information.
     */
    const std::string Format() const;

    boost::optional<const TOOL_EVENT&> Matches( const TOOL_EVENT &b ) const
Loading