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