rendering took msg, bg render active test, crikey show window
[goodguy/history.git] / cinelerra-5.1 / plugins / crikey / crikeywindow.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2014 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include "automation.h"
22 #include "bcdisplayinfo.h"
23 #include "clip.h"
24 #include "crikey.h"
25 #include "crikeywindow.h"
26 #include "cwindow.h"
27 #include "cwindowgui.h"
28 #include "edl.h"
29 #include "edlsession.h"
30 #include "language.h"
31 #include "mwindow.h"
32 #include "plugin.h"
33 #include "pluginserver.h"
34 #include "theme.h"
35 #include "track.h"
36
37 #define COLOR_W 50
38 #define COLOR_H 30
39
40 CriKeyNum::CriKeyNum(CriKeyWindow *gui, int x, int y, float &output)
41  : BC_TumbleTextBox(gui, output, -32767.0f, 32767.0f, x, y, 80)
42 {
43         this->gui = gui;
44         this->output = &output;
45         set_increment(1);
46         set_precision(1);
47 }
48
49 CriKeyNum::~CriKeyNum()
50 {
51 }
52
53 int CriKeyNum::handle_event()
54 {
55         *output = atof(get_text());
56         gui->plugin->send_configure_change();
57         return 1;
58 }
59
60 int CriKeyDrawModeItem::handle_event()
61 {
62         ((CriKeyDrawMode *)get_popup_menu())->update(id);
63         return 1;
64 }
65 CriKeyDrawMode::CriKeyDrawMode(CriKeyWindow *gui, int x, int y)
66  : BC_PopupMenu(x, y, 100, "", 1)
67 {
68         this->gui = gui;
69         draw_modes[DRAW_ALPHA]     = _("Alpha");
70         draw_modes[DRAW_EDGE]      = _("Edge");
71         draw_modes[DRAW_MASK]      = _("Mask");
72         mode = -1;
73 }
74 void CriKeyDrawMode::create_objects()
75 {
76         for( int i=0; i<DRAW_MODES; ++i )
77                 add_item(new CriKeyDrawModeItem(draw_modes[i], i));
78         update(gui->plugin->config.draw_mode, 0);
79 }
80 void CriKeyDrawMode::update(int mode, int send)
81 {
82         if( this->mode == mode ) return;
83         this->mode = mode;
84         set_text(draw_modes[mode]);
85         gui->plugin->config.draw_mode = mode;
86         if( send ) gui->plugin->send_configure_change();
87 }
88
89 int CriKeyKeyModeItem::handle_event()
90 {
91         ((CriKeyKeyMode *)get_popup_menu())->update(id);
92         return 1;
93 }
94 CriKeyKeyMode::CriKeyKeyMode(CriKeyWindow *gui, int x, int y)
95  : BC_PopupMenu(x, y, 100, "", 1)
96 {
97         this->gui = gui;
98         key_modes[KEY_SEARCH]      = _("Search");
99         key_modes[KEY_SEARCH_ALL]  = _("Search all");
100         key_modes[KEY_POINT]       = _("Point");
101         this->mode = -1;
102 }
103 void CriKeyKeyMode::create_objects()
104 {
105         for( int i=0; i<KEY_MODES; ++i )
106                 add_item(new CriKeyKeyModeItem(key_modes[i], i));
107         update(gui->plugin->config.key_mode, 0);
108 }
109 void CriKeyKeyMode::update(int mode, int send)
110 {
111         if( this->mode == mode ) return;
112         this->mode = mode;
113         set_text(key_modes[mode]);
114         gui->draw_key(mode);
115         if( send ) gui->plugin->send_configure_change();
116 }
117
118 CriKeyColorButton::CriKeyColorButton(CriKeyWindow *gui, int x, int y)
119  : BC_GenericButton(x, y, _("Color"))
120 {
121         this->gui = gui;
122 }
123 int CriKeyColorButton::handle_event()
124 {
125         gui->start_color_thread();
126         return 1;
127 }
128
129 CriKeyColorPicker::CriKeyColorPicker(CriKeyColorButton *color_button)
130  : ColorPicker(0, _("Color"))
131 {
132         this->color_button = color_button;
133 }
134
135 void CriKeyColorPicker::start(int color)
136 {
137         start_window(this->color = color, 0, 1);
138 }
139
140 void CriKeyColorPicker::handle_done_event(int result)
141 {
142         if( !result ) {
143                 CriKeyWindow *gui = color_button->gui;
144                 gui->lock_window("CriKeyColorPicker::handle_done_event");
145                 gui->update_color(color);
146                 gui->plugin->config.color = color;
147                 gui->plugin->send_configure_change();
148                 gui->unlock_window();
149         }
150 }
151
152 int CriKeyColorPicker::handle_new_color(int color, int alpha)
153 {
154         CriKeyWindow *gui = color_button->gui;
155         gui->lock_window("CriKeyColorPicker::handle_new_color");
156         gui->update_color(this->color = color);
157         gui->flush();
158         gui->unlock_window();
159         return 1;
160 }
161
162
163 void CriKeyWindow::start_color_thread()
164 {
165         unlock_window();
166         delete color_picker;
167         color_picker = new CriKeyColorPicker(color_button);
168         color_picker->start(plugin->config.color);
169         lock_window("CriKeyWindow::start_color_thread");
170 }
171
172
173 CriKeyWindow::CriKeyWindow(CriKey *plugin)
174  : PluginClientWindow(plugin, 320, 220, 320, 220, 0)
175 {
176         this->plugin = plugin;
177         this->color_button = 0;
178         this->color_picker = 0;
179         this->title_x = 0;  this->point_x = 0;
180         this->title_y = 0;  this->point_y = 0;
181         this->dragging = 0; this->drag = 0;
182 }
183
184 CriKeyWindow::~CriKeyWindow()
185 {
186         delete color_picker;
187 }
188
189 void CriKeyWindow::create_objects()
190 {
191         int x = 10, y = 10;
192         int margin = plugin->get_theme()->widget_border;
193         BC_Title *title;
194         add_subwindow(title = new BC_Title(x, y, _("Threshold:")));
195         y += title->get_h() + margin;
196         add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
197         y += threshold->get_h() + margin;
198         add_subwindow(title = new BC_Title(x, y+5, _("Draw mode:")));
199         int x1 = x + title->get_w() + 10 + margin;
200         add_subwindow(draw_mode = new CriKeyDrawMode(this, x1, y));
201         draw_mode->create_objects();
202         y += draw_mode->get_h() + margin;
203         add_subwindow(title = new BC_Title(x, y+5, _("Key mode:")));
204         add_subwindow(key_mode = new CriKeyKeyMode(this, x1, y));
205         y += key_mode->get_h() + margin;
206         key_x = x + 10 + margin;  key_y = y + 10 + margin;
207         key_mode->create_objects();
208
209         if( plugin->config.drag )
210                 grab(plugin->server->mwindow->cwindow->gui);
211         show_window(1);
212 }
213
214 int CriKeyWindow::grab_event(XEvent *event)
215 {
216         if( key_mode->mode != KEY_POINT ) return 0;
217
218         switch( event->type ) {
219         case ButtonPress:
220                 if( dragging ) return 0;
221                 dragging = 1;
222                 break;
223         case ButtonRelease:
224                 if( !dragging ) return 0;
225                 dragging = 0;
226                 return 1;
227         case MotionNotify:
228                 if( dragging ) break;
229         default:
230                 return 0;
231         }
232         MWindow *mwindow = plugin->server->mwindow;
233         CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
234         CWindowCanvas *canvas = cwindow_gui->canvas;
235         float cursor_x = canvas->get_canvas()->get_relative_cursor_x();
236         float cursor_y = canvas->get_canvas()->get_relative_cursor_y();
237         canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
238         int64_t position = plugin->get_source_position();
239         float projector_x, projector_y, projector_z;
240         Track *track = plugin->server->plugin->track;
241         int track_w = track->track_w, track_h = track->track_h;
242         track->automation->get_projector(
243                 &projector_x, &projector_y, &projector_z,
244                 position, PLAY_FORWARD);
245         projector_x += mwindow->edl->session->output_w / 2;
246         projector_y += mwindow->edl->session->output_h / 2;
247         float output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
248         float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
249         point_x->update((int64_t)(plugin->config.point_x = output_x));
250         point_y->update((int64_t)(plugin->config.point_y = output_y));
251         plugin->send_configure_change();
252         return 1;
253 }
254
255 void CriKeyWindow::done_event(int result)
256 {
257         ungrab(client->server->mwindow->cwindow->gui);
258         if( color_picker ) color_picker->close_window();
259 }
260
261 void CriKeyWindow::draw_key(int mode)
262 {
263         int margin = plugin->get_theme()->widget_border;
264         int x = key_x, y = key_y;
265         delete color_picker;  color_picker = 0;
266         delete color_button;  color_button = 0;
267         delete title_x;  title_x = 0;
268         delete point_x;  point_x = 0;
269         delete title_y;  title_y = 0;
270         delete point_y;  point_y = 0;
271         delete drag;     drag = 0;
272
273         clear_box(x,y, get_w()-x,get_h()-y);
274         flash(x,y, get_w()-x,get_h()-y);
275
276         switch( mode ) {
277         case KEY_SEARCH:
278         case KEY_SEARCH_ALL:
279                 add_subwindow(color_button = new CriKeyColorButton(this, x, y));
280                 x += color_button->get_w() + margin;
281                 color_x = x;  color_y = y;
282                 update_color(plugin->config.color);
283                 break;
284         case KEY_POINT:
285                 add_subwindow(title_x = new BC_Title(x, y, _("X:")));
286                 int x1 = x + title_x->get_w() + margin, y1 = y;
287                 point_x = new CriKeyNum(this, x1, y, plugin->config.point_x);
288                 point_x->create_objects();
289                 y += point_x->get_h() + margin;
290                 add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
291                 point_y = new CriKeyNum(this, x1, y, plugin->config.point_y);
292                 point_y->create_objects();
293                 x1 += point_x->get_w() + margin;
294                 add_subwindow(drag = new CriKeyDrag(this, x1, y1));
295                 break;
296         }
297         plugin->config.key_mode = mode;
298         show_window(1);
299 }
300
301 void CriKeyWindow::update_color(int color)
302 {
303         set_color(color);
304         draw_box(color_x, color_y, COLOR_W, COLOR_H);
305         set_color(BLACK);
306         draw_rectangle(color_x, color_y, COLOR_W, COLOR_H);
307         flash(color_x, color_y, COLOR_W, COLOR_H);
308 }
309
310 void CriKeyWindow::update_gui()
311 {
312         threshold->update(plugin->config.threshold);
313         draw_mode->update(plugin->config.draw_mode);
314         key_mode->update(plugin->config.key_mode);
315         switch( plugin->config.key_mode ) {
316         case KEY_POINT:
317                 point_x->update(plugin->config.point_x);
318                 point_y->update(plugin->config.point_y);
319                 break;
320         case KEY_SEARCH:
321         case KEY_SEARCH_ALL:
322                 update_color(plugin->config.color);
323                 break;
324         }
325 }
326
327
328 CriKeyThreshold::CriKeyThreshold(CriKeyWindow *gui, int x, int y, int w)
329  : BC_FSlider(x, y, 0, w, w, 0, 1, gui->plugin->config.threshold, 0)
330 {
331         this->gui = gui;
332         set_precision(0.005);
333 }
334
335 int CriKeyThreshold::handle_event()
336 {
337         gui->plugin->config.threshold = get_value();
338         gui->plugin->send_configure_change();
339         return 1;
340 }
341
342
343 CriKeyDrag::CriKeyDrag(CriKeyWindow *gui, int x, int y)
344  : BC_CheckBox(x, y, gui->plugin->config.drag, _("Drag"))
345 {
346         this->gui = gui;
347 }
348 int CriKeyDrag::handle_event()
349 {
350         int value = get_value();
351         gui->plugin->config.drag = value;
352         CWindowGUI *cwindow_gui = gui->plugin->server->mwindow->cwindow->gui;
353         if( value )
354                 gui->grab(cwindow_gui);
355         else
356                 gui->ungrab(cwindow_gui);
357         gui->plugin->send_configure_change();
358         return 1;
359 }
360