Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / cinelerra / timeentry.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 "timeentry.h"
23 #include <string.h>
24
25 TimeEntry::TimeEntry(BC_WindowBase *gui, int x, int y, 
26                 int *output_day, double *output_time,
27                 int time_format, int time_w)
28 {
29         this->gui = gui;
30         this->x = x;
31         this->y = y;
32         this->output_day = output_day;
33         this->output_time = output_time;
34         this->time_format = time_format;
35         this->time_w = time_w;
36         enabled = 1;
37         day_text = 0;
38         day_tumbler = 0;
39         time_text = 0;
40 }
41
42 TimeEntry::~TimeEntry()
43 {
44         delete day_text;
45         delete day_tumbler;
46         delete time_text;
47 }
48 const char* TimeEntry::day_table[] = 
49 {
50         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "*"
51 };
52
53 int TimeEntry::day_to_int(const char *day)
54 {
55         for(int i = 0; i < TOTAL_DAYS; i++)
56                 if(!strcasecmp(day, day_table[i])) return i;
57         return 0;
58 }
59
60
61 void TimeEntry::time_to_hours(char *result, double time)
62 {
63         int hour = (int)(time / 3600);
64         sprintf(result, "%d", hour);
65 }
66
67 void TimeEntry::time_to_minutes(char *result, double time)
68 {
69         int hour = (int)(time / 3600);
70         int minute = (int)(time / 60 - hour * 60);
71         sprintf(result, "%d", minute);
72 }
73
74 void TimeEntry::time_to_seconds(char *result, double time)
75 {
76         int hour = (int)(time / 3600);
77         int minute = (int)(time / 60 - hour * 60);
78         float second = (float)time - (int64_t)hour * 3600 - (int64_t)minute * 60;
79         sprintf(result, "%.3f", second);
80 }
81
82 void TimeEntry::create_objects()
83 {
84         int x = this->x;
85         int y = this->y;
86         int time_w = this->time_w;
87         char string[BCTEXTLEN];
88
89         if(output_day) {
90                 day_text = new DayText(this, x, y, 50, 
91                         day_table, TOTAL_DAYS, day_table[*output_day]);
92                 gui->add_subwindow(day_text);
93                 x += day_text->get_w();
94                 time_w -= day_text->get_w();
95                 day_tumbler = new DayTumbler(this, day_text, x, y);
96                 gui->add_subwindow(day_tumbler);
97                 x += day_tumbler->get_w();
98                 time_w -= day_tumbler->get_w();
99         }
100
101         time_text = new TimeTextBox(this, x, y, time_w, 
102                 Units::totext(string, *output_time, time_format));
103         gui->add_subwindow(time_text);
104
105         time_text->set_separators(Units::format_to_separators(time_format));
106 }
107
108 void TimeEntry::enable()
109 {
110         enabled = 1;
111         if( day_text ) day_text->enable();
112         time_text->enable();
113 }
114
115 void TimeEntry::disable()
116 {
117         enabled = 0;
118         if( day_text ) day_text->disable();
119         time_text->disable();
120 }
121
122 int TimeEntry::get_h()
123 {
124         return time_text->get_h();
125 }
126
127 int TimeEntry::get_w()
128 {
129         int w = 0;
130         if(day_text) w += day_text->get_w();
131         if(day_tumbler) w += day_tumbler->get_w();
132         w += time_text->get_w();
133         return w;
134 }
135
136 void TimeEntry::reposition_window(int x, int y)
137 {
138         int time_w = this->time_w;
139         this->x = x;
140         this->y = y;
141         
142         if(day_text) {
143                 day_text->reposition_window(x, y);
144                 x += day_text->get_w();
145                 time_w -= day_text->get_w();
146         }
147         if(day_tumbler) {
148                 day_tumbler->reposition_window(x, y);
149                 x += day_tumbler->get_w();
150                 time_w -= day_tumbler->get_w();
151         }
152         
153         time_text->reposition_window(x, y, time_w);
154 }
155
156 void TimeEntry::update_day(int day)
157 {
158         if( !output_day ) return;
159         *output_day = day;
160         day_text->update(day_table[day]);
161 }
162
163 void TimeEntry::update_time(double time)
164 {
165         *output_time = time;
166         char text[BCTEXTLEN];
167         Units::totext(text, time, time_format);
168         time_text->update(text);
169 }
170
171 void TimeEntry::update(int *day, double *time)
172 {
173         output_day = day;
174         output_time = time;
175
176         if( day != 0 )
177                 day_text->update(day_table[*day]);
178
179         char text[BCTEXTLEN];
180         Units::totext(text, *time, time_format);
181         time_text->update(text);
182 }
183
184 int TimeEntry::handle_event()
185 {
186         return 1;
187 }
188
189
190
191 DayText::DayText(TimeEntry *timeentry, 
192                 int x, int y, int w, 
193                 const char **table, int table_items,
194                 const char *text)
195  : BC_TextBox(x, y, w, 1, text)
196 {
197         this->timeentry = timeentry;
198         this->table = table;
199         this->table_items = table_items;
200 }
201
202 int DayText::handle_event()
203 {
204         *timeentry->output_day = TimeEntry::day_to_int(get_text());
205         return timeentry->handle_event();
206 }
207
208
209 DayTumbler::DayTumbler(TimeEntry *timeentry, DayText *text, int x, int y)
210  : BC_Tumbler(x, y)
211 {
212         this->timeentry = timeentry;
213         this->text = text;
214 }
215
216
217 int DayTumbler::handle_up_event()
218 {
219         if( !timeentry->enabled ) return 1;
220         *timeentry->output_day += 1;
221         if(*timeentry->output_day >= text->table_items)
222                 *timeentry->output_day = 0;
223         text->update(text->table[*timeentry->output_day]);
224         return timeentry->handle_event();
225 }
226
227 int DayTumbler::handle_down_event()
228 {
229         if( !timeentry->enabled ) return 1;
230         *timeentry->output_day -= 1;
231         if(*timeentry->output_day < 0)
232                 *timeentry->output_day = text->table_items - 1;
233         text->update(text->table[*timeentry->output_day]);
234         return timeentry->handle_event();
235 }
236
237
238
239 TimeEntryTumbler::TimeEntryTumbler(BC_WindowBase *gui, int x, int y,
240                 int *output_day, double *output_time, int incr,
241                 int time_format, int time_w)
242  : TimeEntry(gui, x, y, output_day, output_time,
243                  time_format, time_w-BC_Tumbler::calculate_w())
244 {
245         this->time_w = time_w;
246         this->incr = incr;
247         sec_tumbler = 0;
248 }
249
250 TimeEntryTumbler::~TimeEntryTumbler()
251 {
252         delete sec_tumbler;
253 }
254
255 void TimeEntryTumbler::create_objects()
256 {
257         TimeEntry::create_objects();
258         sec_tumbler = new SecTumbler(this, x+TimeEntry::time_w, y);
259         gui->add_subwindow(sec_tumbler);
260 }
261
262 void TimeEntryTumbler::reposition_window(int x, int y)
263 {
264         TimeEntry::reposition_window(x, y);
265         sec_tumbler->reposition_window(x+TimeEntry::time_w, y);
266 }
267
268 int TimeEntryTumbler::get_h()
269 {
270         return TimeEntry::get_h();
271 }
272
273 int TimeEntryTumbler::get_w()
274 {
275         return TimeEntry::get_w() + BC_Tumbler::calculate_w();
276 }
277
278 int TimeEntryTumbler::handle_up_event()
279 {
280         if( !enabled ) return 1;
281         if( output_time ) {
282                 *output_time += incr;
283                 char text[BCTEXTLEN];
284                 Units::totext(text, *output_time, time_format);
285                 time_text->update(text);
286         }
287         return handle_event();
288 }
289
290 int TimeEntryTumbler::handle_down_event()
291 {
292         if( !enabled ) return 1;
293         if( output_time ) {
294                 *output_time -= incr;
295                 char text[BCTEXTLEN];
296                 Units::totext(text, *output_time, time_format);
297                 time_text->update(text);
298         }
299         return handle_event();
300 }
301
302
303 SecTumbler::SecTumbler(TimeEntryTumbler *timetumbler, int x, int y)
304  : BC_Tumbler(x, y)
305 {
306         this->timetumbler = timetumbler;
307 }
308
309 int SecTumbler::handle_up_event()
310 {
311         return timetumbler->handle_up_event();
312 }
313
314 int SecTumbler::handle_down_event()
315 {
316         return timetumbler->handle_down_event();
317 }
318
319
320
321 TimeTextBox::TimeTextBox(TimeEntry *timeentry, 
322                 int x, int y, int w, char *default_text)
323  : BC_TextBox(x, y, w, 1, default_text)
324 {
325         this->timeentry = timeentry;
326 }
327
328 int TimeTextBox::handle_event()
329 {
330         *timeentry->output_time = Units::text_to_seconds(get_text(),
331                                 48000, timeentry->time_format);
332         return timeentry->handle_event();
333 }
334
335