emergency fix for loadmode file overwrite bug
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / manualgoto.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2004 Andraz Tori
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 "bcdisplayinfo.h"
23 #include "editpanel.h"
24 #include "language.h"
25 #include "manualgoto.h"
26 #include "mwindow.h"
27 #include "mwindowgui.h"
28 #include "keys.h"
29
30 #define MGT_W xS(250)
31 #define MGT_H yS(80)
32
33 ManualGoto::ManualGoto(MWindow *mwindow, EditPanel *panel)
34  : BC_DialogThread()
35 {
36         this->mwindow = mwindow;
37         this->panel = panel;
38         gotowindow = 0;
39 }
40
41 ManualGoto::~ManualGoto()
42 {
43         close_window();
44 }
45
46 BC_Window *ManualGoto::new_gui()
47 {
48         BC_DisplayInfo dpy_info;
49         int x = dpy_info.get_abs_cursor_x() - MGT_W / 2;
50         int y = dpy_info.get_abs_cursor_y() - MGT_H / 2;
51         gotowindow = new ManualGotoWindow(this, x, y);
52         gotowindow->create_objects();
53         double position = panel->get_position();
54         gotowindow->reset_data(position);
55         gotowindow->show_window();
56         return gotowindow;
57 }
58
59 void ManualGoto::handle_done_event(int result)
60 {
61         if( result ) return;
62         double current_position = panel->get_position();
63         double new_position = gotowindow->get_new_position();
64         char modifier = gotowindow->signtitle->get_text()[0];
65         switch( modifier ) {
66         case '+':  new_position = current_position + new_position;  break;
67         case '-':  new_position = current_position - new_position;  break;
68         default: break;
69         }
70         panel->subwindow->lock_window("ManualGoto::handle_done_event");
71         panel->set_position(new_position);
72         panel->subwindow->unlock_window();
73 }
74
75
76 ManualGotoWindow::ManualGotoWindow(ManualGoto *mango, int x, int y)
77  : BC_Window(_(PROGRAM_NAME ": Goto position"), x, y,
78         MGT_W, MGT_H, MGT_W, MGT_H, 0, 0, 1)
79 {
80         this->mango = mango;
81 }
82
83 ManualGotoWindow::~ManualGotoWindow()
84 {
85 }
86
87 void ManualGotoWindow::reset_data(double position)
88 {
89         lock_window("ManualGotoWindow::reset_data");
90         update_position(position);
91         signtitle->update("=");
92         unlock_window();
93 }
94
95 double ManualGotoWindow::get_new_position()
96 {
97         int64_t hh = atoi(hours->get_text());
98         int mm = atoi(minutes->get_text());
99         int ss = atoi(seconds->get_text());
100         int ms = atoi(msecs->get_text());
101
102         double seconds = ((((hh * 60) + mm) * 60) + ss) + (1.0 * ms) / 1000;
103         return seconds;
104 }
105
106 void ManualGotoWindow::update_position(double position)
107 {
108         if( position < 0 ) position = 0;
109         int64_t pos = position;
110         int64_t hour = (pos / 3600);
111         int minute = (pos / 60 - hour * 60);
112         int second = pos - hour * 3600 - minute * 60;
113         int thousandths = ((int64_t)(position * 1000)) % 1000;
114
115         hours->update((int)hour);
116         minutes->update(minute);
117         seconds->update(second);
118         msecs->update(thousandths);
119 }
120
121 void ManualGotoWindow::create_objects()
122 {
123         lock_window("ManualGotoWindow::create_objects");
124         int x = xS(76), y = yS(5);
125
126         BC_Title *title = new BC_Title(x - 2, y, _("hour  min     sec     msec"), SMALLFONT);
127         add_subwindow(title);  y += title->get_h() + 3;
128
129         signtitle = new BC_Title(x - xS(17), y, "=", LARGEFONT);
130         add_subwindow(signtitle);
131         hours = new ManualGotoNumber(this, x, y, xS(16), 9, "%i");
132         add_subwindow(hours);    x += hours->get_w() + 4;
133         minutes = new ManualGotoNumber(this, x, y, xS(26), 59, "%02i");
134         add_subwindow(minutes);  x += minutes->get_w() + 4;
135         seconds = new ManualGotoNumber(this, x, y, xS(26), 59, "%02i");
136         add_subwindow(seconds);  x += seconds->get_w() + 4;
137         msecs = new ManualGotoNumber(this, x, y, xS(34), 999, "%03i");
138         add_subwindow(msecs);
139         y += hours->get_h() + yS(10);
140
141         add_subwindow(new BC_OKButton(this));
142         add_subwindow(new BC_CancelButton(this));
143         unlock_window();
144 }
145
146
147 ManualGotoNumber::ManualGotoNumber(ManualGotoWindow *window, int x, int y, int w,
148         int max, const char *format)
149  : BC_TextBox(x, y, w, 1, "")
150 {
151         this->window = window;
152         this->max = max;
153         this->format = format;
154 }
155
156 int ManualGotoNumber::handle_event()
157 {
158         return 1;
159 }
160
161 void ManualGotoNumber::update(int64_t v)
162 {
163         char text[BCTEXTLEN];
164         if( v < 0 ) v = atoll(get_text());
165         if( v > max ) v = max;
166         sprintf(text, format, v);
167         BC_TextBox::update(text);
168 }
169
170 int ManualGotoNumber::keypress_event()
171 {
172         int key = get_keypress();
173         if( key == '+' || key == '-' || key == '=' ) {
174                 window->signtitle->update(key);
175                 return 1;
176         }
177         if( key == '.' || key == TAB ) {
178                 window->cycle_textboxes(1);
179                 return 1;
180         }
181
182         int chars = 1, m = max;
183         while( (m /= 10) > 0 ) ++chars;
184         int in_textlen = strlen(get_text());
185         if( in_textlen >= chars )
186                 BC_TextBox::update("");
187         int result = BC_TextBox::keypress_event();
188         int out_textlen = strlen(get_text());
189         if( out_textlen >= chars && get_ibeam_letter() >= chars )
190                 window->cycle_textboxes(1);
191         return result;
192 }
193
194