r956: README.BUILD - add more library recommendations
[cinelerra_cv/ct.git] / cinelerra / zoompanel.C
blob083d9fad052a084b03efc394ef69c1f149933f1c
1 #include "clip.h"
2 #include "edl.h"
3 #include "edlsession.h"
4 #include "mwindow.h"
5 #include "mwindowgui.h"
6 #include "theme.h"
7 #include "trackcanvas.h"
8 #include "units.h"
9 #include "vframe.h"
10 #include "zoompanel.h"
13 ZoomHash::ZoomHash(double value, char *text)
15         this->value = value;
16         this->text = new char[strlen(text) + 1];
17         strcpy(this->text, text);
20 ZoomHash::~ZoomHash()
22         delete [] text;
41 ZoomPanel::ZoomPanel(MWindow *mwindow, 
42         BC_WindowBase *subwindow, 
43         double value, 
44         int x, 
45         int y,
46         int w, 
47         double min,
48         double max,
49         int zoom_type)
51         this->mwindow = mwindow;
52         this->subwindow = subwindow;
53         this->x = x;
54         this->y = y;
55         this->w = w;
56         this->value = value;
57         this->min = min;
58         this->max = max;
59         this->zoom_type = zoom_type;
60         this->menu_images = 0;
61         this->tumbler_images = 0;
62         this->user_table = 0;
63         this->user_size = 0;
66 ZoomPanel::ZoomPanel(MWindow *mwindow, 
67         BC_WindowBase *subwindow, 
68         double value, 
69         int x, 
70         int y,
71         int w, 
72         double *user_table,
73         int user_size,
74         int zoom_type)
76         this->mwindow = mwindow;
77         this->subwindow = subwindow;
78         this->x = x;
79         this->y = y;
80         this->w = w;
81         this->value = value;
82         this->min = min;
83         this->max = max;
84         this->zoom_type = zoom_type;
85         this->menu_images = 0;
86         this->tumbler_images = 0;
87         this->user_table = user_table;
88         this->user_size = user_size;
91 ZoomPanel::~ZoomPanel()
93         delete zoom_text;
94         delete zoom_tumbler;
95         zoom_table.remove_all_objects();
98 void ZoomPanel::calculate_menu()
100         if(user_size)
101         {
102                 for(int i = 0; i < user_size; i++)
103                 {
104                         zoom_text->add_item(new BC_MenuItem(value_to_text(user_table[i], 0)));
105                         zoom_table.append(new ZoomHash(user_table[i], value_to_text(user_table[i], 0)));
106                 }
107         }
108         else
109         {
110                 for(double zoom = min; zoom <= max; zoom *= 2)
111                 {
112                         zoom_text->add_item(new BC_MenuItem(value_to_text(zoom, 0)));
113                         zoom_table.append(new ZoomHash(zoom, value_to_text(zoom, 0)));
114                 }
115         }
118 void ZoomPanel::update_menu()
120         while(zoom_text->total_items())
121         {
122                 zoom_text->remove_item(0);
123         }
125         zoom_table.remove_all_objects();
126         calculate_menu();
129 void ZoomPanel::set_menu_images(VFrame **data)
131         this->menu_images = data;
134 void ZoomPanel::set_tumbler_images(VFrame **data)
136         this->tumbler_images = data;
139 int ZoomPanel::create_objects()
141         subwindow->add_subwindow(zoom_text = new ZoomPopup(mwindow, 
142                 this, 
143                 x, 
144                 y));
145         x += zoom_text->get_w();
146         subwindow->add_subwindow(zoom_tumbler = new ZoomTumbler(mwindow, 
147                 this, 
148                 x, 
149                 y));
150         calculate_menu();
151         return 0;
154 void ZoomPanel::reposition_window(int x, int y)
156         zoom_text->reposition_window(x, y);
157         x += zoom_text->get_w();
158         zoom_tumbler->reposition_window(x, y);
162 int ZoomPanel::get_w()
164         return zoom_text->get_w() + zoom_tumbler->get_w();
167 double ZoomPanel::get_value()
169         return value;
172 char* ZoomPanel::get_text()
174         return zoom_text->get_text();
177 void ZoomPanel::set_text(char *text)
179         zoom_text->set_text(text);
182 void ZoomPanel::update(double value)
184         this->value = value;
185         zoom_text->set_text(value_to_text(value));
188 void ZoomPanel::update(char *value)
190         zoom_text->set_text(value);
194 char* ZoomPanel::value_to_text(double value, int use_table)
196         if(use_table)
197         {
198                 for(int i = 0; i < zoom_table.total; i++)
199                 {
200 //printf("ZoomPanel::value_to_text %p\n", zoom_table.values[i]);
201                         if(EQUIV(zoom_table.values[i]->value, value))
202                                 return zoom_table.values[i]->text;
203                 }
204 //printf("ZoomPanel::value_to_text: should never get here\n");
205                 return zoom_table.values[0]->text;
206         }
208         switch(zoom_type)
209         {
210                 case ZOOM_PERCENTAGE:
211                         sprintf(string, "%d%%", (int)(value * 100));
212                         break;
214                 case ZOOM_FLOAT:
215                         sprintf(string, "%.1f", value);
216                         break;
218                 case ZOOM_LONG:
219                         sprintf(string, "%ld", (long)value);
220                         break;
222                 case ZOOM_TIME:
223                 {
224                         double total_seconds = (double)mwindow->gui->canvas->get_w() * 
225                                 value / 
226                                 mwindow->edl->session->sample_rate;
227                         Units::totext(string, 
228                                 total_seconds, 
229                                 mwindow->edl->session->time_format, 
230                                 mwindow->edl->session->sample_rate, 
231                                 mwindow->edl->session->frame_rate, 
232                                 mwindow->edl->session->frames_per_foot);
233                         break;
234                 }
235         }
236         return string;
239 double ZoomPanel::text_to_zoom(char *text, int use_table)
241         if(use_table)
242         {
243                 for(int i = 0; i < zoom_table.total; i++)
244                 {
245                         if(!strcasecmp(text, zoom_table.values[i]->text))
246                                 return zoom_table.values[i]->value;
247                 }
248                 return zoom_table.values[0]->value;
249         }
251         switch(zoom_type)
252         {
253                 case ZOOM_PERCENTAGE:
254                         return atof(text) / 100;
255                         break;
256                 case ZOOM_FLOAT:
257                 case ZOOM_LONG:
258                         return atof(text);
259                         break;
260                 case ZOOM_TIME:
261                 {
262                         double result = 1;
263                         double total_samples = Units::fromtext(text, 
264                                 mwindow->edl->session->sample_rate, 
265                                 mwindow->edl->session->time_format, 
266                                 mwindow->edl->session->frame_rate,
267                                 mwindow->edl->session->frames_per_foot);
268                         total_samples /= mwindow->gui->canvas->get_w();
269                         double difference = fabs(total_samples - result);
270                         while(fabs(result - total_samples) <= difference)
271                         {
272                                 difference = fabs(result - total_samples);
273                                 result *= 2;
274                         }
275                         return result;
276                         break;
277                 }
278         }
287 ZoomPopup::ZoomPopup(MWindow *mwindow, ZoomPanel *panel, int x, int y)
288  : BC_PopupMenu(x, 
289                 y, 
290                 panel->w, 
291                 panel->value_to_text(panel->value, 0), 
292                 1,
293                 panel->menu_images)
295         this->mwindow = mwindow;
296         this->panel = panel;
299 ZoomPopup::~ZoomPopup()
303 int ZoomPopup::handle_event()
305         panel->value = panel->text_to_zoom(get_text());
306         panel->handle_event();
307         return 1;
312 ZoomTumbler::ZoomTumbler(MWindow *mwindow, ZoomPanel *panel, int x, int y)
313  : BC_Tumbler(x, 
314         y,
315         panel->tumbler_images)
317         this->mwindow = mwindow;
318         this->panel = panel;
321 ZoomTumbler::~ZoomTumbler()
325 int ZoomTumbler::handle_up_event()
327         if(panel->user_table)
328         {
329                 int current_index = 0;
330                 for(current_index = 0; current_index < panel->user_size; current_index++)
331                         if(EQUIV(panel->user_table[current_index], panel->value)) break;
332                 current_index++;
333                 CLAMP(current_index, 0, panel->user_size - 1);
334                 panel->value = panel->user_table[current_index];
335         }
336         else
337         {
338                 panel->value *= 2;
339                 RECLIP(panel->value, panel->min, panel->max);
340         }
342         panel->zoom_text->set_text(panel->value_to_text(panel->value));
343         panel->handle_event();
344         return 1;
347 int ZoomTumbler::handle_down_event()
349         if(panel->user_table)
350         {
351                 int current_index = 0;
352                 for(current_index = 0; current_index < panel->user_size; current_index++)
353                         if(EQUIV(panel->user_table[current_index], panel->value)) break;
354                 current_index--;
355                 CLAMP(current_index, 0, panel->user_size - 1);
356                 panel->value = panel->user_table[current_index];
357         }
358         else
359         {
360                 panel->value /= 2;
361                 RECLIP(panel->value, panel->min, panel->max);
362         }
363         panel->zoom_text->set_text(panel->value_to_text(panel->value));
364         panel->handle_event();
365         return 1;