Jamba  3.0.2
ScrollbarView.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 pongasoft
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  *
16  * @author Yan Pujante
17  */
18 #pragma once
19 
20 #include "CustomView.h"
22 #include <pongasoft/Utils/Lerp.h>
23 
24 namespace pongasoft {
25 namespace VST {
26 namespace GUI {
27 namespace Views {
28 
29 using namespace VSTGUI;
30 
40 class ScrollbarView : public CustomView
41 {
42 public:
43  // Constructor
44  explicit ScrollbarView(const CRect &iSize) : CustomView(iSize) {}
45 
46  // draw
47  void draw(CDrawContext *iContext) override;
48 
49  // tag to tie offsetPercent to a Vst parameter
50  int32_t getOffsetPercentTag() const { return fOffsetPercentTag; }
51  void setOffsetPercentTag(int32_t offsetPercentTag);
52 
53  // tag to tie zoomPercent to a Vst parameter
54  int32_t getZoomPercentTag() const { return fZoomPercentTag; }
55  void setZoomPercentTag(int32_t zoomPercentTag);
56 
57  // margin : whitespace around the scrollbar
58  Margin const &getMargin() const { return fMargin; }
59  void setMargin(Margin const &iMargin) { fMargin = iMargin; needsRecomputing();}
60 
61  // scrollbar color
62  const CColor &getScrollbarColor() const { return fScrollbarColor; }
63  void setScrollbarColor(const CColor &iColor) { fScrollbarColor = iColor; needsRecomputing(); }
64 
65  // minimum size for the scrollbar. If -1 it will be auto-computed
66  CCoord getScrollbarMinSize() const { return fScrollbarMinSize; }
67  void setScrollbarMinSize(CCoord iScrollbarMinSize) { fScrollbarMinSize = iScrollbarMinSize; needsRecomputing();}
68 
69  // spacing between the scrollbar and zoom handles (only drawn when zoom handles)
70  CCoord getScrollbarGutterSpacing() const { return fScrollbarGutterSpacing; }
71  void setScrollbarGutterSpacing(CCoord iScrollbarGutterSpacing) { fScrollbarGutterSpacing = iScrollbarGutterSpacing; needsRecomputing();}
72 
73  // showHandles
74  bool showHandles() const { return fZoomHandlesSize != 0; }
75 
76  // zoom handles color
77  const CColor &getZoomHandlesColor() const { return fZoomHandlesColor; }
78  void setZoomHandlesColor(const CColor &iColor) { fZoomHandlesColor = iColor; needsRecomputing(); }
79 
80  // zoom handles size. If -1 it will be auto-computed. Set to 0 to disable handles entirely
81  CCoord getZoomHandlesSize() const { return fZoomHandlesSize; }
82  void setZoomHandlesSize(CCoord iSize) { fZoomHandlesSize = iSize; needsRecomputing(); }
83 
84  // how much to slow down (if less than 1) or accelerate (if more than 1) when shift is held when dragging
85  Range const &getShiftDragFactor() const { return fShiftDragFactor; }
86  void setShiftDragFactor(Range const &iShiftDragFactor) { fShiftDragFactor = iShiftDragFactor; }
87 
88  // whether to allow double clicking for zoom
89  bool getEnableZoomDoubleClick() const { return fEnableZoomDoubleClick; }
90  void setEnableZoomDoubleClick(bool iEnableZoomDoubleClick) { fEnableZoomDoubleClick = iEnableZoomDoubleClick; }
91 
92  // offsetPercent accessor
93  double getOffsetPercent() const;
94  void setOffsetPercent(double iOffsetPercent);
95 
96  // zoomPercent accessor
97  double getZoomPercent() const;
98  void setZoomPercent(double iZoomPercent);
99 
100  CLASS_METHODS_NOCOPY(ScrollbarView, CustomView)
101 
102 protected:
103  // setViewSize
104  void setViewSize(const CRect &rect, bool invalid) override;
105 
106  // registerParameters
107  void registerParameters() override;
108 
109  // onParameterChange
110  void onParameterChange(ParamID iParamID) override;
111 
112  // onMouseDown
113  CMouseEventResult onMouseDown(CPoint &where, const CButtonState &buttons) override;
114 
115  // onMouseMoved
116  CMouseEventResult onMouseMoved(CPoint &where, const CButtonState &buttons) override;
117 
118  // onMouseUp
119  CMouseEventResult onMouseUp(CPoint &where, const CButtonState &buttons) override;
120 
121  // onMouseCancel
122  CMouseEventResult onMouseCancel() override;
123 
124 protected:
125  enum class DragType { kNone, kScroll, kZoomLeft, kZoomRight, kStretchLeft, kStretchRight };
126 
130  struct ZoomBox
131  {
132  CRect fViewSize;
136  CCoord fMinWidth;
137  CCoord fMaxWidth;
138  CCoord fHalfWidth;
140 
141  // when the box is full it cannot be moved anymore
142  bool isFull() const { return fMinCenter == fMaxCenter; }
143 
144  // left position
145  RelativeCoord getLeft() const { return fCenter - fHalfWidth; }
146  RelativeCoord getMinLeft() const { return fMinCenter - fHalfWidth; }
147  bool isMinLeft() const { return fCenter == fMinCenter; }
148 
149  // right position
150  RelativeCoord getRight() const { return fCenter + fHalfWidth; }
151  RelativeCoord getMaxRight() const { return fMaxCenter + fHalfWidth; }
152  bool isMaxRight() const { return fCenter == fMaxCenter; }
153 
154  // height of the box
155  CCoord getHeight() const { return fViewSize.getHeight(); }
156 
157  // width of the box
158  CCoord getWidth() const { return fHalfWidth * 2.0; }
159 
160  // the relative view containing the box (which is the original view minus the margin)
161  RelativeView getRelativeView() const { return RelativeView{fViewSize}; }
162 
163  // compute position from offsetPercent
164  RelativeCoord computeCenter(double iOffsetPercent) const
165  {
166  return Utils::mapValueDP(iOffsetPercent, 0.0, 1.0, fMinCenter, fMaxCenter);
167  }
168 
169  // compute the offsetPercent from the position
170  double computeOffsetPercent() const
171  {
172  return Utils::mapValueDP(fCenter, fMinCenter, fMaxCenter, 0.0, 1.0);
173  }
174 
175  // compute size from zoomPercent
176  CCoord computeWidth(double iZoomPercent) const
177  {
178  return Utils::mapValueDP(iZoomPercent, 1.0, 0.0, fMinWidth, fMaxWidth);
179  }
180 
181  // compute zoomPercent from size
182  double computeZoomPercent() const
183  {
184  return Utils::mapValueDP(getWidth(), fMinWidth, fMaxWidth, 1.0, 0.0);
185  }
186 
187  // move the box by iDeltaX (can be positive or negative)
188  void move(CCoord iDeltaX)
189  {
190  fCenter = Utils::clamp(fCenter + iDeltaX, fMinCenter, fMaxCenter);
191  }
192 
193  // move the box to a specific location
194  void moveTo(RelativeCoord const &iNewCenter)
195  {
196  fCenter = Utils::clamp(iNewCenter, fMinCenter, fMaxCenter);
197  }
198 
204  bool stretch(CCoord iDeltaX, DragType iDragType);
205 
206  // zoom to max and move to specific location
207  void maxZoom(RelativeCoord const &iNewCenter);
208 
209  // zoom to minimum (since the box is full, there is no specific location)
210  void minZoom();
211  };
212 
213 protected:
214  // drawLeftHandle - can be overridden to draw something different but should fit in fLeftHandleRect
215  virtual void drawLeftHandle(CDrawContext *iContext);
216 
217  // drawRightHandle - can be overridden to draw something different but should fit in fRightHandleRect
218  virtual void drawRightHandle(CDrawContext *iContext);
219 
220  // drawScrollbar - can be overridden to draw something different but should fit in fScrollbarRect
221  virtual void drawScrollbar(CDrawContext *iContext);
222 
223  // needsRecomputing when something changes that requires recomputing the 3 AbsoluteRect
224  void needsRecomputing() { fNeedsRecomputing = true; markDirty(); }
225 
226  // recompute the 3 AbsoluteRect
227  void recompute();
228 
229  // computeZoomBox
230  ZoomBox computeZoomBox() const;
231 
232  // returns the width of just the scrollbar (excluding handles and gutter)
233  CCoord getScrollbarWidth() const;
234 
235 protected:
236  // set to true when the 3 AbsoluteRect need to be recomputed
237  bool fNeedsRecomputing{true};
238  ZoomBox fZoomBox{};
239 
240  // the 3 Rect representing the position and size of the 3 pieces of the rendering
244 
245  // look and feel
246  Margin fMargin{};
247  CColor fScrollbarColor{kWhiteCColor};
248  CCoord fScrollbarMinSize{-1}; // -1 means it will be computed
249  CCoord fScrollbarGutterSpacing{1};
250 
251  CColor fZoomHandlesColor{kWhiteCColor};
252  CCoord fZoomHandlesSize{-1}; // -1 means it will be computed, 0 means no show
253 
254  // how much to slow down (if less than 1) or accelerate (if more than 1) when shift is held when dragging
255  Range fShiftDragFactor{1.0};
256  bool fEnableZoomDoubleClick{true};
257 
258  // offsetPercent tag/param/value + editor and editor value ("value" is used when no param)
259  int32_t fOffsetPercentTag{-1};
260  GUIRawVstParam fOffsetPercentParam{};
261  double fOffsetPercentValue{};
262  GUIRawVstParamEditor fOffsetPercentEditor{nullptr};
263 
264  // zoomPercent tag/param/value + editor and editor value ("value" is used when no param)
265  int32_t fZoomPercentTag{-1};
266  GUIRawVstParam fZoomPercentParam{};
267  double fZoomPercentValue{};
268  GUIRawVstParamEditor fZoomPercentEditor{nullptr};
269 
270  // used when dragging
271  RelativeCoord fDragGestureX{-1.0};
272  DragType fDragType{DragType::kNone};
273 
274 public:
275  class Creator : public CustomViewCreator<ScrollbarView, CustomView>
276  {
277  public:
278  explicit Creator(char const *iViewName = nullptr, char const *iDisplayName = nullptr) :
279  CustomViewCreator(iViewName, iDisplayName)
280  {
281  registerTagAttribute("offset-percent-tag", &ScrollbarView::getOffsetPercentTag, &ScrollbarView::setOffsetPercentTag);
282  registerTagAttribute("zoom-percent-tag", &ScrollbarView::getZoomPercentTag, &ScrollbarView::setZoomPercentTag);
283  registerMarginAttribute("margin", &ScrollbarView::getMargin, &ScrollbarView::setMargin);
284  registerColorAttribute("scrollbar-color", &ScrollbarView::getScrollbarColor, &ScrollbarView::setScrollbarColor);
285  registerDoubleAttribute("scrollbar-min-size", &ScrollbarView::getScrollbarMinSize, &ScrollbarView::setScrollbarMinSize);
286  registerDoubleAttribute("scrollbar-gutter-spacing", &ScrollbarView::getScrollbarGutterSpacing, &ScrollbarView::setScrollbarGutterSpacing);
287  registerColorAttribute("zoom-handles-color", &ScrollbarView::getZoomHandlesColor, &ScrollbarView::setZoomHandlesColor);
288  registerDoubleAttribute("zoom-handles-size", &ScrollbarView::getZoomHandlesSize, &ScrollbarView::setZoomHandlesSize);
289  registerRangeAttribute("shift-drag-factor", &ScrollbarView::getShiftDragFactor, &ScrollbarView::setShiftDragFactor);
290  registerBooleanAttribute("enable-zoom-double-click", &ScrollbarView::getEnableZoomDoubleClick, &ScrollbarView::setEnableZoomDoubleClick);
291  }
292  };
293 };
294 
295 }
296 }
297 }
298 }
Definition: CustomViewCreator.h:981
static T clamp(const U &iValue, const T &iLower, const T &iUpper)
Definition: Misc.h:33
void move(CCoord iDeltaX)
Definition: ScrollbarView.h:188
void setOffsetPercentTag(int32_t offsetPercentTag)
Definition: ScrollbarView.cpp:362
std::unique_ptr< GUIRawVstParameter::Editor > GUIRawVstParamEditor
Definition: GUIRawVstParameter.h:291
bool showHandles() const
Definition: ScrollbarView.h:74
Definition: GUIRawVstParameter.h:211
Definition: Clock.h:22
RelativeCoord computeCenter(double iOffsetPercent) const
Definition: ScrollbarView.h:164
AbsoluteRect fScrollbarRect
Definition: ScrollbarView.h:243
CCoord computeWidth(double iZoomPercent) const
Definition: ScrollbarView.h:176
CCoord getScrollbarMinSize() const
Definition: ScrollbarView.h:66
Creator(char const *iViewName=nullptr, char const *iDisplayName=nullptr)
Definition: ScrollbarView.h:278
Definition: CustomView.h:100
RelativeCoord fMinCenter
Definition: ScrollbarView.h:133
static double mapValueDP(double iValue, double iFromLow, double iFromHigh, double iToLow, double iToHigh, bool iClamp=true)
Definition: Lerp.h:217
void setScrollbarMinSize(CCoord iScrollbarMinSize)
Definition: ScrollbarView.h:67
RelativeCoord fCenter
Definition: ScrollbarView.h:135
bool getEnableZoomDoubleClick() const
Definition: ScrollbarView.h:89
RelativeCoord fMaxCenter
Definition: ScrollbarView.h:134
void setScrollbarColor(const CColor &iColor)
Definition: ScrollbarView.h:63
RelativeCoord getRight() const
Definition: ScrollbarView.h:150
Range const & getShiftDragFactor() const
Definition: ScrollbarView.h:85
bool isMinLeft() const
Definition: ScrollbarView.h:147
Definition: ScrollbarView.h:40
CCoord fMaxWidth
Definition: ScrollbarView.h:137
AbsoluteRect fRightHandleRect
Definition: ScrollbarView.h:242
void setShiftDragFactor(Range const &iShiftDragFactor)
Definition: ScrollbarView.h:86
AbsoluteRect fLeftHandleRect
Definition: ScrollbarView.h:241
const CColor & getZoomHandlesColor() const
Definition: ScrollbarView.h:77
CCoord fHalfWidth
Definition: ScrollbarView.h:138
bool isFull() const
Definition: ScrollbarView.h:142
Margin const & getMargin() const
Definition: ScrollbarView.h:58
CCoord RelativeCoord
Definition: DrawContext.h:45
CCoord fMinWidth
Definition: ScrollbarView.h:136
RelativeCoord getMaxRight() const
Definition: ScrollbarView.h:151
void setMargin(Margin const &iMargin)
Definition: ScrollbarView.h:59
int32_t getZoomPercentTag() const
Definition: ScrollbarView.h:54
CCoord getScrollbarGutterSpacing() const
Definition: ScrollbarView.h:70
void needsRecomputing()
Definition: ScrollbarView.h:224
Definition: LookAndFeel.h:32
double computeZoomPercent() const
Definition: ScrollbarView.h:182
CRect AbsoluteRect
Definition: DrawContext.h:50
double computeOffsetPercent() const
Definition: ScrollbarView.h:170
bool isMaxRight() const
Definition: ScrollbarView.h:152
void moveTo(RelativeCoord const &iNewCenter)
Definition: ScrollbarView.h:194
CCoord getHeight() const
Definition: ScrollbarView.h:155
void setZoomHandlesColor(const CColor &iColor)
Definition: ScrollbarView.h:78
void setZoomHandlesSize(CCoord iSize)
Definition: ScrollbarView.h:82
ScrollbarView(const CRect &iSize)
Definition: ScrollbarView.h:44
const CColor & getScrollbarColor() const
Definition: ScrollbarView.h:62
CRect fViewSize
Definition: ScrollbarView.h:132
CCoord fZoomHandlesSize
Definition: ScrollbarView.h:139
CCoord getWidth() const
Definition: ScrollbarView.h:158
Definition: DrawContext.h:52
CCoord getZoomHandlesSize() const
Definition: ScrollbarView.h:81
int32_t getOffsetPercentTag() const
Definition: ScrollbarView.h:50
void setZoomPercentTag(int32_t zoomPercentTag)
Definition: ScrollbarView.cpp:372
void setEnableZoomDoubleClick(bool iEnableZoomDoubleClick)
Definition: ScrollbarView.h:90
RelativeCoord getMinLeft() const
Definition: ScrollbarView.h:146
DragType
Definition: ScrollbarView.h:125
RelativeView getRelativeView() const
Definition: ScrollbarView.h:161
RelativeCoord getLeft() const
Definition: ScrollbarView.h:145
void setScrollbarGutterSpacing(CCoord iScrollbarGutterSpacing)
Definition: ScrollbarView.h:71