LMMS
Loading...
Searching...
No Matches
Fl_Osc_Slider.cpp
Go to the documentation of this file.
1/*
2 ZynAddSubFX - a software synthesizer
3
4 Fl_Osc_Slider.cpp - OSC Based Slider
5 Copyright (C) 2016 Mark McCurry
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11*/
12#include <FL/Fl.H>
13#include "Fl_Osc_Slider.H"
14#include "Fl_Osc_Interface.h"
15#include "Fl_Osc_Pane.H"
16#include <cstdlib>
17#include <cstring>
18#include <cmath>
19#include <cassert>
20#include <sstream>
21#include "../Misc/Util.h"
22
23static double min__(double a, double b)
24{
25 return a<b?a:b;
26}
27
28Fl_Osc_Slider::Fl_Osc_Slider(int X, int Y, int W, int H, const char *label)
29 :Fl_Slider(X,Y,W,H,label), Fl_Osc_Widget(this), reset_value(0),
31{
32 //bounds(0.0f,1.0f);
33 Fl_Slider::callback(Fl_Osc_Slider::_cb);
34}
35
36void Fl_Osc_Slider::init(std::string path_, char type_)
37{
38 osc_type = type_;
39 ext = path_;
40 oscRegister(ext.c_str());
41}
42
45
47{
48 const float min_ = min__(minimum(), maximum());//flipped sliders
49 Fl_Slider::value(v+min_+value()-floorf(value()));
50}
51
53{
54 const float min_ = min__(minimum(), maximum());//flipped sliders
55 Fl_Slider::value(v+min_);
56}
57
59{
60 const float min_ = min__(minimum(), maximum());//flipped sliders
61 Fl_Slider::value(v+min_+value()-floorf(value()));
62}
63
65{
66 const float min_ = min__(minimum(), maximum());//flipped sliders
67 const float val = Fl_Slider::value();
68 if(osc_type == 'f')
69 oscWrite(ext, "f", val-min_);
70 else if(osc_type == 'i')
71 oscWrite(ext, "i", (int)(val-min_));
72 else {
73 fprintf(stderr, "invalid `c' from slider %s%s, using `i'\n", loc.c_str(), ext.c_str());
74 oscWrite(ext, "i", (int)(val-min_));
75 }
76 //OSC_value(val);
77
78 if(cb_data.first)
79 cb_data.first(this, cb_data.second);
80}
81
82void Fl_Osc_Slider::callback(Fl_Callback *cb, void *p)
83{
84 cb_data.first = cb;
85 cb_data.second = p;
86}
87
88#define MOD_MASK (FL_CTRL | FL_SHIFT)
89
90int Fl_Osc_Slider::handle(int ev, int X, int Y, int W, int H)
91{
92 bool middle_mouse = (ev == FL_PUSH && Fl::event_state(FL_BUTTON2) && !Fl::event_shift());
93 bool ctl_click = (ev == FL_PUSH && Fl::event_state(FL_BUTTON3) && Fl::event_ctrl());
94 bool shift_middle = (ev == FL_PUSH && Fl::event_state(FL_BUTTON2) && Fl::event_shift());
95 if(middle_mouse || ctl_click) {
96 printf("Trying to learn...\n");
97 osc->write("/learn", "s", (loc+ext).c_str());
98 return 1;
99 } else if(shift_middle) {
100 osc->write("/unlearn", "s", (loc+ext).c_str());
101 return 1;
102 }
103
104 int handled;
105 float rounded;
106
107 const float range = maximum() - minimum();
108 const float absrange = (range > 0 ? range : -range)+1;
109 int old_mod_state;
110 const float normal_step = range / W;
111
112 switch (ev) {
113 case FL_PUSH:
114 just_pushed = true;
115 mod_state = Fl::event_state() & MOD_MASK;
116 slow_state = 0;
117 start_pos = horizontal() ? Fl::event_x() : Fl::event_y();
118 handled = mod_state ? 1 : Fl_Slider::handle(ev, X, Y, W, H);
119 break;
120 case FL_MOUSEWHEEL:
121 mod_state = Fl::event_state() & MOD_MASK;
122 if (Fl::event_buttons())
123 return 1;
124 if (this == Fl::belowmouse() && Fl::e_dy != 0) {
125 int step_ = 1, divisor = 16;
126
127 switch (mod_state) {
128 case FL_SHIFT:
129 if (absrange > divisor * 8)
130 step_ = 8;
131 case FL_SHIFT | FL_CTRL:
132 break;
133 case FL_CTRL:
134 divisor = 128;
135 default:
136 step_ = absrange / divisor;
137 if (step_ < 1)
138 step_ = 1;
139 }
140 int dy = minimum() <= maximum() ? -Fl::e_dy : Fl::e_dy;
141 // Flip sense for vertical sliders.
142 dy = this->horizontal() ? dy : -dy;
143 handle_drag(clamp(value() + step_ * dy));
144 }
145 return 1;
146 case FL_RELEASE:
147 handled = Fl_Slider::handle(ev, X, Y, W, H);
148 if (Fl::event_clicks() == 1) {
149 Fl::event_clicks(0);
151 } else {
152 rounded = floorf(value() + 0.5);
153 value(clamp(rounded));
154 }
155 value_damage();
156 do_callback();
157 break;
158 case FL_DRAG: {
159 old_mod_state = mod_state;
160 mod_state = Fl::event_state() & MOD_MASK;
161 if (slow_state == 0 && mod_state == 0) {
162 int delta = (horizontal() ? Fl::event_x() : Fl::event_y())
163 - start_pos;
164 if (delta < -1 || delta > 1)
165 Fl::event_clicks(0);
166 return Fl_Slider::handle(ev, X, Y, W, H);
167 }
168
169 if (mod_state != 0) {
170 slow_state = 1;
171 } else if (slow_state == 1)
172 slow_state = 2;
173
174 if (just_pushed || old_mod_state != mod_state) {
175 just_pushed = false;
176 old_value = value();
177 start_pos = horizontal() ? Fl::event_x() : Fl::event_y();
178 if (slow_state == 1) {
179 denominator = 2.0;
180 float step_ = step();
181 if (step_ == 0) step_ = 1;
182
183 if (absrange / W / step_ > 32)
184 switch (mod_state) {
185 case FL_CTRL:
186 denominator = 0.15;
187 break;
188 case FL_SHIFT:
189 denominator = 0.7;
190 break;
191 case MOD_MASK:
192 denominator = 3.0;
193 break;
194 }
195 else if (mod_state & FL_SHIFT)
196 denominator = 5.0;
197
198 if (range < 0)
199 denominator *= -1;
200 }
201 }
202
203 int delta = (horizontal() ? Fl::event_x() : Fl::event_y())
204 - start_pos;
205 if (delta < -1 || delta > 1)
206 Fl::event_clicks(0);
207 float new_value;
208 if (slow_state == 1) {
209 new_value = old_value + delta / denominator;
210 } else {
211 new_value = old_value + delta * normal_step;
212 }
213 const float clamped_value = clamp(new_value);
214 rounded = floor(clamped_value + 0.5);
215 if (new_value != clamped_value) {
216 start_pos = horizontal() ? Fl::event_x() : Fl::event_y();
217 old_value = rounded;
218 if (slow_state == 2 &&
219 ((horizontal() &&
220 (Fl::event_x() < X || Fl::event_x() > X + W)) ||
221 (!horizontal() &&
222 (Fl::event_y() < Y || Fl::event_y() > Y + H))))
223 slow_state = 0;
224 }
225 value(rounded);
226 value_damage();
227 do_callback();
228
229 handled = 1;
230 break;
231 }
232 default:
233 handled = Fl_Slider::handle(ev, X, Y, W, H);
234 }
235
236 return handled;
237}
238
240 return handle(ev,
241 x()+Fl::box_dx(box()),
242 y()+Fl::box_dy(box()),
243 w()-Fl::box_dw(box()),
244 h()-Fl::box_dh(box()));
245}
246
248{
249 oscWrite(ext, "");
250}
251
252void Fl_Osc_Slider::_cb(Fl_Widget *w, void *)
253{
254 static_cast<Fl_Osc_Slider*>(w)->cb();
255}
#define NULL
Definition CarlaBridgeFormat.cpp:30
#define MOD_MASK
Definition Fl_Osc_Slider.cpp:88
static double min__(double a, double b)
Definition Fl_Osc_Slider.cpp:23
uint8_t a
Definition Spc_Cpu.h:141
T clamp(T value, T lower, T upper)
Definition basics.h:135
char osc_type
Definition Fl_Osc_Slider.H:42
std::pair< Fl_Callback *, void * > cb_data
Definition Fl_Osc_Slider.H:43
float old_value
Definition Fl_Osc_Slider.H:46
virtual void cb(void)
Definition Fl_Osc_Slider.cpp:64
Fl_Osc_Slider(int X, int Y, int W, int H, const char *label=NULL)
Definition Fl_Osc_Slider.cpp:28
void update(void)
Definition Fl_Osc_Slider.cpp:247
float denominator
Definition Fl_Osc_Slider.H:51
int handle(int ev, int X, int Y, int W, int H)
Definition Fl_Osc_Slider.cpp:90
void OSC_value(int) override
Definition Fl_Osc_Slider.cpp:46
void init(std::string, char type='f')
Definition Fl_Osc_Slider.cpp:36
virtual ~Fl_Osc_Slider(void)
Definition Fl_Osc_Slider.cpp:43
int slow_state
Definition Fl_Osc_Slider.H:48
bool just_pushed
Definition Fl_Osc_Slider.H:50
float reset_value
Definition Fl_Osc_Slider.H:40
int start_pos
Definition Fl_Osc_Slider.H:49
void callback(Fl_Callback *cb, void *p=NULL)
Definition Fl_Osc_Slider.cpp:82
int mod_state
Definition Fl_Osc_Slider.H:47
static void _cb(Fl_Widget *w, void *)
Definition Fl_Osc_Slider.cpp:252
Fl_Osc_Interface * osc
Definition Fl_Osc_Widget.H:65
std::string ext
Definition Fl_Osc_Widget.H:64
Fl_Osc_Widget(void)
Definition Fl_Osc_Widget.cpp:16
std::string loc
Definition Fl_Osc_Widget.H:62
void oscRegister(const char *path)
Definition Fl_Osc_Widget.cpp:91
void oscWrite(std::string path, const char *args,...)
Definition Fl_Osc_Widget.cpp:60
UINT_D64 w
Definition inflate.c:942
int y
Definition inflate.c:1588
unsigned v[N_MAX]
Definition inflate.c:1584
unsigned x[BMAX+1]
Definition inflate.c:1586
static PuglViewHint int value
Definition pugl.h:1708
int val
Definition jpeglib.h:956
#define X(str)
Definition juce_LV2Common.h:197
#define true
Definition ordinals.h:82
Definition jquant2.c:258
uch * p
Definition crypt.c:594
uch h[RAND_HEAD_LEN]
Definition crypt.c:459
b
Definition crypt.c:628
dy
Definition zipinfo.c:2288