From c03a5dc63507933d77a70591bfee58a7e2696b29 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Sun, 28 Feb 2021 07:32:16 +0100 Subject: [PATCH] Labeled CC knobs --- plugins/editor/layout/main.fl | 4 +- plugins/editor/src/editor/Editor.cpp | 8 + plugins/editor/src/editor/GUIComponents.cpp | 207 +++++++++++++++----- plugins/editor/src/editor/GUIComponents.h | 51 ++++- 4 files changed, 213 insertions(+), 57 deletions(-) diff --git a/plugins/editor/layout/main.fl b/plugins/editor/layout/main.fl index d1e5a1abb..b6d7510cc 100644 --- a/plugins/editor/layout/main.fl +++ b/plugins/editor/layout/main.fl @@ -20,7 +20,7 @@ widget_class mainView {open class RoundedGroup } { Fl_Box {} { - comment {tag=kTagFirstChangePanel+kPanelGeneral} selected + comment {tag=kTagFirstChangePanel+kPanelGeneral} image {../resources/logo_text_shaded.png} xywh {35 9 120 60} class SfizzMainButton } @@ -121,7 +121,7 @@ widget_class mainView {open class ChevronValueDropDown } } - Fl_Group {} {open + Fl_Group {} {open selected xywh {570 5 225 100} box ROUNDED_BOX class RoundedGroup } { diff --git a/plugins/editor/src/editor/Editor.cpp b/plugins/editor/src/editor/Editor.cpp index e721a0ee9..09b0d31ba 100644 --- a/plugins/editor/src/editor/Editor.cpp +++ b/plugins/editor/src/editor/Editor.cpp @@ -824,6 +824,14 @@ void Editor::Impl::createFrameContents() menu->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); return menu; }; + auto createKnobCCBox = [this, &theme](const CRect& bounds, int tag, const char* label, CHoriTxtAlign, int) { + SKnobCCBox* box = new SKnobCCBox(bounds, this, tag); + box->setNameLabelText(label); + box->setNameLabelFontColor(theme->text); + box->setKnobFontColor(theme->text); + box->setKnobLineIndicatorColor(theme->knobLineIndicatorColor); + return box; + }; auto createBackground = [&background](const CRect& bounds, int, const char*, CHoriTxtAlign, int) { CViewContainer* container = new CViewContainer(bounds); container->setBackground(background); diff --git a/plugins/editor/src/editor/GUIComponents.cpp b/plugins/editor/src/editor/GUIComponents.cpp index c0025af08..73f7c3020 100644 --- a/plugins/editor/src/editor/GUIComponents.cpp +++ b/plugins/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 "ColorHelpers.h" #include #include @@ -488,10 +489,32 @@ void SStyledKnob::setLineIndicatorColor(const CColor& color) invalid(); } +void SStyledKnob::setFont(CFontRef font) +{ + if (font_ == font) + return; + font_ = font; + invalid(); +} + +void SStyledKnob::setFontColor(CColor fontColor) +{ + if (fontColor_ == fontColor) + return; + fontColor_ = fontColor; + invalid(); +} + +void SStyledKnob::setValueToStringFunction(ValueToStringFunction func) +{ + valueToStringFunction_ = std::move(func); + invalid(); +} + void SStyledKnob::draw(CDrawContext* dc) { const CCoord lineWidth = 4.0; - const CCoord indicatorLineLength = 10.0; + const CCoord indicatorLineLength = 8.0; const CCoord angleSpread = 250.0; const CCoord angle1 = 270.0 - 0.5 * angleSpread; const CCoord angle2 = 270.0 + 0.5 * angleSpread; @@ -546,6 +569,106 @@ void SStyledKnob::draw(CDrawContext* dc) dc->setLineStyle(kLineSolid); dc->drawLine(p1, p2); } + + if (valueToStringFunction_ && fontColor_.alpha > 0) { + std::string text; + if (valueToStringFunction_(getValue(), text)) { + dc->setFont(font_); + dc->setFontColor(fontColor_); + dc->drawString(text.c_str(), bounds); + } + } +} + +/// +SKnobCCBox::SKnobCCBox(const CRect& size, IControlListener* listener, int32_t tag) + : CViewContainer(size), + label_(makeOwned(CRect())), + knob_(makeOwned(CRect(), listener, tag)), + ccLabel_(makeOwned(CRect())) +{ + setBackgroundColor(CColor(0x00, 0x00, 0x00, 0x00)); + + label_->setText("Parameter"); + label_->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label_->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label_->setFontColor(CColor(0x00, 0x00, 0x00, 0xff)); + + knob_->setLineIndicatorColor(CColor(0x00, 0x00, 0x00, 0xff)); + + ccLabel_->setText("CC 1"); + ccLabel_->setStyle(CParamDisplay::kRoundRectStyle); + ccLabel_->setRoundRectRadius(5.0); + ccLabel_->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + ccLabel_->setFontColor(CColor(0xff, 0xff, 0xff)); + + addView(label_); + label_->remember(); + addView(knob_); + knob_->remember(); + addView(ccLabel_); + ccLabel_->remember(); + + updateViewColors(); + updateViewSizes(); +} + +void SKnobCCBox::setHue(float hue) +{ + hue_ = hue; + updateViewColors(); +} + +void SKnobCCBox::setNameLabelFont(CFontRef font) +{ + label_->setFont(font); + updateViewSizes(); +} + +void SKnobCCBox::setCCLabelFont(CFontRef font) +{ + ccLabel_->setFont(font); + updateViewSizes(); +} + +void SKnobCCBox::updateViewSizes() +{ + const CRect size = getViewSize(); + const CCoord ypad = 4.0; + + const CFontRef nameFont = ccLabel_->getFont(); + const CFontRef ccFont = ccLabel_->getFont(); + + nameLabelSize_ = CRect(0.0, 0.0, size.getWidth(), nameFont->getSize() + 2 * ypad); + ccLabelSize_ = CRect(0.0, size.bottom - ccFont->getSize() - 2 * ypad, size.getWidth(), size.bottom); + knobSize_ = CRect(0.0, nameLabelSize_.bottom, size.getWidth(), ccLabelSize_.top); + + // remove knob side areas + CCoord side = std::max(0.0, knobSize_.getWidth() - knobSize_.getHeight()); + knobSize_.extend(-0.5 * side, 0.0); + + // + label_->setViewSize(nameLabelSize_); + knob_->setViewSize(knobSize_); + ccLabel_->setViewSize(ccLabelSize_); + + invalid(); +} + +void SKnobCCBox::updateViewColors() +{ + const float knobLuma = 0.4; + const float ccLuma = 0.25; + + SColorHCY knobActiveTrackColor { hue_, 1.0, knobLuma }; + SColorHCY knobInactiveTrackColor { 0.0, 0.0, knobLuma }; + knob_->setActiveTrackColor(knobActiveTrackColor.toColor()); + knob_->setInactiveTrackColor(knobInactiveTrackColor.toColor()); + + SColorHCY ccLabelColor { hue_, 1.0, ccLuma }; + ccLabel_->setBackColor(ccLabelColor.toColor()); + + invalid(); } /// @@ -579,7 +702,8 @@ void SControlsPanel::setControlUsed(uint32_t index, bool used) std::string SControlsPanel::getDefaultLabelText(uint32_t index) { - return "CC " + std::to_string(index); + (void)index; + return {}; } SControlsPanel::ControlSlot* SControlsPanel::getSlot(uint32_t index) @@ -602,42 +726,15 @@ SControlsPanel::ControlSlot* SControlsPanel::getOrCreateSlot(uint32_t index) slot = new ControlSlot; slots_[index].reset(slot); - // create controls etc... - CCoord knobWidth = 48.0; - CCoord knobHeight = knobWidth; - CCoord labelWidth = 96.0; - CCoord labelHeight = 24.0; - CCoord verticalPadding = 0.0; - - CCoord totalWidth = std::max(knobWidth, labelWidth); - CCoord knobX = (totalWidth - knobWidth) / 2.0; - CCoord labelX = (totalWidth - labelWidth) / 2.0; - - CRect knobBounds(knobX, 0.0, knobX + knobWidth, knobHeight); - CRect labelBounds(labelX, knobHeight + verticalPadding, labelX + labelWidth, knobHeight + verticalPadding + labelHeight); - CRect boxBounds = CRect(knobBounds).unite(labelBounds); - - SharedPointer knob = owned(new SStyledKnob(knobBounds, listener_.get(), index)); - SharedPointer label = owned(new CTextLabel(labelBounds)); - SharedPointer box = owned(new CViewContainer(boxBounds)); - - box->addView(knob); - knob->remember(); - box->addView(label); - label->remember(); - - box->setBackgroundColor(CColor(0x00, 0x00, 0x00, 0x00)); - label->setStyle(CTextLabel::kRoundRectStyle); - label->setRoundRectRadius(5.0); - label->setBackColor(CColor(0x2e, 0x34, 0x36)); - label->setText(getDefaultLabelText(index)); - knob->setActiveTrackColor(CColor(0x00, 0xb6, 0x2a)); - knob->setInactiveTrackColor(CColor(0x30, 0x30, 0x30)); - knob->setLineIndicatorColor(CColor(0x00, 0x00, 0x00)); - - slot->knob = knob; - slot->label = label; + CRect boxSize { 0.0, 0.0, 120.0, 90.0 }; + SharedPointer box = makeOwned(boxSize, listener_.get(), index); slot->box = box; + slot->box->setCCLabelText(("CC " + std::to_string(index)).c_str()); + + slot->box->setValueToStringFunction([](float value, std::string& text) -> bool { + text = std::to_string(std::lround(value * 127)); + return true; + }); return slot; } @@ -645,27 +742,27 @@ SControlsPanel::ControlSlot* SControlsPanel::getOrCreateSlot(uint32_t index) void SControlsPanel::setControlValue(uint32_t index, float value) { ControlSlot* slot = getOrCreateSlot(index); - CControl* knob = slot->knob; - knob->setValue(value); - knob->invalid(); + SKnobCCBox* box = slot->box; + box->getControl()->setValue(value); + box->invalid(); } void SControlsPanel::setControlDefaultValue(uint32_t index, float value) { ControlSlot* slot = getOrCreateSlot(index); - CControl* knob = slot->knob; - knob->setDefaultValue(value); + SKnobCCBox* box = slot->box; + box->getControl()->setDefaultValue(value); } void SControlsPanel::setControlLabelText(uint32_t index, UTF8StringPtr text) { ControlSlot* slot = getOrCreateSlot(index); - CTextLabel* label = slot->label; + SKnobCCBox* box = slot->box; if (text && text[0] != '\0') - label->setText(text); + box->setNameLabelText(text); else - label->setText(getDefaultLabelText(index).c_str()); - label->invalid(); + box->setNameLabelText(getDefaultLabelText(index).c_str()); + box->invalid(); } void SControlsPanel::recalculateSubViews() @@ -693,8 +790,10 @@ void SControlsPanel::updateLayout() CCoord itemOffsetX {}; int numColumns {}; - const CCoord horizontalPadding = 24.0; - const CCoord verticalPadding = 18.0; + const CCoord horizontalPadding = 4.0; + CCoord verticalPadding = 4.0; + CCoord interRowPadding = {}; + CCoord interColumnPadding = 8.0; int currentRow = 0; int currentColumn = 0; @@ -713,16 +812,20 @@ void SControlsPanel::updateLayout() itemHeight = box->getHeight(); isFirstSlot = false; numColumns = int((viewBounds.getWidth() - horizontalPadding) / - (itemWidth + horizontalPadding)); + (itemWidth + interColumnPadding)); numColumns = std::max(1, numColumns); itemOffsetX = (viewBounds.getWidth() - horizontalPadding - - numColumns * (itemWidth + horizontalPadding)) / 2.0; + numColumns * (itemWidth + interColumnPadding)) / 2.0; + + int maxRowsShown = int((viewBounds.getHeight() - 2 * verticalPadding) / itemHeight); + if (maxRowsShown > 1) + interRowPadding = (viewBounds.getHeight() - 2 * verticalPadding - itemHeight * maxRowsShown) / (maxRowsShown - 1); } CRect itemBounds = box->getViewSize(); itemBounds.moveTo( - itemOffsetX + horizontalPadding + currentColumn * (horizontalPadding + itemWidth), - verticalPadding + currentRow * (verticalPadding + itemHeight)); + itemOffsetX + horizontalPadding + currentColumn * (interColumnPadding + itemWidth), + verticalPadding + currentRow * (interRowPadding + itemHeight)); box->setViewSize(itemBounds); diff --git a/plugins/editor/src/editor/GUIComponents.h b/plugins/editor/src/editor/GUIComponents.h index b7de29ff3..a890b3ed7 100644 --- a/plugins/editor/src/editor/GUIComponents.h +++ b/plugins/editor/src/editor/GUIComponents.h @@ -215,6 +215,14 @@ class SStyledKnob : public CKnobBase { const CColor& getLineIndicatorColor() const { return lineIndicatorColor_; } void setLineIndicatorColor(const CColor& color); + void setFont(CFontRef font); + CFontRef getFont() const { return font_; } + void setFontColor(CColor fontColor); + CColor getFontColor() const { return fontColor_; } + + using ValueToStringFunction = std::function; + void setValueToStringFunction(ValueToStringFunction func); + CLASS_METHODS(SStyledKnob, CKnobBase) protected: void draw(CDrawContext* dc) override; @@ -223,6 +231,45 @@ class SStyledKnob : public CKnobBase { CColor activeTrackColor_; CColor inactiveTrackColor_; CColor lineIndicatorColor_; + + SharedPointer font_ = kNormalFont; + CColor fontColor_ { 0x00, 0x00, 0x00 }; + + ValueToStringFunction valueToStringFunction_; +}; + +/// +class SKnobCCBox : public CViewContainer { +public: + SKnobCCBox(const CRect& size, IControlListener* listener, int32_t tag); + void setHue(float hue); + SStyledKnob* getControl() const { return knob_; } + + void setNameLabelText(const UTF8String& name) { label_->setText(name); } + void setNameLabelFont(CFontRef font); + void setNameLabelFontColor(CColor color) { label_->setFontColor(color); } + void setCCLabelText(const UTF8String& name) { ccLabel_->setText(name); } + void setCCLabelFont(CFontRef font); + void setCCLabelFontColor(CColor color) { ccLabel_->setFontColor(color); } + void setKnobLineIndicatorColor(CColor color) { knob_->setLineIndicatorColor(color); } + void setKnobFont(CFontRef font) { knob_->setFont(font); } + void setKnobFontColor(CColor color) { knob_->setFontColor(color); } + + using ValueToStringFunction = SStyledKnob::ValueToStringFunction; + void setValueToStringFunction(ValueToStringFunction f) { knob_->setValueToStringFunction(std::move(f)); } + +private: + void updateViewSizes(); + void updateViewColors(); + +private: + SharedPointer label_; + SharedPointer knob_; + SharedPointer ccLabel_; + CRect nameLabelSize_; + CRect knobSize_; + CRect ccLabelSize_; + float hue_ = 0.35; }; /// @@ -253,9 +300,7 @@ class SControlsPanel : public CScrollView { private: struct ControlSlot { bool used = false; - SharedPointer knob; - SharedPointer label; - SharedPointer box; + SharedPointer box; }; class ControlSlotListener : public IControlListener {