Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Labeled CC knobs #673

Merged
merged 1 commit into from
Feb 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions plugins/editor/layout/main.fl
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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
} {
Expand Down
8 changes: 8 additions & 0 deletions plugins/editor/src/editor/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
207 changes: 155 additions & 52 deletions plugins/editor/src/editor/GUIComponents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz

#include "GUIComponents.h"
#include "ColorHelpers.h"
#include <complex>
#include <cmath>

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<CTextLabel>(CRect())),
knob_(makeOwned<SStyledKnob>(CRect(), listener, tag)),
ccLabel_(makeOwned<CTextLabel>(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();
}

///
Expand Down Expand Up @@ -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)
Expand All @@ -602,70 +726,43 @@ 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<SStyledKnob> knob = owned(new SStyledKnob(knobBounds, listener_.get(), index));
SharedPointer<CTextLabel> label = owned(new CTextLabel(labelBounds));
SharedPointer<CViewContainer> 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<SKnobCCBox> box = makeOwned<SKnobCCBox>(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;
}

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()
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand Down
51 changes: 48 additions & 3 deletions plugins/editor/src/editor/GUIComponents.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool(float value, std::string& result)>;
void setValueToStringFunction(ValueToStringFunction func);

CLASS_METHODS(SStyledKnob, CKnobBase)
protected:
void draw(CDrawContext* dc) override;
Expand All @@ -223,6 +231,45 @@ class SStyledKnob : public CKnobBase {
CColor activeTrackColor_;
CColor inactiveTrackColor_;
CColor lineIndicatorColor_;

SharedPointer<CFontDesc> 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<CTextLabel> label_;
SharedPointer<SStyledKnob> knob_;
SharedPointer<CTextLabel> ccLabel_;
CRect nameLabelSize_;
CRect knobSize_;
CRect ccLabelSize_;
float hue_ = 0.35;
};

///
Expand Down Expand Up @@ -253,9 +300,7 @@ class SControlsPanel : public CScrollView {
private:
struct ControlSlot {
bool used = false;
SharedPointer<CControl> knob;
SharedPointer<CTextLabel> label;
SharedPointer<CViewContainer> box;
SharedPointer<SKnobCCBox> box;
};

class ControlSlotListener : public IControlListener {
Expand Down