|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2022 - Raw Material Software Limited
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- By using JUCE, you agree to the terms of both the JUCE 7 End-User License
- Agreement and JUCE Privacy Policy.
-
- End User License Agreement: www.juce.com/juce-7-licence
- Privacy Policy: www.juce.com/juce-privacy-policy
-
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- namespace juce
- {
-
- //==============================================================================
- /**
- A command target publishes a list of command IDs that it can perform.
-
- An ApplicationCommandManager despatches commands to targets, which must be
- able to provide information about what commands they can handle.
-
- To create a target, you'll need to inherit from this class, implementing all of
- its pure virtual methods.
-
- For info about how a target is chosen to receive a command, see
- ApplicationCommandManager::getFirstCommandTarget().
-
- @see ApplicationCommandManager, ApplicationCommandInfo
-
- @tags{GUI}
- */
- class JUCE_API ApplicationCommandTarget
- {
- public:
- //==============================================================================
- /** Creates a command target. */
- ApplicationCommandTarget();
-
- /** Destructor. */
- virtual ~ApplicationCommandTarget();
-
- //==============================================================================
- /**
- Contains contextual details about the invocation of a command.
- */
- struct JUCE_API InvocationInfo
- {
- //==============================================================================
- InvocationInfo (const CommandID commandID);
-
- //==============================================================================
- /** The UID of the command that should be performed. */
- CommandID commandID;
-
- /** The command's flags.
- See ApplicationCommandInfo for a description of these flag values.
- */
- int commandFlags;
-
- //==============================================================================
- /** The types of context in which the command might be called. */
- enum InvocationMethod
- {
- direct = 0, /**< The command is being invoked directly by a piece of code. */
- fromKeyPress, /**< The command is being invoked by a key-press. */
- fromMenu, /**< The command is being invoked by a menu selection. */
- fromButton /**< The command is being invoked by a button click. */
- };
-
- /** The type of event that triggered this command. */
- InvocationMethod invocationMethod;
-
- //==============================================================================
- /** If triggered by a keypress or menu, this will be the component that had the
- keyboard focus at the time.
-
- If triggered by a button, it may be set to that component, or it may be null.
- */
- Component* originatingComponent;
-
- //==============================================================================
- /** The keypress that was used to invoke it.
-
- Note that this will be an invalid keypress if the command was invoked
- by some other means than a keyboard shortcut.
- */
- KeyPress keyPress;
-
- /** True if the callback is being invoked when the key is pressed,
- false if the key is being released.
-
- @see KeyPressMappingSet::addCommand()
- */
- bool isKeyDown;
-
- /** If the key is being released, this indicates how long it had been held
- down for.
-
- (Only relevant if isKeyDown is false.)
- */
- int millisecsSinceKeyPressed;
- };
-
- //==============================================================================
- /** This must return the next target to try after this one.
-
- When a command is being sent, and the first target can't handle
- that command, this method is used to determine the next target that should
- be tried.
-
- It may return nullptr if it doesn't know of another target.
-
- If your target is a Component, you would usually use the findFirstTargetParentComponent()
- method to return a parent component that might want to handle it.
-
- @see invoke
- */
- virtual ApplicationCommandTarget* getNextCommandTarget() = 0;
-
- /** This must return a complete list of commands that this target can handle.
-
- Your target should add all the command IDs that it handles to the array that is
- passed-in.
- */
- virtual void getAllCommands (Array<CommandID>& commands) = 0;
-
- /** This must provide details about one of the commands that this target can perform.
-
- This will be called with one of the command IDs that the target provided in its
- getAllCommands() methods.
-
- It should fill-in all appropriate fields of the ApplicationCommandInfo structure with
- suitable information about the command. (The commandID field will already have been filled-in
- by the caller).
-
- The easiest way to set the info is using the ApplicationCommandInfo::setInfo() method to
- set all the fields at once.
-
- If the command is currently inactive for some reason, this method must use
- ApplicationCommandInfo::setActive() to make that clear, (or it should set the isDisabled
- bit of the ApplicationCommandInfo::flags field).
-
- Any default key-presses for the command should be appended to the
- ApplicationCommandInfo::defaultKeypresses field.
-
- Note that if you change something that affects the status of the commands
- that would be returned by this method (e.g. something that makes some commands
- active or inactive), you should call ApplicationCommandManager::commandStatusChanged()
- to cause the manager to refresh its status.
- */
- virtual void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result) = 0;
-
- /** This must actually perform the specified command.
-
- If this target is able to perform the command specified by the commandID field of the
- InvocationInfo structure, then it should do so, and must return true.
-
- If it can't handle this command, it should return false, which tells the caller to pass
- the command on to the next target in line.
-
- @see invoke, ApplicationCommandManager::invoke
- */
- virtual bool perform (const InvocationInfo& info) = 0;
-
- //==============================================================================
- /** Makes this target invoke a command.
-
- Your code can call this method to invoke a command on this target, but normally
- you'd call it indirectly via ApplicationCommandManager::invoke() or
- ApplicationCommandManager::invokeDirectly().
-
- If this target can perform the given command, it will call its perform() method to
- do so. If not, then getNextCommandTarget() will be used to determine the next target
- to try, and the command will be passed along to it.
-
- @param invocationInfo this must be correctly filled-in, describing the context for
- the invocation.
- @param asynchronously if false, the command will be performed before this method returns.
- If true, a message will be posted so that the command will be performed
- later on the message thread, and this method will return immediately.
- @see perform, ApplicationCommandManager::invoke
- */
- bool invoke (const InvocationInfo& invocationInfo,
- const bool asynchronously);
-
- /** Invokes a given command directly on this target.
-
- This is just an easy way to call invoke() without having to fill out the InvocationInfo
- structure.
- */
- bool invokeDirectly (const CommandID commandID,
- const bool asynchronously);
-
- //==============================================================================
- /** Searches this target and all subsequent ones for the first one that can handle
- the specified command.
-
- This will use getNextCommandTarget() to determine the chain of targets to try
- after this one.
- */
- ApplicationCommandTarget* getTargetForCommand (const CommandID commandID);
-
- /** Checks whether this command can currently be performed by this target.
-
- This will return true only if a call to getCommandInfo() doesn't set the
- isDisabled flag to indicate that the command is inactive.
- */
- bool isCommandActive (const CommandID commandID);
-
- /** If this object is a Component, this method will search upwards in its current
- UI hierarchy for the next parent component that implements the
- ApplicationCommandTarget class.
-
- If your target is a Component, this is a very handy method to use in your
- getNextCommandTarget() implementation.
- */
- ApplicationCommandTarget* findFirstTargetParentComponent();
-
- private:
- //==============================================================================
- class CommandMessage;
- friend class CommandMessage;
-
- bool tryToInvoke (const InvocationInfo&, bool async);
-
- JUCE_DECLARE_WEAK_REFERENCEABLE (ApplicationCommandTarget)
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget)
- };
-
- } // namespace juce
|