| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- // zlib open source license
- //
- // Copyright (c) 2020 to 2022 David Forsgren Piuva
- //
- // This software is provided 'as-is', without any express or implied
- // warranty. In no event will the authors be held liable for any damages
- // arising from the use of this software.
- //
- // Permission is granted to anyone to use this software for any purpose,
- // including commercial applications, and to alter it and redistribute it
- // freely, subject to the following restrictions:
- //
- // 1. The origin of this software must not be misrepresented; you must not
- // claim that you wrote the original software. If you use this software
- // in a product, an acknowledgment in the product documentation would be
- // appreciated but is not required.
- //
- // 2. Altered source versions must be plainly marked as such, and must not be
- // misrepresented as being the original software.
- //
- // 3. This notice may not be removed or altered from any source
- // distribution.
- #ifndef DFPSR_GUI_HELPER_SCROLL_BAR_IMPL
- #define DFPSR_GUI_HELPER_SCROLL_BAR_IMPL
- #include "../../VisualComponent.h"
- namespace dsr {
- struct ScrollRange {
- // The minimum value the scrollbar can be assigned in the current range.
- // Set minValue to 0 for scrolling through items in a list.
- int64_t minValue = 0;
- // The maximum value the scrollbar can be assigned in the current range.
- // Set maxValue to length - 1 and visibleItems to 1 for selecting an item in a list directly.
- // Set maxValue to length - visibleItems for scrolling through items with visibleItems sepresented by the knob's length.
- int64_t maxValue = 0;
- // Scrolling represents a range starting at the selected value of length visibleItems.
- // Use 1 if you are just selecting one integer value.
- // Use the value that you subtracted from the total length in maxValue if you want to represent a range of multiple values.
- // This argument only affects the knob size and how the selected range is constrained to include a certain value.
- int64_t visibleItems = 1;
- ScrollRange() {}
- ScrollRange(int64_t minValue, int64_t maxValue, int64_t visibleItems)
- : minValue(minValue), maxValue(maxValue), visibleItems(visibleItems) {}
- };
- // To be value allocated inside of components that need a scroll-bar.
- // Initialized with true if the scroll-bar is vertical, and with false if the scroll-bar is horizontal.
- // Call loadTheme when the parent component loads a new theme, or you will have a crash when trying to draw the scroll-bar.
- // When the range of values or view's size changed, recalculate the range of valid values and send it to updateScrollRange.
- class ScrollBarImpl {
- private:
- // Locked settings.
- const bool vertical;
- // Calculated automatically.
- bool visible = false;
- // Temporary.
- bool pressScrollUp = false;
- bool pressScrollDown = false;
- bool holdingScrollBar = false;
- const int scrollBarThickness = 16;
- const int scrollButtonLength = 16;
- int64_t knobHoldOffset = 0; // The number of pixels right or down from the center that the knob was grabbed at.
- // Updated manually.
- ScrollRange scrollRange; // Range of valid values.
- int64_t value = 0; // The selected value.
- int64_t reservedStart = 0; // How many pixels to leave empty at the left/top side to avoid collisions.
- int64_t reservedEnd = 0; // How many pixels to leave empty at the right/bottom side to avoid collisions.
- // Scalable parametric images.
- MediaMethod scalableImage_scrollTop, scalableImage_scrollBottom, scalableImage_scrollBackground, scalableImage_scrollKnob;
- // Generated raster images.
- OrderedImageRgbaU8 scrollButtonTopImage_normal, scrollButtonTopImage_pressed;
- OrderedImageRgbaU8 scrollButtonBottomImage_normal, scrollButtonBottomImage_pressed;
- OrderedImageRgbaU8 scrollKnobImage_normal, scrollKnobImage_pressed;
- OrderedImageRgbaU8 scrollBarImage;
- private:
- IRect getScrollBarLocation(int32_t parentWidth, int32_t parentHeight);
- IRect getScrollRegion(const IRect &scrollBarLocation);
- IRect getDecreaseButton(const IRect &scrollBarLocation);
- IRect getIncreaseButton(const IRect &scrollBarLocation);
- IRect getKnobLocation(const IRect &scrollBarLocation);
- // Returns true iff value updated.
- bool pressScrollBar(const IRect &parentLocation, int64_t localY);
- public:
- ScrollBarImpl(bool vertical, bool reserveEnd = false)
- : vertical(vertical), reservedStart(0), reservedEnd(reserveEnd ? 16 : 0) {}
- void loadTheme(VisualTheme theme, const ColorRgbI32 &color);
- // Pre-condition: range.minValue <= range.maxValue
- void updateScrollRange(const ScrollRange &range);
- void setValue(int64_t newValue);
- int64_t getValue();
- // Pre-condition: scrollRange must have been updated since the last changes that may affect it
- // Side-effects: Constrains value within minValue and maxValue.
- // If keepPinValueInRange is true, it will also try to constrain the selected range to include pinValue,
- // which is used for making sure that something selected stays visible, when scrolling is used for navigating a view.
- void limitScrolling(const IRect &parentLocation, bool keepPinValueInRange = false, int64_t pinValue = 0);
- // For mouse-down events, it returns true iff the event landed inside of the scroll-bar.
- // For other event types, it returns true iff the scroll-bar needs to be redrawn.
- bool receiveMouseEvent(const IRect &parentLocation, const MouseEvent& event);
- // Draw the scroll-bar on top of target.
- void draw(OrderedImageRgbaU8 &target, VisualTheme &theme, const ColorRgbI32 &color);
- };
- }
- #endif
|