|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- /*
- ZynAddSubFX - a software synthesizer
-
- WidgetPDial.cpp - Fl_Dial With Custom Behavior
- Copyright (C) 2016 Mark McCurry
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- */
- // generated by Fast Light User Interface Designer (fluid) version 1.0107f
-
- #include <cmath>
- #include <FL/fl_draw.H>
- #include "../Misc/Util.h"
- #include "WidgetPDial.h"
- //Copyright (c) 2003-2005 Nasca Octavian Paul
- //License: GNU GPL version 2 or later
-
-
- //static int numobj = 0;
-
- static float identity(float value)
- {
- return value;
- }
-
- WidgetPDial::WidgetPDial(int x, int y, int w, int h, const char *label)
- :Fl_Dial(x, y, w, h, label), reset_value(0), integer_step(true),
- use_rounding(false), oldvalue(0.0f), pos(false), textset(false),
- transform(identity)
- {
- //cout << "[" << label << "] There are now " << ++numobj << endl;
- Fl_Group *save = Fl_Group::current();
- tipwin = new TipWin();
- tipwin->hide();
- Fl_Group::current(save);
- }
-
- WidgetPDial::~WidgetPDial()
- {
- //cout << "There are now " << --numobj << endl;
- delete tipwin;
- }
-
- void WidgetPDial::set_rounding(unsigned int digits)
- {
- tipwin->set_rounding(digits);
- }
-
- #define MOD_MASK (FL_CTRL | FL_SHIFT)
-
- int WidgetPDial::handle(int event)
- {
- double dragsize, min = minimum(), max = maximum(), result;
- int dy;
-
- if (event == FL_RELEASE && Fl::event_clicks() == 1) {
- Fl::event_clicks(0);
- value(reset_value);
- tipwin->hide();
- value_damage();
- if (this->when() != 0)
- do_callback();
- return 1;
- }
-
- int old_mod_state;
-
- switch(event) {
- case FL_PUSH:
- mod_state = Fl::event_state() & MOD_MASK;
- if (!use_rounding) {
- if (integer_step)
- set_rounding(0);
- else if (mod_state == MOD_MASK)
- set_rounding(5);
- else if (mod_state == FL_SHIFT)
- set_rounding(4);
- else
- set_rounding((Fl::event_button3() || mod_state & FL_CTRL)
- ? 3 : 2);
- }
- oldvalue = value();
- old_y = Fl::event_y();
- case FL_DRAG:
- getPos();
- old_mod_state = mod_state;
- mod_state = Fl::event_state() & MOD_MASK;
- if (old_mod_state != mod_state) {
- oldvalue = value();
- old_y = Fl::event_y();
- if (!use_rounding) {
- if (integer_step)
- set_rounding(0);
- else if (mod_state == MOD_MASK)
- set_rounding(5);
- else if (mod_state == FL_SHIFT)
- set_rounding(4);
- else
- set_rounding((Fl::event_button3() ||
- mod_state & FL_CTRL)
- ? 3 : 2);
- }
- break;
- }
- dy = old_y - Fl::event_y();
- if (dy < -1 || dy > 1)
- Fl::event_clicks(0);
-
- if (!integer_step && mod_state == MOD_MASK)
- dragsize = 200000.0f;
- else if (!integer_step && mod_state == FL_SHIFT)
- dragsize = 20000.0f;
- else
- dragsize = (Fl::event_button3() || mod_state & MOD_MASK)
- ? 1000.0f : 200.0f;
-
- value(clamp(oldvalue + dy / dragsize * (max - min)));
- tipwin->showValue(transform(value()));
- value_damage();
- if(this->when() != 0)
- do_callback();
- return 1;
- case FL_MOUSEWHEEL:
- if (Fl::event_buttons() || Fl::belowmouse() != this)
- return 1;
- mod_state = Fl::event_state() & MOD_MASK;
- dy = - Fl::event_dy();
-
- if (integer_step) {
- if (!use_rounding) set_rounding(0);
- result = (int)(value() +
- dy * ((Fl::event_ctrl() ||
- Fl::event_shift()) ? 1 : 8));
- } else {
- float dragsize;
- if (mod_state == MOD_MASK) {
- dragsize = 100000.0;
- if (!use_rounding) set_rounding(5);
- } else if (mod_state == FL_SHIFT) {
- dragsize = 10000.0;
- if (!use_rounding) set_rounding(4);
- } else if (mod_state == FL_CTRL) {
- dragsize = 1000.0;
- if (!use_rounding) set_rounding(3);
- } else {
- dragsize = 100.0;
- if (!use_rounding) set_rounding(2);
- }
- result = value() + dy / dragsize * (max - min);
- }
- value(clamp(result));
-
- tipwin->showValue(transform(value()));
- value_damage();
- if(this->when() != 0)
- do_callback();
- return 1;
- case FL_ENTER:
- getPos();
- tipwin->showText();
- return 1;
- case FL_HIDE:
- case FL_LEAVE:
- tipwin->hide();
- resetPos();
- break;
- case FL_RELEASE:
- if (integer_step) {
- float rounded = floorf(value() + 0.5);
- value(clamp(rounded));
- }
- tipwin->hide();
- resetPos();
- if(this->when() == 0)
- do_callback();
- return 1;
- }
- return 0;
- //#endif
- }
-
- void WidgetPDial::draw()
- {
- #ifdef NTK_GUI
- box( FL_NO_BOX );
-
- Fl_Dial::draw();
-
- return;
- #else
- const int cx = x(), cy = y(), sx = w(), sy = h();
- const double a1 = angle1(), a2 = angle2();
- const double val = (value() - minimum()) / (maximum() - minimum());
- // even radius produces less artifacts if no antialiasing is avail
- const int rad = (sx > sy ? sy : sx) &~1;
-
- /* clears the button background */
- pdialcolor(160, 160, 160);
- fl_pie(cx - 2, cy - 2, rad + 4, rad + 4, 0, 360);
-
- /* dark outline */
- fl_color(60, 60, 60);
- fl_pie(cx - 1, cy - 1, rad + 2, rad + 2, 0, 360);
-
- /* Draws the button faceplate, min/max */
- pdialcolor(110, 110, 115);
- fl_pie(cx, cy, rad, rad, 270 - a2, 270 - a1);
-
- /* knob center */
- if (rad > 8) {
- pdialcolor(140, 140, 145);
- fl_pie(cx + 4, cy + 4, rad - 8, rad - 8, 0, 360);
- }
-
- /* value circle */
- double a = -(a2 - a1) * val - a1;
- fl_line_style(0, 2, 0);
- pdialcolor(0, 200, 0);
- fl_arc(cx + 1, cy + 1, rad - 2, rad - 2, a - 90, a1 - 180);
- fl_line_style(0);
-
- /* draw value line */
- int ll = rad/4;
- if (ll < 2) ll = 2;
-
- fl_push_matrix();
-
- fl_translate(cx + rad / 2, cy + rad / 2);
- fl_rotate(a - 90.0f);
-
- fl_translate(rad / 2, 0);
-
- fl_begin_polygon();
- pdialcolor(0, 0, 0);
- fl_vertex(-ll, 0);
- fl_vertex(0, 0);
- fl_end_polygon();
-
- fl_pop_matrix();
-
- #endif
- }
-
- void WidgetPDial::pdialcolor(int r, int g, int b)
- {
- if(active_r())
- fl_color(r, g, b);
- else
- fl_color(160 - (160 - r) / 3, 160 - (160 - b) / 3, 160 - (160 - b) / 3);
- }
-
- void WidgetPDial::tooltip(const char *c)
- {
- tipwin->setText(c);
- textset = true;
- }
-
- void WidgetPDial::getPos()
- {
- if(!pos) {
- tipwin->position(Fl::event_x_root(), Fl::event_y_root() + 20);
- pos = true;
- }
- }
-
- void WidgetPDial::resetPos()
- {
- pos = false;
- }
-
- void WidgetPDial::set_transform(float (*transformer)(float))
- {
- transform = transformer;
- use_rounding = true;
- }
|