nanogui-experiments/nanogui_knobs.cpp

145 lines
4.1 KiB
C++

/*
src/nanogui_customwidget.cpp -- C++ version of an customwidget example application
*/
#include <nanogui/button.h>
#include <nanogui/label.h>
#include <nanogui/layout.h>
#include <nanogui/opengl.h>
#include <nanogui/screen.h>
#include <nanogui/textbox.h>
#include <nanogui/widget.h>
#include <nanogui/window.h>
#include <iostream>
#include <string>
#include "fancyknob.hpp"
using namespace nanogui;
struct KnobSpec {
std::string name;
float default_value;
float min_value;
float max_value;
float increment;
std::string unit;
Vector4i color;
};
KnobSpec knobs[4] = {
{ "Attack", 0.0, 0.0, 5.0, 0.01, "s", { 224, 128, 128, 255 } },
{ "Decay", 0.2, 0.0, 5.0, 0.01, "s", { 128, 224, 128, 255 } },
{ "Sustain", 100.0, 0.0, 100.0, 0.01, "%", { 128, 128, 224, 255 } },
{ "Release", 0.2, 0.0, 5.0, 0.01, "s", { 224, 224, 128, 255 } },
};
class KnobsApplication : public Screen {
public:
KnobsApplication()
: Screen(Vector2i(452, 250), "NanoGUI Knobs")
{
inc_ref();
set_background(Color(96, 96, 96, 255));
window = new Window(this, "Envelope");
window->set_layout(new BoxLayout(Orientation::Horizontal, Alignment::Middle, 20, 20));
resize_event(size());
for (int i = 0; i < 4; i++) {
Widget* box = new Widget(window);
box->set_layout(new BoxLayout(Orientation::Vertical, Alignment::Middle, 0, 10));
KnobSpec knob = knobs[i];
FancyKnob* k = new FancyKnob(box);
k->set_default(knob.default_value);
k->set_value(knob.default_value);
k->set_min_value(knob.min_value);
k->set_max_value(knob.max_value);
k->set_increment(knob.increment);
k->set_gauge_color(Color(knob.color));
FloatBox<float>* entry = new FloatBox<float>(box);
entry->set_fixed_size({ 88, 24 });
entry->set_font_size(20);
entry->set_editable(true);
entry->set_spinnable(true);
entry->set_value(k->value());
entry->number_format("%02.2f");
entry->set_min_value(k->min_value());
entry->set_max_value(k->max_value());
entry->set_value_increment(k->increment());
entry->set_units(knob.unit);
entry->set_callback([k](float f) { k->set_value(f); });
k->set_callback([entry, knob](float f) {
entry->set_value(f);
std::cout << "'" << knob.name << "' value: " << f << std::endl;
});
Label* l = new Label(box, knob.name, "sans", 20);
}
perform_layout();
}
virtual bool resize_event(const Vector2i& size)
{
window->set_fixed_size(size);
window->set_size(size);
window->center();
window->perform_layout(nvg_context());
return true;
}
virtual bool keyboard_event(int key, int scancode, int action, int modifiers)
{
if (Screen::keyboard_event(key, scancode, action, modifiers))
return true;
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
set_visible(false);
return true;
}
return false;
}
virtual void draw(NVGcontext* ctx)
{
/* Draw the user interface */
Screen::draw(ctx);
}
private:
Window* window;
};
int main(int /* argc */, char** /* argv */)
{
try {
nanogui::init();
/* scoped variables */ {
ref<KnobsApplication> app = new KnobsApplication();
app->dec_ref();
app->draw_all();
app->set_visible(true);
nanogui::mainloop(1 / 60.f * 1000);
}
nanogui::shutdown();
} catch (const std::exception& e) {
std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
#if defined(_WIN32)
MessageBoxA(nullptr, error_msg.c_str(), NULL, MB_ICONERROR | MB_OK);
#else
std::cerr << error_msg << std::endl;
#endif
return -1;
} catch (...) {
std::cerr << "Caught an unknown error!" << std::endl;
}
return 0;
}