// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This source file has been modified by the following contributors: // Copyright (C) 2012 Laszlo KIS-ADAM (dfighter) // Copyright (C) 2015-2020 Jan BOON (Kaetemi) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef CL_ACTIONS_H #define CL_ACTIONS_H ///////////// // INCLUDE // ///////////// // client #include "events_listener.h" /////////// // CLASS // class CCombo; class CAction; class CActionsManager; /** * The goal of CCombo is to gather together Inputs that will validate an Action. * For now, CCombo is composed of keyboard inputs or mouse inputs * (not Keyboard and mouse inputs in the same CCombo). * * \author Guillaume PUZIN * \author Nevrax France * \date 2001 * * \todo Load/Save. * \todo Check if there is memory leak. * \todo Check comments. */ class CCombo { public: // The key NLMISC::TKey Key; // The CTRL - SHIFT - ALT state NLMISC::TKeyButton KeyButtons; public: /// Init the combo void init (NLMISC::TKey key, NLMISC::TKeyButton keyButtons); /// Get the combo in human readable form std::string toString() const; // For maps bool operator<(const CCombo &other) const { if (Key < other.Key) return true; if (Key > other.Key) return false; return KeyButtons < other.KeyButtons; } }; /** * The Goal of CAction is to know the state of an Action. * * \author Guillaume PUZIN * \author Nevrax France * \date 2001 * * \todo Check comments. */ class CAction { public: // The name of an action class CName { public: std::string Name; std::string Argu; CName() { } CName(const char *name) { Name = name; } CName(const char *name, const char *argu) { Name = name; Argu = argu; } // For the maps bool operator<(const CName &other) const { if (Name < other.Name) return true; if (Name > other.Name) return false; return Argu < other.Argu; } // For the maps bool operator== (const CName &other) const { return (Name == other.Name) && (Argu == other.Argu); } }; // The icon of an action class CIcon { public: // The background color NLMISC::CRGBA Color; // The bitmaps (1 over 0) std::string Bitmaps[2]; // The text (6 letters, only A-Z 0-9) std::string Text; }; /// Constructor CAction(); // Execute the action void runAction (); // True if the action has begun (key down..) bool Valide; // Repetition for this action ? bool Repeat; // Do we have to run an AH on key up ? bool KeyUp; // Do we have to run an AH on key down ? bool KeyDown; // The name of the action CName Name; }; /* * The base action is a class used to generate actions */ class CBaseAction { public: // Init default values CBaseAction (); // The parameter descriptor of an action class CParameter { public: enum TType { Hidden=0, Constant, // The parameter is a list of const string User, // The parameter is a user string UserName, // The parameter is a user "name" string } Type; // Init default values CParameter (); // The parameter name (optional) std::string Name; // The parameter localized name (optional) std::string LocalizedName; // Default value std::string DefaultValue; // The parameter constant value is Type == Constant class CValue { public: // The value std::string Value; // contexts in which this value is possible std::string Contexts; // The localized value std::string LocalizedValue; }; std::vector Values; }; // The action parameter descritors std::vector Parameters; // Repetition for this action ? bool Repeat; // Do we have to run an AH on key up ? bool KeyUp; // Do we have to run an AH on key down ? bool KeyDown; // Do we have to wait for an answer from the server before continuing execution in macros ? bool WaitForServer; // Is this action can be macroized? bool Macroisable; // The name of the action handler used by the action std::string Name; // The localized name std::string LocalizedName; // Contexts in which this action exists std::string Contexts; /// Get an action localized text std::string getActionLocalizedText (const CAction::CName &name) const; // see if there's at least one set of parameters for which this action is usable in current context bool isUsableInCurrentContext() const; // The action icon // CAction::CIcon Icon; }; /* * Category of action */ class CCategory { public: // The category name std::string Name; // The category localized name std::string LocalizedName; // The set of base action for this category std::vector BaseActions; // Is this whole category can be macroized? bool Macroisable; public: CCategory() { Macroisable= true; } }; // HashMapTraits for NLMISC::TKey struct CTKeyHashMapTraits { enum { bucket_size = 4, min_buckets = 8, }; CTKeyHashMapTraits() { } size_t operator() (NLMISC::TKey key) const { return (size_t)key; } bool operator() (NLMISC::TKey key1, NLMISC::TKey key2) const { return key1 < key2; } }; /** * The aims of CActionsManager ... * * \author Guillaume PUZIN * \author Nevrax France * \date 2001 * * \todo DelCombo(...); * \todo Load/Save. * \todo Check if there is memory leak. * \todo Check comments. */ class CActionsManager { public: /// Typedef to use the map easily. typedef std::map TActionsMap; typedef std::set TActionsForceDisplaySet; typedef std::map TActionComboMap; typedef std::map TComboActionMap; typedef CHashMultiMap TKeyActionMap; // Category locator class CCategoryLocator { public: uint CategoryId; uint BaseActionId; }; typedef CHashMultiMap TActionBaseActionMap; /// Constructor CActionsManager(); /// Add a new Action in the context. bool addAction(const CAction::CName &name); /// Return an action from its name CAction* getAction(const CAction::CName &name); /// Clear actions void clear (); /// Enable / disable combos void enable (bool enable); /// Remove a combo void removeCombo (const CCombo &combo); // Remove all the combos void removeAllCombos(); /// Add a combo in an Action. bool addCombo(const CAction::CName &name, const CCombo &combo, bool createAction = true); /// Get the base action and category of an action const CCategoryLocator *getActionLocator (const CAction::CName &name) const; /// Get the base action of an action const CBaseAction *getBaseAction (const CAction::CName &name) const; // remove an action from the action manager void removeBaseAction(const CAction::CName &name); /// Get the category of an action const CCategory *getCategory (const CAction::CName &name) const; /// Return if the Action is valide. bool valide(const CAction::CName &name) const; // Return true if the action is present in current (global) context bool isActionPresentInContext(const CAction::CName &name) const; /// A key has been pushed. Return true if an action handler is associated with this key. bool keyPushed (const NLMISC::CEventKeyDown &keyDown); /// A key has been released void keyReleased (const NLMISC::CEventKeyUp &keyUp); /// Get the category array const std::vector &getCategories () const; /// Reserve space in the category array void reserveCategories (uint space); /// Add a category void addCategory (const CCategory &category); /// Remove a category void removeCategory (const std::string &catName); /// Get combo / action map const TComboActionMap &getComboActionMap () const; /// Get action / combo map const TActionComboMap &getActionComboMap () const; /// Release All keys, without running any AH void releaseAllKeyNoRunning(); /// true if a combo is already associated to an action bool isComboAssociated(const CCombo &combo) const {return _ComboAction.find(combo)!=_ComboAction.end();} /// true if an action is already associated to a combo bool isActionAssociated(const CAction::CName &name) const {return _ActionCombo.find(name)!=_ActionCombo.end();} /// Force the action to be always displayed in the "Keys" interface, even if the key is unbound. default is false void forceDisplayForAction(const CAction::CName &name, bool state); /// see forceDisplayForAction bool isActionDisplayForced(const CAction::CName &name) const; /// see forceDisplayForAction const TActionsForceDisplaySet &getActionsForceDisplaySet() const {return _ActionForceDisplay;} /// Get an action localized text std::string getActionLocalizedText (const CAction::CName &name) const; //@} private: /// Update key buttons void updateKeyButton (NLMISC::TKeyButton); /// Map with all Actions in the context. the string = Action name. TActionsMap _Actions; TActionsForceDisplaySet _ActionForceDisplay; TActionComboMap _ActionCombo; TComboActionMap _ComboAction; TKeyActionMap _KeyAction; TKeyActionMap _WatchedActions; TActionBaseActionMap _ActionCategory; std::vector _Categories; bool _Enabled; };// CActionsManager // /** * Action context */ class CActionsContext { public: CActionsContext(); // Add an action manager. bool addActionsManager (CActionsManager *actionManager, const std::string &category=""); // Get an action manager. Returns NULL if not found. CActionsManager *getActionsManager (const std::string &category="") const; void setContext(const std::string &context) { _Context = context; } bool matchContext(const std::string &contexts) const; void removeAllCombos(); private: typedef std::map TActionsManagerMap; TActionsManagerMap _ActionsManagers; std::string _Context; }; extern CActionsContext ActionsContext; #endif // CL_ACTIONS_H /* End of actions.h */