Add TAL-Reverb-II plugin to test
[juce-lv2.git] / juce / source / src / gui / components / controls / juce_Label.cpp
blob260971233ce1ccab5760b3b583fbe123085b72a8
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../../core/juce_StandardHeader.h"
28 BEGIN_JUCE_NAMESPACE
30 #include "juce_Label.h"
31 #include "../lookandfeel/juce_LookAndFeel.h"
32 #include "../windows/juce_ComponentPeer.h"
33 #include "../keyboard/juce_CaretComponent.h"
36 //==============================================================================
37 Label::Label (const String& name,
38 const String& labelText)
39 : Component (name),
40 textValue (labelText),
41 lastTextValue (labelText),
42 font (15.0f),
43 justification (Justification::centredLeft),
44 horizontalBorderSize (5),
45 verticalBorderSize (1),
46 minimumHorizontalScale (0.7f),
47 editSingleClick (false),
48 editDoubleClick (false),
49 lossOfFocusDiscardsChanges (false)
51 setColour (TextEditor::textColourId, Colours::black);
52 setColour (TextEditor::backgroundColourId, Colours::transparentBlack);
53 setColour (TextEditor::outlineColourId, Colours::transparentBlack);
55 textValue.addListener (this);
58 Label::~Label()
60 textValue.removeListener (this);
62 if (ownerComponent != nullptr)
63 ownerComponent->removeComponentListener (this);
65 editor = nullptr;
68 //==============================================================================
69 void Label::setText (const String& newText,
70 const bool broadcastChangeMessage)
72 hideEditor (true);
74 if (lastTextValue != newText)
76 lastTextValue = newText;
77 textValue = newText;
78 repaint();
80 textWasChanged();
82 if (ownerComponent != nullptr)
83 componentMovedOrResized (*ownerComponent, true, true);
85 if (broadcastChangeMessage)
86 callChangeListeners();
90 String Label::getText (const bool returnActiveEditorContents) const
92 return (returnActiveEditorContents && isBeingEdited())
93 ? editor->getText()
94 : textValue.toString();
97 void Label::valueChanged (Value&)
99 if (lastTextValue != textValue.toString())
100 setText (textValue.toString(), true);
103 //==============================================================================
104 void Label::setFont (const Font& newFont)
106 if (font != newFont)
108 font = newFont;
109 repaint();
113 const Font& Label::getFont() const noexcept
115 return font;
118 void Label::setEditable (const bool editOnSingleClick,
119 const bool editOnDoubleClick,
120 const bool lossOfFocusDiscardsChanges_)
122 editSingleClick = editOnSingleClick;
123 editDoubleClick = editOnDoubleClick;
124 lossOfFocusDiscardsChanges = lossOfFocusDiscardsChanges_;
126 setWantsKeyboardFocus (editOnSingleClick || editOnDoubleClick);
127 setFocusContainer (editOnSingleClick || editOnDoubleClick);
130 void Label::setJustificationType (const Justification& newJustification)
132 if (justification != newJustification)
134 justification = newJustification;
135 repaint();
139 void Label::setBorderSize (int h, int v)
141 if (horizontalBorderSize != h || verticalBorderSize != v)
143 horizontalBorderSize = h;
144 verticalBorderSize = v;
145 repaint();
149 //==============================================================================
150 Component* Label::getAttachedComponent() const
152 return static_cast<Component*> (ownerComponent);
155 void Label::attachToComponent (Component* owner,
156 const bool onLeft)
158 if (ownerComponent != nullptr)
159 ownerComponent->removeComponentListener (this);
161 ownerComponent = owner;
163 leftOfOwnerComp = onLeft;
165 if (ownerComponent != nullptr)
167 setVisible (owner->isVisible());
168 ownerComponent->addComponentListener (this);
169 componentParentHierarchyChanged (*ownerComponent);
170 componentMovedOrResized (*ownerComponent, true, true);
174 void Label::componentMovedOrResized (Component& component, bool /*wasMoved*/, bool /*wasResized*/)
176 if (leftOfOwnerComp)
178 setSize (jmin (getFont().getStringWidth (textValue.toString()) + 8, component.getX()),
179 component.getHeight());
181 setTopRightPosition (component.getX(), component.getY());
183 else
185 setSize (component.getWidth(),
186 8 + roundToInt (getFont().getHeight()));
188 setTopLeftPosition (component.getX(), component.getY() - getHeight());
192 void Label::componentParentHierarchyChanged (Component& component)
194 if (component.getParentComponent() != nullptr)
195 component.getParentComponent()->addChildComponent (this);
198 void Label::componentVisibilityChanged (Component& component)
200 setVisible (component.isVisible());
203 //==============================================================================
204 void Label::textWasEdited()
208 void Label::textWasChanged()
212 void Label::showEditor()
214 if (editor == nullptr)
216 addAndMakeVisible (editor = createEditorComponent());
217 editor->setText (getText(), false);
218 editor->addListener (this);
219 editor->grabKeyboardFocus();
220 editor->setHighlightedRegion (Range<int> (0, textValue.toString().length()));
221 editor->addListener (this);
223 resized();
224 repaint();
226 editorShown (editor);
228 enterModalState (false);
229 editor->grabKeyboardFocus();
233 void Label::editorShown (TextEditor*)
237 void Label::editorAboutToBeHidden (TextEditor*)
241 bool Label::updateFromTextEditorContents (TextEditor& ed)
243 const String newText (ed.getText());
245 if (textValue.toString() != newText)
247 lastTextValue = newText;
248 textValue = newText;
249 repaint();
251 textWasChanged();
253 if (ownerComponent != nullptr)
254 componentMovedOrResized (*ownerComponent, true, true);
256 return true;
259 return false;
262 void Label::hideEditor (const bool discardCurrentEditorContents)
264 if (editor != nullptr)
266 WeakReference<Component> deletionChecker (this);
268 ScopedPointer<TextEditor> outgoingEditor (editor);
270 editorAboutToBeHidden (outgoingEditor);
272 const bool changed = (! discardCurrentEditorContents)
273 && updateFromTextEditorContents (*outgoingEditor);
274 outgoingEditor = nullptr;
275 repaint();
277 if (changed)
278 textWasEdited();
280 if (deletionChecker != nullptr)
281 exitModalState (0);
283 if (changed && deletionChecker != nullptr)
284 callChangeListeners();
288 void Label::inputAttemptWhenModal()
290 if (editor != nullptr)
292 if (lossOfFocusDiscardsChanges)
293 textEditorEscapeKeyPressed (*editor);
294 else
295 textEditorReturnKeyPressed (*editor);
299 bool Label::isBeingEdited() const noexcept
301 return editor != nullptr;
304 TextEditor* Label::createEditorComponent()
306 TextEditor* const ed = new TextEditor (getName());
307 ed->setFont (font);
309 // copy these colours from our own settings..
310 const int cols[] = { TextEditor::backgroundColourId,
311 TextEditor::textColourId,
312 TextEditor::highlightColourId,
313 TextEditor::highlightedTextColourId,
314 TextEditor::outlineColourId,
315 TextEditor::focusedOutlineColourId,
316 TextEditor::shadowColourId,
317 CaretComponent::caretColourId };
319 for (int i = 0; i < numElementsInArray (cols); ++i)
320 ed->setColour (cols[i], findColour (cols[i]));
322 return ed;
325 //==============================================================================
326 void Label::paint (Graphics& g)
328 getLookAndFeel().drawLabel (g, *this);
331 void Label::mouseUp (const MouseEvent& e)
333 if (editSingleClick
334 && e.mouseWasClicked()
335 && contains (e.getPosition())
336 && ! e.mods.isPopupMenu())
338 showEditor();
342 void Label::mouseDoubleClick (const MouseEvent& e)
344 if (editDoubleClick && ! e.mods.isPopupMenu())
345 showEditor();
348 void Label::resized()
350 if (editor != nullptr)
351 editor->setBoundsInset (BorderSize<int> (0));
354 void Label::focusGained (FocusChangeType cause)
356 if (editSingleClick && cause == focusChangedByTabKey)
357 showEditor();
360 void Label::enablementChanged()
362 repaint();
365 void Label::colourChanged()
367 repaint();
370 void Label::setMinimumHorizontalScale (const float newScale)
372 if (minimumHorizontalScale != newScale)
374 minimumHorizontalScale = newScale;
375 repaint();
379 //==============================================================================
380 // We'll use a custom focus traverser here to make sure focus goes from the
381 // text editor to another component rather than back to the label itself.
382 class LabelKeyboardFocusTraverser : public KeyboardFocusTraverser
384 public:
385 LabelKeyboardFocusTraverser() {}
387 Component* getNextComponent (Component* current)
389 return KeyboardFocusTraverser::getNextComponent (dynamic_cast <TextEditor*> (current) != nullptr
390 ? current->getParentComponent() : current);
393 Component* getPreviousComponent (Component* current)
395 return KeyboardFocusTraverser::getPreviousComponent (dynamic_cast <TextEditor*> (current) != nullptr
396 ? current->getParentComponent() : current);
400 KeyboardFocusTraverser* Label::createFocusTraverser()
402 return new LabelKeyboardFocusTraverser();
405 //==============================================================================
406 void Label::addListener (LabelListener* const listener)
408 listeners.add (listener);
411 void Label::removeListener (LabelListener* const listener)
413 listeners.remove (listener);
416 void Label::callChangeListeners()
418 Component::BailOutChecker checker (this);
419 listeners.callChecked (checker, &LabelListener::labelTextChanged, this); // (can't use Label::Listener due to idiotic VC2005 bug)
422 //==============================================================================
423 void Label::textEditorTextChanged (TextEditor& ed)
425 if (editor != nullptr)
427 jassert (&ed == editor);
429 if (! (hasKeyboardFocus (true) || isCurrentlyBlockedByAnotherModalComponent()))
431 if (lossOfFocusDiscardsChanges)
432 textEditorEscapeKeyPressed (ed);
433 else
434 textEditorReturnKeyPressed (ed);
439 void Label::textEditorReturnKeyPressed (TextEditor& ed)
441 if (editor != nullptr)
443 jassert (&ed == editor);
445 const bool changed = updateFromTextEditorContents (ed);
446 hideEditor (true);
448 if (changed)
450 WeakReference<Component> deletionChecker (this);
451 textWasEdited();
453 if (deletionChecker != nullptr)
454 callChangeListeners();
459 void Label::textEditorEscapeKeyPressed (TextEditor& ed)
461 if (editor != nullptr)
463 jassert (&ed == editor);
464 (void) ed;
466 editor->setText (textValue.toString(), false);
467 hideEditor (true);
471 void Label::textEditorFocusLost (TextEditor& ed)
473 textEditorTextChanged (ed);
477 END_JUCE_NAMESPACE