LMMS
Loading...
Searching...
No Matches
juce_ScrollBar.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
30{
31public:
33 : Button (String()), direction (direc), owner (s)
34 {
36 }
37
38 void paintButton (Graphics& g, bool over, bool down) override
39 {
40 getLookAndFeel().drawScrollbarButton (g, owner, getWidth(), getHeight(),
41 direction, owner.isVertical(), over, down);
42 }
43
44 void clicked() override
45 {
46 owner.moveScrollbarInSteps ((direction == 1 || direction == 2) ? 1 : -1);
47 }
48
49 using Button::clicked;
50
52
53private:
55
57};
58
59
60//==============================================================================
66
68{
69 upButton.reset();
70 downButton.reset();
71}
72
73//==============================================================================
75{
76 if (totalRange != newRangeLimit)
77 {
78 totalRange = newRangeLimit;
79 setCurrentRange (visibleRange, notification);
81 }
82}
83
84void ScrollBar::setRangeLimits (double newMinimum, double newMaximum, NotificationType notification)
85{
86 jassert (newMaximum >= newMinimum); // these can't be the wrong way round!
87 setRangeLimits (Range<double> (newMinimum, newMaximum), notification);
88}
89
91{
92 auto constrainedRange = totalRange.constrainRange (newRange);
93
94 if (visibleRange != constrainedRange)
95 {
96 visibleRange = constrainedRange;
97
99
100 if (notification != dontSendNotification)
102
103 if (notification == sendNotificationSync)
105
106 return true;
107 }
108
109 return false;
110}
111
112void ScrollBar::setCurrentRange (double newStart, double newSize, NotificationType notification)
113{
114 setCurrentRange (Range<double> (newStart, newStart + newSize), notification);
115}
116
117void ScrollBar::setCurrentRangeStart (double newStart, NotificationType notification)
118{
119 setCurrentRange (visibleRange.movedToStartAt (newStart), notification);
120}
121
122void ScrollBar::setSingleStepSize (double newSingleStepSize) noexcept
123{
124 singleStepSize = newSingleStepSize;
125}
126
127bool ScrollBar::moveScrollbarInSteps (int howManySteps, NotificationType notification)
128{
129 return setCurrentRange (visibleRange + howManySteps * singleStepSize, notification);
130}
131
132bool ScrollBar::moveScrollbarInPages (int howManyPages, NotificationType notification)
133{
134 return setCurrentRange (visibleRange + howManyPages * visibleRange.getLength(), notification);
135}
136
138{
139 return setCurrentRange (visibleRange.movedToStartAt (getMinimumRangeLimit()), notification);
140}
141
143{
144 return setCurrentRange (visibleRange.movedToEndAt (getMaximumRangeLimit()), notification);
145}
146
147void ScrollBar::setButtonRepeatSpeed (int newInitialDelay,
148 int newRepeatDelay,
149 int newMinimumDelay)
150{
151 initialDelayInMillisecs = newInitialDelay;
152 repeatDelayInMillisecs = newRepeatDelay;
153 minimumDelayInMillisecs = newMinimumDelay;
154
155 if (upButton != nullptr)
156 {
157 upButton ->setRepeatSpeed (newInitialDelay, newRepeatDelay, newMinimumDelay);
158 downButton->setRepeatSpeed (newInitialDelay, newRepeatDelay, newMinimumDelay);
159 }
160}
161
162//==============================================================================
164{
165 listeners.add (listener);
166}
167
169{
170 listeners.remove (listener);
171}
172
174{
175 auto start = visibleRange.getStart(); // (need to use a temp variable for VC7 compatibility)
176 listeners.call ([this, start] (Listener& l) { l.scrollBarMoved (this, start); });
177}
178
179//==============================================================================
181{
182 auto minimumScrollBarThumbSize = getLookAndFeel().getMinimumScrollbarThumbSize (*this);
183
184 int newThumbSize = roundToInt (totalRange.getLength() > 0 ? (visibleRange.getLength() * thumbAreaSize) / totalRange.getLength()
185 : thumbAreaSize);
186
187 if (newThumbSize < minimumScrollBarThumbSize)
188 newThumbSize = jmin (minimumScrollBarThumbSize, thumbAreaSize - 1);
189
190 if (newThumbSize > thumbAreaSize)
191 newThumbSize = thumbAreaSize;
192
193 int newThumbStart = thumbAreaStart;
194
195 if (totalRange.getLength() > visibleRange.getLength())
196 newThumbStart += roundToInt (((visibleRange.getStart() - totalRange.getStart()) * (thumbAreaSize - newThumbSize))
197 / (totalRange.getLength() - visibleRange.getLength()));
198
200
201 if (thumbStart != newThumbStart || thumbSize != newThumbSize)
202 {
203 auto repaintStart = jmin (thumbStart, newThumbStart) - 4;
204 auto repaintSize = jmax (thumbStart + thumbSize, newThumbStart + newThumbSize) + 8 - repaintStart;
205
206 if (vertical)
207 repaint (0, repaintStart, getWidth(), repaintSize);
208 else
209 repaint (repaintStart, 0, repaintSize, getHeight());
210
211 thumbStart = newThumbStart;
212 thumbSize = newThumbSize;
213 }
214}
215
216void ScrollBar::setOrientation (bool shouldBeVertical)
217{
218 if (vertical != shouldBeVertical)
219 {
220 vertical = shouldBeVertical;
221
222 if (upButton != nullptr)
223 {
224 upButton->direction = vertical ? 0 : 3;
225 downButton->direction = vertical ? 2 : 1;
226 }
227
229 }
230}
231
232void ScrollBar::setAutoHide (bool shouldHideWhenFullRange)
233{
234 autohides = shouldHideWhenFullRange;
236}
237
239{
240 return autohides;
241}
242
243//==============================================================================
245{
246 if (thumbAreaSize > 0)
247 {
248 auto& lf = getLookAndFeel();
249
250 auto thumb = (thumbAreaSize > lf.getMinimumScrollbarThumbSize (*this))
251 ? thumbSize : 0;
252
253 if (vertical)
254 lf.drawScrollbar (g, *this, 0, thumbAreaStart, getWidth(), thumbAreaSize,
256 else
257 lf.drawScrollbar (g, *this, thumbAreaStart, 0, thumbAreaSize, getHeight(),
259 }
260}
261
263{
264 setComponentEffect (getLookAndFeel().getScrollbarEffect());
265
266 if (isVisible())
267 resized();
268}
269
271{
272 auto length = vertical ? getHeight() : getWidth();
273
274 auto& lf = getLookAndFeel();
275 bool buttonsVisible = lf.areScrollbarButtonsVisible();
276 int buttonSize = 0;
277
278 if (buttonsVisible)
279 {
280 if (upButton == nullptr)
281 {
282 upButton .reset (new ScrollbarButton (vertical ? 0 : 3, *this));
283 downButton.reset (new ScrollbarButton (vertical ? 2 : 1, *this));
284
287
289 }
290
291 buttonSize = jmin (lf.getScrollbarButtonSize (*this), length / 2);
292 }
293 else
294 {
295 upButton.reset();
296 downButton.reset();
297 }
298
299 if (length < 32 + lf.getMinimumScrollbarThumbSize (*this))
300 {
302 thumbAreaSize = 0;
303 }
304 else
305 {
306 thumbAreaStart = buttonSize;
307 thumbAreaSize = length - 2 * buttonSize;
308 }
309
310 if (upButton != nullptr)
311 {
312 auto r = getLocalBounds();
313
314 if (vertical)
315 {
316 upButton->setBounds (r.removeFromTop (buttonSize));
317 downButton->setBounds (r.removeFromBottom (buttonSize));
318 }
319 else
320 {
321 upButton->setBounds (r.removeFromLeft (buttonSize));
322 downButton->setBounds (r.removeFromRight (buttonSize));
323 }
324 }
325
327}
328
333
335{
336 isDraggingThumb = false;
337 lastMousePos = vertical ? e.y : e.x;
339 dragStartRange = visibleRange.getStart();
340
342 {
344 startTimer (400);
345 }
347 {
349 startTimer (400);
350 }
351 else
352 {
353 isDraggingThumb = (thumbAreaSize > getLookAndFeel().getMinimumScrollbarThumbSize (*this))
355 }
356}
357
359{
360 auto mousePos = vertical ? e.y : e.x;
361
362 if (isDraggingThumb && lastMousePos != mousePos && thumbAreaSize > thumbSize)
363 {
364 auto deltaPixels = mousePos - dragStartMousePos;
365
367 + deltaPixels * (totalRange.getLength() - visibleRange.getLength())
369 }
370
371 lastMousePos = mousePos;
372}
373
375{
376 isDraggingThumb = false;
377 stopTimer();
378 repaint();
379}
380
382{
383 float increment = 10.0f * (vertical ? wheel.deltaY : wheel.deltaX);
384
385 if (increment < 0)
386 increment = jmin (increment, -1.0f);
387 else if (increment > 0)
388 increment = jmax (increment, 1.0f);
389
391}
392
394{
395 if (isMouseButtonDown())
396 {
397 startTimer (40);
398
401 else if (lastMousePos > thumbStart + thumbSize)
403 }
404 else
405 {
406 stopTimer();
407 }
408}
409
411{
412 if (isVisible())
413 {
416 if (key == KeyPress::pageUpKey) return moveScrollbarInPages (-1);
418 if (key == KeyPress::homeKey) return scrollToTop();
419 if (key == KeyPress::endKey) return scrollToBottom();
420 }
421
422 return false;
423}
424
425void ScrollBar::setVisible (bool shouldBeVisible)
426{
427 if (userVisibilityFlag != shouldBeVisible)
428 {
429 userVisibilityFlag = shouldBeVisible;
431 }
432}
433
435{
436 if (! userVisibilityFlag)
437 return false;
438
439 return (! autohides) || (totalRange.getLength() > visibleRange.getLength()
440 && visibleRange.getLength() > 0.0);
441}
442
443//==============================================================================
444std::unique_ptr<AccessibilityHandler> ScrollBar::createAccessibilityHandler()
445{
446 class ValueInterface : public AccessibilityRangedNumericValueInterface
447 {
448 public:
449 explicit ValueInterface (ScrollBar& scrollBarToWrap) : scrollBar (scrollBarToWrap) {}
450
451 bool isReadOnly() const override { return false; }
452
453 double getCurrentValue() const override { return scrollBar.getCurrentRangeStart(); }
454 void setValue (double newValue) override { scrollBar.setCurrentRangeStart (newValue); }
455
456 AccessibleValueRange getRange() const override
457 {
458 if (scrollBar.getRangeLimit().isEmpty())
459 return {};
460
461 return { { scrollBar.getMinimumRangeLimit(), scrollBar.getMaximumRangeLimit() },
462 scrollBar.getSingleStepSize() };
463 }
464
465 private:
467
469 };
470
471 return std::make_unique<AccessibilityHandler> (*this,
474 AccessibilityHandler::Interfaces { std::make_unique<ValueInterface> (*this) });
475}
476
477} // namespace juce
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
#define noexcept
Definition DistrhoDefines.h:72
Definition juce_AccessibilityActions.h:73
Definition juce_AccessibilityValueInterface.h:198
void handleUpdateNowIfNeeded()
Definition juce_AsyncUpdater.cpp:79
void triggerAsyncUpdate()
Definition juce_AsyncUpdater.cpp:62
virtual void clicked()
Definition juce_Button.cpp:339
Button(const String &buttonName)
Definition juce_Button.cpp:76
bool isMouseButtonDown(bool includeChildren=false) const
Definition juce_Component.cpp:3177
void setRepaintsOnMouseActivity(bool shouldRepaint) noexcept
Definition juce_Component.cpp:1881
bool isVisible() const noexcept
Definition juce_Component.h:122
void setFocusContainerType(FocusContainerType containerType) noexcept
Definition juce_Component.cpp:2862
int getHeight() const noexcept
Definition juce_Component.h:274
void addAndMakeVisible(Component *child, int zOrder=-1)
Definition juce_Component.cpp:1554
void repaint()
Definition juce_Component.cpp:1917
@ keyboardFocusContainer
Definition juce_Component.h:1307
void setWantsKeyboardFocus(bool wantsFocus) noexcept
Definition juce_Component.cpp:2842
bool isMouseOver(bool includeChildren=false) const
Definition juce_Component.cpp:3159
int getWidth() const noexcept
Definition juce_Component.h:271
LookAndFeel & getLookAndFeel() const noexcept
Definition juce_Component.cpp:2173
Rectangle< int > getLocalBounds() const noexcept
Definition juce_Component.cpp:2283
void setComponentEffect(ImageEffectFilter *newEffect)
Definition juce_Component.cpp:2163
virtual void setVisible(bool shouldBeVisible)
Definition juce_Component.cpp:575
Definition juce_GraphicsContext.h:45
Definition juce_KeyPress.h:40
static const int homeKey
Definition juce_KeyPress.h:204
static const int upKey
Definition juce_KeyPress.h:198
static const int endKey
Definition juce_KeyPress.h:205
static const int rightKey
Definition juce_KeyPress.h:201
static const int downKey
Definition juce_KeyPress.h:199
static const int leftKey
Definition juce_KeyPress.h:200
static const int pageUpKey
Definition juce_KeyPress.h:202
static const int pageDownKey
Definition juce_KeyPress.h:203
Definition juce_MouseEvent.h:39
Definition juce_Range.h:40
Definition juce_ScrollBar.h:309
Definition juce_ScrollBar.cpp:30
int direction
Definition juce_ScrollBar.cpp:51
ScrollBar & owner
Definition juce_ScrollBar.cpp:54
void clicked() override
Definition juce_ScrollBar.cpp:44
void paintButton(Graphics &g, bool over, bool down) override
Definition juce_ScrollBar.cpp:38
ScrollbarButton(int direc, ScrollBar &s)
Definition juce_ScrollBar.cpp:32
Range< double > visibleRange
Definition juce_ScrollBar.h:420
int lastMousePos
Definition juce_ScrollBar.h:423
void removeListener(Listener *listener)
Definition juce_ScrollBar.cpp:168
bool moveScrollbarInPages(int howManyPages, NotificationType notification=sendNotificationAsync)
Definition juce_ScrollBar.cpp:132
bool moveScrollbarInSteps(int howManySteps, NotificationType notification=sendNotificationAsync)
Definition juce_ScrollBar.cpp:127
int thumbSize
Definition juce_ScrollBar.h:422
bool setCurrentRange(Range< double > newRange, NotificationType notification=sendNotificationAsync)
Definition juce_ScrollBar.cpp:90
void parentHierarchyChanged() override
Definition juce_ScrollBar.cpp:329
void addListener(Listener *listener)
Definition juce_ScrollBar.cpp:163
void updateThumbPosition()
Definition juce_ScrollBar.cpp:180
ScrollBar(bool isVertical)
Definition juce_ScrollBar.cpp:61
void handleAsyncUpdate() override
Definition juce_ScrollBar.cpp:173
bool userVisibilityFlag
Definition juce_ScrollBar.h:425
void setOrientation(bool shouldBeVertical)
Definition juce_ScrollBar.cpp:216
bool autohides
Definition juce_ScrollBar.h:425
void mouseDown(const MouseEvent &) override
Definition juce_ScrollBar.cpp:334
bool isDraggingThumb
Definition juce_ScrollBar.h:425
int dragStartMousePos
Definition juce_ScrollBar.h:423
void mouseUp(const MouseEvent &) override
Definition juce_ScrollBar.cpp:374
ListenerList< Listener > listeners
Definition juce_ScrollBar.h:428
int thumbAreaStart
Definition juce_ScrollBar.h:422
std::unique_ptr< ScrollbarButton > downButton
Definition juce_ScrollBar.h:427
double singleStepSize
Definition juce_ScrollBar.h:421
bool keyPressed(const KeyPress &) override
Definition juce_ScrollBar.cpp:410
bool scrollToBottom(NotificationType notification=sendNotificationAsync)
Definition juce_ScrollBar.cpp:142
int thumbAreaSize
Definition juce_ScrollBar.h:422
bool scrollToTop(NotificationType notification=sendNotificationAsync)
Definition juce_ScrollBar.cpp:137
std::unique_ptr< AccessibilityHandler > createAccessibilityHandler() override
Definition juce_ScrollBar.cpp:444
bool getVisibility() const noexcept
Definition juce_ScrollBar.cpp:434
int minimumDelayInMillisecs
Definition juce_ScrollBar.h:424
void setVisible(bool) override
Definition juce_ScrollBar.cpp:425
int initialDelayInMillisecs
Definition juce_ScrollBar.h:424
Range< double > totalRange
Definition juce_ScrollBar.h:420
void lookAndFeelChanged() override
Definition juce_ScrollBar.cpp:262
bool vertical
Definition juce_ScrollBar.h:425
void resized() override
Definition juce_ScrollBar.cpp:270
double getMaximumRangeLimit() const noexcept
Definition juce_ScrollBar.h:138
double dragStartRange
Definition juce_ScrollBar.h:421
void mouseWheelMove(const MouseEvent &, const MouseWheelDetails &) override
Definition juce_ScrollBar.cpp:381
void paint(Graphics &) override
Definition juce_ScrollBar.cpp:244
void mouseDrag(const MouseEvent &) override
Definition juce_ScrollBar.cpp:358
~ScrollBar() override
Definition juce_ScrollBar.cpp:67
void setCurrentRangeStart(double newStart, NotificationType notification=sendNotificationAsync)
Definition juce_ScrollBar.cpp:117
void setRangeLimits(Range< double > newRangeLimit, NotificationType notification=sendNotificationAsync)
Definition juce_ScrollBar.cpp:74
void setButtonRepeatSpeed(int initialDelayInMillisecs, int repeatDelayInMillisecs, int minimumDelayInMillisecs=-1)
Definition juce_ScrollBar.cpp:147
void timerCallback() override
Definition juce_ScrollBar.cpp:393
std::unique_ptr< ScrollbarButton > upButton
Definition juce_ScrollBar.h:427
void setAutoHide(bool shouldHideWhenFullRange)
Definition juce_ScrollBar.cpp:232
int thumbStart
Definition juce_ScrollBar.h:422
bool autoHides() const noexcept
Definition juce_ScrollBar.cpp:238
int repeatDelayInMillisecs
Definition juce_ScrollBar.h:424
double getMinimumRangeLimit() const noexcept
Definition juce_ScrollBar.h:132
void setSingleStepSize(double newSingleStepSize) noexcept
Definition juce_ScrollBar.cpp:122
Definition juce_String.h:53
void stopTimer() noexcept
Definition juce_Timer.cpp:357
void startTimer(int intervalInMilliseconds) noexcept
Definition juce_Timer.cpp:332
* e
Definition inflate.c:1404
int * l
Definition inflate.c:1579
int g
Definition inflate.c:1573
unsigned s
Definition inflate.c:1555
virtual ASIOError start()=0
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
Definition carla_juce.cpp:31
NotificationType
Definition juce_NotificationType.h:32
@ sendNotificationSync
Definition juce_NotificationType.h:35
@ dontSendNotification
Definition juce_NotificationType.h:33
int roundToInt(const FloatType value) noexcept
Definition juce_MathsFunctions.h:465
@ scrollBar
Definition juce_AccessibilityRole.h:64
png_uint_32 length
Definition png.c:2247
Definition juce_AccessibilityHandler.h:49
Definition juce_MouseEvent.h:392
float deltaY
Definition juce_MouseEvent.h:410
float deltaX
Definition juce_MouseEvent.h:401
ZCONST char * key
Definition crypt.c:587
int r
Definition crypt.c:458
#define const
Definition zconf.h:137