diff --git a/editor/layout/main.fl b/editor/layout/main.fl index 30e3488a..dffc20d7 100644 --- a/editor/layout/main.fl +++ b/editor/layout/main.fl @@ -3,7 +3,7 @@ version 1.0305 header_name {.h} code_name {.cxx} widget_class mainView {open - xywh {572 266 800 475} type Double + xywh {576 416 800 475} type Double class LogicalGroup visible } { Fl_Box {} { @@ -128,7 +128,7 @@ widget_class mainView {open Fl_Dial volumeSlider_ { comment {tag=kTagSetVolume} xywh {680 20 48 48} value 0.5 - class Knob48 + class StyledKnob } Fl_Box volumeLabel_ { label {0.0 dB} @@ -216,12 +216,12 @@ widget_class mainView {open } } } - Fl_Group {subPanels_[kPanelSettings]} {open + Fl_Group {subPanels_[kPanelSettings]} {selected xywh {5 109 790 286} class LogicalGroup } { Fl_Group {} { - label Engine open selected + label Engine open xywh {260 135 280 100} box ROUNDED_BOX labelsize 12 align 17 class TitleGroup } { @@ -279,7 +279,7 @@ widget_class mainView {open Fl_Dial stretchedTuningSlider_ { comment {tag=kTagSetStretchedTuning} xywh {515 315 48 48} value 0.5 - class Knob48 + class StyledKnob } Fl_Box {} { label Stretch diff --git a/editor/src/editor/Editor.cpp b/editor/src/editor/Editor.cpp index 752601f0..ba16d43f 100644 --- a/editor/src/editor/Editor.cpp +++ b/editor/src/editor/Editor.cpp @@ -335,6 +335,9 @@ void Editor::Impl::createFrameContents() CColor iconHighlight; CColor valueText; CColor valueBackground; + CColor knobActiveTrackColor; + CColor knobInactiveTrackColor; + CColor knobLineIndicatorColor; }; Theme lightTheme; @@ -346,6 +349,9 @@ void Editor::Impl::createFrameContents() lightTheme.iconHighlight = { 0xa8, 0x62, 0x34 }; lightTheme.valueText = { 0xff, 0xff, 0xff }; lightTheme.valueBackground = { 0x2e, 0x34, 0x36 }; + lightTheme.knobActiveTrackColor = { 0x00, 0xb6, 0x2a }; + lightTheme.knobInactiveTrackColor = { 0x30, 0x30, 0x30 }; + lightTheme.knobLineIndicatorColor = { 0x00, 0x00, 0x00 }; Theme darkTheme; darkTheme.boxBackground = { 0x2e, 0x34, 0x36 }; darkTheme.text = { 0xff, 0xff, 0xff }; @@ -355,6 +361,9 @@ void Editor::Impl::createFrameContents() darkTheme.iconHighlight = { 0xa8, 0x62, 0x34 }; darkTheme.valueText = { 0x2e, 0x34, 0x36 }; darkTheme.valueBackground = { 0xff, 0xff, 0xff }; + darkTheme.knobActiveTrackColor = { 0x00, 0xb6, 0x2a }; + darkTheme.knobInactiveTrackColor = { 0x60, 0x60, 0x60 }; + darkTheme.knobLineIndicatorColor = { 0xff, 0xff, 0xff }; Theme& defaultTheme = lightTheme; Theme* theme = &defaultTheme; @@ -367,6 +376,7 @@ void Editor::Impl::createFrameContents() typedef CTextLabel Label; typedef CViewContainer HLine; typedef CAnimKnob Knob48; + typedef SStyledKnob StyledKnob; typedef CTextLabel ValueLabel; typedef CViewContainer VMeter; typedef SValueMenu ValueMenu; @@ -426,6 +436,13 @@ void Editor::Impl::createFrameContents() auto createKnob48 = [this, &knob48](const CRect& bounds, int tag, const char*, CHoriTxtAlign, int) { return new CAnimKnob(bounds, this, tag, 31, 48, knob48); }; + auto createStyledKnob = [this, &theme](const CRect& bounds, int tag, const char*, CHoriTxtAlign, int) { + SStyledKnob* knob = new SStyledKnob(bounds, this, tag); + knob->setActiveTrackColor(theme->knobActiveTrackColor); + knob->setInactiveTrackColor(theme->knobInactiveTrackColor); + knob->setLineIndicatorColor(theme->knobLineIndicatorColor); + return knob; + }; auto createValueLabel = [&theme](const CRect& bounds, int, const char* label, CHoriTxtAlign align, int fontsize) { CTextLabel* lbl = new CTextLabel(bounds, label); lbl->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); diff --git a/editor/src/editor/GUIComponents.cpp b/editor/src/editor/GUIComponents.cpp index be9899ef..d3e11b02 100644 --- a/editor/src/editor/GUIComponents.cpp +++ b/editor/src/editor/GUIComponents.cpp @@ -5,6 +5,7 @@ // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #include "GUIComponents.h" +#include #include #include "utility/vstgui_before.h" @@ -428,6 +429,7 @@ void SValueMenu::onItemClicked(int32_t index) valueChanged(); } +/// void STextButton::setHoverColor (const CColor& color) { hoverColor_ = color; @@ -458,3 +460,93 @@ CMouseEventResult STextButton::onMouseExited (CPoint& where, const CButtonState& setDirty(); return CTextButton::onMouseExited(where, buttons); } + +/// +SStyledKnob::SStyledKnob(const CRect& size, IControlListener* listener, int32_t tag) + : CKnobBase(size, listener, tag, nullptr) +{ +} + +void SStyledKnob::setActiveTrackColor(const CColor& color) +{ + if (activeTrackColor_ == color) + return; + activeTrackColor_ = color; + setDirty(); +} + +void SStyledKnob::setInactiveTrackColor(const CColor& color) +{ + if (inactiveTrackColor_ == color) + return; + inactiveTrackColor_ = color; + setDirty(); +} + +void SStyledKnob::setLineIndicatorColor(const CColor& color) +{ + if (lineIndicatorColor_ == color) + return; + lineIndicatorColor_ = color; + setDirty(); +} + +void SStyledKnob::draw(CDrawContext* dc) +{ + const CCoord lineWidth = 4.0; + const CCoord indicatorLineLength = 10.0; + const CCoord angleSpread = 250.0; + const CCoord angle1 = 270.0 - 0.5 * angleSpread; + const CCoord angle2 = 270.0 + 0.5 * angleSpread; + + dc->setDrawMode(kAntiAliasing); + + const CRect bounds = getViewSize(); + + // compute inner bounds + CRect rect(bounds); + rect.setWidth(std::min(rect.getWidth(), rect.getHeight())); + rect.setHeight(rect.getWidth()); + rect.centerInside(bounds); + rect.extend(-lineWidth, -lineWidth); + + SharedPointer path; + + // inactive track + path = owned(dc->createGraphicsPath()); + path->addArc(rect, angle1, angle2, true); + + dc->setFrameColor(inactiveTrackColor_); + dc->setLineWidth(lineWidth); + dc->setLineStyle(kLineSolid); + dc->drawGraphicsPath(path, CDrawContext::kPathStroked); + + // active track + const CCoord v = getValueNormalized(); + const CCoord vAngle = angle1 + v * angleSpread; + path = owned(dc->createGraphicsPath()); + path->addArc(rect, angle1, vAngle, true); + + dc->setFrameColor(activeTrackColor_); + dc->setLineWidth(lineWidth + 0.5); + dc->setLineStyle(kLineSolid); + dc->drawGraphicsPath(path, CDrawContext::kPathStroked); + + // indicator line + { + CCoord module1 = 0.5 * rect.getWidth() - indicatorLineLength; + CCoord module2 = 0.5 * rect.getWidth(); + std::complex c1 = std::polar(module1, vAngle * (M_PI / 180.0)); + std::complex c2 = std::polar(module2, vAngle * (M_PI / 180.0)); + + CPoint p1(c1.real(), c1.imag()); + CPoint p2(c2.real(), c2.imag()); + p1.offset(rect.getCenter()); + p2.offset(rect.getCenter()); + + dc->setFrameColor(lineIndicatorColor_); + dc->setLineWidth(1.0); + dc->setLineStyle(kLineSolid); + dc->drawLine(p1, p2); + } +} diff --git a/editor/src/editor/GUIComponents.h b/editor/src/editor/GUIComponents.h index e0f3b173..c9afccba 100644 --- a/editor/src/editor/GUIComponents.h +++ b/editor/src/editor/GUIComponents.h @@ -162,3 +162,25 @@ private: CColor hoverColor_; bool hovered { false }; }; + +/// +class SStyledKnob : public CKnobBase { +public: + SStyledKnob(const CRect& size, IControlListener* listener, int32_t tag); + + const CColor& getActiveTrackColor() const { return activeTrackColor_; } + void setActiveTrackColor(const CColor& color); + const CColor& getInactiveTrackColor() const { return inactiveTrackColor_; } + void setInactiveTrackColor(const CColor& color); + const CColor& getLineIndicatorColor() const { return lineIndicatorColor_; } + void setLineIndicatorColor(const CColor& color); + + CLASS_METHODS(SStyledKnob, CKnobBase) +protected: + void draw(CDrawContext* dc) override; + +private: + CColor activeTrackColor_; + CColor inactiveTrackColor_; + CColor lineIndicatorColor_; +}; diff --git a/editor/src/editor/layout/main.hpp b/editor/src/editor/layout/main.hpp index 18a413a5..af348d36 100644 --- a/editor/src/editor/layout/main.hpp +++ b/editor/src/editor/layout/main.hpp @@ -58,7 +58,7 @@ view__24->setVisible(false); ValueLabel* const view__25 = createValueLabel(CRect(40, 65, 100, 70), -1, "Center", kCenterText, 12); view__23->addView(view__25); view__25->setVisible(false); -Knob48* const view__26 = createKnob48(CRect(110, 15, 158, 63), kTagSetVolume, "", kCenterText, 14); +StyledKnob* const view__26 = createStyledKnob(CRect(110, 15, 158, 63), kTagSetVolume, "", kCenterText, 14); volumeSlider_ = view__26; view__23->addView(view__26); ValueLabel* const view__27 = createValueLabel(CRect(105, 65, 165, 87), -1, "0.0 dB", kCenterText, 12); @@ -135,7 +135,7 @@ tuningFrequencySlider_ = view__54; view__52->addView(view__54); ValueLabel* const view__55 = createValueLabel(CRect(210, 20, 290, 45), -1, "Frequency", kCenterText, 12); view__52->addView(view__55); -Knob48* const view__56 = createKnob48(CRect(310, 45, 358, 93), kTagSetStretchedTuning, "", kCenterText, 14); +StyledKnob* const view__56 = createStyledKnob(CRect(310, 45, 358, 93), kTagSetStretchedTuning, "", kCenterText, 14); stretchedTuningSlider_ = view__56; view__52->addView(view__56); ValueLabel* const view__57 = createValueLabel(CRect(295, 20, 375, 45), -1, "Stretch", kCenterText, 12);