/* src/nanogui_customwidget.cpp -- C++ version of an customwidget example application */ #include #include #include #include #include #include #include #include #include #include #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* entry = new FloatBox(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 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; }