1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - Raw Material Software Limited
6 
7    JUCE is an open source library subject to commercial or open-source
8    licensing.
9 
10    By using JUCE, you agree to the terms of both the JUCE 6 End-User License
11    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
12 
13    End User License Agreement: www.juce.com/juce-6-licence
14    Privacy Policy: www.juce.com/juce-privacy-policy
15 
16    Or: You may also use this code under the terms of the GPL v3 (see
17    www.gnu.org/licenses).
18 
19    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21    DISCLAIMED.
22 
23   ==============================================================================
24 */
25 
26 namespace juce
27 {
28 
29 //==============================================================================
30 /**
31     Represents a key press, including any modifier keys that are needed.
32 
33     E.g. a KeyPress might represent CTRL+C, SHIFT+ALT+H, Spacebar, Escape, etc.
34 
35     @see Component, KeyListener, KeyPressMappingSet, Button::addShortcut
36 
37     @tags{GUI}
38 */
39 class JUCE_API  KeyPress
40 {
41 public:
42     //==============================================================================
43     /** Creates an (invalid) KeyPress.
44 
45         @see isValid
46     */
47     KeyPress() = default;
48 
49     /** Destructor. */
50     ~KeyPress() = default;
51 
52     /** Creates a KeyPress for a key and some modifiers.
53 
54         e.g.
55         CTRL+C would be: KeyPress ('c', ModifierKeys::ctrlModifier, 0)
56         SHIFT+Escape would be: KeyPress (KeyPress::escapeKey, ModifierKeys::shiftModifier, 0)
57 
58         @param keyCode      a code that represents the key - this value must be
59                             one of special constants listed in this class, or an
60                             8-bit character code such as a letter (case is ignored),
61                             digit or a simple key like "," or ".". Note that this
62                             isn't the same as the textCharacter parameter, so for example
63                             a keyCode of 'a' and a shift-key modifier should have a
64                             textCharacter value of 'A'.
65         @param modifiers    the modifiers to associate with the keystroke
66         @param textCharacter    the character that would be printed if someone typed
67                             this keypress into a text editor. This value may be
68                             null if the keypress is a non-printing character
69         @see getKeyCode, isKeyCode, getModifiers
70     */
71     KeyPress (int keyCode,
72               ModifierKeys modifiers,
73               juce_wchar textCharacter) noexcept;
74 
75     /** Creates a keypress with a keyCode but no modifiers or text character. */
76     explicit KeyPress (int keyCode) noexcept;
77 
78     /** Creates a copy of another KeyPress. */
79     KeyPress (const KeyPress&) = default;
80 
81     /** Copies this KeyPress from another one. */
82     KeyPress& operator= (const KeyPress&) = default;
83 
84     /** Compares two KeyPress objects. */
85     bool operator== (const KeyPress& other) const noexcept;
86 
87     /** Compares two KeyPress objects. */
88     bool operator!= (const KeyPress& other) const noexcept;
89 
90     /** Returns true if this keypress is for the given keycode without any modifiers. */
91     bool operator== (int keyCode) const noexcept;
92 
93     /** Returns true if this keypress is not for the given keycode without any modifiers. */
94     bool operator!= (int keyCode) const noexcept;
95 
96     //==============================================================================
97     /** Returns true if this is a valid KeyPress.
98 
99         A null keypress can be created by the default constructor, in case it's
100         needed.
101     */
isValid()102     bool isValid() const noexcept                               { return keyCode != 0; }
103 
104     /** Returns the key code itself.
105 
106         This will either be one of the special constants defined in this class,
107         or an 8-bit character code.
108     */
getKeyCode()109     int getKeyCode() const noexcept                             { return keyCode; }
110 
111     /** Returns the key modifiers.
112 
113         @see ModifierKeys
114     */
getModifiers()115     ModifierKeys getModifiers() const noexcept                  { return mods; }
116 
117     /** Returns the character that is associated with this keypress.
118 
119         This is the character that you'd expect to see printed if you press this
120         keypress in a text editor or similar component.
121     */
getTextCharacter()122     juce_wchar getTextCharacter() const noexcept                { return textCharacter; }
123 
124     /** Checks whether the KeyPress's key is the same as the one provided, without checking
125         the modifiers.
126 
127         The values for key codes can either be one of the special constants defined in
128         this class, or an 8-bit character code.
129 
130         @see getKeyCode
131     */
isKeyCode(int keyCodeToCompare)132     bool isKeyCode (int keyCodeToCompare) const noexcept        { return keyCode == keyCodeToCompare; }
133 
134     //==============================================================================
135     /** Converts a textual key description to a KeyPress.
136 
137         This attempts to decode a textual version of a keypress, e.g. "ctrl + c" or "spacebar".
138 
139         This isn't designed to cope with any kind of input, but should be given the
140         strings that are created by the getTextDescription() method.
141 
142         If the string can't be parsed, the object returned will be invalid.
143 
144         @see getTextDescription
145     */
146     static KeyPress createFromDescription (const String& textVersion);
147 
148     /** Creates a textual description of the key combination.
149 
150         e.g. "ctrl + c" or "delete".
151 
152         To store a keypress in a file, use this method, along with createFromDescription()
153         to retrieve it later.
154     */
155     String getTextDescription() const;
156 
157     /** Creates a textual description of the key combination, using unicode icon symbols if possible.
158 
159         On OSX, this uses the Apple symbols for command, option, shift, etc, instead of the textual
160         modifier key descriptions that are returned by getTextDescription()
161     */
162     String getTextDescriptionWithIcons() const;
163 
164     //==============================================================================
165     /** Checks whether the user is currently holding down the keys that make up this
166         KeyPress.
167 
168         Note that this will return false if any extra modifier keys are
169         down - e.g. if the keypress is CTRL+X and the user is actually holding CTRL+ALT+x
170         then it will be false.
171     */
172     bool isCurrentlyDown() const;
173 
174     /** Checks whether a particular key is held down, irrespective of modifiers.
175 
176         The values for key codes can either be one of the special constants defined in
177         this class, or an 8-bit character code.
178     */
179     static bool isKeyCurrentlyDown (int keyCode);
180 
181     //==============================================================================
182     // Key codes
183     //
184     // Note that the actual values of these are platform-specific and may change
185     // without warning, so don't store them anywhere as constants. For persisting/retrieving
186     // KeyPress objects, use getTextDescription() and createFromDescription() instead.
187     //
188 
189     static const int spaceKey;      /**< key-code for the space bar */
190     static const int escapeKey;     /**< key-code for the escape key */
191     static const int returnKey;     /**< key-code for the return key*/
192     static const int tabKey;        /**< key-code for the tab key*/
193 
194     static const int deleteKey;     /**< key-code for the delete key (not backspace) */
195     static const int backspaceKey;  /**< key-code for the backspace key */
196     static const int insertKey;     /**< key-code for the insert key */
197 
198     static const int upKey;         /**< key-code for the cursor-up key */
199     static const int downKey;       /**< key-code for the cursor-down key */
200     static const int leftKey;       /**< key-code for the cursor-left key */
201     static const int rightKey;      /**< key-code for the cursor-right key */
202     static const int pageUpKey;     /**< key-code for the page-up key */
203     static const int pageDownKey;   /**< key-code for the page-down key */
204     static const int homeKey;       /**< key-code for the home key */
205     static const int endKey;        /**< key-code for the end key */
206 
207     static const int F1Key;         /**< key-code for the F1 key */
208     static const int F2Key;         /**< key-code for the F2 key */
209     static const int F3Key;         /**< key-code for the F3 key */
210     static const int F4Key;         /**< key-code for the F4 key */
211     static const int F5Key;         /**< key-code for the F5 key */
212     static const int F6Key;         /**< key-code for the F6 key */
213     static const int F7Key;         /**< key-code for the F7 key */
214     static const int F8Key;         /**< key-code for the F8 key */
215     static const int F9Key;         /**< key-code for the F9 key */
216     static const int F10Key;        /**< key-code for the F10 key */
217     static const int F11Key;        /**< key-code for the F11 key */
218     static const int F12Key;        /**< key-code for the F12 key */
219     static const int F13Key;        /**< key-code for the F13 key */
220     static const int F14Key;        /**< key-code for the F14 key */
221     static const int F15Key;        /**< key-code for the F15 key */
222     static const int F16Key;        /**< key-code for the F16 key */
223     static const int F17Key;        /**< key-code for the F17 key */
224     static const int F18Key;        /**< key-code for the F18 key */
225     static const int F19Key;        /**< key-code for the F19 key */
226     static const int F20Key;        /**< key-code for the F20 key */
227     static const int F21Key;        /**< key-code for the F21 key */
228     static const int F22Key;        /**< key-code for the F22 key */
229     static const int F23Key;        /**< key-code for the F23 key */
230     static const int F24Key;        /**< key-code for the F24 key */
231     static const int F25Key;        /**< key-code for the F25 key */
232     static const int F26Key;        /**< key-code for the F26 key */
233     static const int F27Key;        /**< key-code for the F27 key */
234     static const int F28Key;        /**< key-code for the F28 key */
235     static const int F29Key;        /**< key-code for the F29 key */
236     static const int F30Key;        /**< key-code for the F30 key */
237     static const int F31Key;        /**< key-code for the F31 key */
238     static const int F32Key;        /**< key-code for the F32 key */
239     static const int F33Key;        /**< key-code for the F33 key */
240     static const int F34Key;        /**< key-code for the F34 key */
241     static const int F35Key;        /**< key-code for the F35 key */
242 
243     static const int numberPad0;     /**< key-code for the 0 on the numeric keypad. */
244     static const int numberPad1;     /**< key-code for the 1 on the numeric keypad. */
245     static const int numberPad2;     /**< key-code for the 2 on the numeric keypad. */
246     static const int numberPad3;     /**< key-code for the 3 on the numeric keypad. */
247     static const int numberPad4;     /**< key-code for the 4 on the numeric keypad. */
248     static const int numberPad5;     /**< key-code for the 5 on the numeric keypad. */
249     static const int numberPad6;     /**< key-code for the 6 on the numeric keypad. */
250     static const int numberPad7;     /**< key-code for the 7 on the numeric keypad. */
251     static const int numberPad8;     /**< key-code for the 8 on the numeric keypad. */
252     static const int numberPad9;     /**< key-code for the 9 on the numeric keypad. */
253 
254     static const int numberPadAdd;            /**< key-code for the add sign on the numeric keypad. */
255     static const int numberPadSubtract;       /**< key-code for the subtract sign on the numeric keypad. */
256     static const int numberPadMultiply;       /**< key-code for the multiply sign on the numeric keypad. */
257     static const int numberPadDivide;         /**< key-code for the divide sign on the numeric keypad. */
258     static const int numberPadSeparator;      /**< key-code for the comma on the numeric keypad. */
259     static const int numberPadDecimalPoint;   /**< key-code for the decimal point sign on the numeric keypad. */
260     static const int numberPadEquals;         /**< key-code for the equals key on the numeric keypad. */
261     static const int numberPadDelete;         /**< key-code for the delete key on the numeric keypad. */
262 
263     static const int playKey;        /**< key-code for a multimedia 'play' key, (not all keyboards will have one) */
264     static const int stopKey;        /**< key-code for a multimedia 'stop' key, (not all keyboards will have one) */
265     static const int fastForwardKey; /**< key-code for a multimedia 'fast-forward' key, (not all keyboards will have one) */
266     static const int rewindKey;      /**< key-code for a multimedia 'rewind' key, (not all keyboards will have one) */
267 
268 private:
269     //==============================================================================
270     int keyCode = 0;
271     ModifierKeys mods;
272     juce_wchar textCharacter = 0;
273 
274     JUCE_LEAK_DETECTOR (KeyPress)
275 };
276 
277 } // namespace juce
278