diff --git a/include/ui.hpp b/include/ui.hpp
index 4ddd5a19..a720ceb7 100644
--- a/include/ui.hpp
+++ b/include/ui.hpp
@@ -130,6 +130,9 @@ struct MenuItem : MenuEntry {
}
};
+struct TooltipOverlay : TransparentWidget {
+};
+
struct WindowOverlay : OpaqueWidget {
};
@@ -246,12 +249,14 @@ struct ProgressBar : QuantityWidget {
};
struct Tooltip : VirtualWidget {
- void step() override;
+ std::string text;
+ Tooltip();
void draw(NVGcontext *vg) override;
};
struct Scene : OpaqueWidget {
Widget *overlay = NULL;
+ /** Takes ownership of `w` */
void setOverlay(Widget *w);
Menu *createMenu();
void step() override;
diff --git a/res/icons/030-feed.svg b/res/icons/030-feed.svg
new file mode 100755
index 00000000..76680d66
--- /dev/null
+++ b/res/icons/030-feed.svg
@@ -0,0 +1,58 @@
+
+
+
+
diff --git a/res/icons/037-file-empty.svg b/res/icons/037-file-empty.svg
new file mode 100755
index 00000000..0202e211
--- /dev/null
+++ b/res/icons/037-file-empty.svg
@@ -0,0 +1,58 @@
+
+
+
+
diff --git a/res/icons/049-folder-open.svg b/res/icons/049-folder-open.svg
new file mode 100755
index 00000000..ea3dd33f
--- /dev/null
+++ b/res/icons/049-folder-open.svg
@@ -0,0 +1,57 @@
+
+
+
+
diff --git a/res/icons/file.svg b/res/icons/099-floppy-disk.svg
old mode 100644
new mode 100755
similarity index 60%
rename from res/icons/file.svg
rename to res/icons/099-floppy-disk.svg
index a369c472..df43a937
--- a/res/icons/file.svg
+++ b/res/icons/099-floppy-disk.svg
@@ -1,4 +1,6 @@
+
+
diff --git a/res/icons/167-meter.svg b/res/icons/167-meter.svg
new file mode 100755
index 00000000..67a044ca
--- /dev/null
+++ b/res/icons/167-meter.svg
@@ -0,0 +1,58 @@
+
+
+
+
diff --git a/res/icons/LICENSE.md b/res/icons/LICENSE.md
index cbff1d61..b1944854 100644
--- a/res/icons/LICENSE.md
+++ b/res/icons/LICENSE.md
@@ -1,2 +1,2 @@
-SVG icons in this directory are licensed under the CC BY 4.0 License by Font Awesome.
-https://fontawesome.com/license
+SVG icons in this directory are licensed under the CC BY 4.0 License by IcoMoon.io.
+https://icomoon.io/
\ No newline at end of file
diff --git a/src/app/Toolbar.cpp b/src/app/Toolbar.cpp
index 7da3be57..ee944473 100644
--- a/src/app/Toolbar.cpp
+++ b/src/app/Toolbar.cpp
@@ -7,116 +7,134 @@
namespace rack {
-struct NewButton : IconButton {
- NewButton() {
- setSVG(SVG::load(assetGlobal("res/icons/file.svg")));
+struct TooltipIconButton : IconButton {
+ std::string tooltipText;
+ void onMouseEnter(EventMouseEnter &e) override {
+ TooltipOverlay *overlay = new TooltipOverlay();
+ Tooltip *tooltip = new Tooltip();
+ tooltip->box.pos = getAbsoluteOffset(Vec(0, BND_WIDGET_HEIGHT));
+ tooltip->text = tooltipText;
+ overlay->addChild(tooltip);
+ gScene->setOverlay(overlay);
}
- void onAction(EventAction &e) override {
- gRackWidget->reset();
+ void onMouseLeave(EventMouseLeave &e) override {
+ gScene->setOverlay(NULL);
}
};
-
-struct NewItem : MenuItem {
+struct NewButton : TooltipIconButton {
+ NewButton() {
+ setSVG(SVG::load(assetGlobal("res/icons/037-file-empty.svg")));
+ tooltipText = "New patch (" WINDOW_MOD_KEY_NAME "+N)";
+ }
void onAction(EventAction &e) override {
gRackWidget->reset();
}
};
-struct DisconnectItem : MenuItem {
- void onAction(EventAction &e) override {
- gRackWidget->disconnect();
+struct OpenButton : TooltipIconButton {
+ OpenButton() {
+ setSVG(SVG::load(assetGlobal("res/icons/049-folder-open.svg")));
+ tooltipText = "Open patch (" WINDOW_MOD_KEY_NAME "+O)";
}
-};
-
-struct OpenItem : MenuItem {
void onAction(EventAction &e) override {
gRackWidget->openDialog();
}
};
-struct SaveItem : MenuItem {
+struct SaveButton : TooltipIconButton {
+ SaveButton() {
+ setSVG(SVG::load(assetGlobal("res/icons/099-floppy-disk.svg")));
+ tooltipText = "Save patch (" WINDOW_MOD_KEY_NAME "+S)";
+ }
void onAction(EventAction &e) override {
gRackWidget->saveDialog();
}
};
-struct SaveAsItem : MenuItem {
+struct MeterButton : TooltipIconButton {
+ MeterButton() {
+ setSVG(SVG::load(assetGlobal("res/icons/167-meter.svg")));
+ tooltipText = "Toggle CPU meter\nSee manual for mV definition";
+ }
void onAction(EventAction &e) override {
- gRackWidget->saveAsDialog();
+ gCpuMeters ^= true;
}
};
-struct RevertItem : MenuItem {
+struct EnginePauseItem : MenuItem {
void onAction(EventAction &e) override {
- gRackWidget->revert();
+ gPaused ^= true;
}
};
-struct QuitItem : MenuItem {
+struct SampleRateItem : MenuItem {
+ float sampleRate;
void onAction(EventAction &e) override {
- windowClose();
+ engineSetSampleRate(sampleRate);
+ gPaused = false;
}
};
-struct FileChoice : ChoiceButton {
+struct SampleRateButton : TooltipIconButton {
+ SampleRateButton() {
+ setSVG(SVG::load(assetGlobal("res/icons/030-feed.svg")));
+ tooltipText = "Internal sample rate";
+ }
void onAction(EventAction &e) override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y));
menu->box.size.x = box.size.x;
- menu->addChild(MenuItem::create("New", WINDOW_MOD_KEY_NAME "+N"));
- menu->addChild(MenuItem::create("Disconnect cables"));
- menu->addChild(MenuItem::create("Open", WINDOW_MOD_KEY_NAME "+O"));
- menu->addChild(MenuItem::create("Save", WINDOW_MOD_KEY_NAME "+S"));
- menu->addChild(MenuItem::create("Save as", WINDOW_MOD_KEY_NAME "+Shift+S"));
- menu->addChild(MenuItem::create("Revert"));
- menu->addChild(MenuItem::create("Quit", WINDOW_MOD_KEY_NAME "+Q"));
+ EnginePauseItem *pauseItem = new EnginePauseItem();
+ pauseItem->text = gPaused ? "Resume engine" : "Pause engine";
+ menu->addChild(pauseItem);
+
+ std::vector sampleRates = {44100, 48000, 88200, 96000, 176400, 192000};
+ for (float sampleRate : sampleRates) {
+ SampleRateItem *item = new SampleRateItem();
+ item->text = stringf("%.0f Hz", sampleRate);
+ item->rightText = CHECKMARK(engineGetSampleRate() == sampleRate);
+ item->sampleRate = sampleRate;
+ menu->addChild(item);
+ }
}
};
-struct EnginePauseItem : MenuItem {
+
+struct DisconnectItem : MenuItem {
void onAction(EventAction &e) override {
- gPaused = !gPaused;
+ gRackWidget->disconnect();
}
};
-struct EngineSampleRateItem : MenuItem {
- float sampleRate;
+struct SaveAsItem : MenuItem {
void onAction(EventAction &e) override {
- engineSetSampleRate(sampleRate);
- gPaused = false;
+ gRackWidget->saveAsDialog();
+ }
+};
+
+struct RevertItem : MenuItem {
+ void onAction(EventAction &e) override {
+ gRackWidget->revert();
}
};
-struct EngineSampleRateChoice : ChoiceButton {
+struct FileChoice : ChoiceButton {
void onAction(EventAction &e) override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y));
menu->box.size.x = box.size.x;
- EnginePauseItem *pauseItem = new EnginePauseItem();
- pauseItem->text = gPaused ? "Resume engine" : "Pause engine";
- menu->addChild(pauseItem);
-
- std::vector sampleRates = {44100, 48000, 88200, 96000, 176400, 192000};
- for (float sampleRate : sampleRates) {
- EngineSampleRateItem *item = new EngineSampleRateItem();
- item->text = stringf("%.0f Hz", sampleRate);
- item->sampleRate = sampleRate;
- menu->addChild(item);
- }
- }
- void step() override {
- if (gPaused)
- text = "Paused";
- else
- text = stringf("%.0f Hz", engineGetSampleRate());
+ menu->addChild(MenuItem::create("Disconnect cables"));
+ menu->addChild(MenuItem::create("Save as", WINDOW_MOD_KEY_NAME "+Shift+S"));
+ menu->addChild(MenuItem::create("Revert"));
}
};
+
Toolbar::Toolbar() {
box.size.y = BND_WIDGET_HEIGHT + 2*5;
@@ -125,18 +143,17 @@ Toolbar::Toolbar() {
layout->spacing = 5;
addChild(layout);
- NewButton *newButton = new NewButton();
- layout->addChild(newButton);
+ layout->addChild(new NewButton());
+ layout->addChild(new OpenButton());
+ layout->addChild(new SaveButton());
+ layout->addChild(new SampleRateButton());
+ layout->addChild(new MeterButton());
ChoiceButton *fileChoice = new FileChoice();
fileChoice->box.size.x = 100;
fileChoice->text = "File";
layout->addChild(fileChoice);
- EngineSampleRateChoice *srChoice = new EngineSampleRateChoice();
- srChoice->box.size.x = 100;
- layout->addChild(srChoice);
-
wireOpacitySlider = new Slider();
wireOpacitySlider->box.size.x = 150;
wireOpacitySlider->label = "Cable opacity";
diff --git a/src/ui/IconButton.cpp b/src/ui/IconButton.cpp
index 31fa427e..aacbab3f 100644
--- a/src/ui/IconButton.cpp
+++ b/src/ui/IconButton.cpp
@@ -5,9 +5,9 @@ namespace rack {
IconButton::IconButton() {
- box.size.x = BND_WIDGET_HEIGHT;
+ box.size.x = BND_TOOL_WIDTH;
sw = new SVGWidget();
- sw->box.pos = Vec(2.75, 1.75);
+ sw->box.pos = Vec(2, 2);
addChild(sw);
}
diff --git a/src/ui/Tooltip.cpp b/src/ui/Tooltip.cpp
index 8977976a..f65c68bc 100644
--- a/src/ui/Tooltip.cpp
+++ b/src/ui/Tooltip.cpp
@@ -4,19 +4,18 @@
namespace rack {
-void Tooltip::step() {
- // Follow the mouse
- box.pos = gMousePos;
- // Wrap size to contents
- // box.size = getChildrenBoundingBox().getBottomRight();
-
- Widget::step();
+Tooltip::Tooltip() {
}
-
void Tooltip::draw(NVGcontext *vg) {
+ // Wrap size to contents
+ float bounds[4];
+ nvgTextBounds(gVg, 0.0, 0.0, text.c_str(), NULL, bounds);
+ box.size = Vec(bounds[2], BND_WIDGET_HEIGHT);
+
bndTooltipBackground(vg, 0.0, 0.0, box.size.x, box.size.y);
+ bndMenuLabel(vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str());
Widget::draw(vg);
}