x265 upgrade to 2.5, cinfinity cc lic, keyframe reticle redraw, crikey/titler event...
[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->plugin->config.color = color;
159         gui->plugin->send_configure_change();
160         gui->unlock_window();
161         return 1;
162 }
163
164
165 void CriKeyWindow::start_color_thread()
166 {
167         unlock_window();
168         delete color_picker;
169         color_picker = new CriKeyColorPicker(color_button);
170         color_picker->start(plugin->config.color);
171         lock_window("CriKeyWindow::start_color_thread");
172 }
173
174
175 CriKeyWindow::CriKeyWindow(CriKey *plugin)
176  : PluginClientWindow(plugin, 320, 220, 320, 220, 0)
177 {
178         this->plugin = plugin;
179         this->color_button = 0;
180         this->color_picker = 0;
181         this->title_x = 0;  this->point_x = 0;
182         this->title_y = 0;  this->point_y = 0;
183         this->dragging = 0; this->drag = 0;
184 }
185
186 CriKeyWindow::~CriKeyWindow()
187 {
188         delete color_picker;
189 }
190
191 void CriKeyWindow::create_objects()
192 {
193         int x = 10, y = 10;
194         int margin = plugin->get_theme()->widget_border;
195         BC_Title *title;
196         add_subwindow(title = new BC_Title(x, y, _("Threshold:")));
197         y += title->get_h() + margin;
198         add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
199         y += threshold->get_h() + margin;
200         add_subwindow(title = new BC_Title(x, y+5, _("Draw mode:")));
201         int x1 = x + title->get_w() + 10 + margin;
202         add_subwindow(draw_mode = new CriKeyDrawMode(this, x1, y));
203         draw_mode->create_objects();
204         y += draw_mode->get_h() + margin;
205         add_subwindow(title = new BC_Title(x, y+5, _("Key mode:")));
206         add_subwindow(key_mode = new CriKeyKeyMode(this, x1, y));
207         y += key_mode->get_h() + margin;
208         key_x = x + 10 + margin;  key_y = y + 10 + margin;
209         key_mode->create_objects();
210
211         if( plugin->config.drag )
212                 grab(plugin->server->mwindow->cwindow->gui);
213         show_window(1);
214 }
215
216 int CriKeyWindow::grab_event(XEvent *event)
217 {
218         if( key_mode->mode != KEY_POINT ) return 0;
219
220         MWindow *mwindow = plugin->server->mwindow;
221         CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
222         CWindowCanvas *canvas = cwindow_gui->canvas;
223         int cx, cy;  canvas->get_canvas()->get_relative_cursor_xy(cx, cy);
224         if( cx < mwindow->theme->ccanvas_x ) return 0;
225         if( cx >= mwindow->theme->ccanvas_x+mwindow->theme->ccanvas_w ) return 0;
226         if( cy < mwindow->theme->ccanvas_y ) return 0;
227         if( cy >= mwindow->theme->ccanvas_y+mwindow->theme->ccanvas_h ) return 0;
228
229         switch( event->type ) {
230         case ButtonPress:
231                 if( dragging ) return 0;
232                 dragging = 1;
233                 break;
234         case ButtonRelease:
235                 if( !dragging ) return 0;
236                 dragging = 0;
237                 return 1;
238         case MotionNotify:
239                 if( dragging ) break;
240         default:
241                 return 0;
242         }
243
244         float cursor_x = cx, cursor_y = cy;
245         canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
246         int64_t position = plugin->get_source_position();
247         float projector_x, projector_y, projector_z;
248         Track *track = plugin->server->plugin->track;
249         int track_w = track->track_w, track_h = track->track_h;
250         track->automation->get_projector(
251                 &projector_x, &projector_y, &projector_z,
252                 position, PLAY_FORWARD);
253         projector_x += mwindow->edl->session->output_w / 2;
254         projector_y += mwindow->edl->session->output_h / 2;
255         float output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
256         float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
257         point_x->update((int64_t)(plugin->config.point_x = output_x));
258         point_y->update((int64_t)(plugin->config.point_y = output_y));
259         plugin->send_configure_change();
260         return 1;
261 }
262
263 void CriKeyWindow::done_event(int result)
264 {
265         ungrab(client->server->mwindow->cwindow->gui);
266         if( color_picker ) color_picker->close_window();
267 }
268
269 void CriKeyWindow::draw_key(int mode)
270 {
271         int margin = plugin->get_theme()->widget_border;
272         int x = key_x, y = key_y;
273         delete color_picker;  color_picker = 0;
274         delete color_button;  color_button = 0;
275         delete title_x;  title_x = 0;
276         delete point_x;  point_x = 0;
277         delete title_y;  title_y = 0;
278         delete point_y;  point_y = 0;
279         delete drag;     drag = 0;
280
281         clear_box(x,y, get_w()-x,get_h()-y);
282         flash(x,y, get_w()-x,get_h()-y);
283
284         switch( mode ) {
285         case KEY_SEARCH:
286         case KEY_SEARCH_ALL:
287                 add_subwindow(color_button = new CriKeyColorButton(this, x, y));
288                 x += color_button->get_w() + margin;
289                 color_x = x;  color_y = y;
290                 update_color(plugin->config.color);
291                 break;
292         case KEY_POINT:
293                 add_subwindow(title_x = new BC_Title(x, y, _("X:")));
294                 int x1 = x + title_x->get_w() + margin, y1 = y;
295                 point_x = new CriKeyNum(this, x1, y, plugin->config.point_x);
296                 point_x->create_objects();
297                 y += point_x->get_h() + margin;
298                 add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
299                 point_y = new CriKeyNum(this, x1, y, plugin->config.point_y);
300                 point_y->create_objects();
301                 x1 += point_x->get_w() + margin;
302                 add_subwindow(drag = new CriKeyDrag(this, x1, y1));
303                 break;
304         }
305         plugin->config.key_mode = mode;
306         show_window(1);
307 }
308
309 void CriKeyWindow::update_color(int color)
310 {
311         set_color(color);
312         draw_box(color_x, color_y, COLOR_W, COLOR_H);
313         set_color(BLACK);
314         draw_rectangle(color_x, color_y, COLOR_W, COLOR_H);
315         flash(color_x, color_y, COLOR_W, COLOR_H);
316 }
317
318 void CriKeyWindow::update_gui()
319 {
320         threshold->update(plugin->config.threshold);
321         draw_mode->update(plugin->config.draw_mode);
322         key_mode->update(plugin->config.key_mode);
323         switch( plugin->config.key_mode ) {
324         case KEY_POINT:
325                 point_x->update(plugin->config.point_x);
326                 point_y->update(plugin->config.point_y);
327                 break;
328         case KEY_SEARCH:
329         case KEY_SEARCH_ALL:
330                 update_color(plugin->config.color);
331                 break;
332         }
333 }
334
335
336 CriKeyThreshold::CriKeyThreshold(CriKeyWindow *gui, int x, int y, int w)
337  : BC_FSlider(x, y, 0, w, w, 0, 1, gui->plugin->config.threshold, 0)
338 {
339         this->gui = gui;
340         set_precision(0.005);
341 }
342
343 int CriKeyThreshold::handle_event()
344 {
345         gui->plugin->config.threshold = get_value();
346         gui->plugin->send_configure_change();
347         return 1;
348 }
349
350
351 CriKeyDrag::CriKeyDrag(CriKeyWindow *gui, int x, int y)
352  : BC_CheckBox(x, y, gui->plugin->config.drag, _("Drag"))
353 {
354         this->gui = gui;
355 }
356 int CriKeyDrag::handle_event()
357 {
358         int value = get_value();
359         gui->plugin->config.drag = value;
360         CWindowGUI *cwindow_gui = gui->plugin->server->mwindow->cwindow->gui;
361         if( value )
362                 gui->grab(cwindow_gui);
363         else
364                 gui->ungrab(cwindow_gui);
365         gui->plugin->send_configure_change();
366         return 1;
367 }
368