1 /*
2 * 0BSD
3 *
4 * BSD Zero Clause License
5 *
6 * Copyright (c) 2019 Hermann Meyer
7 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted.
10
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21 #include "xadjustment.h"
22 #include "xadjustment_private.h"
23
24
add_adjustment(Widget_t * w,float std_value,float value,float min_value,float max_value,float step,CL_type type)25 Adjustment_t *add_adjustment(Widget_t *w, float std_value, float value,
26 float min_value,float max_value, float step, CL_type type) {
27 Adjustment_t *adj = (Adjustment_t*)malloc(sizeof(Adjustment_t));
28 assert(adj);
29 adj->log_scale = 20.0;
30
31 switch(type) {
32 case (CL_LOGSCALE) :
33 *(adj) = (Adjustment_t) {
34 .w = w,
35 .std_value = powf(10,(std_value/adj->log_scale)),
36 .value = powf(10,(value/adj->log_scale)),
37 .min_value = powf(10,(min_value/adj->log_scale)),
38 .max_value = powf(10,(max_value/adj->log_scale)),
39 .step = step,
40 .start_value = powf(10,(value/adj->log_scale)),
41 .scale = 1.0,
42 .type = type,
43 .log_scale = adj->log_scale
44 };
45 break;
46 case (CL_LOGARITHMIC) :
47 *(adj) = (Adjustment_t) {
48 .w = w,
49 .std_value = log10(std_value),
50 .value = log10(value),
51 .min_value = log10(min_value),
52 .max_value = log10(max_value),
53 .step = step,
54 .start_value = log10(value),
55 .scale = 1.0,
56 .type = type,
57 .log_scale = adj->log_scale
58 };
59 break;
60 default:
61 *(adj) = (Adjustment_t) {
62 .w = w,
63 .std_value = std_value,
64 .value = value,
65 .min_value = min_value,
66 .max_value = max_value,
67 .step = step,
68 .start_value = value,
69 .scale = 1.0,
70 .type = type,
71 .log_scale = adj->log_scale
72 };
73 break;
74 }
75
76 debug_print("Widget_t add adjustment\n");
77 return adj;
78 }
79
set_adjustment(Adjustment_t * adj,float std_value,float value,float min_value,float max_value,float step,CL_type type)80 void set_adjustment(Adjustment_t *adj, float std_value, float value,
81 float min_value,float max_value, float step, CL_type type) {
82 if (!adj) adj = (Adjustment_t*)malloc(sizeof(Adjustment_t));
83 assert(adj);
84
85 switch(type) {
86 case (CL_LOGSCALE) :
87 *(adj) = (Adjustment_t) {
88 .w = adj->w,
89 .std_value = powf(10,(std_value/adj->log_scale)),
90 .value = powf(10,(value/adj->log_scale)),
91 .min_value = powf(10,(min_value/adj->log_scale)),
92 .max_value = powf(10,(max_value/adj->log_scale)),
93 .step = step,
94 .start_value = powf(10,(value/adj->log_scale)),
95 .scale = 1.0,
96 .type = type,
97 .log_scale = adj->log_scale
98 };
99 break;
100 case (CL_LOGARITHMIC) :
101 *(adj) = (Adjustment_t) {
102 .w = adj->w,
103 .std_value = log10(std_value),
104 .value = log10(value),
105 .min_value = log10(min_value),
106 .max_value = log10(max_value),
107 .step = step,
108 .start_value = log10(value),
109 .scale = 1.0,
110 .type = type,
111 .log_scale = adj->log_scale
112 };
113 break;
114 default:
115 *(adj) = (Adjustment_t) {
116 .w = adj->w,
117 .std_value = std_value,
118 .value = value,
119 .min_value = min_value,
120 .max_value = max_value,
121 .step = step,
122 .start_value = value,
123 .scale = 1.0,
124 .type = type,
125 .log_scale = adj->log_scale
126 };
127 break;
128 }
129
130 debug_print("Widget_t set adjustment\n");
131 }
132
delete_adjustment(Adjustment_t * adj)133 void *delete_adjustment(Adjustment_t *adj) {
134 if(adj) {
135 free(adj);
136 debug_print("Widget_t delete adjustment\n");
137 }
138 return NULL;
139 }
140
adj_set_state(Adjustment_t * adj,float state)141 void adj_set_state(Adjustment_t *adj, float state) {
142 if (!adj) return;
143 float nvalue = min(1.0,max(0.0,state));
144 float value = nvalue * (adj->max_value - adj->min_value) + adj->min_value;
145 check_value_changed(adj, &value);
146 }
147
adj_get_state(Adjustment_t * adj)148 float adj_get_state(Adjustment_t *adj) {
149 if (!adj) return 0.0;
150 return (adj->value - adj->min_value) /
151 (adj->max_value - adj->min_value);
152 }
153
adj_get_value(Adjustment_t * adj)154 float adj_get_value(Adjustment_t *adj) {
155 if (!adj) return 0.0;
156 if (adj->type == CL_LOGSCALE)
157 return log10(adj->value)*adj->log_scale;
158 else if (adj->type == CL_LOGARITHMIC)
159 return powf(10,adj->value);
160 return (adj->value);
161 }
162
adj_set_value(Adjustment_t * adj,float v)163 void adj_set_value(Adjustment_t *adj, float v) {
164 if (!adj) return;
165 if (adj->type == CL_LOGSCALE)
166 v = powf(10,(v/adj->log_scale));
167 else if (adj->type == CL_LOGARITHMIC)
168 v = log10(v);
169 v = min(adj->max_value,max(adj->min_value, v));
170 check_value_changed(adj, &v);
171 }
172
adj_set_start_value(void * w)173 void adj_set_start_value(void *w) {
174 Widget_t * wid = (Widget_t*)w;
175 if(wid->adj_x)wid->adj_x->start_value = wid->adj_x->value;
176 if(wid->adj_y)wid->adj_y->start_value = wid->adj_y->value;
177 }
178
adj_set_scale(Adjustment_t * adj,float value)179 void adj_set_scale(Adjustment_t *adj, float value) {
180 adj->scale = value;
181 }
182
adj_set_log_scale(Adjustment_t * adj,float value)183 void adj_set_log_scale(Adjustment_t *adj, float value) {
184 adj->log_scale = value;
185 }
186
adj_set_motion_state(void * w,float x,float y)187 void adj_set_motion_state(void *w, float x, float y) {
188 Widget_t * wid = (Widget_t*)w;
189 if(wid->adj_x) {
190 float value= wid->adj_x->value;
191 switch(wid->adj_x->type) {
192 case (CL_LOGSCALE):
193 case (CL_LOGARITHMIC):
194 case (CL_CONTINUOS):
195 {
196 float state = (wid->adj_x->start_value - wid->adj_x->min_value) /
197 (wid->adj_x->max_value - wid->adj_x->min_value);
198 float nsteps = wid->adj_x->step / (wid->adj_x->max_value - wid->adj_x->min_value);
199 float nvalue = min(1.0,max(0.0,state + ((float)(x - wid->pos_x)*wid->adj_x->scale *nsteps)));
200 float prevalue = nvalue * (wid->adj_x->max_value - wid->adj_x->min_value) + wid->adj_x->min_value;
201 float mulscale = round(prevalue/wid->adj_x->step);
202 value = min(wid->adj_x->max_value,max(wid->adj_x->min_value,mulscale*wid->adj_x->step));
203 }
204 break;
205 case (CL_VIEWPORTSLIDER):
206 {
207 float state = (wid->adj_x->start_value - wid->adj_x->min_value) /
208 (wid->adj_x->max_value - wid->adj_x->min_value);
209 float nsteps = wid->adj_x->step / (wid->adj_x->max_value - wid->adj_x->min_value);
210 float nvalue = min(1.0,max(0.0,state - ((float)(x - wid->pos_x)*wid->adj_x->scale *nsteps)));
211 float prevalue = nvalue * (wid->adj_x->max_value - wid->adj_x->min_value) + wid->adj_x->min_value;
212 float mulscale = round(prevalue/wid->adj_x->step);
213 value = min(wid->adj_x->max_value,max(wid->adj_x->min_value,mulscale*wid->adj_x->step));
214 }
215 break;
216 case (CL_TOGGLE):
217 // dont toggle on motion!
218 // value = wid->adj_x->value ? 0.0 : 1.0;
219 break;
220 default:
221 break;
222 }
223 check_value_changed(wid->adj_x, &value);
224 }
225 if(wid->adj_y) {
226 float value = wid->adj_y->value;
227 switch(wid->adj_y->type) {
228 case (CL_LOGSCALE):
229 case (CL_LOGARITHMIC):
230 case (CL_CONTINUOS):
231 {
232 float state = (wid->adj_y->start_value - wid->adj_y->min_value) /
233 (wid->adj_y->max_value - wid->adj_y->min_value);
234 float nsteps = wid->adj_y->step / (wid->adj_y->max_value - wid->adj_y->min_value);
235 float nvalue = min(1.0,max(0.0,state + ((float)(wid->pos_y - y)*wid->adj_y->scale *nsteps)));
236 float prevalue = nvalue * (wid->adj_y->max_value - wid->adj_y->min_value) + wid->adj_y->min_value;
237 float mulscale = round(prevalue/wid->adj_y->step);
238 value = min(wid->adj_y->max_value,max(wid->adj_y->min_value,mulscale*wid->adj_y->step));
239 }
240 break;
241 case (CL_VIEWPORTSLIDER):
242 {
243 float state = (wid->adj_y->start_value - wid->adj_y->min_value) /
244 (wid->adj_y->max_value - wid->adj_y->min_value);
245 float nsteps = wid->adj_y->step / (wid->adj_y->max_value - wid->adj_y->min_value);
246 float nvalue = min(1.0,max(0.0,state - ((float)(wid->pos_y - y)*wid->adj_y->scale *nsteps)));
247 float prevalue = nvalue * (wid->adj_y->max_value - wid->adj_y->min_value) + wid->adj_y->min_value;
248 float mulscale = round(prevalue/wid->adj_y->step);
249 value = min(wid->adj_y->max_value,max(wid->adj_y->min_value,mulscale*wid->adj_y->step));
250 }
251 break;
252 case (CL_TOGGLE):
253 // dont toggle on motion!
254 // value = wid->adj_y->value ? 0.0 : 1.0;
255 break;
256 default:
257 break;
258 }
259 check_value_changed(wid->adj_y, &value);
260 }
261 }
262
check_value_changed(Adjustment_t * adj,float * value)263 void check_value_changed(Adjustment_t *adj, float *value) {
264 debug_print("Adjustment_t check_value_changed %f\n", *(value));
265 if(fabs(*(value) - adj->value)>=0.00001) {
266 adj->value = *(value);
267 adj->w->func.adj_callback(adj->w, NULL);
268 adj->w->func.value_changed_callback(adj->w, value);
269 }
270 }
271