1616
1717NAMESPACE_BEGIN (nanogui)
1818
19- Slider::Slider(Widget *parent)
20- : Widget(parent), mValue(0 .0f ), mRange(0 .f, 1 .f),
19+ Slider::Slider(Widget *parent, Orientation orientation )
20+ : Widget(parent), mValue(0 .0f ), mOrientation(orientation), mRange(0 .f, 1 .f),
2121 mHighlightedRange(0 .f, 0 .f) {
2222 mHighlightColor = Color (255 , 80 , 80 , 70 );
2323}
2424
2525Vector2i Slider::preferredSize (NVGcontext *) const {
26- return Vector2i (70 , 16 );
26+ return ( mOrientation == Orientation::Horizontal) ? Vector2i (70 , 16 ) : Vector2i ( 16 , 70 );
2727}
2828
2929bool Slider::mouseDragEvent (const Vector2i &p, const Vector2i & /* rel */ ,
3030 int /* button */ , int /* modifiers */ ) {
3131 if (!mEnabled )
3232 return false ;
3333
34- const float kr = (int ) (mSize .y () * 0 .4f ), kshadow = 3 ;
35- const float startX = kr + kshadow + mPos .x () - 1 ;
36- const float widthX = mSize .x () - 2 * (kr + kshadow);
37-
38- float value = (p.x () - startX) / widthX;
39- value = value * (mRange .second - mRange .first ) + mRange .first ;
40- mValue = std::min (std::max (value, mRange .first ), mRange .second );
34+ if (mOrientation == Orientation::Horizontal) {
35+ const float kr = (int ) (mSize .y () * 0 .4f ), kshadow = 3 ;
36+ const float startX = kr + kshadow + mPos .x () - 1 ;
37+ const float widthX = mSize .x () - 2 * (kr + kshadow);
38+
39+ float value = (p.x () - startX) / widthX;
40+ value = value * (mRange .second - mRange .first ) + mRange .first ;
41+ mValue = std::min (std::max (value, mRange .first ), mRange .second );
42+ } else {
43+ const float kr = (int ) (mSize .x () * 0 .4f ), kshadow = 3 ;
44+ const float startY = kr + kshadow + mPos .y () - 1 ;
45+ const float heightY = mSize .y () - 2 * (kr + kshadow);
46+
47+ float value = (p.y () - startY) / heightY;
48+ value = value * (mRange .second - mRange .first ) + mRange .first ;
49+ mValue = mRange .second - std::min (std::max (value, mRange .first ), mRange .second );
50+ }
4151 if (mCallback )
4252 mCallback (mValue );
4353 return true ;
@@ -47,13 +57,23 @@ bool Slider::mouseButtonEvent(const Vector2i &p, int /* button */, bool down, in
4757 if (!mEnabled )
4858 return false ;
4959
50- const float kr = (int ) (mSize .y () * 0 .4f ), kshadow = 3 ;
51- const float startX = kr + kshadow + mPos .x () - 1 ;
52- const float widthX = mSize .x () - 2 * (kr + kshadow);
53-
54- float value = (p.x () - startX) / widthX;
55- value = value * (mRange .second - mRange .first ) + mRange .first ;
56- mValue = std::min (std::max (value, mRange .first ), mRange .second );
60+ if (mOrientation == Orientation::Horizontal) {
61+ const float kr = (int ) (mSize .y () * 0 .4f ), kshadow = 3 ;
62+ const float startX = kr + kshadow + mPos .x () - 1 ;
63+ const float widthX = mSize .x () - 2 * (kr + kshadow);
64+
65+ float value = (p.x () - startX) / widthX;
66+ value = value * (mRange .second - mRange .first ) + mRange .first ;
67+ mValue = std::min (std::max (value, mRange .first ), mRange .second );
68+ } else {
69+ const float kr = (int ) (mSize .x () * 0 .4f ), kshadow = 3 ;
70+ const float startY = kr + kshadow + mPos .y () - 1 ;
71+ const float heightY = mSize .y () - 2 * (kr + kshadow);
72+
73+ float value = (p.y () - startY) / heightY;
74+ value = value * (mRange .second - mRange .first ) + mRange .first ;
75+ mValue = mRange .second - std::min (std::max (value, mRange .first ), mRange .second );
76+ }
5777 if (mCallback )
5878 mCallback (mValue );
5979 if (mFinalCallback && !down)
@@ -63,67 +83,134 @@ bool Slider::mouseButtonEvent(const Vector2i &p, int /* button */, bool down, in
6383
6484void Slider::draw (NVGcontext* ctx) {
6585 Vector2f center = mPos .cast <float >() + mSize .cast <float >() * 0 .5f ;
66- float kr = (int ) (mSize .y () * 0 .4f ), kshadow = 3 ;
6786
68- float startX = kr + kshadow + mPos . x ();
69- float widthX = mSize .x () - 2 *(kr+kshadow) ;
87+ if ( mOrientation == Orientation::Horizontal) {
88+ float kr = ( int ) ( mSize .y () * 0 . 4f ), kshadow = 3 ;
7089
71- Vector2f knobPos (startX + (mValue - mRange .first ) /
72- (mRange .second - mRange .first ) * widthX,
73- center.y () + 0 .5f );
90+ float startX = kr + kshadow + mPos .x ();
91+ float widthX = mSize .x () - 2 *(kr+kshadow);
7492
75- NVGpaint bg = nvgBoxGradient (
76- ctx, startX, center. y () - 3 + 1 , widthX, 6 , 3 , 3 ,
77- Color ( 0 , mEnabled ? 32 : 10 ), Color ( 0 , mEnabled ? 128 : 210 ) );
93+ Vector2f knobPos (startX + ( mValue - mRange . first ) /
94+ ( mRange . second - mRange . first ) * widthX ,
95+ center. y () + 0 . 5f );
7896
79- nvgBeginPath (ctx);
80- nvgRoundedRect (ctx, startX, center.y () - 3 + 1 , widthX, 6 , 2 );
81- nvgFillPaint (ctx, bg);
82- nvgFill (ctx);
97+ NVGpaint bg = nvgBoxGradient (
98+ ctx, startX, center.y () - 3 + 1 , widthX, 6 , 3 , 3 ,
99+ Color (0 , mEnabled ? 32 : 10 ), Color (0 , mEnabled ? 128 : 210 ));
83100
84- if (mHighlightedRange .second != mHighlightedRange .first ) {
85101 nvgBeginPath (ctx);
86- nvgRoundedRect (ctx, startX + mHighlightedRange .first * mSize .x (),
87- center.y () - kshadow + 1 ,
88- widthX *
102+ nvgRoundedRect (ctx, startX, center.y () - 3 + 1 , widthX, 6 , 2 );
103+ nvgFillPaint (ctx, bg);
104+ nvgFill (ctx);
105+
106+ if (mHighlightedRange .second != mHighlightedRange .first ) {
107+ nvgBeginPath (ctx);
108+ nvgRoundedRect (ctx, startX + mHighlightedRange .first * mSize .x (),
109+ center.y () - kshadow + 1 ,
110+ widthX *
89111 (mHighlightedRange .second - mHighlightedRange .first ),
90- kshadow * 2 , 2 );
91- nvgFillColor (ctx, mHighlightColor );
112+ kshadow * 2 , 2 );
113+ nvgFillColor (ctx, mHighlightColor );
114+ nvgFill (ctx);
115+ }
116+
117+ NVGpaint knobShadow =
118+ nvgRadialGradient (ctx, knobPos.x (), knobPos.y (), kr - kshadow,
119+ kr + kshadow, Color (0 , 64 ), mTheme ->mTransparent );
120+
121+ nvgBeginPath (ctx);
122+ nvgRect (ctx, knobPos.x () - kr - 5 , knobPos.y () - kr - 5 , kr * 2 + 10 ,
123+ kr * 2 + 10 + kshadow);
124+ nvgCircle (ctx, knobPos.x (), knobPos.y (), kr);
125+ nvgPathWinding (ctx, NVG_HOLE);
126+ nvgFillPaint (ctx, knobShadow);
92127 nvgFill (ctx);
93- }
94128
95- NVGpaint knobShadow =
96- nvgRadialGradient (ctx, knobPos.x (), knobPos.y (), kr - kshadow,
97- kr + kshadow, Color (0 , 64 ), mTheme ->mTransparent );
98-
99- nvgBeginPath (ctx);
100- nvgRect (ctx, knobPos.x () - kr - 5 , knobPos.y () - kr - 5 , kr * 2 + 10 ,
101- kr * 2 + 10 + kshadow);
102- nvgCircle (ctx, knobPos.x (), knobPos.y (), kr);
103- nvgPathWinding (ctx, NVG_HOLE);
104- nvgFillPaint (ctx, knobShadow);
105- nvgFill (ctx);
106-
107- NVGpaint knob = nvgLinearGradient (ctx,
108- mPos .x (), center.y () - kr, mPos .x (), center.y () + kr,
109- mTheme ->mBorderLight , mTheme ->mBorderMedium );
110- NVGpaint knobReverse = nvgLinearGradient (ctx,
111- mPos .x (), center.y () - kr, mPos .x (), center.y () + kr,
112- mTheme ->mBorderMedium ,
113- mTheme ->mBorderLight );
114-
115- nvgBeginPath (ctx);
116- nvgCircle (ctx, knobPos.x (), knobPos.y (), kr);
117- nvgStrokeColor (ctx, mTheme ->mBorderDark );
118- nvgFillPaint (ctx, knob);
119- nvgStroke (ctx);
120- nvgFill (ctx);
121- nvgBeginPath (ctx);
122- nvgCircle (ctx, knobPos.x (), knobPos.y (), kr/2 );
123- nvgFillColor (ctx, Color (150 , mEnabled ? 255 : 100 ));
124- nvgStrokePaint (ctx, knobReverse);
125- nvgStroke (ctx);
126- nvgFill (ctx);
129+ NVGpaint knob = nvgLinearGradient (ctx,
130+ mPos .x (), center.y () - kr, mPos .x (), center.y () + kr,
131+ mTheme ->mBorderLight , mTheme ->mBorderMedium );
132+ NVGpaint knobReverse = nvgLinearGradient (ctx,
133+ mPos .x (), center.y () - kr, mPos .x (), center.y () + kr,
134+ mTheme ->mBorderMedium ,
135+ mTheme ->mBorderLight );
136+
137+ nvgBeginPath (ctx);
138+ nvgCircle (ctx, knobPos.x (), knobPos.y (), kr);
139+ nvgStrokeColor (ctx, mTheme ->mBorderDark );
140+ nvgFillPaint (ctx, knob);
141+ nvgStroke (ctx);
142+ nvgFill (ctx);
143+ nvgBeginPath (ctx);
144+ nvgCircle (ctx, knobPos.x (), knobPos.y (), kr/2 );
145+ nvgFillColor (ctx, Color (150 , mEnabled ? 255 : 100 ));
146+ nvgStrokePaint (ctx, knobReverse);
147+ nvgStroke (ctx);
148+ nvgFill (ctx);
149+ } else {
150+ float kr = (int ) (mSize .x () * 0 .4f ), kshadow = 3 ;
151+
152+ float startY = kr + kshadow + mPos .y ();
153+ float heightY = mSize .y () - 2 *(kr+kshadow);
154+
155+ Vector2f knobPos (center.x () + 0 .5f ,
156+ startY + (mRange .second - mValue ) /
157+ (mRange .second - mRange .first ) * heightY);
158+
159+ NVGpaint bg = nvgBoxGradient ( ctx,
160+ center.x () - 3 + 1 , startY, 6 , heightY, 3 , 3 ,
161+ nanogui::Color (0 , mEnabled ? 32 : 10 ), nanogui::Color (0 , mEnabled ? 128 : 210 ));
162+
163+ nvgBeginPath (ctx);
164+ nvgRoundedRect (ctx, center.x () - 3 + 1 , startY, 6 , heightY, 2 );
165+ nvgFillPaint (ctx, bg);
166+ nvgFill (ctx);
167+
168+ if (mHighlightedRange .second != mHighlightedRange .first ) {
169+ nvgBeginPath (ctx);
170+ nvgRoundedRect (ctx,
171+ center.x () - kshadow + 1 ,
172+ mSize .y () - (kr+kshadow) - mHighlightedRange .second * heightY,
173+ kshadow * 2 ,
174+ heightY *
175+ (mHighlightedRange .second - mHighlightedRange .first ),
176+ 2 );
177+ nvgFillColor (ctx, mHighlightColor );
178+ nvgFill (ctx);
179+ }
180+
181+ NVGpaint knobShadow =
182+ nvgRadialGradient (ctx, knobPos.x (), knobPos.y (), kr + kshadow,
183+ kr - kshadow, nanogui::Color (0 , 64 ), mTheme ->mTransparent );
184+
185+ nvgBeginPath (ctx);
186+ nvgRect (ctx, knobPos.x () - kr - 5 , knobPos.y () - kr - 5 ,
187+ kr * 2 + 10 + kshadow, kr * 2 + 10 );
188+ nvgCircle (ctx, knobPos.x (), knobPos.y (), kr);
189+ nvgPathWinding (ctx, NVG_HOLE);
190+ nvgFillPaint (ctx, knobShadow);
191+ nvgFill (ctx);;
192+
193+ NVGpaint knob = nvgLinearGradient (ctx,
194+ center.x (), knobPos.y () - kr, center.x (), knobPos.y () + kr,
195+ mTheme ->mBorderLight , mTheme ->mBorderMedium );
196+ NVGpaint knobReverse = nvgLinearGradient (ctx,
197+ center.x (), knobPos.y () - kr, center.x (), knobPos.y () + kr,
198+ mTheme ->mBorderMedium ,
199+ mTheme ->mBorderLight );
200+
201+ nvgBeginPath (ctx);
202+ nvgCircle (ctx, knobPos.x (), knobPos.y (), kr);
203+ nvgStrokeColor (ctx, mTheme ->mBorderDark );
204+ nvgFillPaint (ctx, knob);
205+ nvgStroke (ctx);
206+ nvgFill (ctx);
207+ nvgBeginPath (ctx);
208+ nvgCircle (ctx, knobPos.x (), knobPos.y (), kr/2 );
209+ nvgFillColor (ctx, nanogui::Color (150 , mEnabled ? 255 : 100 ));
210+ nvgStrokePaint (ctx, knobReverse);
211+ nvgStroke (ctx);
212+ nvgFill (ctx);
213+ }
127214}
128215
129216void Slider::save (Serializer &s) const {
0 commit comments