StoneyVCV v2
StoneyDSP Modules for VCV Rack 2.
Loading...
Searching...
No Matches
RoundKnobWidget.hpp
Go to the documentation of this file.
1
31#pragma once
32
33#define STONEYVCV_COMPONENTLIBRARY_ROUNDKNOB_HPP_INCLUDED 1
34
35#if defined (STONEYVCV_BUILD_COMPONENTLIBRARY)
36
37//==============================================================================
38
39#include <StoneyVCV.hpp>
43
44//==============================================================================
45
46#include <rack.hpp>
47#include <StoneyDSP/Core.hpp>
48
49//==============================================================================
50
51#include <string>
52
53//==============================================================================
54
55namespace StoneyDSP
56{
61//==============================================================================
62
63namespace StoneyVCV
64{
69//==============================================================================
70
71namespace ComponentLibrary
72{
77//==============================================================================
78
84{
85
86 //==========================================================================
87
88public:
89
90 //==========================================================================
91
93
94 //==========================================================================
95
97 : ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedParamPanelWidget(),
98 minAngle(0.0F),
99 maxAngle(0.0F)
100 {
101 DBG("Constructing StoneyVCV::ComponentLibrary::ThemedRoundKnobPanelWidget");
102
103 this->minAngle = (0.0F - (5.0F / 6.0F)) * M_PI;
104 this->maxAngle = (5.0F / 6.0F) * M_PI;
105 this->leading = (4.0F);
106 }
107
109 {
110 DBG("Destroying StoneyVCV::ComponentLibrary::ThemedRoundKnobPanelWidget");
111 assert(!this->parent);
112
113 this->clearChildren();
114 }
115
116 //==========================================================================
117
118 virtual void step() override
119 {
120 return ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedParamPanelWidget::step();
121 }
122
123 float radiansToDegrees(const float &radians)
124 {
125 return radians * (180.0F / M_PI);
126 }
127
128 ::rack::math::Vec radiusToXY(const float &radius, float angle, float rotation = 0.0F)
129 {
130 const float theta = (angle + rotation) * (M_PI / 180.0F);
131
132 return ::rack::math::Vec(
133 radius * ::std::cos(theta),
134 -radius * ::std::sin(theta)
135 );
136 }
137
138 virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedRoundKnobPanelWidget::DrawArgs &args) override
139 {
140 const bool &prefersDarkPanels = this->getPrefersDarkPanels();
141 const auto &size = this->getSize();
142
143 const auto &minAngle = this->getMinAngle();
144 const auto &maxAngle = this->getMaxAngle();
145 const auto &leading = this->getLeading();
146
147 // For debugging the bounding box of the widget
149 // const auto &borderColor = ::StoneyDSP::StoneyVCV::Panels::borderColor;
151 const auto &fontSize = this->getFontSize();
152
153 // Load font from cache
154 ::std::shared_ptr<::rack::window::Font> font = APP->window->loadFont(
155 ::rack::asset::system("res/fonts/DejaVuSans.ttf"
156 )
157 );
158
159 // Don't draw text if font failed to load
160 if (font) {
161 // ::nvgBeginPath(args.vg);
162 // Select font handle
163 ::nvgFontFaceId(args.vg, font->handle);
164
165 // Set font size and alignment
166 ::nvgFontSize(args.vg, fontSize);
167 ::nvgTextAlign(args.vg,
168 ::NVGalign::NVG_ALIGN_CENTER | ::NVGalign::NVG_ALIGN_BASELINE
169 );
170 ::nvgFillColor(args.vg, textColor);
171
172 // Draw the text at a position
173 ::nvgText(args.vg,
174 (size.x * 0.5F),
175 0.0F - (fontSize), // font size / 2
176 this->getLabelText().c_str(),
177 NULL
178 );
179 }
180
181 ::nvgBeginPath(args.vg);
182 ::nvgLineCap(args.vg, NVG_ROUND); // set rounded lines
183 ::nvgLineJoin(args.vg, NVG_ROUND); // set the line join to round corners
184
185 float radius = (size.x * 0.5F) + leading;
186 float rotationOffset = -M_PI / 2.0F; // Knob Widgets are actually rotated -90 degress in rads
187
188 // Draw knob ring
189 ::nvgArc(args.vg,
190 (size.x * 0.5F), // knob ring centre x
191 (size.y * 0.5F), // knob ring center y
192 radius, // knob ring diameter
193 (minAngle + rotationOffset), // knob ring start position
194 (maxAngle + rotationOffset), // knob ring end position
195 NVG_CW // knob ring direction
196 );
197
198 // reset cursor
199 ::nvgMoveTo(args.vg,
200 size.x * 0.5F,
201 size.y * 0.5F
202 );
203
208
219
220 ::std::vector<::rack::math::Vec> ranges;
221
222 ranges.reserve(3);
223
224 // ranges = {
225 // // rangeStart, rangeEnd
226 // this->radiusToXY(radius, this->radiansToDegrees(this->minAngle - rotationOffset)),
227 // // this->radiusToXY(radius, 0.0F),
228 // // this->radiusToXY(radius, 45.0F),
229 // // this->radiusToXY(radius, 90.0F),
230 // // this->radiusToXY(radius, 180.0F),
231 // // this->radiusToXY(radius, 270.0F),
232 // this->radiusToXY(radius, this->radiansToDegrees(this->maxAngle - rotationOffset))
233 // };
234
235 ranges.emplace_back(
236 this->radiusToXY(radius, this->radiansToDegrees(this->minAngle - rotationOffset))
237 );
238
239 if(this->isBipolar)
240 ranges.emplace_back(
241 // this->radiusToXY(
242 // radius,
243 // this->radiansToDegrees(this->minAngle - rotationOffset) - this->radiansToDegrees(this->maxAngle - rotationOffset)
244 // )
245 this->radiusToXY(radius, 90.0F)
246 );
247
248 ranges.emplace_back(
249 this->radiusToXY(radius, this->radiansToDegrees(this->maxAngle - rotationOffset))
250
251 );
252
253 // Draw ranges as lines from the knob centre-point to the outer radius (includes leading)
254 for(const auto &range : ranges) {
255 ::nvgLineTo(args.vg,
256 (size.x * 0.5F) + range.x,
257 (size.y * 0.5F) + range.y
258 );
259 ::nvgMoveTo(args.vg,
260 size.x * 0.5F,
261 size.y * 0.5F
262 );
263 }
264
265 // Draw ranges as lines
266 ::nvgStrokeWidth(args.vg, (5.0F / 6.0F));
267 ::nvgStrokeColor(args.vg, bgColor);
268 ::nvgStroke(args.vg);
269 ::nvgClosePath(args.vg);
270
271 return ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedParamPanelWidget::draw(args);
272 }
273
274 //==========================================================================
275
276 virtual void setMinAngle(const float &newMinAngle)
277 {
278 this->minAngle = newMinAngle;
279 }
280
281 virtual const float &getMinAngle() const noexcept
282 {
283 return this->minAngle;
284 }
285
286 //==========================================================================
287
288 virtual void setMaxAngle(const float &newMaxAngle)
289 {
290 this->maxAngle = newMaxAngle;
291 }
292
293 virtual const float &getMaxAngle() const noexcept
294 {
295 return this->maxAngle;
296 }
297
298 //==========================================================================
299
300protected:
301
302 //==========================================================================
303
304 float minAngle = (0.0F - (5.0F / 6.0F)) * M_PI; // -0.8333... * pi
305 float maxAngle = (5.0F / 6.0F) * M_PI; // +0.8333... * pi
306
307 //==========================================================================
308
309private:
310
311 //==========================================================================
312
315};
316
317//==============================================================================
318
319struct RoundKnob : virtual ::rack::app::SvgKnob
320{
322 : ::rack::app::SvgKnob(),
323 bg(nullptr)
324 {
325 this->minAngle = (0.0F - (5.0F / 6.0F)) * M_PI; // -0.83 * pi
326 this->maxAngle = (5.0F / 6.0F) * M_PI; // 0.83 * pi
327
328 this->bg = new ::rack::widget::SvgWidget;
329 this->fb->addChildBelow(this->bg, this->tw);
330 }
331
333 {
334 assert(!this->parent);
335
336 this->clearChildren();
337 }
338
340 ::rack::widget::SvgWidget* bg = NULL;
341
342private:
343
346};
347
348//==============================================================================
349
350struct RoundBlackKnob : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob
351{
352public:
353
355 : ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob()
356 {
357
358 this->setSvg(
359 ::rack::window::Svg::load(
360 ::rack::asset::system(
361 "res/ComponentLibrary/RoundBlackKnob.svg"
362 )
363 )
364 );
365
366 this->bg->setSvg(
367 ::rack::window::Svg::load(
368 ::rack::asset::system(
369 "res/ComponentLibrary/RoundBlackKnob_bg.svg"
370 )
371 )
372 );
373
374 }
375
377 {
378 assert(!this->parent);
379
380 this->clearChildren();
381 }
382
383private:
384
387};
388
389
390struct RoundSmallBlackKnob : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob
391{
392
393public:
394
396 : ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob()
397 {
398 this->setSvg(
399 ::rack::window::Svg::load(
400 ::rack::asset::system(
401 "res/ComponentLibrary/RoundSmallBlackKnob.svg"
402 )
403 )
404 );
405
406 this->bg->setSvg(
407 ::rack::window::Svg::load(
408 ::rack::asset::system(
409 "res/ComponentLibrary/RoundSmallBlackKnob_bg.svg"
410 )
411 )
412 );
413 }
414
416 {
417 assert(!this->parent);
418
419 this->clearChildren();
420 }
421
422private:
423
426};
427
428struct RoundLargeBlackKnob : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob
429{
430
431public:
432
434 : ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob()
435 {
436 this->setSvg(
437 ::rack::window::Svg::load(
438 ::rack::asset::system(
439 "res/ComponentLibrary/RoundLargeBlackKnob.svg"
440 )
441 )
442 );
443
444 this->bg->setSvg(
445 ::rack::window::Svg::load(
446 ::rack::asset::system(
447 "res/ComponentLibrary/RoundLargeBlackKnob_bg.svg"
448 )
449 )
450 );
451 }
452
454 {
455 assert(!this->parent);
456
457 this->clearChildren();
458 }
459
460private:
461
464};
465
466struct RoundBigBlackKnob : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob
467{
468
469public:
470
472 : ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob()
473 {
474 this->setSvg(
475 ::rack::window::Svg::load(
476 ::rack::asset::system(
477 "res/ComponentLibrary/RoundBigBlackKnob.svg"
478 )
479 )
480 );
481
482 this->bg->setSvg(
483 ::rack::window::Svg::load(
484 ::rack::asset::system(
485 "res/ComponentLibrary/RoundBigBlackKnob_bg.svg"
486 )
487 )
488 );
489 }
490
492 {
493 assert(!this->parent);
494
495 this->clearChildren();
496 }
497
498private:
499
502};
503
504struct RoundHugeBlackKnob : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob
505{
506
507public:
508
510 : ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob()
511 {
512 this->setSvg(
513 ::rack::window::Svg::load(
514 ::rack::asset::system(
515 "res/ComponentLibrary/RoundHugeBlackKnob.svg"
516 )
517 )
518 );
519
520 this->bg->setSvg(
521 ::rack::window::Svg::load(
522 ::rack::asset::system(
523 "res/ComponentLibrary/RoundHugeBlackKnob_bg.svg"
524 )
525 )
526 );
527 }
528
530 {
531 assert(!this->parent);
532
533 this->clearChildren();
534 }
535
536private:
537
540};
541
542struct RoundBlackSnapKnob : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob
543{
544
545public:
546
548 : ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob()
549 {
550 snap = true;
551 }
552
554 {
555 assert(!this->parent);
556
557 this->clearChildren();
558 }
559
560private:
561
564};
565
566struct Trimpot : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob
567{
568public:
569
571 : ::StoneyDSP::StoneyVCV::ComponentLibrary::RoundKnob()
572 {
573 this->minAngle = -0.75 * M_PI;
574 this->maxAngle = 0.75 * M_PI;
575
576 this->setSvg(
577 ::rack::Svg::load(
578 ::rack::asset::system(
579 "res/ComponentLibrary/Trimpot.svg"
580 )
581 )
582 );
583 this->bg->setSvg(
584 ::rack::Svg::load(
585 ::rack::asset::system(
586 "res/ComponentLibrary/Trimpot_bg.svg"
587 )
588 )
589 );
590 }
591
593 {
594 assert(!this->parent);
595
596 this->clearChildren();
597 }
598
599private:
600
603};
604
605//==============================================================================
606
608} // namespace ComponentLibrary
609
610//==============================================================================
611
613} // namespace StoneyVCV
614
615//==============================================================================
616
618} // namespace StoneyDSP
619
620//==============================================================================
621
622#endif // STONEYVCV_BUILD_COMPONENTLIBRARY
623
624//==============================================================================
StoneyDSP Modules for VCV Rack 2.
StoneyDSP Modules for VCV Rack 2.
#define DBG(msg,...)
Definition StoneyVCV.hpp:46
StoneyDSP Modules for VCV Rack 2.
const ::NVGcolor bgPortLight
const ::NVGcolor bgPortDark
The StoneyDSP namespace.
Definition StoneyVCV.hpp:78
RoundBigBlackKnob()
Definition RoundKnobWidget.hpp:471
virtual ~RoundBigBlackKnob() noexcept
Definition RoundKnobWidget.hpp:491
RoundBlackKnob()
Definition RoundKnobWidget.hpp:354
virtual ~RoundBlackKnob() noexcept
Definition RoundKnobWidget.hpp:376
RoundBlackSnapKnob()
Definition RoundKnobWidget.hpp:547
virtual ~RoundBlackSnapKnob() noexcept
Definition RoundKnobWidget.hpp:553
RoundHugeBlackKnob()
Definition RoundKnobWidget.hpp:509
virtual ~RoundHugeBlackKnob() noexcept
Definition RoundKnobWidget.hpp:529
Definition RoundKnobWidget.hpp:320
RoundKnob()
Definition RoundKnobWidget.hpp:321
virtual ~RoundKnob() noexcept
Definition RoundKnobWidget.hpp:332
RoundLargeBlackKnob()
Definition RoundKnobWidget.hpp:433
virtual ~RoundLargeBlackKnob() noexcept
Definition RoundKnobWidget.hpp:453
virtual ~RoundSmallBlackKnob() noexcept
Definition RoundKnobWidget.hpp:415
RoundSmallBlackKnob()
Definition RoundKnobWidget.hpp:395
The ThemedParamPanelWidget struct.
Definition ParamWidget.hpp:85
virtual const bool & getPrefersDarkPanels() const noexcept
::StoneyDSP::StoneyVCV::ComponentLibrary::TransparentWidget::DrawArgs DrawArgs
Definition ParamWidget.hpp:93
virtual const float & getFontSize() const noexcept
virtual const float & getMinAngle() const noexcept
Definition RoundKnobWidget.hpp:281
virtual void setMaxAngle(const float &newMaxAngle)
Definition RoundKnobWidget.hpp:288
virtual void step() override
Advances the ThemedParamPanelWidget by one frame.
Definition RoundKnobWidget.hpp:118
virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedRoundKnobPanelWidget::DrawArgs &args) override
Renders the ThemedParamPanelWidget to the NanoVG context.
Definition RoundKnobWidget.hpp:138
virtual const float & getMaxAngle() const noexcept
Definition RoundKnobWidget.hpp:293
virtual void setMinAngle(const float &newMinAngle)
Definition RoundKnobWidget.hpp:276
virtual ~ThemedRoundKnobPanelWidget() noexcept
Definition RoundKnobWidget.hpp:108
::rack::math::Vec radiusToXY(const float &radius, float angle, float rotation=0.0F)
Definition RoundKnobWidget.hpp:128
::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedParamPanelWidget::DrawArgs DrawArgs
Definition RoundKnobWidget.hpp:92
float radiansToDegrees(const float &radians)
Definition RoundKnobWidget.hpp:123
Definition RoundKnobWidget.hpp:567
Trimpot()
Definition RoundKnobWidget.hpp:570
virtual ~Trimpot() noexcept
Definition RoundKnobWidget.hpp:592
::rack::Widget * parent
Automatically set when Widget is added as a child to another Widget.
Definition Widget.hpp:188
Definition StoneyVCV.hpp:125