When the user clicks outside of textEditor I want the TextEditor to lose focus. Whats the best way to do this?
(Thankyou for spelling "lose" correctly. I think you must be in the minority on this forum!)
It will of course lose focus if something else gets focus, so you'd just need to make sure that whatever other component you expect the user to click on is set up to accept focus.
For accepting focus is using setWantsKeyboardFocus(true) the correct way?Â
Yep. There are a few methods in component for controlling the way focus is passed around, but that's the main one.
Does anybody have a generic solution for when the user clicks anywhere outside the TextEditor, even on components that don’t want focus, the TextEditor loses focus?
Like every normal non-JUCE app already does? Users expect this and we don’t want to give our background/group/main component to suddenly receive focus, and thus disrupt the current focus order.
I’ve done this, which may do the trick for you. It was written to allow tabbing around by setting setExplicitFocusOrder
on the text editors.
class TabHighlightedTextEditor : public TextEditor
{
public:
TabHighlightedTextEditor() = default;
void focusGained (FocusChangeType cause) override
{
if (cause == focusChangedByTabKey)
setHighlightedRegion ({ 0, getTotalNumChars() });
TextEditor::focusGained (cause);
}
void focusLost (FocusChangeType cause) override
{
setHighlightedRegion ({});
TextEditor::focusLost (cause);
}
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TabHighlightedTextEditor)
};
I’ve used global mouse listeners to solve similar issues and it’s worked alright. Something like:
struct FocusAwareTextEditor : juce::TextEditor
{
FocusAwareTextEditor() = default;
void parentHierarchyChanged() override
{
if (getParentComponent())
{
juce::Desktop::getInstance().addGlobalMouseListener (this);
}
else
{
juce::Desktop::getInstance().removeGlobalMouseListener (this);
}
}
void mouseDown (const juce::MouseEvent& e) override
{
if (getScreenBounds().contains (e.getScreenPosition()))
{
// Delegate mouse clicks inside the editor to the TextEditor
// class so as to not break its functionality.
juce::TextEditor::mouseDown (e);
}
else
{
// Lose focus when mouse clicks occur outside the editor.
giveAwayKeyboardFocus();
}
}
};
I made some changes to it. I’ve moved the addGlobalMouse listener into focusGained and the removeGlobalListener into focusLost. That way the listener is not needlessly being called if the TextEditor doesn’t even have focus.