7dd78161597ce4fb947adb042fc6f26e4283c8c9
[goodguy/history.git] / cinelerra-5.1 / guicast / bctumble.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcpixmap.h"
23 #include "bcresources.h"
24 #include "bctextbox.h"
25 #include "bctumble.h"
26 #include "math.h"
27 #include "vframe.h"
28
29
30 #define TUMBLE_UP 0
31 #define TUMBLE_UPHI 1
32 #define TUMBLEBOTTOM_DN 2
33 #define TUMBLETOP_DN 3
34 #define TOTAL_STATES 4
35
36 BC_Tumbler::BC_Tumbler(int x, int y, VFrame **data)
37  : BC_SubWindow(x, y, 0, 0, -1)
38 {
39         for(int i = 0; i < TOTAL_STATES; i++)
40                 images[i] = 0;
41         status = TUMBLE_UP;
42         repeat_count = 0;
43         this->data = data;
44 }
45
46
47 BC_Tumbler::~BC_Tumbler()
48 {
49         for(int i = 0; i < TOTAL_STATES; i ++)
50                 delete images[i];
51 }
52
53
54 int BC_Tumbler::calculate_w()
55 {
56         return BC_WindowBase::get_resources()->tumble_data[0]->get_w();
57 }
58
59 int BC_Tumbler::calculate_h()
60 {
61         return BC_WindowBase::get_resources()->tumble_data[0]->get_h();
62 }
63
64
65 int BC_Tumbler::initialize()
66 {
67 // Get the image
68         if(data)
69                 set_images(data);
70         else
71                 set_images(get_resources()->tumble_data);
72         w = images[TUMBLE_UP]->get_w();
73         h = images[TUMBLE_UP]->get_h();
74
75 // Create the subwindow
76         BC_SubWindow::initialize();
77
78 // Display the bitmap
79         draw_face(0);
80         return 0;
81 }
82
83 int BC_Tumbler::reposition_window(int x, int y, int w, int h)
84 {
85         if (w > 0 || h > 0)
86                 printf("BC_Tumbler::reposition_window - w & h haven't been implemented yet!! (probably never will be)");
87
88         BC_WindowBase::reposition_window(x, y);
89         draw_face(0);
90         return 0;
91 }
92
93
94 int BC_Tumbler::update_bitmaps(VFrame **data)
95 {
96         set_images(data);
97         draw_top_background(parent_window, 0, 0, w, h);
98         draw_face(1);
99         return 0;
100 }
101
102 int BC_Tumbler::set_images(VFrame **data)
103 {
104         for(int i = 0; i < TOTAL_STATES; i++)
105         {
106                 if(images[i]) delete images[i];
107                 images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
108         }
109
110         return 0;
111 }
112
113 int BC_Tumbler::draw_face(int flush)
114 {
115         draw_top_background(parent_window, 0, 0, w, h);
116         pixmap->draw_pixmap(images[status],
117                         0,
118                         0,
119                         w,
120                         h,
121                         0,
122                         0);
123         flash(flush);
124         return 0;
125 }
126
127 int BC_Tumbler::repeat_event(int64_t duration)
128 {
129 //printf("BC_Tumbler::repeat_event 1 %d\n", duration);
130         if(duration == top_level->get_resources()->tooltip_delay)
131         {
132                 if(tooltip_text && tooltip_text[0] != 0 &&
133                         status == TUMBLE_UPHI && !tooltip_done)
134                 {
135                         show_tooltip();
136                         tooltip_done = 1;
137                         return 1;
138                 }
139         }
140         else
141         if(duration == top_level->get_resources()->tumble_duration)
142         {
143 //printf("BC_Tumbler::repeat_event 2\n");
144                 repeat_count++;
145 // delay the 1st repeat
146                 if(repeat_count > 1 && repeat_count < 5) return 0;
147                 if(status == TUMBLETOP_DN)
148                 {
149                         handle_up_event();
150                         return 1;
151                 }
152                 else
153                 if(status == TUMBLEBOTTOM_DN)
154                 {
155                         handle_down_event();
156                         return 1;
157                 }
158         }
159         return 0;
160 }
161
162 int BC_Tumbler::cursor_enter_event()
163 {
164         if(top_level->event_win == win)
165         {
166                 tooltip_done = 0;
167                 if(! top_level->button_down && status == TUMBLE_UP)
168                 {
169                         status = TUMBLE_UPHI;
170                         draw_face(1);
171                 }
172         }
173         return 0;
174 }
175
176 int BC_Tumbler::cursor_leave_event()
177 {
178         hide_tooltip();
179         if(status == TUMBLE_UPHI)
180         {
181                 status = TUMBLE_UP;
182                 draw_face(1);
183         }
184         return 0;
185 }
186
187 int BC_Tumbler::button_press_event()
188 {
189         hide_tooltip();
190         if(top_level->event_win == win)
191         {
192 //printf("BC_Tumbler::button_press_event 1 %d\n", get_buttonpress());
193                 if(get_buttonpress() == 4)
194                 {
195                         status = TUMBLETOP_DN;
196                         draw_face(1);
197                         handle_up_event();
198 //                      repeat_count = 0;
199 //                      repeat_event(top_level->get_resources()->tumble_duration);
200                 }
201                 else
202                 if(get_buttonpress() == 5)
203                 {
204                         status = TUMBLEBOTTOM_DN;
205                         draw_face(1);
206                         handle_down_event();
207 //                      repeat_count = 0;
208 //                      repeat_event(top_level->get_resources()->tumble_duration);
209                 }
210                 else
211                 {
212                         if(top_level->cursor_y < get_h() / 2)
213                         {
214                                 status = TUMBLETOP_DN;
215                         }
216                         else
217                         {
218                                 status = TUMBLEBOTTOM_DN;
219                         }
220
221                         draw_face(1);
222
223                         top_level->set_repeat(top_level->get_resources()->tumble_duration);
224                         repeat_count = 0;
225                         repeat_event(top_level->get_resources()->tumble_duration);
226 //printf("BC_Tumbler::button_press_event 2 %d\n", get_buttonpress());
227                 }
228                 return 1;
229         }
230         return 0;
231 }
232
233 int BC_Tumbler::button_release_event()
234 {
235         hide_tooltip();
236         if(top_level->event_win == win)
237         {
238                 if(status == TUMBLEBOTTOM_DN || status == TUMBLETOP_DN)
239                 {
240                         top_level->unset_repeat(top_level->get_resources()->tumble_duration);
241                         if(cursor_inside())
242                                 status = TUMBLE_UPHI;
243                         else
244                                 status = TUMBLE_UP;
245                 }
246                 draw_face(1);
247         }
248         return 0;
249 }
250
251 int BC_Tumbler::cursor_motion_event()
252 {
253         if(top_level->button_down && top_level->event_win == win &&
254                 !cursor_inside() &&
255                 !(status == TUMBLETOP_DN || status == TUMBLEBOTTOM_DN))
256         {
257                 status = TUMBLE_UP;
258                 draw_face(1);
259         }
260         return 0;
261 }
262
263
264
265
266 BC_ITumbler::BC_ITumbler(BC_TextBox *textbox, int64_t min, int64_t max, int x, int y)
267  : BC_Tumbler(x, y)
268 {
269         this->textbox = textbox;
270         this->min = min;
271         this->max = max;
272         this->increment = 1;
273 }
274
275 BC_ITumbler::~BC_ITumbler()
276 {
277 }
278
279 void BC_ITumbler::set_increment(float value)
280 {
281         this->increment = (int64_t)value;
282         if(increment < 1) increment = 1;
283 }
284
285 int BC_ITumbler::handle_up_event()
286 {
287         int64_t value = atol(textbox->get_text());
288         value += increment;
289         if(value > max) value = max;
290         textbox->update(value);
291         textbox->handle_event();
292         return 1;
293 }
294
295 int BC_ITumbler::handle_down_event()
296 {
297         int64_t value = atol(textbox->get_text());
298         value -= increment;
299         if(value < min) value = min;
300         textbox->update(value);
301         textbox->handle_event();
302         return 1;
303 }
304
305 void BC_ITumbler::set_boundaries(int64_t min, int64_t max)
306 {
307         this->min = min;
308         this->max = max;
309 }
310
311
312
313
314
315
316
317
318
319
320 BC_FTumbler::BC_FTumbler(BC_TextBox *textbox,
321         float min,
322         float max,
323         int x,
324         int y)
325  : BC_Tumbler(x, y)
326 {
327         this->textbox = textbox;
328         this->min = min;
329         this->max = max;
330         this->increment = 1.0;
331         this->log_floatincrement = 0;
332 }
333
334 BC_FTumbler::~BC_FTumbler()
335 {
336 }
337
338 int BC_FTumbler::handle_up_event()
339 {
340         float value = atof(textbox->get_text());
341         if (log_floatincrement) {
342                 // round off to to current precision (i.e. 250 -> 200)
343                 float cp = floor(log(value)/log(10) + 0.0001);
344                 value = floor((value/pow(10,cp))+ 0.0001)*pow(10,cp);
345                 value += pow(10,cp);
346         }
347         else
348         value += increment;
349         if(value > max) value = max;
350         textbox->update(value);
351         textbox->handle_event();
352         return 1;
353 }
354
355 int BC_FTumbler::handle_down_event()
356 {
357         float value = atof(textbox->get_text());
358         if (log_floatincrement) {
359                 // round off to to current precision (i.e. 250 -> 200)
360                 float cp = floor(log(value)/log(10));
361                 value = floor(value/pow(10,cp))*pow(10,cp);
362                 // Need to make it so that: [.001 .01 .1 1 10 100] => [.0001 .001 .01 .1 1 10]
363                 cp = floor(log(value)/log(10)-.01);
364                 value -= pow(10,cp);
365         }
366         else
367         value -= increment;
368         if(value < min) value = min;
369         textbox->update(value);
370         textbox->handle_event();
371         return 1;
372 }
373
374 void BC_FTumbler::set_boundaries(float min, float max)
375 {
376         this->min = min;
377         this->max = max;
378 }
379
380 void BC_FTumbler::set_increment(float value)
381 {
382         this->increment = value;
383 }
384
385 void BC_FTumbler::set_log_floatincrement(int value)
386 {
387         this->log_floatincrement = value;
388 }