@@ -29,6 +29,7 @@ struct PortWidget : OpaqueWidget { | |||
void onDragDrop(const event::DragDrop &e) override; | |||
void onDragEnter(const event::DragEnter &e) override; | |||
void onDragLeave(const event::DragLeave &e) override; | |||
void setHovered(); | |||
}; | |||
@@ -37,7 +37,6 @@ | |||
#include "ui/IconButton.hpp" | |||
#include "ui/ChoiceButton.hpp" | |||
#include "ui/RadioButton.hpp" | |||
#include "ui/WindowWidget.hpp" | |||
#include "ui/ProgressBar.hpp" | |||
#include "app/AudioWidget.hpp" | |||
@@ -13,45 +13,14 @@ struct Button : OpaqueWidget { | |||
/** Optional, owned. Tracks the pressed state of the button.*/ | |||
Quantity *quantity = NULL; | |||
Button() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
~Button() { | |||
if (quantity) | |||
delete quantity; | |||
} | |||
void draw(NVGcontext *vg) override { | |||
bndToolButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str()); | |||
} | |||
void onEnter(const event::Enter &e) override { | |||
state = BND_HOVER; | |||
} | |||
void onLeave(const event::Leave &e) override { | |||
state = BND_DEFAULT; | |||
} | |||
void onDragStart(const event::DragStart &e) override { | |||
state = BND_ACTIVE; | |||
if (quantity) | |||
quantity->setMax(); | |||
} | |||
void onDragEnd(const event::DragEnd &e) override { | |||
state = BND_HOVER; | |||
if (quantity) | |||
quantity->setMin(); | |||
} | |||
void onDragDrop(const event::DragDrop &e) override { | |||
if (e.origin == this) { | |||
event::Action eAction; | |||
onAction(eAction); | |||
} | |||
} | |||
Button(); | |||
~Button(); | |||
void draw(NVGcontext *vg) override; | |||
void onEnter(const event::Enter &e) override; | |||
void onLeave(const event::Leave &e) override; | |||
void onDragStart(const event::DragStart &e) override; | |||
void onDragEnd(const event::DragEnd &e) override; | |||
void onDragDrop(const event::DragDrop &e) override; | |||
}; | |||
@@ -7,9 +7,7 @@ namespace rack { | |||
struct ChoiceButton : Button { | |||
void draw(NVGcontext *vg) override { | |||
bndChoiceButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str()); | |||
} | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
@@ -12,22 +12,8 @@ struct IconButton : Button { | |||
FramebufferWidget *fw; | |||
SVGWidget *sw; | |||
IconButton() { | |||
box.size.x = BND_TOOL_WIDTH; | |||
fw = new FramebufferWidget; | |||
fw->oversample = 2; | |||
addChild(fw); | |||
sw = new SVGWidget; | |||
sw->box.pos = math::Vec(2, 2); | |||
fw->addChild(sw); | |||
} | |||
void setSVG(std::shared_ptr<SVG> svg) { | |||
sw->setSVG(svg); | |||
fw->dirty = true; | |||
} | |||
IconButton(); | |||
void setSVG(std::shared_ptr<SVG> svg); | |||
}; | |||
@@ -18,31 +18,8 @@ struct Label : virtual Widget { | |||
NVGcolor color; | |||
Alignment alignment = LEFT_ALIGNMENT; | |||
Label() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
fontSize = 13; | |||
color = bndGetTheme()->regularTheme.textColor; | |||
} | |||
void draw(NVGcontext *vg) override { | |||
// TODO | |||
// Custom font sizes do not work with right or center alignment | |||
float x; | |||
switch (alignment) { | |||
default: | |||
case LEFT_ALIGNMENT: { | |||
x = 0.0; | |||
} break; | |||
case RIGHT_ALIGNMENT: { | |||
x = box.size.x - bndLabelWidth(vg, -1, text.c_str()); | |||
} break; | |||
case CENTER_ALIGNMENT: { | |||
x = (box.size.x - bndLabelWidth(vg, -1, text.c_str())) / 2.0; | |||
} break; | |||
} | |||
bndIconLabelValue(vg, x, 0.0, box.size.x, box.size.y, -1, color, BND_LEFT, fontSize, text.c_str(), NULL); | |||
} | |||
Label(); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
@@ -7,21 +7,7 @@ namespace rack { | |||
struct List : OpaqueWidget { | |||
void step() override { | |||
Widget::step(); | |||
// Set positions of children | |||
box.size.y = 0.0; | |||
for (Widget *child : children) { | |||
if (!child->visible) | |||
continue; | |||
// Increment height, set position of child | |||
child->box.pos = math::Vec(0.0, box.size.y); | |||
box.size.y += child->box.size.y; | |||
// Resize width of child | |||
child->box.size.x = box.size.x; | |||
} | |||
} | |||
void step() override; | |||
}; | |||
@@ -7,9 +7,7 @@ namespace rack { | |||
struct MenuEntry : OpaqueWidget { | |||
MenuEntry() { | |||
box.size = math::Vec(0, BND_WIDGET_HEIGHT); | |||
} | |||
MenuEntry(); | |||
}; | |||
@@ -1,7 +1,6 @@ | |||
#pragma once | |||
#include "ui/common.hpp" | |||
#include "ui/MenuEntry.hpp" | |||
#include "app.hpp" | |||
namespace rack { | |||
@@ -10,17 +9,8 @@ namespace rack { | |||
struct MenuLabel : MenuEntry { | |||
std::string text; | |||
void draw(NVGcontext *vg) override { | |||
bndMenuLabel(vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str()); | |||
} | |||
void step() override { | |||
// Add 10 more pixels because Retina measurements are sometimes too small | |||
const float rightPadding = 10.0; | |||
// HACK use app()->window->vg from the window. | |||
box.size.x = bndLabelWidth(app()->window->vg, -1, text.c_str()) + rightPadding; | |||
Widget::step(); | |||
} | |||
void draw(NVGcontext *vg) override; | |||
void step() override; | |||
}; | |||
@@ -7,19 +7,8 @@ namespace rack { | |||
struct MenuSeparator : MenuEntry { | |||
MenuSeparator() { | |||
box.size.y = BND_WIDGET_HEIGHT / 2; | |||
} | |||
void draw(NVGcontext *vg) override { | |||
nvgBeginPath(vg); | |||
const float margin = 8.0; | |||
nvgMoveTo(vg, margin, box.size.y / 2.0); | |||
nvgLineTo(vg, box.size.x - margin, box.size.y / 2.0); | |||
nvgStrokeWidth(vg, 1.0); | |||
nvgStrokeColor(vg, color::alpha(bndGetTheme()->menuTheme.textColor, 0.25)); | |||
nvgStroke(vg); | |||
} | |||
MenuSeparator(); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
@@ -7,12 +7,7 @@ namespace rack { | |||
struct PasswordField : TextField { | |||
void draw(NVGcontext *vg) override { | |||
std::string textTmp = text; | |||
text = std::string(textTmp.size(), '*'); | |||
TextField::draw(vg); | |||
text = textTmp; | |||
} | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
@@ -1,5 +1,7 @@ | |||
#pragma once | |||
#include "ui/common.hpp" | |||
#include "widgets/Widget.hpp" | |||
#include "ui/Quantity.hpp" | |||
namespace rack { | |||
@@ -8,20 +10,9 @@ namespace rack { | |||
struct ProgressBar : virtual Widget { | |||
Quantity *quantity = NULL; | |||
ProgressBar() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
~ProgressBar() { | |||
if (quantity) | |||
delete quantity; | |||
} | |||
void draw(NVGcontext *vg) override { | |||
float progress = quantity ? quantity->getScaledValue() : 0.f; | |||
std::string text = quantity ? quantity->getString() : ""; | |||
bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL, BND_DEFAULT, progress, text.c_str(), NULL); | |||
} | |||
ProgressBar(); | |||
~ProgressBar(); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
@@ -1,6 +1,7 @@ | |||
#pragma once | |||
#include "widgets/OpaqueWidget.hpp" | |||
#include "ui/common.hpp" | |||
#include "widgets/OpaqueWidget.hpp" | |||
#include "ui/Quantity.hpp" | |||
namespace rack { | |||
@@ -10,49 +11,12 @@ struct RadioButton : OpaqueWidget { | |||
BNDwidgetState state = BND_DEFAULT; | |||
Quantity *quantity = NULL; | |||
RadioButton() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
~RadioButton() { | |||
if (quantity) | |||
delete quantity; | |||
} | |||
void draw(NVGcontext *vg) override { | |||
std::string label; | |||
if (quantity) | |||
label = quantity->getLabel(); | |||
bndRadioButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, label.c_str()); | |||
} | |||
void onEnter(const event::Enter &e) override { | |||
if (state != BND_ACTIVE) | |||
state = BND_HOVER; | |||
} | |||
void onLeave(const event::Leave &e) override { | |||
if (state != BND_ACTIVE) | |||
state = BND_DEFAULT; | |||
} | |||
void onDragDrop(const event::DragDrop &e) override { | |||
if (e.origin == this) { | |||
if (state == BND_ACTIVE) { | |||
state = BND_HOVER; | |||
if (quantity) | |||
quantity->setMin(); | |||
} | |||
else { | |||
state = BND_ACTIVE; | |||
if (quantity) | |||
quantity->setMax(); | |||
} | |||
event::Action eAction; | |||
onAction(eAction); | |||
} | |||
} | |||
RadioButton(); | |||
~RadioButton(); | |||
void draw(NVGcontext *vg) override; | |||
void onEnter(const event::Enter &e) override; | |||
void onLeave(const event::Leave &e) override; | |||
void onDragDrop(const event::DragDrop &e) override; | |||
}; | |||
@@ -15,44 +15,13 @@ struct Slider : OpaqueWidget { | |||
BNDwidgetState state = BND_DEFAULT; | |||
Quantity *quantity = NULL; | |||
Slider() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
~Slider() { | |||
if (quantity) | |||
delete quantity; | |||
} | |||
void draw(NVGcontext *vg) override { | |||
float progress = quantity ? quantity->getScaledValue() : 0.f; | |||
std::string text = quantity ? quantity->getString() : ""; | |||
bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, progress, text.c_str(), NULL); | |||
} | |||
void onDragStart(const event::DragStart &e) override { | |||
state = BND_ACTIVE; | |||
app()->window->cursorLock(); | |||
} | |||
void onDragMove(const event::DragMove &e) override { | |||
if (quantity) { | |||
quantity->moveScaledValue(SLIDER_SENSITIVITY * e.mouseDelta.x); | |||
} | |||
} | |||
void onDragEnd(const event::DragEnd &e) override { | |||
state = BND_DEFAULT; | |||
app()->window->cursorUnlock(); | |||
} | |||
void onButton(const event::Button &e) override { | |||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | |||
if (quantity) | |||
quantity->reset(); | |||
} | |||
e.consume(this); | |||
} | |||
Slider(); | |||
~Slider(); | |||
void draw(NVGcontext *vg) override; | |||
void onDragStart(const event::DragStart &e) override; | |||
void onDragMove(const event::DragMove &e) override; | |||
void onDragEnd(const event::DragEnd &e) override; | |||
void onButton(const event::Button &e) override; | |||
}; | |||
@@ -1,13 +0,0 @@ | |||
#pragma once | |||
#include "widgets/OpaqueWidget.hpp" | |||
#include "ui/common.hpp" | |||
namespace rack { | |||
struct WindowOverlay : OpaqueWidget { | |||
}; | |||
} // namespace rack |
@@ -1,23 +0,0 @@ | |||
#pragma once | |||
#include "widgets/OpaqueWidget.hpp" | |||
#include "ui/common.hpp" | |||
namespace rack { | |||
struct WindowWidget : OpaqueWidget { | |||
std::string title; | |||
void draw(NVGcontext *vg) override { | |||
bndNodeBackground(vg, 0.0, 0.0, box.size.x, box.size.y, BND_DEFAULT, -1, title.c_str(), bndGetTheme()->backgroundColor); | |||
Widget::draw(vg); | |||
} | |||
void onDragMove(const event::DragMove &e) override { | |||
box.pos = box.pos.plus(e.mouseDelta); | |||
} | |||
}; | |||
} // namespace rack |
@@ -99,10 +99,7 @@ void PortWidget::onDragDrop(const event::DragDrop &e) { | |||
if (!originPort) | |||
return; | |||
// Fake onDragEnter because onDragLeave is triggered immediately before this one | |||
event::DragEnter eDragEnter; | |||
eDragEnter.origin = e.origin; | |||
onDragEnter(eDragEnter); | |||
setHovered(); | |||
} | |||
void PortWidget::onDragEnter(const event::DragEnter &e) { | |||
@@ -110,17 +107,7 @@ void PortWidget::onDragEnter(const event::DragEnter &e) { | |||
if (!originPort) | |||
return; | |||
// Reject ports if this is an input port and something is already plugged into it | |||
if (type == INPUT) { | |||
CableWidget *topCable = app()->scene->rackWidget->cableContainer->getTopCable(this); | |||
if (topCable) | |||
return; | |||
} | |||
CableWidget *activeCable = app()->scene->rackWidget->cableContainer->activeCable; | |||
if (activeCable) { | |||
(type == INPUT ? activeCable->hoveredInputPort : activeCable->hoveredOutputPort) = this; | |||
} | |||
setHovered(); | |||
} | |||
void PortWidget::onDragLeave(const event::DragLeave &e) { | |||
@@ -134,5 +121,19 @@ void PortWidget::onDragLeave(const event::DragLeave &e) { | |||
} | |||
} | |||
void PortWidget::setHovered() { | |||
// Reject ports if this is an input port and something is already plugged into it | |||
if (type == INPUT) { | |||
CableWidget *topCable = app()->scene->rackWidget->cableContainer->getTopCable(this); | |||
if (topCable) | |||
return; | |||
} | |||
CableWidget *activeCable = app()->scene->rackWidget->cableContainer->activeCable; | |||
if (activeCable) { | |||
(type == INPUT ? activeCable->hoveredInputPort : activeCable->hoveredOutputPort) = this; | |||
} | |||
} | |||
} // namespace rack |
@@ -0,0 +1,48 @@ | |||
#include "ui/Button.hpp" | |||
namespace rack { | |||
Button::Button() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
Button::~Button() { | |||
if (quantity) | |||
delete quantity; | |||
} | |||
void Button::draw(NVGcontext *vg) { | |||
bndToolButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str()); | |||
} | |||
void Button::onEnter(const event::Enter &e) { | |||
state = BND_HOVER; | |||
} | |||
void Button::onLeave(const event::Leave &e) { | |||
state = BND_DEFAULT; | |||
} | |||
void Button::onDragStart(const event::DragStart &e) { | |||
state = BND_ACTIVE; | |||
if (quantity) | |||
quantity->setMax(); | |||
} | |||
void Button::onDragEnd(const event::DragEnd &e) { | |||
state = BND_HOVER; | |||
if (quantity) | |||
quantity->setMin(); | |||
} | |||
void Button::onDragDrop(const event::DragDrop &e) { | |||
if (e.origin == this) { | |||
event::Action eAction; | |||
onAction(eAction); | |||
} | |||
} | |||
} // namespace rack |
@@ -0,0 +1,12 @@ | |||
#include "ui/ChoiceButton.hpp" | |||
namespace rack { | |||
void ChoiceButton::draw(NVGcontext *vg) { | |||
bndChoiceButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str()); | |||
} | |||
} // namespace rack |
@@ -0,0 +1,25 @@ | |||
#include "ui/IconButton.hpp" | |||
namespace rack { | |||
IconButton::IconButton() { | |||
box.size.x = BND_TOOL_WIDTH; | |||
fw = new FramebufferWidget; | |||
fw->oversample = 2; | |||
addChild(fw); | |||
sw = new SVGWidget; | |||
sw->box.pos = math::Vec(2, 2); | |||
fw->addChild(sw); | |||
} | |||
void IconButton::setSVG(std::shared_ptr<SVG> svg) { | |||
sw->setSVG(svg); | |||
fw->dirty = true; | |||
} | |||
} // namespace rack |
@@ -0,0 +1,34 @@ | |||
#include "ui/Label.hpp" | |||
namespace rack { | |||
Label::Label() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
fontSize = 13; | |||
color = bndGetTheme()->regularTheme.textColor; | |||
} | |||
void Label::draw(NVGcontext *vg) { | |||
// TODO | |||
// Custom font sizes do not work with right or center alignment | |||
float x; | |||
switch (alignment) { | |||
default: | |||
case LEFT_ALIGNMENT: { | |||
x = 0.0; | |||
} break; | |||
case RIGHT_ALIGNMENT: { | |||
x = box.size.x - bndLabelWidth(vg, -1, text.c_str()); | |||
} break; | |||
case CENTER_ALIGNMENT: { | |||
x = (box.size.x - bndLabelWidth(vg, -1, text.c_str())) / 2.0; | |||
} break; | |||
} | |||
bndIconLabelValue(vg, x, 0.0, box.size.x, box.size.y, -1, color, BND_LEFT, fontSize, text.c_str(), NULL); | |||
} | |||
} // namespace rack |
@@ -0,0 +1,24 @@ | |||
#include "ui/List.hpp" | |||
namespace rack { | |||
void List::step() { | |||
Widget::step(); | |||
// Set positions of children | |||
box.size.y = 0.0; | |||
for (Widget *child : children) { | |||
if (!child->visible) | |||
continue; | |||
// Increment height, set position of child | |||
child->box.pos = math::Vec(0.0, box.size.y); | |||
box.size.y += child->box.size.y; | |||
// Resize width of child | |||
child->box.size.x = box.size.x; | |||
} | |||
} | |||
} // namespace rack |
@@ -0,0 +1,12 @@ | |||
#include "ui/MenuEntry.hpp" | |||
namespace rack { | |||
MenuEntry::MenuEntry() { | |||
box.size = math::Vec(0, BND_WIDGET_HEIGHT); | |||
} | |||
} // namespace rack |
@@ -0,0 +1,21 @@ | |||
#include "ui/MenuLabel.hpp" | |||
#include "app.hpp" | |||
namespace rack { | |||
void MenuLabel::draw(NVGcontext *vg) { | |||
bndMenuLabel(vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str()); | |||
} | |||
void MenuLabel::step() { | |||
// Add 10 more pixels because Retina measurements are sometimes too small | |||
const float rightPadding = 10.0; | |||
// HACK use app()->window->vg from the window. | |||
box.size.x = bndLabelWidth(app()->window->vg, -1, text.c_str()) + rightPadding; | |||
Widget::step(); | |||
} | |||
} // namespace rack |
@@ -0,0 +1,22 @@ | |||
#include "ui/MenuSeparator.hpp" | |||
namespace rack { | |||
MenuSeparator::MenuSeparator() { | |||
box.size.y = BND_WIDGET_HEIGHT / 2; | |||
} | |||
void MenuSeparator::draw(NVGcontext *vg) { | |||
nvgBeginPath(vg); | |||
const float margin = 8.0; | |||
nvgMoveTo(vg, margin, box.size.y / 2.0); | |||
nvgLineTo(vg, box.size.x - margin, box.size.y / 2.0); | |||
nvgStrokeWidth(vg, 1.0); | |||
nvgStrokeColor(vg, color::alpha(bndGetTheme()->menuTheme.textColor, 0.25)); | |||
nvgStroke(vg); | |||
} | |||
} // namespace rack |
@@ -0,0 +1,15 @@ | |||
#include "ui/PasswordField.hpp" | |||
namespace rack { | |||
void PasswordField::draw(NVGcontext *vg) { | |||
std::string textTmp = text; | |||
text = std::string(textTmp.size(), '*'); | |||
TextField::draw(vg); | |||
text = textTmp; | |||
} | |||
} // namespace rack |
@@ -0,0 +1,23 @@ | |||
#include "ui/ProgressBar.hpp" | |||
namespace rack { | |||
ProgressBar::ProgressBar() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
ProgressBar::~ProgressBar() { | |||
if (quantity) | |||
delete quantity; | |||
} | |||
void ProgressBar::draw(NVGcontext *vg) { | |||
float progress = quantity ? quantity->getScaledValue() : 0.f; | |||
std::string text = quantity ? quantity->getString() : ""; | |||
bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL, BND_DEFAULT, progress, text.c_str(), NULL); | |||
} | |||
} // namespace rack |
@@ -0,0 +1,52 @@ | |||
#include "ui/RadioButton.hpp" | |||
namespace rack { | |||
RadioButton::RadioButton() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
RadioButton::~RadioButton() { | |||
if (quantity) | |||
delete quantity; | |||
} | |||
void RadioButton::draw(NVGcontext *vg) { | |||
std::string label; | |||
if (quantity) | |||
label = quantity->getLabel(); | |||
bndRadioButton(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, label.c_str()); | |||
} | |||
void RadioButton::onEnter(const event::Enter &e) { | |||
if (state != BND_ACTIVE) | |||
state = BND_HOVER; | |||
} | |||
void RadioButton::onLeave(const event::Leave &e) { | |||
if (state != BND_ACTIVE) | |||
state = BND_DEFAULT; | |||
} | |||
void RadioButton::onDragDrop(const event::DragDrop &e) { | |||
if (e.origin == this) { | |||
if (state == BND_ACTIVE) { | |||
state = BND_HOVER; | |||
if (quantity) | |||
quantity->setMin(); | |||
} | |||
else { | |||
state = BND_ACTIVE; | |||
if (quantity) | |||
quantity->setMax(); | |||
} | |||
event::Action eAction; | |||
onAction(eAction); | |||
} | |||
} | |||
} // namespace rack |
@@ -0,0 +1,47 @@ | |||
#include "ui/Slider.hpp" | |||
namespace rack { | |||
Slider::Slider() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
Slider::~Slider() { | |||
if (quantity) | |||
delete quantity; | |||
} | |||
void Slider::draw(NVGcontext *vg) { | |||
float progress = quantity ? quantity->getScaledValue() : 0.f; | |||
std::string text = quantity ? quantity->getString() : ""; | |||
bndSlider(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, progress, text.c_str(), NULL); | |||
} | |||
void Slider::onDragStart(const event::DragStart &e) { | |||
state = BND_ACTIVE; | |||
app()->window->cursorLock(); | |||
} | |||
void Slider::onDragMove(const event::DragMove &e) { | |||
if (quantity) { | |||
quantity->moveScaledValue(SLIDER_SENSITIVITY * e.mouseDelta.x); | |||
} | |||
} | |||
void Slider::onDragEnd(const event::DragEnd &e) { | |||
state = BND_DEFAULT; | |||
app()->window->cursorUnlock(); | |||
} | |||
void Slider::onButton(const event::Button &e) { | |||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | |||
if (quantity) | |||
quantity->reset(); | |||
} | |||
e.consume(this); | |||
} | |||
} // namespace rack |