LMMS
Loading...
Searching...
No Matches
juce_KeyMappingEditorComponent.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - 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 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-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
26namespace juce
27{
28
30{
31public:
33 const String& keyName, int keyIndex)
34 : Button (keyName),
35 owner (kec),
36 commandID (command),
37 keyNum (keyIndex)
38 {
41
42 setTooltip (keyIndex < 0 ? TRANS("Adds a new key-mapping")
43 : TRANS("Click to change this key-mapping"));
44 }
45
46 void paintButton (Graphics& g, bool /*isOver*/, bool /*isDown*/) override
47 {
48 getLookAndFeel().drawKeymapChangeButton (g, getWidth(), getHeight(), *this,
49 keyNum >= 0 ? getName() : String());
50 }
51
52 void clicked() override
53 {
54 if (keyNum >= 0)
55 {
58
59 m.addItem (TRANS("Change this key-mapping"),
60 [button]
61 {
62 if (button != nullptr)
63 button.getComponent()->assignNewKey();
64 });
65
66 m.addSeparator();
67
68 m.addItem (TRANS("Remove this key-mapping"),
69 [button]
70 {
71 if (button != nullptr)
72 button->owner.getMappings().removeKeyPress (button->commandID,
73 button->keyNum);
74 });
75
76 m.showMenuAsync (PopupMenu::Options().withTargetComponent (this));
77 }
78 else
79 {
80 assignNewKey(); // + button pressed..
81 }
82 }
83
84 using Button::clicked;
85
86 void fitToContent (const int h) noexcept
87 {
88 if (keyNum < 0)
89 setSize (h, h);
90 else
91 setSize (jlimit (h * 4, h * 8, 6 + Font ((float) h * 0.6f).getStringWidth (getName())), h);
92 }
93
94 //==============================================================================
96 {
97 public:
99 : AlertWindow (TRANS("New key-mapping"),
100 TRANS("Please press a key combination now..."),
102 owner (kec)
103 {
104 addButton (TRANS("OK"), 1);
105 addButton (TRANS("Cancel"), 0);
106
107 // (avoid return + escape keys getting processed by the buttons..)
108 for (auto* child : getChildren())
109 child->setWantsKeyboardFocus (false);
110
113 }
114
115 bool keyPressed (const KeyPress& key) override
116 {
117 lastPress = key;
118 String message (TRANS("Key") + ": " + owner.getDescriptionForKeyPress (key));
119
120 auto previousCommand = owner.getMappings().findCommandForKeyPress (key);
121
122 if (previousCommand != 0)
123 message << "\n\n("
124 << TRANS("Currently assigned to \"CMDN\"")
125 .replace ("CMDN", TRANS (owner.getCommandManager().getNameOfCommand (previousCommand)))
126 << ')';
127
129 return true;
130 }
131
132 bool keyStateChanged (bool) override
133 {
134 return true;
135 }
136
138
139 private:
141
143 };
144
145 static void assignNewKeyCallback (int result, ChangeKeyButton* button, KeyPress newKey)
146 {
147 if (result != 0 && button != nullptr)
148 button->setNewKey (newKey, true);
149 }
150
151 void setNewKey (const KeyPress& newKey, bool dontAskUser)
152 {
153 if (newKey.isValid())
154 {
155 auto previousCommand = owner.getMappings().findCommandForKeyPress (newKey);
156
157 if (previousCommand == 0 || dontAskUser)
158 {
159 owner.getMappings().removeKeyPress (newKey);
160
161 if (keyNum >= 0)
162 owner.getMappings().removeKeyPress (commandID, keyNum);
163
164 owner.getMappings().addKeyPress (commandID, newKey, keyNum);
165 }
166 else
167 {
169 TRANS("Change key-mapping"),
170 TRANS("This key is already assigned to the command \"CMDN\"")
171 .replace ("CMDN", owner.getCommandManager().getNameOfCommand (previousCommand))
172 + "\n\n"
173 + TRANS("Do you want to re-assign it to this new command instead?"),
174 TRANS("Re-assign"),
175 TRANS("Cancel"),
176 this,
178 this, KeyPress (newKey)));
179 }
180 }
181 }
182
183 static void keyChosen (int result, ChangeKeyButton* button)
184 {
185 if (button != nullptr && button->currentKeyEntryWindow != nullptr)
186 {
187 if (result != 0)
188 {
189 button->currentKeyEntryWindow->setVisible (false);
190 button->setNewKey (button->currentKeyEntryWindow->lastPress, false);
191 }
192
193 button->currentKeyEntryWindow.reset();
194 }
195 }
196
198 {
201 }
202
203private:
206 const int keyNum;
207 std::unique_ptr<KeyEntryWindow> currentKeyEntryWindow;
208
210};
211
212//==============================================================================
214{
215public:
217 : owner (kec), commandID (command)
218 {
219 setInterceptsMouseClicks (false, true);
220
221 const bool isReadOnly = owner.isCommandReadOnly (commandID);
222
223 auto keyPresses = owner.getMappings().getKeyPressesAssignedToCommand (commandID);
224
225 for (int i = 0; i < jmin ((int) maxNumAssignments, keyPresses.size()); ++i)
226 addKeyPressButton (owner.getDescriptionForKeyPress (keyPresses.getReference (i)), i, isReadOnly);
227
228 addKeyPressButton ("Change Key Mapping", -1, isReadOnly);
229 }
230
231 void addKeyPressButton (const String& desc, const int index, const bool isReadOnly)
232 {
233 auto* b = new ChangeKeyButton (owner, commandID, desc, index);
234 keyChangeButtons.add (b);
235
236 b->setEnabled (! isReadOnly);
237 b->setVisible (keyChangeButtons.size() <= (int) maxNumAssignments);
239 }
240
241 void paint (Graphics& g) override
242 {
243 g.setFont ((float) getHeight() * 0.7f);
244 g.setColour (owner.findColour (KeyMappingEditorComponent::textColourId));
245
246 g.drawFittedText (TRANS (owner.getCommandManager().getNameOfCommand (commandID)),
247 4, 0, jmax (40, getChildComponent (0)->getX() - 5), getHeight(),
249 }
250
251 void resized() override
252 {
253 int x = getWidth() - 4;
254
255 for (int i = keyChangeButtons.size(); --i >= 0;)
256 {
257 auto* b = keyChangeButtons.getUnchecked(i);
258
259 b->fitToContent (getHeight() - 2);
260 b->setTopRightPosition (x, 1);
261 x = b->getX() - 5;
262 }
263 }
264
265private:
266 std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
267 {
269 }
270
274
275 enum { maxNumAssignments = 3 };
276
278};
279
280//==============================================================================
282{
283public:
285 : owner (kec), commandID (command)
286 {}
287
288 String getUniqueName() const override { return String ((int) commandID) + "_id"; }
289 bool mightContainSubItems() override { return false; }
290 int getItemHeight() const override { return 20; }
291 std::unique_ptr<Component> createItemComponent() override { return std::make_unique<ItemComponent> (owner, commandID); }
292 String getAccessibilityName() override { return TRANS (owner.getCommandManager().getNameOfCommand (commandID)); }
293
294private:
297
299};
300
301
302//==============================================================================
304{
305public:
309
310 String getUniqueName() const override { return categoryName + "_cat"; }
311 bool mightContainSubItems() override { return true; }
312 int getItemHeight() const override { return 22; }
314
315 void paintItem (Graphics& g, int width, int height) override
316 {
317 g.setFont (Font ((float) height * 0.7f, Font::bold));
318 g.setColour (owner.findColour (KeyMappingEditorComponent::textColourId));
319
320 g.drawText (TRANS (categoryName), 2, 0, width - 2, height, Justification::centredLeft, true);
321 }
322
323 void itemOpennessChanged (bool isNowOpen) override
324 {
325 if (isNowOpen)
326 {
327 if (getNumSubItems() == 0)
328 for (auto command : owner.getCommandManager().getCommandsInCategory (categoryName))
329 if (owner.shouldCommandBeIncluded (command))
330 addSubItem (new MappingItem (owner, command));
331 }
332 else
333 {
335 }
336 }
337
338private:
341
343};
344
345//==============================================================================
347 private ChangeListener
348{
349public:
351 {
353 owner.getMappings().addChangeListener (this);
354 }
355
356 ~TopLevelItem() override
357 {
358 owner.getMappings().removeChangeListener (this);
359 }
360
361 bool mightContainSubItems() override { return true; }
362 String getUniqueName() const override { return "keys"; }
363
365 {
366 const OpennessRestorer opennessRestorer (*this);
368
369 for (auto category : owner.getCommandManager().getCommandCategories())
370 {
371 int count = 0;
372
373 for (auto command : owner.getCommandManager().getCommandsInCategory (category))
374 if (owner.shouldCommandBeIncluded (command))
375 ++count;
376
377 if (count > 0)
378 addSubItem (new CategoryItem (owner, category));
379 }
380 }
381
382private:
384};
385
387{
388 if (result != 0 && owner != nullptr)
390}
391
392//==============================================================================
394 const bool showResetToDefaultButton)
395 : mappings (mappingManager),
396 resetButton (TRANS ("reset to defaults"))
397{
398 treeItem.reset (new TopLevelItem (*this));
399
400 if (showResetToDefaultButton)
401 {
403
404 resetButton.onClick = [this]
405 {
407 TRANS("Reset to defaults"),
408 TRANS("Are you sure you want to reset all the key-mappings to their default state?"),
409 TRANS("Reset"),
410 {}, this,
412 };
413 }
414
416 tree.setTitle ("Key Mappings");
418 tree.setRootItemVisible (false);
419 tree.setDefaultOpenness (true);
420 tree.setRootItem (treeItem.get());
421 tree.setIndentSize (12);
422}
423
425{
426 tree.setRootItem (nullptr);
427}
428
429//==============================================================================
431 Colour textColour)
432{
433 setColour (backgroundColourId, mainBackground);
434 setColour (textColourId, textColour);
435 tree.setColour (TreeView::backgroundColourId, mainBackground);
436}
437
439{
440 treeItem->changeListenerCallback (nullptr);
441}
442
444{
445 int h = getHeight();
446
447 if (resetButton.isVisible())
448 {
449 const int buttonHeight = 20;
450 h -= buttonHeight + 8;
451 int x = getWidth() - 8;
452
453 resetButton.changeWidthToFitText (buttonHeight);
454 resetButton.setTopRightPosition (x, h + 6);
455 }
456
457 tree.setBounds (0, 0, getWidth(), h);
458}
459
460//==============================================================================
462{
463 auto* ci = mappings.getCommandManager().getCommandForID (commandID);
464
465 return ci != nullptr && (ci->flags & ApplicationCommandInfo::hiddenFromKeyEditor) == 0;
466}
467
469{
470 auto* ci = mappings.getCommandManager().getCommandForID (commandID);
471
472 return ci != nullptr && (ci->flags & ApplicationCommandInfo::readOnlyInKeyEditor) != 0;
473}
474
476{
477 return key.getTextDescription();
478}
479
480} // namespace juce
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
static void message(int level, const char *fmt,...)
Definition adplugdb.cpp:120
void addButton(const String &name, int returnValue, const KeyPress &shortcutKey1=KeyPress(), const KeyPress &shortcutKey2=KeyPress())
Definition juce_AlertWindow.cpp:111
static bool JUCE_CALLTYPE showOkCancelBox(MessageBoxIconType iconType, const String &title, const String &message, const String &button1Text, const String &button2Text, Component *associatedComponent, ModalComponentManager::Callback *callback)
Definition juce_AlertWindow.cpp:752
void setMessage(const String &message)
Definition juce_AlertWindow.cpp:86
static constexpr auto NoIcon
Definition juce_AlertWindow.h:479
AlertWindow(const String &title, const String &message, MessageBoxIconType iconType, Component *associatedComponent=nullptr)
Definition juce_AlertWindow.cpp:39
virtual void clicked()
Definition juce_Button.cpp:339
Button(const String &buttonName)
Definition juce_Button.cpp:76
void setTriggeredOnMouseDown(bool isTriggeredOnMouseDown) noexcept
Definition juce_Button.cpp:328
void setTooltip(const String &newTooltip) override
Definition juce_Button.cpp:105
Definition juce_ChangeBroadcaster.h:35
Definition juce_ChangeListener.h:45
Definition juce_Colour.h:38
Definition juce_Component.h:2287
void setInterceptsMouseClicks(bool allowClicksOnThisComponent, bool allowClicksOnChildComponents) noexcept
Definition juce_Component.cpp:1420
int getHeight() const noexcept
Definition juce_Component.h:274
void grabKeyboardFocus()
Definition juce_Component.cpp:2995
int getX() const noexcept
Definition juce_Component.h:259
void addAndMakeVisible(Component *child, int zOrder=-1)
Definition juce_Component.cpp:1554
Component() noexcept
Definition juce_Component.cpp:517
Component * getChildComponent(int index) const noexcept
Definition juce_Component.cpp:1648
void setSize(int newWidth, int newHeight)
Definition juce_Component.cpp:1262
void setColour(int colourID, Colour newColour)
Definition juce_Component.cpp:2242
void setWantsKeyboardFocus(bool wantsFocus) noexcept
Definition juce_Component.cpp:2842
Colour findColour(int colourID, bool inheritFromParent=false) const
Definition juce_Component.cpp:2219
static std::unique_ptr< AccessibilityHandler > createIgnoredAccessibilityHandler(Component &)
Definition juce_Component.cpp:3292
int getWidth() const noexcept
Definition juce_Component.h:271
LookAndFeel & getLookAndFeel() const noexcept
Definition juce_Component.cpp:2173
void addChildComponent(Component *child, int zOrder=-1)
Definition juce_Component.cpp:1548
const Array< Component * > & getChildren() const noexcept
Definition juce_Component.h:685
String getName() const noexcept
Definition juce_Component.h:76
Definition juce_Font.h:42
@ bold
Definition juce_Font.h:51
Definition juce_GraphicsContext.h:45
@ centredLeft
Definition juce_Justification.h:143
Definition juce_KeyMappingEditorComponent.cpp:304
void itemOpennessChanged(bool isNowOpen) override
Definition juce_KeyMappingEditorComponent.cpp:323
String getAccessibilityName() override
Definition juce_KeyMappingEditorComponent.cpp:313
int getItemHeight() const override
Definition juce_KeyMappingEditorComponent.cpp:312
bool mightContainSubItems() override
Definition juce_KeyMappingEditorComponent.cpp:311
void paintItem(Graphics &g, int width, int height) override
Definition juce_KeyMappingEditorComponent.cpp:315
String categoryName
Definition juce_KeyMappingEditorComponent.cpp:340
String getUniqueName() const override
Definition juce_KeyMappingEditorComponent.cpp:310
KeyMappingEditorComponent & owner
Definition juce_KeyMappingEditorComponent.cpp:339
CategoryItem(KeyMappingEditorComponent &kec, const String &name)
Definition juce_KeyMappingEditorComponent.cpp:306
Definition juce_KeyMappingEditorComponent.cpp:96
bool keyStateChanged(bool) override
Definition juce_KeyMappingEditorComponent.cpp:132
bool keyPressed(const KeyPress &key) override
Definition juce_KeyMappingEditorComponent.cpp:115
KeyMappingEditorComponent & owner
Definition juce_KeyMappingEditorComponent.cpp:140
KeyEntryWindow(KeyMappingEditorComponent &kec)
Definition juce_KeyMappingEditorComponent.cpp:98
KeyPress lastPress
Definition juce_KeyMappingEditorComponent.cpp:137
Definition juce_KeyMappingEditorComponent.cpp:30
void fitToContent(const int h) noexcept
Definition juce_KeyMappingEditorComponent.cpp:86
void assignNewKey()
Definition juce_KeyMappingEditorComponent.cpp:197
std::unique_ptr< KeyEntryWindow > currentKeyEntryWindow
Definition juce_KeyMappingEditorComponent.cpp:207
const CommandID commandID
Definition juce_KeyMappingEditorComponent.cpp:205
KeyMappingEditorComponent & owner
Definition juce_KeyMappingEditorComponent.cpp:204
static void keyChosen(int result, ChangeKeyButton *button)
Definition juce_KeyMappingEditorComponent.cpp:183
static void assignNewKeyCallback(int result, ChangeKeyButton *button, KeyPress newKey)
Definition juce_KeyMappingEditorComponent.cpp:145
const int keyNum
Definition juce_KeyMappingEditorComponent.cpp:206
void setNewKey(const KeyPress &newKey, bool dontAskUser)
Definition juce_KeyMappingEditorComponent.cpp:151
ChangeKeyButton(KeyMappingEditorComponent &kec, CommandID command, const String &keyName, int keyIndex)
Definition juce_KeyMappingEditorComponent.cpp:32
void clicked() override
Definition juce_KeyMappingEditorComponent.cpp:52
void paintButton(Graphics &g, bool, bool) override
Definition juce_KeyMappingEditorComponent.cpp:46
Definition juce_KeyMappingEditorComponent.cpp:214
const CommandID commandID
Definition juce_KeyMappingEditorComponent.cpp:273
OwnedArray< ChangeKeyButton > keyChangeButtons
Definition juce_KeyMappingEditorComponent.cpp:272
KeyMappingEditorComponent & owner
Definition juce_KeyMappingEditorComponent.cpp:271
void resized() override
Definition juce_KeyMappingEditorComponent.cpp:251
void paint(Graphics &g) override
Definition juce_KeyMappingEditorComponent.cpp:241
@ maxNumAssignments
Definition juce_KeyMappingEditorComponent.cpp:275
ItemComponent(KeyMappingEditorComponent &kec, CommandID command)
Definition juce_KeyMappingEditorComponent.cpp:216
void addKeyPressButton(const String &desc, const int index, const bool isReadOnly)
Definition juce_KeyMappingEditorComponent.cpp:231
std::unique_ptr< AccessibilityHandler > createAccessibilityHandler() override
Definition juce_KeyMappingEditorComponent.cpp:266
Definition juce_KeyMappingEditorComponent.cpp:282
String getUniqueName() const override
Definition juce_KeyMappingEditorComponent.cpp:288
std::unique_ptr< Component > createItemComponent() override
Definition juce_KeyMappingEditorComponent.cpp:291
String getAccessibilityName() override
Definition juce_KeyMappingEditorComponent.cpp:292
KeyMappingEditorComponent & owner
Definition juce_KeyMappingEditorComponent.cpp:295
const CommandID commandID
Definition juce_KeyMappingEditorComponent.cpp:296
bool mightContainSubItems() override
Definition juce_KeyMappingEditorComponent.cpp:289
MappingItem(KeyMappingEditorComponent &kec, CommandID command)
Definition juce_KeyMappingEditorComponent.cpp:284
int getItemHeight() const override
Definition juce_KeyMappingEditorComponent.cpp:290
Definition juce_KeyMappingEditorComponent.cpp:348
String getUniqueName() const override
Definition juce_KeyMappingEditorComponent.cpp:362
TopLevelItem(KeyMappingEditorComponent &kec)
Definition juce_KeyMappingEditorComponent.cpp:350
void changeListenerCallback(ChangeBroadcaster *) override
Definition juce_KeyMappingEditorComponent.cpp:364
KeyMappingEditorComponent & owner
Definition juce_KeyMappingEditorComponent.cpp:383
~TopLevelItem() override
Definition juce_KeyMappingEditorComponent.cpp:356
bool mightContainSubItems() override
Definition juce_KeyMappingEditorComponent.cpp:361
Definition juce_KeyMappingEditorComponent.h:39
@ backgroundColourId
Definition juce_KeyMappingEditorComponent.h:106
@ textColourId
Definition juce_KeyMappingEditorComponent.h:107
~KeyMappingEditorComponent() override
Definition juce_KeyMappingEditorComponent.cpp:424
void setColours(Colour mainBackground, Colour textColour)
Definition juce_KeyMappingEditorComponent.cpp:430
virtual bool isCommandReadOnly(CommandID commandID)
Definition juce_KeyMappingEditorComponent.cpp:468
virtual bool shouldCommandBeIncluded(CommandID commandID)
Definition juce_KeyMappingEditorComponent.cpp:461
void parentHierarchyChanged() override
Definition juce_KeyMappingEditorComponent.cpp:438
std::unique_ptr< TopLevelItem > treeItem
Definition juce_KeyMappingEditorComponent.h:127
TreeView tree
Definition juce_KeyMappingEditorComponent.h:119
void resized() override
Definition juce_KeyMappingEditorComponent.cpp:443
KeyPressMappingSet & mappings
Definition juce_KeyMappingEditorComponent.h:118
virtual String getDescriptionForKeyPress(const KeyPress &key)
Definition juce_KeyMappingEditorComponent.cpp:475
KeyPressMappingSet & getMappings() const noexcept
Definition juce_KeyMappingEditorComponent.h:65
TextButton resetButton
Definition juce_KeyMappingEditorComponent.h:120
KeyMappingEditorComponent(KeyPressMappingSet &mappingSet, bool showResetToDefaultButton)
Definition juce_KeyMappingEditorComponent.cpp:393
Definition juce_KeyPress.h:40
bool isValid() const noexcept
Definition juce_KeyPress.h:102
Definition juce_KeyPressMappingSet.h:89
void resetToDefaultMappings()
Definition juce_KeyPressMappingSet.cpp:104
static ModalComponentManager::Callback * forComponent(void(*functionToCall)(int, ComponentType *), ComponentType *component)
Definition juce_ModalComponentManager.h:276
Definition juce_OwnedArray.h:51
Definition juce_PopupMenu.h:457
Definition juce_PopupMenu.h:80
Definition juce_String.h:53
@ backgroundColourId
Definition juce_TreeView.h:870
Definition juce_TreeView.h:596
void clearSubItems()
Definition juce_TreeView.cpp:1503
int getNumSubItems() const noexcept
Definition juce_TreeView.cpp:1493
void setLinesDrawnForSubItems(bool shouldDrawLines) noexcept
Definition juce_TreeView.cpp:1988
TreeViewItem()
Definition juce_TreeView.cpp:1472
void addSubItem(TreeViewItem *newItem, int insertPosition=-1)
Definition juce_TreeView.cpp:1525
unsigned * m
Definition inflate.c:1559
int g
Definition inflate.c:1573
register unsigned i
Definition inflate.c:1575
unsigned x[BMAX+1]
Definition inflate.c:1586
static const char * name
Definition pugl.h:1582
static int int height
Definition pugl.h:1594
static int width
Definition pugl.h:1593
#define TRANS(stringLiteral)
Definition juce_LocalisedStrings.h:208
#define JUCE_DECLARE_NON_COPYABLE(className)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
Definition carla_juce.cpp:31
int CommandID
Definition juce_ApplicationCommandID.h:37
constexpr Type jmax(Type a, Type b)
Definition juce_MathsFunctions.h:94
MessageBoxIconType
Definition juce_MessageBoxOptions.h:31
@ WarningIcon
Definition juce_MessageBoxOptions.h:35
@ QuestionIcon
Definition juce_MessageBoxOptions.h:33
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Definition juce_MathsFunctions.h:262
static void resetKeyMappingsToDefaultsCallback(int result, KeyMappingEditorComponent *owner)
Definition juce_KeyMappingEditorComponent.cpp:386
@ button
Definition juce_AccessibilityRole.h:38
@ readOnlyInKeyEditor
Definition juce_ApplicationCommandInfo.h:173
@ hiddenFromKeyEditor
Definition juce_ApplicationCommandInfo.h:168
ZCONST char * key
Definition crypt.c:587
uch h[RAND_HEAD_LEN]
Definition crypt.c:459
b
Definition crypt.c:628
int result
Definition process.c:1455
_WDL_CSTRING_PREFIX void INT_PTR count
Definition wdlcstring.h:263