diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index 0d954dacb7..14f0efd337 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -1338,27 +1338,10 @@ private: return getIvar (self, "owner"); } - //============================================================================== - static void drawRect (id self, SEL, NSRect r) - { - NSViewComponentPeer* const owner = getOwner (self); - - if (owner != nullptr) - owner->drawRect (r); - } - - static BOOL isOpaque (id self, SEL) - { - NSViewComponentPeer* const owner = getOwner (self); - return owner == nullptr || owner->isOpaque(); - } - - //============================================================================== - static void mouseDown (id self, SEL, NSEvent* ev) + static void mouseDown (id self, SEL s, NSEvent* ev) { if (JUCEApplication::isStandaloneApp()) - [self performSelector: @selector (asyncMouseDown:) - withObject: ev]; + asyncMouseDown (self, s, ev); else // In some host situations, the host will stop modal loops from working // correctly if they're called from a mouse event, so we'll trigger @@ -1368,19 +1351,10 @@ private: waitUntilDone: NO]; } - static void asyncMouseDown (id self, SEL, NSEvent* ev) - { - NSViewComponentPeer* const owner = getOwner (self); - - if (owner != nullptr) - owner->redirectMouseDown (ev); - } - - static void mouseUp (id self, SEL, NSEvent* ev) + static void mouseUp (id self, SEL s, NSEvent* ev) { if (! JUCEApplication::isStandaloneApp()) - [self performSelector: @selector (asyncMouseUp:) - withObject: ev]; + asyncMouseUp (self, s, ev); else // In some host situations, the host will stop modal loops from working // correctly if they're called from a mouse event, so we'll trigger @@ -1390,55 +1364,51 @@ private: waitUntilDone: NO]; } - static void asyncMouseUp (id self, SEL, NSEvent* ev) { NSViewComponentPeer* const owner = getOwner (self); if (owner != nullptr) owner->redirectMouseUp (ev); } - static void mouseDragged (id self, SEL, NSEvent* ev) { NSViewComponentPeer* const owner = getOwner (self); if (owner != nullptr) owner->redirectMouseDrag (ev); } - static void mouseMoved (id self, SEL, NSEvent* ev) { NSViewComponentPeer* const owner = getOwner (self); if (owner != nullptr) owner->redirectMouseMove (ev); } - static void mouseEntered (id self, SEL, NSEvent* ev) { NSViewComponentPeer* const owner = getOwner (self); if (owner != nullptr) owner->redirectMouseEnter (ev); } - static void mouseExited (id self, SEL, NSEvent* ev) { NSViewComponentPeer* const owner = getOwner (self); if (owner != nullptr) owner->redirectMouseExit (ev); } - static void scrollWheel (id self, SEL, NSEvent* ev) { NSViewComponentPeer* const owner = getOwner (self); if (owner != nullptr) owner->redirectMouseWheel (ev); } - - static void rightMouseDown (id self, SEL, NSEvent* ev) { [(NSView*) self mouseDown: ev]; } - static void rightMouseDragged (id self, SEL, NSEvent* ev) { [(NSView*) self mouseDragged: ev]; } - static void rightMouseUp (id self, SEL, NSEvent* ev) { [(NSView*) self mouseUp: ev]; } - static void otherMouseDown (id self, SEL, NSEvent* ev) { [(NSView*) self mouseDown: ev]; } - static void otherMouseDragged (id self, SEL, NSEvent* ev) { [(NSView*) self mouseDragged: ev]; } - static void otherMouseUp (id self, SEL, NSEvent* ev) { [(NSView*) self mouseUp: ev]; } + static void asyncMouseDown (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseDown (ev); } + static void asyncMouseUp (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseUp (ev); } + static void mouseDragged (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseDrag (ev); } + static void mouseMoved (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseMove (ev); } + static void mouseEntered (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseEnter (ev); } + static void mouseExited (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseExit (ev); } + static void scrollWheel (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseWheel (ev); } - static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; } + static void rightMouseDown (id self, SEL s, NSEvent* ev) { mouseDown (self, s, ev); } + static void otherMouseDown (id self, SEL s, NSEvent* ev) { mouseDown (self, s, ev); } + static void rightMouseDragged (id self, SEL s, NSEvent* ev) { mouseDragged (self, s, ev); } + static void otherMouseDragged (id self, SEL s, NSEvent* ev) { mouseDragged (self, s, ev); } + static void rightMouseUp (id self, SEL s, NSEvent* ev) { mouseUp (self, s, ev); } + static void otherMouseUp (id self, SEL s, NSEvent* ev) { mouseUp (self, s, ev); } - static void frameChanged (id self, SEL, NSNotification*) - { - NSViewComponentPeer* const owner = getOwner (self); + static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; } - if (owner != nullptr) - owner->redirectMovedOrResized(); - } + static void drawRect (id self, SEL, NSRect r) { if (NSViewComponentPeer* const p = getOwner (self)) p->drawRect (r); } + static void frameChanged (id self, SEL, NSNotification*) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMovedOrResized(); } + static void viewDidMoveToWindow (id self, SEL) { if (NSViewComponentPeer* const p = getOwner (self)) p->viewMovedToWindow(); } - static void viewDidMoveToWindow (id self, SEL) + static BOOL isOpaque (id self, SEL) { NSViewComponentPeer* const owner = getOwner (self); - - if (owner != nullptr) - owner->viewMovedToWindow(); + return owner == nullptr || owner->isOpaque(); } //============================================================================== static void keyDown (id self, SEL, NSEvent* ev) { - NSViewComponentPeer* const owner = getOwner (self); - - TextInputTarget* const target = owner->findCurrentTextInputTarget(); - owner->textWasInserted = false; + if (NSViewComponentPeer* const owner = getOwner (self)) + { + TextInputTarget* const target = owner->findCurrentTextInputTarget(); + owner->textWasInserted = false; - if (target != nullptr) - [(NSView*) self interpretKeyEvents: [NSArray arrayWithObject: ev]]; - else - owner->stringBeingComposed = String::empty; + if (target != nullptr) + [(NSView*) self interpretKeyEvents: [NSArray arrayWithObject: ev]]; + else + owner->stringBeingComposed = String::empty; - if ((! owner->textWasInserted) && (owner == nullptr || ! owner->redirectKeyDown (ev))) - { - objc_super s = { self, [NSView class] }; - objc_msgSendSuper (&s, @selector (keyDown:), ev); + if ((! owner->textWasInserted) && (owner == nullptr || ! owner->redirectKeyDown (ev))) + { + objc_super s = { self, [NSView class] }; + objc_msgSendSuper (&s, @selector (keyDown:), ev); + } } } @@ -1457,65 +1427,63 @@ private: static void insertText (id self, SEL, id aString) { // This commits multi-byte text when return is pressed, or after every keypress for western keyboards - NSViewComponentPeer* const owner = getOwner (self); - - NSString* newText = [aString isKindOfClass: [NSAttributedString class]] ? [aString string] : aString; - - if ([newText length] > 0) + if (NSViewComponentPeer* const owner = getOwner (self)) { - TextInputTarget* const target = owner->findCurrentTextInputTarget(); + NSString* newText = [aString isKindOfClass: [NSAttributedString class]] ? [aString string] : aString; - if (target != nullptr) + if ([newText length] > 0) { - target->insertTextAtCaret (nsStringToJuce (newText)); - owner->textWasInserted = true; + if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + { + target->insertTextAtCaret (nsStringToJuce (newText)); + owner->textWasInserted = true; + } } - } - owner->stringBeingComposed = String::empty; + owner->stringBeingComposed = String::empty; + } } static void doCommandBySelector (id, SEL, SEL) {} static void setMarkedText (id self, SEL, id aString, NSRange) { - NSViewComponentPeer* const owner = getOwner (self); - - owner->stringBeingComposed = nsStringToJuce ([aString isKindOfClass: [NSAttributedString class]] - ? [aString string] : aString); - - TextInputTarget* const target = owner->findCurrentTextInputTarget(); - - if (target != nullptr) + if (NSViewComponentPeer* const owner = getOwner (self)) { - const Range currentHighlight (target->getHighlightedRegion()); - target->insertTextAtCaret (owner->stringBeingComposed); - target->setHighlightedRegion (currentHighlight.withLength (owner->stringBeingComposed.length())); - owner->textWasInserted = true; + owner->stringBeingComposed = nsStringToJuce ([aString isKindOfClass: [NSAttributedString class]] + ? [aString string] : aString); + + if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + { + const Range currentHighlight (target->getHighlightedRegion()); + target->insertTextAtCaret (owner->stringBeingComposed); + target->setHighlightedRegion (currentHighlight.withLength (owner->stringBeingComposed.length())); + owner->textWasInserted = true; + } } } static void unmarkText (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); - - if (owner->stringBeingComposed.isNotEmpty()) + if (NSViewComponentPeer* const owner = getOwner (self)) { - TextInputTarget* const target = owner->findCurrentTextInputTarget(); - - if (target != nullptr) + if (owner->stringBeingComposed.isNotEmpty()) { - target->insertTextAtCaret (owner->stringBeingComposed); - owner->textWasInserted = true; - } + if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + { + target->insertTextAtCaret (owner->stringBeingComposed); + owner->textWasInserted = true; + } - owner->stringBeingComposed = String::empty; + owner->stringBeingComposed = String::empty; + } } } static BOOL hasMarkedText (id self, SEL) { - return getOwner (self)->stringBeingComposed.isNotEmpty(); + NSViewComponentPeer* const owner = getOwner (self); + return owner != nullptr && owner->stringBeingComposed.isNotEmpty(); } static long conversationIdentifier (id self, SEL) @@ -1525,15 +1493,15 @@ private: static NSAttributedString* attributedSubstringFromRange (id self, SEL, NSRange theRange) { - NSViewComponentPeer* const owner = getOwner (self); - TextInputTarget* const target = owner->findCurrentTextInputTarget(); - - if (target != nullptr) + if (NSViewComponentPeer* const owner = getOwner (self)) { - const Range r ((int) theRange.location, - (int) (theRange.location + theRange.length)); + if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + { + const Range r ((int) theRange.location, + (int) (theRange.location + theRange.length)); - return [[[NSAttributedString alloc] initWithString: juceStringToNS (target->getTextInRange (r))] autorelease]; + return [[[NSAttributedString alloc] initWithString: juceStringToNS (target->getTextInRange (r))] autorelease]; + } } return nil; @@ -1548,15 +1516,15 @@ private: static NSRange selectedRange (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); - TextInputTarget* const target = owner->findCurrentTextInputTarget(); - - if (target != nullptr) + if (NSViewComponentPeer* const owner = getOwner (self)) { - const Range highlight (target->getHighlightedRegion()); + if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + { + const Range highlight (target->getHighlightedRegion()); - if (! highlight.isEmpty()) - return NSMakeRange (highlight.getStart(), highlight.getLength()); + if (! highlight.isEmpty()) + return NSMakeRange (highlight.getStart(), highlight.getLength()); + } } return NSMakeRange (NSNotFound, 0); @@ -1564,18 +1532,20 @@ private: static NSRect firstRectForCharacterRange (id self, SEL, NSRange) { - NSViewComponentPeer* const owner = getOwner (self); - Component* const comp = dynamic_cast (owner->findCurrentTextInputTarget()); - - if (comp == nullptr) - return NSMakeRect (0, 0, 0, 0); + if (NSViewComponentPeer* const owner = getOwner (self)) + { + if (Component* const comp = dynamic_cast (owner->findCurrentTextInputTarget())) + { + const Rectangle bounds (comp->getScreenBounds()); - const Rectangle bounds (comp->getScreenBounds()); + return NSMakeRect (bounds.getX(), + [[[NSScreen screens] objectAtIndex: 0] frame].size.height - bounds.getY(), + bounds.getWidth(), + bounds.getHeight()); + } + } - return NSMakeRect (bounds.getX(), - [[[NSScreen screens] objectAtIndex: 0] frame].size.height - bounds.getY(), - bounds.getWidth(), - bounds.getHeight()); + return NSZeroRect; } static NSUInteger characterIndexForPoint (id, SEL, NSPoint) { return NSNotFound; } @@ -1584,9 +1554,7 @@ private: //============================================================================== static void flagsChanged (id self, SEL, NSEvent* ev) { - NSViewComponentPeer* const owner = getOwner (self); - - if (owner != nullptr) + if (NSViewComponentPeer* const owner = getOwner (self)) owner->redirectModKeyChange (ev); } @@ -1605,8 +1573,7 @@ private: static BOOL becomeFirstResponder (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); - if (owner != nullptr) + if (NSViewComponentPeer* const owner = getOwner (self)) owner->viewFocusGain(); return YES; @@ -1614,8 +1581,7 @@ private: static BOOL resignFirstResponder (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); - if (owner != nullptr) + if (NSViewComponentPeer* const owner = getOwner (self)) owner->viewFocusLoss(); return YES; @@ -1628,14 +1594,9 @@ private: } //============================================================================== - static NSDragOperation draggingEntered (id self, SEL, id sender) + static NSDragOperation draggingEntered (id self, SEL s, id sender) { - NSViewComponentPeer* const owner = getOwner (self); - - if (owner != nullptr && owner->sendDragCallback (0, sender)) - return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric; - else - return NSDragOperationNone; + return draggingUpdated (self, s, sender); } static NSDragOperation draggingUpdated (id self, SEL, id sender) @@ -1648,19 +1609,14 @@ private: return NSDragOperationNone; } - static void draggingEnded (id self, SEL, id sender) + static void draggingEnded (id self, SEL s, id sender) { - NSViewComponentPeer* const owner = getOwner (self); - - if (owner != nullptr) - owner->sendDragCallback (1, sender); + draggingExited (self, s, sender); } static void draggingExited (id self, SEL, id sender) { - NSViewComponentPeer* const owner = getOwner (self); - - if (owner != nullptr) + if (NSViewComponentPeer* const owner = getOwner (self)) owner->sendDragCallback (1, sender); } diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index 9de6f154b5..ba10fc3e34 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -32,8 +32,8 @@ struct TextAtom int numChars; //============================================================================== - bool isWhitespace() const { return CharacterFunctions::isWhitespace (atomText[0]); } - bool isNewLine() const { return atomText[0] == '\r' || atomText[0] == '\n'; } + bool isWhitespace() const noexcept { return CharacterFunctions::isWhitespace (atomText[0]); } + bool isNewLine() const noexcept { return atomText[0] == '\r' || atomText[0] == '\n'; } String getText (const juce_wchar passwordCharacter) const { @@ -60,7 +60,6 @@ struct TextAtom class TextEditor::UniformTextSection { public: - //============================================================================== UniformTextSection (const String& text, const Font& font_, const Colour& colour_, @@ -321,7 +320,6 @@ private: class TextEditor::Iterator { public: - //============================================================================== Iterator (const Array & sections_, const float wordWrapWidth_, const juce_wchar passwordCharacter_) @@ -751,14 +749,14 @@ private: class TextEditor::InsertAction : public UndoableAction { public: - InsertAction (TextEditor& owner_, + InsertAction (TextEditor& ed, const String& text_, const int insertIndex_, const Font& font_, const Colour& colour_, const int oldCaretPos_, const int newCaretPos_) - : owner (owner_), + : owner (ed), text (text_), insertIndex (insertIndex_), oldCaretPos (oldCaretPos_), @@ -799,12 +797,12 @@ private: class TextEditor::RemoveAction : public UndoableAction { public: - RemoveAction (TextEditor& owner_, + RemoveAction (TextEditor& ed, const Range range_, const int oldCaretPos_, const int newCaretPos_, const Array & removedSections_) - : owner (owner_), + : owner (ed), range (range_), oldCaretPos (oldCaretPos_), newCaretPos (newCaretPos_), @@ -860,8 +858,7 @@ class TextEditor::TextHolderComponent : public Component, private ValueListener { public: - TextHolderComponent (TextEditor& owner_) - : owner (owner_) + TextHolderComponent (TextEditor& ed) : owner (ed) { setWantsKeyboardFocus (false); setInterceptsMouseClicks (false, true); @@ -905,8 +902,8 @@ private: class TextEditorViewport : public Viewport { public: - TextEditorViewport (TextEditor& owner_) - : owner (owner_), lastWordWrapWidth (0), rentrant (false) + TextEditorViewport (TextEditor& ed) + : owner (ed), lastWordWrapWidth (0), rentrant (false) { } @@ -970,6 +967,7 @@ TextEditor::TextEditor (const String& name, tabKeyUsed (false), menuActive (false), valueTextNeedsUpdating (false), + consumeEscAndReturnKeys (true), maxTextLength (0), leftIndent (4), topIndent (4), @@ -2062,6 +2060,11 @@ bool TextEditor::selectAll() } //============================================================================== +void TextEditor::setEscapeAndReturnKeysConsumed (bool shouldBeConsumed) noexcept +{ + consumeEscAndReturnKeys = shouldBeConsumed; +} + bool TextEditor::keyPressed (const KeyPress& key) { if (isReadOnly() && key != KeyPress ('c', ModifierKeys::commandModifier, 0)) @@ -2076,13 +2079,17 @@ bool TextEditor::keyPressed (const KeyPress& key) if (returnKeyStartsNewLine) insertTextAtCaret ("\n"); else + { returnPressed(); + return consumeEscAndReturnKeys; + } } else if (key.isKeyCode (KeyPress::escapeKey)) { newTransaction(); moveCaretTo (getCaretPosition(), false); escapePressed(); + return consumeEscAndReturnKeys; } else if (key.getTextCharacter() >= ' ' || (tabKeyUsed && (key.getTextCharacter() == '\t'))) @@ -2110,6 +2117,11 @@ bool TextEditor::keyStateChanged (const bool isKeyDown) return false; // We need to explicitly allow alt-F4 to pass through on Windows #endif + if ((! consumeEscAndReturnKeys) + && (KeyPress (KeyPress::escapeKey).isCurrentlyDown() + || KeyPress (KeyPress::returnKey).isCurrentlyDown())) + return false; + // (overridden to avoid forwarding key events to the parent) return ! ModifierKeys::getCurrentModifiers().isCommandDown(); } @@ -2213,7 +2225,7 @@ void TextEditor::setTemporaryUnderlining (const Array >& newUnderlin //============================================================================== UndoManager* TextEditor::getUndoManager() noexcept { - return isReadOnly() ? 0 : &undoManager; + return readOnly ? nullptr : &undoManager; } void TextEditor::clearInternal (UndoManager* const um) @@ -2252,17 +2264,13 @@ void TextEditor::insert (const String& text, if (insertIndex == index) { - sections.insert (i, new UniformTextSection (text, - font, colour, - passwordCharacter)); + sections.insert (i, new UniformTextSection (text, font, colour, passwordCharacter)); break; } else if (insertIndex > index && insertIndex < nextIndex) { splitSection (i, insertIndex - index); - sections.insert (i + 1, new UniformTextSection (text, - font, colour, - passwordCharacter)); + sections.insert (i + 1, new UniformTextSection (text, font, colour, passwordCharacter)); break; } @@ -2270,9 +2278,7 @@ void TextEditor::insert (const String& text, } if (nextIndex == insertIndex) - sections.add (new UniformTextSection (text, - font, colour, - passwordCharacter)); + sections.add (new UniformTextSection (text, font, colour, passwordCharacter)); coalesceSimilarSections(); totalNumChars = -1; diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.h b/modules/juce_gui_basics/widgets/juce_TextEditor.h index 729b2bb634..ff63157457 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.h +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.h @@ -109,6 +109,14 @@ public: */ bool isTabKeyUsedAsCharacter() const { return tabKeyUsed; } + /** This can be used to change whether escape and return keypress events are + propagated up to the parent component. + The default here is true, meaning that these events are not allowed to reach the + parent, but you may want to allow them through so that they can trigger other + actions, e.g. closing a dialog box, etc. + */ + void setEscapeAndReturnKeysConsumed (bool shouldBeConsumed) noexcept; + //============================================================================== /** Changes the editor to read-only mode. @@ -390,11 +398,6 @@ public: */ void setCaretPosition (int newIndex); - /** Moves the caret to be the end of all the text. - @see setCaretPosition - */ - void moveCaretToEnd(); - /** Attempts to scroll the text editor so that the caret ends up at a specified position. @@ -476,6 +479,7 @@ public: void setScrollToShowCursor (bool shouldScrollToShowCaret); //============================================================================== + void moveCaretToEnd(); bool moveCaretLeft (bool moveInWholeWordSteps, bool selecting); bool moveCaretRight (bool moveInWholeWordSteps, bool selecting); bool moveCaretUp (bool selecting); @@ -536,21 +540,21 @@ public: //============================================================================== /** @internal */ - void paint (Graphics& g); + void paint (Graphics&); /** @internal */ - void paintOverChildren (Graphics& g); + void paintOverChildren (Graphics&); /** @internal */ - void mouseDown (const MouseEvent& e); + void mouseDown (const MouseEvent&); /** @internal */ - void mouseUp (const MouseEvent& e); + void mouseUp (const MouseEvent&); /** @internal */ - void mouseDrag (const MouseEvent& e); + void mouseDrag (const MouseEvent&); /** @internal */ - void mouseDoubleClick (const MouseEvent& e); + void mouseDoubleClick (const MouseEvent&); /** @internal */ void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&); /** @internal */ - bool keyPressed (const KeyPress& key); + bool keyPressed (const KeyPress&); /** @internal */ bool keyStateChanged (bool isKeyDown); /** @internal */ @@ -575,30 +579,18 @@ protected: /** Scrolls the minimum distance needed to get the caret into view. */ void scrollToMakeSureCursorIsVisible(); - /** @internal */ - void moveCaret (int newCaretPos); - - /** @internal */ - void moveCaretTo (int newPosition, bool isSelecting); - /** Used internally to dispatch a text-change message. */ void textChanged(); /** Begins a new transaction in the UndoManager. */ void newTransaction(); - /** Used internally to trigger an undo or redo. */ - void doUndoRedo (bool isRedo); - /** Can be overridden to intercept return key presses directly */ virtual void returnPressed(); /** Can be overridden to intercept escape key presses directly */ virtual void escapePressed(); - /** @internal */ - void handleCommandMessage (int commandId); - private: //============================================================================== class Iterator; @@ -625,6 +617,7 @@ private: bool tabKeyUsed : 1; bool menuActive : 1; bool valueTextNeedsUpdating : 1; + bool consumeEscAndReturnKeys : 1; UndoManager undoManager; ScopedPointer caret; @@ -652,13 +645,15 @@ private: ListenerList listeners; Array > underlinedSections; + void moveCaret (int newCaretPos); + void moveCaretTo (int newPosition, bool isSelecting); + void handleCommandMessage (int); void coalesceSimilarSections(); void splitSection (int sectionIndex, int charToSplitAt); - void clearInternal (UndoManager* um); - void insert (const String& text, int insertIndex, const Font& font, - const Colour& colour, UndoManager* um, int caretPositionToMoveTo); - void reinsert (int insertIndex, const Array & sections); - void remove (const Range& range, UndoManager* um, int caretPositionToMoveTo); + void clearInternal (UndoManager*); + void insert (const String&, int insertIndex, const Font&, const Colour&, UndoManager*, int newCaretPos); + void reinsert (int insertIndex, const Array &); + void remove (const Range& range, UndoManager*, int caretPositionToMoveTo); void getCharPosition (int index, float& x, float& y, float& lineHeight) const; void updateCaretPosition(); void updateValueFromText(); @@ -669,11 +664,11 @@ private: bool moveCaretWithTransation (int newPos, bool selecting); friend class TextHolderComponent; friend class TextEditorViewport; - void drawContent (Graphics& g); + void drawContent (Graphics&); void updateTextHolderSize(); float getWordWrapWidth() const; void timerCallbackInt(); - void repaintText (const Range& range); + void repaintText (const Range&); void scrollByLines (int deltaLines); bool undoOrRedo (bool shouldUndo); UndoManager* getUndoManager() noexcept; diff --git a/modules/juce_gui_basics/windows/juce_AlertWindow.cpp b/modules/juce_gui_basics/windows/juce_AlertWindow.cpp index 421d7c9a6e..a218b80fc6 100644 --- a/modules/juce_gui_basics/windows/juce_AlertWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_AlertWindow.cpp @@ -23,49 +23,23 @@ ============================================================================== */ -class AlertWindowTextEditor : public TextEditor +static juce_wchar getDefaultPasswordChar() noexcept { -public: - AlertWindowTextEditor (const String& name, const bool isPasswordBox) - : TextEditor (name, isPasswordBox ? getDefaultPasswordChar() : 0) - { - setSelectAllWhenFocused (true); - } - - void returnPressed() - { - // pass these up the component hierarchy to be trigger the buttons - getParentComponent()->keyPressed (KeyPress (KeyPress::returnKey, 0, '\n')); - } - - void escapePressed() - { - // pass these up the component hierarchy to be trigger the buttons - getParentComponent()->keyPressed (KeyPress (KeyPress::escapeKey, 0, 0)); - } - -private: - JUCE_DECLARE_NON_COPYABLE (AlertWindowTextEditor); - - static juce_wchar getDefaultPasswordChar() noexcept - { - #if JUCE_LINUX - return 0x2022; - #else - return 0x25cf; - #endif - } -}; - + #if JUCE_LINUX + return 0x2022; + #else + return 0x25cf; + #endif +} //============================================================================== AlertWindow::AlertWindow (const String& title, const String& message, AlertIconType iconType, - Component* associatedComponent_) + Component* comp) : TopLevelWindow (title, true), alertIconType (iconType), - associatedComponent (associatedComponent_), + associatedComponent (comp), escapeKeyCancels (true) { if (message.isEmpty()) @@ -175,15 +149,17 @@ void AlertWindow::addTextEditor (const String& name, const String& onScreenLabel, const bool isPasswordBox) { - AlertWindowTextEditor* const tc = new AlertWindowTextEditor (name, isPasswordBox); - textBoxes.add (tc); - allComps.add (tc); - - tc->setColour (TextEditor::outlineColourId, findColour (ComboBox::outlineColourId)); - tc->setFont (getLookAndFeel().getAlertWindowMessageFont()); - tc->setText (initialContents); - tc->setCaretPosition (initialContents.length()); - addAndMakeVisible (tc); + TextEditor* ed = new TextEditor (name, isPasswordBox ? getDefaultPasswordChar() : 0); + ed->setSelectAllWhenFocused (true); + ed->setEscapeAndReturnKeysConsumed (false); + textBoxes.add (ed); + allComps.add (ed); + + ed->setColour (TextEditor::outlineColourId, findColour (ComboBox::outlineColourId)); + ed->setFont (getLookAndFeel().getAlertWindowMessageFont()); + ed->setText (initialContents); + ed->setCaretPosition (initialContents.length()); + addAndMakeVisible (ed); textboxNames.add (onScreenLabel); updateLayout (false); @@ -343,8 +319,7 @@ void AlertWindow::paint (Graphics& g) g.setColour (findColour (textColourId)); g.setFont (getLookAndFeel().getAlertWindowFont()); - int i; - for (i = textBoxes.size(); --i >= 0;) + for (int i = textBoxes.size(); --i >= 0;) { const TextEditor* const te = textBoxes.getUnchecked(i); @@ -354,7 +329,7 @@ void AlertWindow::paint (Graphics& g) Justification::centredLeft, 1); } - for (i = comboBoxNames.size(); --i >= 0;) + for (int i = comboBoxNames.size(); --i >= 0;) { const ComboBox* const cb = comboBoxes.getUnchecked(i); @@ -364,7 +339,7 @@ void AlertWindow::paint (Graphics& g) Justification::centredLeft, 1); } - for (i = customComps.size(); --i >= 0;) + for (int i = customComps.size(); --i >= 0;) { const Component* const c = customComps.getUnchecked(i); @@ -419,8 +394,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) int h = textBottom; int buttonW = 40; - int i; - for (i = 0; i < buttons.size(); ++i) + for (int i = 0; i < buttons.size(); ++i) buttonW += 16 + buttons.getUnchecked(i)->getWidth(); w = jmax (buttonW, w); @@ -430,7 +404,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) if (buttons.size() > 0) h += 20 + buttons.getUnchecked(0)->getHeight(); - for (i = customComps.size(); --i >= 0;) + for (int i = customComps.size(); --i >= 0;) { Component* c = customComps.getUnchecked(i); w = jmax (w, (c->getWidth() * 100) / 80); @@ -440,7 +414,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) h += labelHeight; } - for (i = textBlocks.size(); --i >= 0;) + for (int i = textBlocks.size(); --i >= 0;) { const AlertTextComp* const ac = static_cast (textBlocks.getUnchecked(i)); w = jmax (w, ac->getPreferredWidth()); @@ -448,7 +422,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) w = jmin (w, (int) (getParentWidth() * 0.7f)); - for (i = textBlocks.size(); --i >= 0;) + for (int i = textBlocks.size(); --i >= 0;) { AlertTextComp* const ac = static_cast (textBlocks.getUnchecked(i)); ac->updateLayout ((int) (w * 0.8f)); @@ -482,13 +456,13 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) const int spacer = 16; int totalWidth = -spacer; - for (i = buttons.size(); --i >= 0;) + for (int i = buttons.size(); --i >= 0;) totalWidth += buttons.getUnchecked(i)->getWidth() + spacer; int x = (w - totalWidth) / 2; int y = (int) (getHeight() * 0.95f); - for (i = 0; i < buttons.size(); ++i) + for (int i = 0; i < buttons.size(); ++i) { TextButton* const c = buttons.getUnchecked(i); int ny = proportionOfHeight (0.95f) - c->getHeight(); @@ -503,7 +477,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) y = textBottom; - for (i = 0; i < allComps.size(); ++i) + for (int i = 0; i < allComps.size(); ++i) { Component* const c = allComps.getUnchecked(i); h = 22;