diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp index 0d6a75ec95..ae6fbcca9a 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp @@ -38,10 +38,10 @@ public: addAndMakeVisible (&chooserComponent); addAndMakeVisible (&okButton); - okButton.addShortcut (KeyPress::returnKey); + okButton.addShortcut (KeyPress (KeyPress::returnKey)); addAndMakeVisible (&cancelButton); - cancelButton.addShortcut (KeyPress::escapeKey); + cancelButton.addShortcut (KeyPress (KeyPress::escapeKey)); addChildComponent (&newFolderButton); @@ -245,8 +245,8 @@ void FileChooserDialogBox::createNewFolder() AlertWindow::NoIcon, this); aw->addTextEditor ("name", String::empty, String::empty, false); - aw->addButton (TRANS("ok"), 1, KeyPress::returnKey); - aw->addButton (TRANS("cancel"), KeyPress::escapeKey); + aw->addButton (TRANS("ok"), 1, KeyPress (KeyPress::returnKey)); + aw->addButton (TRANS("cancel"), 0, KeyPress (KeyPress::escapeKey)); aw->enterModalState (true, ModalCallbackFunction::forComponent (createNewFolderCallback, this, diff --git a/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp b/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp index fdeb4c7e93..b918da235c 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp +++ b/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp @@ -60,6 +60,11 @@ KeyPress& KeyPress::operator= (const KeyPress& other) noexcept return *this; } +bool KeyPress::operator== (int otherKeyCode) const noexcept +{ + return keyCode == otherKeyCode && ! mods.isAnyModifierKeyDown(); +} + bool KeyPress::operator== (const KeyPress& other) const noexcept { return mods.getRawFlags() == other.mods.getRawFlags() @@ -78,6 +83,11 @@ bool KeyPress::operator!= (const KeyPress& other) const noexcept return ! operator== (other); } +bool KeyPress::operator!= (int otherKeyCode) const noexcept +{ + return ! operator== (otherKeyCode); +} + bool KeyPress::isCurrentlyDown() const { return isKeyCurrentlyDown (keyCode) diff --git a/modules/juce_gui_basics/keyboard/juce_KeyPress.h b/modules/juce_gui_basics/keyboard/juce_KeyPress.h index 7599f377c7..d8900354a0 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyPress.h +++ b/modules/juce_gui_basics/keyboard/juce_KeyPress.h @@ -70,9 +70,8 @@ public: const ModifierKeys& modifiers, juce_wchar textCharacter) noexcept; - /** Creates a keypress with a keyCode but no modifiers or text character. - */ - KeyPress (int keyCode) noexcept; + /** Creates a keypress with a keyCode but no modifiers or text character. */ + explicit KeyPress (int keyCode) noexcept; /** Creates a copy of another KeyPress. */ KeyPress (const KeyPress& other) noexcept; @@ -86,6 +85,12 @@ public: /** Compares two KeyPress objects. */ bool operator!= (const KeyPress& other) const noexcept; + /** Returns true if this keypress is for the given keycode without any modifiers. */ + bool operator== (int keyCode) const noexcept; + + /** Returns true if this keypress is not for the given keycode without any modifiers. */ + bool operator!= (int keyCode) const noexcept; + //============================================================================== /** Returns true if this is a valid KeyPress. diff --git a/modules/juce_gui_basics/layout/juce_ScrollBar.cpp b/modules/juce_gui_basics/layout/juce_ScrollBar.cpp index 4e87fb2bd8..e0a16319d1 100644 --- a/modules/juce_gui_basics/layout/juce_ScrollBar.cpp +++ b/modules/juce_gui_basics/layout/juce_ScrollBar.cpp @@ -27,21 +27,15 @@ class ScrollBar::ScrollbarButton : public Button { public: ScrollbarButton (const int direction_, ScrollBar& owner_) - : Button (String::empty), - direction (direction_), - owner (owner_) + : Button (String::empty), direction (direction_), owner (owner_) { setWantsKeyboardFocus (false); } void paintButton (Graphics& g, bool over, bool down) { - getLookAndFeel() - .drawScrollbarButton (g, owner, - getWidth(), getHeight(), - direction, - owner.isVertical(), - over, down); + getLookAndFeel().drawScrollbarButton (g, owner, getWidth(), getHeight(), + direction, owner.isVertical(), over, down); } void clicked() @@ -101,7 +95,7 @@ void ScrollBar::setRangeLimits (const double newMinimum, const double newMaximum setRangeLimits (Range (newMinimum, newMaximum)); } -void ScrollBar::setCurrentRange (const Range& newRange) +bool ScrollBar::setCurrentRange (const Range& newRange) { const Range constrainedRange (totalRange.constrainRange (newRange)); @@ -111,7 +105,11 @@ void ScrollBar::setCurrentRange (const Range& newRange) updateThumbPosition(); triggerAsyncUpdate(); + + return true; } + + return false; } void ScrollBar::setCurrentRange (const double newStart, const double newSize) @@ -124,29 +122,29 @@ void ScrollBar::setCurrentRangeStart (const double newStart) setCurrentRange (visibleRange.movedToStartAt (newStart)); } -void ScrollBar::setSingleStepSize (const double newSingleStepSize) +void ScrollBar::setSingleStepSize (const double newSingleStepSize) noexcept { singleStepSize = newSingleStepSize; } -void ScrollBar::moveScrollbarInSteps (const int howManySteps) +bool ScrollBar::moveScrollbarInSteps (const int howManySteps) { - setCurrentRange (visibleRange + howManySteps * singleStepSize); + return setCurrentRange (visibleRange + howManySteps * singleStepSize); } -void ScrollBar::moveScrollbarInPages (const int howManyPages) +bool ScrollBar::moveScrollbarInPages (const int howManyPages) { - setCurrentRange (visibleRange + howManyPages * visibleRange.getLength()); + return setCurrentRange (visibleRange + howManyPages * visibleRange.getLength()); } -void ScrollBar::scrollToTop() +bool ScrollBar::scrollToTop() { - setCurrentRange (visibleRange.movedToStartAt (getMinimumRangeLimit())); + return setCurrentRange (visibleRange.movedToStartAt (getMinimumRangeLimit())); } -void ScrollBar::scrollToBottom() +bool ScrollBar::scrollToBottom() { - setCurrentRange (visibleRange.movedToEndAt (getMaximumRangeLimit())); + return setCurrentRange (visibleRange.movedToEndAt (getMaximumRangeLimit())); } void ScrollBar::setButtonRepeatSpeed (const int initialDelayInMillisecs_, @@ -154,13 +152,13 @@ void ScrollBar::setButtonRepeatSpeed (const int initialDelayInMillisecs_, const int minimumDelayInMillisecs_) { initialDelayInMillisecs = initialDelayInMillisecs_; - repeatDelayInMillisecs = repeatDelayInMillisecs_; + repeatDelayInMillisecs = repeatDelayInMillisecs_; minimumDelayInMillisecs = minimumDelayInMillisecs_; if (upButton != nullptr) { - upButton->setRepeatSpeed (initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs); - downButton->setRepeatSpeed (initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs); + upButton ->setRepeatSpeed (initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs); + downButton->setRepeatSpeed (initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs); } } @@ -187,8 +185,10 @@ void ScrollBar::updateThumbPosition() int newThumbSize = roundToInt (totalRange.getLength() > 0 ? (visibleRange.getLength() * thumbAreaSize) / totalRange.getLength() : thumbAreaSize); - if (newThumbSize < getLookAndFeel().getMinimumScrollbarThumbSize (*this)) - newThumbSize = jmin (getLookAndFeel().getMinimumScrollbarThumbSize (*this), thumbAreaSize - 1); + LookAndFeel& lf = getLookAndFeel(); + + if (newThumbSize < lf.getMinimumScrollbarThumbSize (*this)) + newThumbSize = jmin (lf.getMinimumScrollbarThumbSize (*this), thumbAreaSize - 1); if (newThumbSize > thumbAreaSize) newThumbSize = thumbAreaSize; @@ -251,26 +251,14 @@ void ScrollBar::paint (Graphics& g) LookAndFeel& lf = getLookAndFeel(); const int thumb = (thumbAreaSize > lf.getMinimumScrollbarThumbSize (*this)) - ? thumbSize : 0; + ? thumbSize : 0; if (vertical) - { - lf.drawScrollbar (g, *this, - 0, thumbAreaStart, - getWidth(), thumbAreaSize, - vertical, - thumbStart, thumb, - isMouseOver(), isMouseButtonDown()); - } + lf.drawScrollbar (g, *this, 0, thumbAreaStart, getWidth(), thumbAreaSize, + vertical, thumbStart, thumb, isMouseOver(), isMouseButtonDown()); else - { - lf.drawScrollbar (g, *this, - thumbAreaStart, 0, - thumbAreaSize, getHeight(), - vertical, - thumbStart, thumb, - isMouseOver(), isMouseButtonDown()); - } + lf.drawScrollbar (g, *this, thumbAreaStart, 0, thumbAreaSize, getHeight(), + vertical, thumbStart, thumb, isMouseOver(), isMouseButtonDown()); } } @@ -284,7 +272,9 @@ void ScrollBar::resized() { const int length = vertical ? getHeight() : getWidth(); - const bool buttonsVisible = getLookAndFeel().areScrollbarButtonsVisible(); + LookAndFeel& lf = getLookAndFeel(); + const bool buttonsVisible = lf.areScrollbarButtonsVisible(); + int buttonSize = 0; if (buttonsVisible) { @@ -295,6 +285,8 @@ void ScrollBar::resized() setButtonRepeatSpeed (initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs); } + + buttonSize = jmin (lf.getScrollbarButtonSize (*this), length / 2); } else { @@ -302,10 +294,7 @@ void ScrollBar::resized() downButton = nullptr; } - const int buttonSize = upButton != nullptr ? jmin (getLookAndFeel().getScrollbarButtonSize (*this), length / 2) - : 0; - - if (length < 32 + getLookAndFeel().getMinimumScrollbarThumbSize (*this)) + if (length < 32 + lf.getMinimumScrollbarThumbSize (*this)) { thumbAreaStart = length / 2; thumbAreaSize = 0; @@ -411,18 +400,15 @@ void ScrollBar::timerCallback() bool ScrollBar::keyPressed (const KeyPress& key) { - if (! isVisible()) - return false; - - if (key.isKeyCode (KeyPress::upKey) - || key.isKeyCode (KeyPress::leftKey)) moveScrollbarInSteps (-1); - else if (key.isKeyCode (KeyPress::downKey) - || key.isKeyCode (KeyPress::rightKey)) moveScrollbarInSteps (1); - else if (key.isKeyCode (KeyPress::pageUpKey)) moveScrollbarInPages (-1); - else if (key.isKeyCode (KeyPress::pageDownKey)) moveScrollbarInPages (1); - else if (key.isKeyCode (KeyPress::homeKey)) scrollToTop(); - else if (key.isKeyCode (KeyPress::endKey)) scrollToBottom(); - else return false; - - return true; + if (isVisible()) + { + if (key == KeyPress::upKey || key == KeyPress::leftKey) return moveScrollbarInSteps (-1); + else if (key == KeyPress::downKey || key == KeyPress::rightKey) return moveScrollbarInSteps (1); + else if (key == KeyPress::pageUpKey) return moveScrollbarInPages (-1); + else if (key == KeyPress::pageDownKey) return moveScrollbarInPages (1); + else if (key == KeyPress::homeKey) return scrollToTop(); + else if (key == KeyPress::endKey) return scrollToBottom(); + } + + return false; } diff --git a/modules/juce_gui_basics/layout/juce_ScrollBar.h b/modules/juce_gui_basics/layout/juce_ScrollBar.h index 5a78236b18..486f09efde 100644 --- a/modules/juce_gui_basics/layout/juce_ScrollBar.h +++ b/modules/juce_gui_basics/layout/juce_ScrollBar.h @@ -115,7 +115,7 @@ public: /** Returns the current limits on the thumb position. @see setRangeLimits */ - const Range getRangeLimit() const noexcept { return totalRange; } + Range getRangeLimit() const noexcept { return totalRange; } /** Returns the lower value that the thumb can be set to. @@ -132,13 +132,17 @@ public: //============================================================================== /** Changes the position of the scrollbar's 'thumb'. + This sets both the position and size of the thumb - to just set the position without + changing the size, you can use setCurrentRangeStart(). + If this method call actually changes the scrollbar's position, it will trigger an asynchronous call to ScrollBar::Listener::scrollBarMoved() for all the listeners that are registered. + @returns true if the range was changed, or false if nothing was changed. @see getCurrentRange. setCurrentRangeStart */ - void setCurrentRange (const Range& newRange); + bool setCurrentRange (const Range& newRange); /** Changes the position of the scrollbar's 'thumb'. @@ -175,7 +179,7 @@ public: /** Returns the current thumb range. @see getCurrentRange, setCurrentRange */ - const Range getCurrentRange() const noexcept { return visibleRange; } + Range getCurrentRange() const noexcept { return visibleRange; } /** Returns the position of the top of the thumb. @see getCurrentRange, setCurrentRangeStart @@ -193,7 +197,7 @@ public: The value here is in terms of the total range, and is added or subtracted from the thumb position when the user clicks an up/down (or left/right) button. */ - void setSingleStepSize (double newSingleStepSize); + void setSingleStepSize (double newSingleStepSize) noexcept; /** Moves the scrollbar by a number of single-steps. @@ -202,8 +206,9 @@ public: A positive value here will move the bar down or to the right, a negative value moves it up or to the left. + @returns true if the scrollbar's position actually changed. */ - void moveScrollbarInSteps (int howManySteps); + bool moveScrollbarInSteps (int howManySteps); /** Moves the scroll bar up or down in pages. @@ -212,20 +217,21 @@ public: A positive value here will move the bar down or to the right, a negative value moves it up or to the left. + @returns true if the scrollbar's position actually changed. */ - void moveScrollbarInPages (int howManyPages); + bool moveScrollbarInPages (int howManyPages); /** Scrolls to the top (or left). - This is the same as calling setCurrentRangeStart (getMinimumRangeLimit()); + @returns true if the scrollbar's position actually changed. */ - void scrollToTop(); + bool scrollToTop(); /** Scrolls to the bottom (or right). - This is the same as calling setCurrentRangeStart (getMaximumRangeLimit() - getCurrentRangeSize()); + @returns true if the scrollbar's position actually changed. */ - void scrollToBottom(); + bool scrollToBottom(); /** Changes the delay before the up and down buttons autorepeat when they are held down. diff --git a/modules/juce_gui_basics/layout/juce_Viewport.cpp b/modules/juce_gui_basics/layout/juce_Viewport.cpp index c914ed8054..4a9cb60a26 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -406,18 +406,18 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelD bool Viewport::keyPressed (const KeyPress& key) { - const bool isUpDownKey = key.isKeyCode (KeyPress::upKey) - || key.isKeyCode (KeyPress::downKey) - || key.isKeyCode (KeyPress::pageUpKey) - || key.isKeyCode (KeyPress::pageDownKey) - || key.isKeyCode (KeyPress::homeKey) - || key.isKeyCode (KeyPress::endKey); + const bool isUpDownKey = key == KeyPress::upKey + || key == KeyPress::downKey + || key == KeyPress::pageUpKey + || key == KeyPress::pageDownKey + || key == KeyPress::homeKey + || key == KeyPress::endKey; if (verticalScrollBar.isVisible() && isUpDownKey) return verticalScrollBar.keyPressed (key); - const bool isLeftRightKey = key.isKeyCode (KeyPress::leftKey) - || key.isKeyCode (KeyPress::rightKey); + const bool isLeftRightKey = key == KeyPress::leftKey + || key == KeyPress::rightKey; if (horizontalScrollBar.isVisible() && (isUpDownKey || isLeftRightKey)) return horizontalScrollBar.keyPressed (key); diff --git a/modules/juce_gui_basics/widgets/juce_ComboBox.cpp b/modules/juce_gui_basics/widgets/juce_ComboBox.cpp index bfe2571c19..94bd55bc79 100644 --- a/modules/juce_gui_basics/widgets/juce_ComboBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_ComboBox.cpp @@ -451,7 +451,7 @@ void ComboBox::colourChanged() //============================================================================== bool ComboBox::keyPressed (const KeyPress& key) { - if (key.isKeyCode (KeyPress::upKey) || key.isKeyCode (KeyPress::leftKey)) + if (key == KeyPress::upKey || key == KeyPress::leftKey) { int index = getSelectedItemIndex() - 1; @@ -460,7 +460,7 @@ bool ComboBox::keyPressed (const KeyPress& key) return true; } - else if (key.isKeyCode (KeyPress::downKey) || key.isKeyCode (KeyPress::rightKey)) + else if (key == KeyPress::downKey || key == KeyPress::rightKey) { int index = getSelectedItemIndex() + 1; @@ -469,7 +469,7 @@ bool ComboBox::keyPressed (const KeyPress& key) return true; } - else if (key.isKeyCode (KeyPress::returnKey)) + else if (key == KeyPress::returnKey) { showPopup(); return true; diff --git a/modules/juce_gui_basics/widgets/juce_ListBox.cpp b/modules/juce_gui_basics/widgets/juce_ListBox.cpp index 242faee003..e1a81cdd5a 100644 --- a/modules/juce_gui_basics/widgets/juce_ListBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_ListBox.cpp @@ -310,9 +310,14 @@ public: || key.isKeyCode (KeyPress::homeKey) || key.isKeyCode (KeyPress::endKey)) { - // we want to avoid these keypresses going to the viewport, and instead allow - // them to pass up to our listbox.. - return false; + const int allowableMods = owner.multipleSelection ? ModifierKeys::shiftModifier : 0; + + if ((key.getModifiers().getRawFlags() & ~allowableMods) == 0) + { + // we want to avoid these keypresses going to the viewport, and instead allow + // them to pass up to our listbox.. + return false; + } } return Viewport::keyPressed (key); @@ -672,10 +677,8 @@ bool ListBox::keyPressed (const KeyPress& key) const int numVisibleRows = viewport->getHeight() / getRowHeight(); const bool multiple = multipleSelection - && (lastRowSelected >= 0) - && (key.getModifiers().isShiftDown() - || key.getModifiers().isCtrlDown() - || key.getModifiers().isCommandDown()); + && lastRowSelected >= 0 + && key.getModifiers().isShiftDown(); if (key.isKeyCode (KeyPress::upKey)) { @@ -684,11 +687,12 @@ bool ListBox::keyPressed (const KeyPress& key) else selectRow (jmax (0, lastRowSelected - 1)); } - else if (key.isKeyCode (KeyPress::returnKey) - && isRowSelected (lastRowSelected)) + else if (key.isKeyCode (KeyPress::downKey)) { - if (model != nullptr) - model->returnKeyPressed (lastRowSelected); + if (multiple) + selectRangeOfRows (lastRowSelected, lastRowSelected + 1); + else + selectRow (jmin (totalItems - 1, jmax (0, lastRowSelected) + 1)); } else if (key.isKeyCode (KeyPress::pageUpKey)) { @@ -706,24 +710,22 @@ bool ListBox::keyPressed (const KeyPress& key) } else if (key.isKeyCode (KeyPress::homeKey)) { - if (multiple && key.getModifiers().isShiftDown()) + if (multiple) selectRangeOfRows (lastRowSelected, 0); else selectRow (0); } else if (key.isKeyCode (KeyPress::endKey)) { - if (multiple && key.getModifiers().isShiftDown()) + if (multiple) selectRangeOfRows (lastRowSelected, totalItems - 1); else selectRow (totalItems - 1); } - else if (key.isKeyCode (KeyPress::downKey)) + else if (key.isKeyCode (KeyPress::returnKey) && isRowSelected (lastRowSelected)) { - if (multiple) - selectRangeOfRows (lastRowSelected, lastRowSelected + 1); - else - selectRow (jmin (totalItems - 1, jmax (0, lastRowSelected) + 1)); + if (model != nullptr) + model->returnKeyPressed (lastRowSelected); } else if ((key.isKeyCode (KeyPress::deleteKey) || key.isKeyCode (KeyPress::backspaceKey)) && isRowSelected (lastRowSelected)) @@ -731,7 +733,7 @@ bool ListBox::keyPressed (const KeyPress& key) if (model != nullptr) model->deleteKeyPressed (lastRowSelected); } - else if (multiple && key == KeyPress ('a', ModifierKeys::commandModifier, 0)) + else if (multipleSelection && key == KeyPress ('a', ModifierKeys::commandModifier, 0)) { selectRangeOfRows (0, std::numeric_limits::max()); } diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.cpp b/modules/juce_gui_basics/widgets/juce_TreeView.cpp index b9bba7c657..3cbbe778ba 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.cpp +++ b/modules/juce_gui_basics/widgets/juce_TreeView.cpp @@ -840,18 +840,17 @@ void TreeView::moveByPages (int numPages) bool TreeView::keyPressed (const KeyPress& key) { - if (rootItem != nullptr - && ! key.getModifiers().testFlags (ModifierKeys::ctrlAltCommandModifiers)) - { - if (key.getKeyCode() == KeyPress::upKey) { moveSelectedRow (-1); return true; } - if (key.getKeyCode() == KeyPress::downKey) { moveSelectedRow (1); return true; } - if (key.getKeyCode() == KeyPress::homeKey) { moveSelectedRow (-0x3fffffff); return true; } - if (key.getKeyCode() == KeyPress::endKey) { moveSelectedRow (0x3fffffff); return true; } - if (key.getKeyCode() == KeyPress::pageUpKey) { moveByPages (-1); return true; } - if (key.getKeyCode() == KeyPress::pageDownKey) { moveByPages (1); return true; } - if (key.getKeyCode() == KeyPress::returnKey) { toggleOpenSelectedItem(); return true; } - if (key.getKeyCode() == KeyPress::leftKey) { moveOutOfSelectedItem(); return true; } - if (key.getKeyCode() == KeyPress::rightKey) { moveIntoSelectedItem(); return true; } + if (rootItem != nullptr) + { + if (key == KeyPress::upKey) { moveSelectedRow (-1); return true; } + if (key == KeyPress::downKey) { moveSelectedRow (1); return true; } + if (key == KeyPress::homeKey) { moveSelectedRow (-0x3fffffff); return true; } + if (key == KeyPress::endKey) { moveSelectedRow (0x3fffffff); return true; } + if (key == KeyPress::pageUpKey) { moveByPages (-1); return true; } + if (key == KeyPress::pageDownKey) { moveByPages (1); return true; } + if (key == KeyPress::returnKey) { toggleOpenSelectedItem(); return true; } + if (key == KeyPress::leftKey) { moveOutOfSelectedItem(); return true; } + if (key == KeyPress::rightKey) { moveIntoSelectedItem(); return true; } } return false;