add collect/paste effects, new videoscope graticules, boxblur update fix, theora...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / boxblur / boxblur.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2020 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 "guicast.h"
23 #include "boxblur.h"
24 #include "dragcheckbox.h"
25 #include "edl.h"
26 #include "filexml.h"
27 #include "language.h"
28 #include "mainerror.h"
29 #include "plugin.h"
30 #include "pluginserver.h"
31 #include "pluginvclient.h"
32 #include "track.h"
33 #include "tracks.h"
34 #include "theme.h"
35
36 #include <stdint.h>
37 #include <string.h>
38
39 class BoxBlurConfig;
40 class BoxBlurNumISlider;
41 class BoxBlurNumIText;
42 class BoxBlurNumClear;
43 class BoxBlurNum;
44 class BoxBlurRadius;
45 class BoxBlurPower;
46 class BoxBlurDrag;
47 class BoxBlurReset;
48 class BoxBlurX;
49 class BoxBlurY;
50 class BoxBlurW;
51 class BoxBlurH;
52 class BoxBlurWindow;
53 class BoxBlurEffect;
54
55
56 class BoxBlurConfig
57 {
58 public:
59         BoxBlurConfig();
60         void copy_from(BoxBlurConfig &that);
61         int equivalent(BoxBlurConfig &that);
62         void interpolate(BoxBlurConfig &prev, BoxBlurConfig &next,
63                 int64_t prev_frame, int64_t next_frame, int64_t current_frame);
64         void reset();
65         void preset();
66
67         int horz_radius, vert_radius, power;
68         float box_x, box_y;
69         int box_w, box_h;
70         int drag;
71 };
72
73
74 class BoxBlurNumISlider : public BC_ISlider
75 {
76 public:
77         BoxBlurNumISlider(BoxBlurNum *num, int x, int y);
78         int handle_event();
79         BoxBlurNum *num;
80 };
81
82 class BoxBlurNumIText : public BC_TumbleTextBox
83 {
84 public:
85         BoxBlurNumIText(BoxBlurNum *num, int x, int y);
86         int handle_event();
87         BoxBlurNum *num;
88 };
89
90 class BoxBlurNumClear : public BC_Button
91 {
92 public:
93         BoxBlurNumClear(BoxBlurNum *num, int x, int y);
94         static int calculate_w(BoxBlurNum *num);
95         int handle_event();
96
97         BoxBlurNum *num;
98 };
99
100 class BoxBlurNum
101 {
102 public:
103         BoxBlurNum(BoxBlurWindow *gui, int x, int y, int w,
104                 const char *name, int *iv, int imn, int imx);
105         ~BoxBlurNum();
106         void create_objects();
107         void update(int value);
108         int get_w();
109         int get_h();
110
111         BoxBlurWindow *gui;
112         int x, y, w, h;
113         const char *name;
114         int imn, imx, *ivalue;
115         int title_w, text_w, slider_w;
116         BC_Title *title;
117         BoxBlurNumIText *text;
118         BoxBlurNumISlider *slider;
119         BoxBlurNumClear *clear;
120 };
121
122
123 class BoxBlurRadius : public BoxBlurNum
124 {
125 public:
126         BoxBlurRadius(BoxBlurWindow *gui, int x, int y, int w,
127                         const char *name, int *radius);
128 };
129
130 class BoxBlurPower : public BoxBlurNum
131 {
132 public:
133         BoxBlurPower(BoxBlurWindow *gui, int x, int y, int w,
134                         const char *name, int *power);
135 };
136
137 class BoxBlurX : public BC_TumbleTextBox
138 {
139 public:
140         BoxBlurX(BoxBlurWindow *gui, int x, int y);
141         int handle_event();
142         BoxBlurWindow *gui;
143 };
144 class BoxBlurY : public BC_TumbleTextBox
145 {
146 public:
147         BoxBlurY(BoxBlurWindow *gui, int x, int y);
148         int handle_event();
149         BoxBlurWindow *gui;
150 };
151 class BoxBlurW : public BC_TumbleTextBox
152 {
153 public:
154         BoxBlurW(BoxBlurWindow *gui, int x, int y);
155         int handle_event();
156         BoxBlurWindow *gui;
157 };
158 class BoxBlurH : public BC_TumbleTextBox
159 {
160 public:
161         BoxBlurH(BoxBlurWindow *gui, int x, int y);
162         int handle_event();
163         BoxBlurWindow *gui;
164 };
165
166 class BoxBlurDrag : public DragCheckBox
167 {
168 public:
169         BoxBlurDrag(BoxBlurWindow *gui, BoxBlurEffect *plugin, int x, int y);
170         int handle_event();
171         void update_gui();
172         Track *get_drag_track();
173         int64_t get_drag_position();
174         static int calculate_w(BoxBlurWindow *gui);
175
176         BoxBlurWindow *gui;
177         BoxBlurEffect *plugin;
178 };
179
180 class BoxBlurReset : public BC_GenericButton
181 {
182 public:
183         BoxBlurReset(BoxBlurWindow *gui, int x, int y);
184         int handle_event();
185         static int calculate_w(BoxBlurWindow *gui);
186
187         BoxBlurWindow *gui;
188 };
189
190 class BoxBlurPreset : public BC_GenericButton
191 {
192 public:
193         BoxBlurPreset(BoxBlurWindow *gui, int x, int y);
194         int handle_event();
195         static int calculate_w(BoxBlurWindow *gui);
196
197         BoxBlurWindow *gui;
198 };
199
200 class BoxBlurWindow : public PluginClientWindow
201 {
202 public:
203         BoxBlurWindow(BoxBlurEffect *plugin);
204         ~BoxBlurWindow();
205         void create_objects();
206         void update_gui();
207         void update_drag();
208
209         BoxBlurEffect *plugin;
210         BoxBlurReset *reset;
211         BoxBlurPreset *preset;
212         BoxBlurRadius *blur_horz;
213         BoxBlurRadius *blur_vert;
214         BoxBlurPower *blur_power;
215         BoxBlurDrag *drag;
216         BoxBlurX *box_x;
217         BoxBlurY *box_y;
218         BoxBlurW *box_w;
219         BoxBlurH *box_h;
220 };
221
222
223 class BoxBlurEffect : public PluginVClient
224 {
225 public:
226         BoxBlurEffect(PluginServer *server);
227         ~BoxBlurEffect();
228
229         PLUGIN_CLASS_MEMBERS(BoxBlurConfig)
230         int process_realtime(VFrame *input, VFrame *output);
231         void update_gui();
232         int is_realtime();
233         void save_data(KeyFrame *keyframe);
234         void read_data(KeyFrame *keyframe);
235         void draw_boundry();
236
237         VFrame *input, *output;
238         BoxBlur *box_blur;
239 };
240
241
242 void BoxBlurConfig::reset()
243 {
244         horz_radius = 0;
245         vert_radius = 0;
246         power = 1;
247         drag = 0;
248         box_x = box_y = 0.0;
249         box_w = box_h = 0;
250 }
251
252 void BoxBlurConfig::preset()
253 {
254         horz_radius = 2;
255         vert_radius = 2;
256         power = 2;
257         drag = 0;
258         box_x = box_y = 0.0;
259         box_w = box_h = 0;
260 }
261
262
263 BoxBlurConfig::BoxBlurConfig()
264 {
265         preset();
266 }
267
268 void BoxBlurConfig::copy_from(BoxBlurConfig &that)
269 {
270         horz_radius = that.horz_radius;
271         vert_radius = that.vert_radius;
272         power = that.power;
273         drag = that.drag;
274         box_x = that.box_x;  box_y = that.box_y;
275         box_w = that.box_w;  box_h = that.box_h;
276 }
277
278 int BoxBlurConfig::equivalent(BoxBlurConfig &that)
279 {
280         return horz_radius == that.horz_radius &&
281                 vert_radius == that.vert_radius &&
282                 power == that.power && // drag == that.drag &&
283                 EQUIV(box_x, that.box_x) && EQUIV(box_y, that.box_y) &&
284                 box_w == that.box_w && box_h == that.box_h;
285 }
286
287 void BoxBlurConfig::interpolate(BoxBlurConfig &prev, BoxBlurConfig &next,
288         int64_t prev_frame, int64_t next_frame, int64_t current_frame)
289 {
290         double u = (double)(next_frame - current_frame) / (next_frame - prev_frame);
291         double v = 1. - u;
292         this->horz_radius = u*prev.horz_radius + v*next.horz_radius;
293         this->vert_radius = u*prev.vert_radius + v*next.vert_radius;
294         this->power = u*prev.power + v*next.power;
295         this->drag = prev.drag;
296         this->box_x = u*prev.box_x + v*next.box_x;
297         this->box_y = u*prev.box_y + v*next.box_y;
298         this->box_w = u*prev.box_w + v*next.box_w;
299         this->box_h = u*prev.box_h + v*next.box_h;
300 }
301
302
303 int BoxBlurNum::get_w() { return w; }
304 int BoxBlurNum::get_h() { return h; }
305
306 BoxBlurNumISlider::BoxBlurNumISlider(BoxBlurNum *num, int x, int y)
307  : BC_ISlider(x, y, 0, num->slider_w, num->slider_w,
308                 num->imn, num->imx, *num->ivalue)
309 {
310         this->num = num;
311 }
312
313 int BoxBlurNumISlider::handle_event()
314 {
315         int iv = get_value();
316         num->update(iv);
317         num->gui->update_drag();
318         return 1;
319 }
320
321 BoxBlurNumIText::BoxBlurNumIText(BoxBlurNum *num, int x, int y)
322  : BC_TumbleTextBox(num->gui, *num->ivalue, num->imn, num->imx,
323                         x, y, num->text_w)
324 {
325         this->num = num;
326 }
327
328 int BoxBlurNumIText::handle_event()
329 {
330         int iv = atoi(get_text());
331         num->update(iv);
332         num->gui->update_drag();
333         return 1;
334 }
335
336 BoxBlurNumClear::BoxBlurNumClear(BoxBlurNum *num, int x, int y)
337  : BC_Button(x, y, num->gui->plugin->get_theme()->get_image_set("reset_button"))
338 {
339         this->num = num;
340 }
341
342 int BoxBlurNumClear::calculate_w(BoxBlurNum *num)
343 {
344         VFrame **imgs = num->gui->plugin->get_theme()->get_image_set("reset_button");
345         return imgs[0]->get_w();
346 }
347
348 int BoxBlurNumClear::handle_event()
349 {
350         int v = num->imn;
351         num->update(v);
352         num->gui->update_drag();
353         return 1;
354 }
355
356 BoxBlurNum::BoxBlurNum(BoxBlurWindow *gui, int x, int y, int w,
357                  const char *name, int *iv, int imn, int imx)
358 {
359         this->gui = gui;
360         this->x = x;
361         this->y = y;
362         this->w = w;
363         this->h = 0;
364         this->name = name;
365         this->ivalue = iv;
366         this->imn = imn;
367         this->imx = imx;
368         int margin = gui->plugin->get_theme()->widget_border;
369         int clear_w = BoxBlurNumClear::calculate_w(this);
370         int tumble_w = BC_Tumbler::calculate_w();
371         int len = w - 2*margin - clear_w - tumble_w;
372         this->title_w = xS(60);
373         this->text_w = xS(60) - tumble_w;
374         this->slider_w = len - title_w - text_w - 2*margin;
375
376         title = 0;
377         text = 0;
378         slider = 0;
379         clear = 0;
380 }
381
382 BoxBlurNum::~BoxBlurNum()
383 {
384         delete text;
385 }
386
387 void BoxBlurNum::create_objects()
388 {
389         int x1 = this->x;
390         gui->add_subwindow(title = new BC_Title(x1, y, name));
391         int margin = gui->plugin->get_theme()->widget_border;
392         x1 += title_w + margin;
393         text = new BoxBlurNumIText(this, x1, y);
394         text->create_objects();
395         x1 += text_w + BC_Tumbler::calculate_w() + margin;
396         gui->add_subwindow(slider = new BoxBlurNumISlider(this, x1, y));
397         x1 += slider_w + 2*margin;
398         gui->add_subwindow(clear = new BoxBlurNumClear(this, x1, y));
399         h = bmax(title->get_h(), bmax(text->get_h(),
400                 bmax(slider->get_h(), clear->get_h())));
401 }
402
403 void BoxBlurNum::update(int value)
404 {
405         text->update((int64_t)value);
406         slider->update(value);
407         *ivalue = value;
408 }
409
410
411 BoxBlurRadius::BoxBlurRadius(BoxBlurWindow *gui, int x, int y, int w,
412                 const char *name, int *radius)
413  : BoxBlurNum(gui, x, y, w, name, radius, 0, 100)
414 {
415 }
416
417 BoxBlurPower::BoxBlurPower(BoxBlurWindow *gui, int x, int y, int w,
418                 const char *name, int *power)
419  : BoxBlurNum(gui, x, y, w, name, power, 1, 10)
420 {
421 }
422
423 BoxBlurWindow::BoxBlurWindow(BoxBlurEffect *plugin)
424  : PluginClientWindow(plugin, xS(360), yS(246), xS(360), yS(246), 0)
425 {
426         this->plugin = plugin;
427         blur_horz = 0;
428         blur_vert = 0;
429         blur_power = 0;
430         box_x = 0;  box_y = 0;
431         box_w = 0;  box_h = 0;
432 }
433
434 BoxBlurWindow::~BoxBlurWindow()
435 {
436         delete blur_horz;
437         delete blur_vert;
438         delete blur_power;
439         delete box_x;
440         delete box_y;
441         delete box_w;
442         delete box_h;
443 }
444
445 void BoxBlurWindow::create_objects()
446 {
447         int x = xS(10), y = yS(10);
448         int t1 = x, t2 = t1+xS(24), t3 = t2+xS(100), t4 = t3+xS(24);
449         int ww = get_w() - 2*x, bar_o = xS(30), bar_m = xS(15);
450         int margin = plugin->get_theme()->widget_border;
451
452         BC_TitleBar *tbar;
453         add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Position & Size")));
454         y += tbar->get_h() + margin;
455         int x1 = ww - BoxBlurDrag::calculate_w(this) - margin;
456         add_subwindow(drag = new BoxBlurDrag(this, plugin, x1, y));
457         drag->create_objects();
458         if( plugin->config.drag && drag->drag_activate() )
459                 eprintf("drag enabled, but compositor already grabbed\n");
460
461         BC_Title *title;
462         add_subwindow(title = new BC_Title(t1, y, _("X:")));
463         box_x = new BoxBlurX(this, t2, y);
464         box_x->create_objects();
465         add_subwindow(title = new BC_Title(t3, y, _("W:")));
466         box_w = new BoxBlurW(this, t4, y);
467         box_w->create_objects();
468         y += bmax(title->get_h(), box_w->get_h()) + margin;
469         add_subwindow(title = new BC_Title(t1, y, _("Y:")));
470         box_y = new BoxBlurY(this, t2, y);
471         box_y->create_objects();
472         add_subwindow(title = new BC_Title(t3, y, _("H:")));
473         box_h = new BoxBlurH(this, t4, y);
474         box_h->create_objects();
475         y += bmax(title->get_h(), box_h->get_h()) + 2*margin;
476
477         add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Blur")));
478         y += tbar->get_h() + margin;
479         blur_horz = new BoxBlurRadius(this, x, y, ww, _("Horz:"),
480                         &plugin->config.horz_radius);
481         blur_horz->create_objects();
482         y += blur_horz->get_h() + margin;
483         blur_vert = new BoxBlurRadius(this, x, y, ww, _("Vert:"),
484                         &plugin->config.vert_radius);
485         blur_vert->create_objects();
486         y += blur_vert->get_h() + margin;
487         blur_power = new BoxBlurPower(this, x, y, ww, _("Power:"),
488                         &plugin->config.power);
489         blur_power->create_objects();
490         y += blur_power->get_h() + margin + yS(8);
491         BC_Bar *bar;
492         add_subwindow(bar = new BC_Bar(x, y, ww));
493         y += bar->get_h() + 2*margin;
494
495         add_subwindow(reset = new BoxBlurReset(this, x, y));
496         x1 = x + ww - BoxBlurPreset::calculate_w(this);
497         add_subwindow(preset = new BoxBlurPreset(this, x1, y));
498         y += bmax(title->get_h(), reset->get_h()) + 2*margin;
499         show_window(1);
500 }
501
502 void BoxBlurWindow::update_gui()
503 {
504         BoxBlurConfig &config = plugin->config;
505         blur_horz->update(config.horz_radius);
506         blur_vert->update(config.vert_radius);
507         blur_power->update(config.power);
508         box_x->update(config.box_x);
509         box_y->update(config.box_y);
510         box_w->update((int64_t)config.box_w);
511         box_h->update((int64_t)config.box_h);
512         drag->drag_x = config.box_x;
513         drag->drag_y = config.box_y;
514         drag->drag_w = config.box_w;
515         drag->drag_h = config.box_h;
516 }
517
518
519 REGISTER_PLUGIN(BoxBlurEffect)
520 NEW_WINDOW_MACRO(BoxBlurEffect, BoxBlurWindow)
521 LOAD_CONFIGURATION_MACRO(BoxBlurEffect, BoxBlurConfig)
522
523
524 BoxBlurEffect::BoxBlurEffect(PluginServer *server)
525  : PluginVClient(server)
526 {
527         box_blur = 0;
528 }
529
530 BoxBlurEffect::~BoxBlurEffect()
531 {
532         delete box_blur;
533 }
534
535 const char* BoxBlurEffect::plugin_title() { return N_("BoxBlur"); }
536 int BoxBlurEffect::is_realtime() { return 1; }
537
538
539 void BoxBlurEffect::save_data(KeyFrame *keyframe)
540 {
541         FileXML output;
542         output.set_shared_output(keyframe->xbuf);
543         output.tag.set_title("BOXBLUR");
544         output.tag.set_property("HORZ_RADIUS", config.horz_radius);
545         output.tag.set_property("VERT_RADIUS", config.vert_radius);
546         output.tag.set_property("POWER", config.power);
547         output.tag.set_property("DRAG", config.drag);
548         output.tag.set_property("BOX_X", config.box_x);
549         output.tag.set_property("BOX_Y", config.box_y);
550         output.tag.set_property("BOX_W", config.box_w);
551         output.tag.set_property("BOX_H", config.box_h);
552         output.append_tag();
553         output.tag.set_title("/BOXBLUR");
554         output.append_tag();
555         output.append_newline();
556         output.terminate_string();
557 }
558
559 void BoxBlurEffect::read_data(KeyFrame *keyframe)
560 {
561         FileXML input;
562         input.set_shared_input(keyframe->xbuf);
563         int result = 0;
564
565         while( !(result = input.read_tag()) ) {
566                 if( input.tag.title_is("BOXBLUR") ) {
567                         config.horz_radius = input.tag.get_property("HORZ_RADIUS", config.horz_radius);
568                         config.vert_radius = input.tag.get_property("VERT_RADIUS", config.vert_radius);
569                         config.power = input.tag.get_property("POWER", config.power);
570                         config.drag = input.tag.get_property("DRAG", config.drag);
571                         config.box_x = input.tag.get_property("BOX_X", config.box_x);
572                         config.box_y = input.tag.get_property("BOX_Y", config.box_y);
573                         config.box_w = input.tag.get_property("BOX_W", config.box_w);
574                         config.box_h = input.tag.get_property("BOX_H", config.box_h);
575                 }
576         }
577 }
578
579 void BoxBlurEffect::draw_boundry()
580 {
581         if( !gui_open() ) return;
582         int box_x = config.box_x, box_y = config.box_y;
583         int box_w = config.box_w ? config.box_w : input->get_w();
584         int box_h = config.box_h ? config.box_h : input->get_h();
585         DragCheckBox::draw_boundary(output, box_x, box_y, box_w, box_h);
586 }
587
588 int BoxBlurEffect::process_realtime(VFrame *input, VFrame *output)
589 {
590         this->input = input;
591         this->output = output;
592         load_configuration();
593         int out_w = output->get_w(), out_h = output->get_h();
594
595         if( !box_blur ) {
596                 int cpus = (out_w * out_h)/0x80000 + 1;
597                 box_blur = new BoxBlur(cpus);
598         }
599         int x = config.box_x, y = config.box_y;
600         int ow = config.box_w ? config.box_w : out_w;
601         int oh = config.box_h ? config.box_h : out_h;
602         if( config.horz_radius ) {
603                 box_blur->hblur(output, input, config.horz_radius, config.power,
604                         -1, x,y, ow, oh);
605                 input = output;
606         }
607         if( config.vert_radius ) {
608                 box_blur->vblur(output, input, config.vert_radius, config.power,
609                         -1, x,y, ow, oh);
610         }
611
612         if( config.drag )
613                 draw_boundry();
614
615         return 1;
616 }
617
618 void BoxBlurEffect::update_gui()
619 {
620         if( !thread ) return;
621         load_configuration();
622         thread->window->lock_window("BoxBlurEffect::update_gui");
623         BoxBlurWindow *gui = (BoxBlurWindow *)thread->window;
624         gui->update_gui();
625         thread->window->unlock_window();
626 }
627
628
629 BoxBlurX::BoxBlurX(BoxBlurWindow *gui, int x, int y)
630  : BC_TumbleTextBox(gui, gui->plugin->config.box_x,
631                 -32767.f, 32767.f, x, y, xS(64))
632 {
633         this->gui = gui;
634         set_precision(1);
635 }
636 int BoxBlurX::handle_event()
637 {
638         gui->plugin->config.box_x = atof(get_text());
639         gui->update_drag();
640         return 1;
641 }
642
643 BoxBlurY::BoxBlurY(BoxBlurWindow *gui, int x, int y)
644  : BC_TumbleTextBox(gui, gui->plugin->config.box_y,
645                 -32767.f, 32767.f, x, y, xS(64))
646 {
647         this->gui = gui;
648         set_precision(1);
649 }
650 int BoxBlurY::handle_event()
651 {
652         gui->plugin->config.box_y = atof(get_text());
653         gui->update_drag();
654         return 1;
655 }
656
657 BoxBlurW::BoxBlurW(BoxBlurWindow *gui, int x, int y)
658  : BC_TumbleTextBox(gui, gui->plugin->config.box_w,
659                 0, 32767, x, y, xS(64))
660 {
661         this->gui = gui;
662 }
663 int BoxBlurW::handle_event()
664 {
665         gui->plugin->config.box_w = atol(get_text());
666         gui->update_drag();
667         return 1;
668 }
669
670 BoxBlurH::BoxBlurH(BoxBlurWindow *gui, int x, int y)
671  : BC_TumbleTextBox(gui, gui->plugin->config.box_h,
672                 0, 32767, x, y, xS(64))
673 {
674         this->gui = gui;
675 }
676 int BoxBlurH::handle_event()
677 {
678         gui->plugin->config.box_h = atol(get_text());
679         gui->update_drag();
680         return 1;
681 }
682
683 BoxBlurDrag::BoxBlurDrag(BoxBlurWindow *gui, BoxBlurEffect *plugin, int x, int y)
684  : DragCheckBox(plugin->server->mwindow, x, y, _("Drag"), &plugin->config.drag,
685                 plugin->config.box_x, plugin->config.box_y,
686                 plugin->config.box_w, plugin->config.box_h)
687 {
688         this->plugin = plugin;
689         this->gui = gui;
690 }
691
692 int BoxBlurDrag::calculate_w(BoxBlurWindow *gui)
693 {
694         int w, h;
695         calculate_extents(gui, &w, &h, _("Drag"));
696         return w;
697 }
698
699 Track *BoxBlurDrag::get_drag_track()
700 {
701         PluginServer *server = plugin->server;
702         int plugin_id = server->plugin_id;
703         Plugin *plugin = server->edl->tracks->plugin_exists(plugin_id);
704         return !plugin ? 0 : plugin->track;
705 }
706 int64_t BoxBlurDrag::get_drag_position()
707 {
708         return plugin->get_source_position();
709 }
710
711 void BoxBlurDrag::update_gui()
712 {
713         plugin->config.drag = get_value();
714         plugin->config.box_x = drag_x;
715         plugin->config.box_y = drag_y;
716         plugin->config.box_w = drag_w+0.5;
717         plugin->config.box_h = drag_h+0.5;
718         gui->box_x->update((float)plugin->config.box_x);
719         gui->box_y->update((float)plugin->config.box_y);
720         gui->box_w->update((int64_t)plugin->config.box_w);
721         gui->box_h->update((int64_t)plugin->config.box_h);
722         plugin->send_configure_change();
723 }
724
725 int BoxBlurDrag::handle_event()
726 {
727         int ret = DragCheckBox::handle_event();
728         plugin->send_configure_change();
729         return ret;
730 }
731
732 void BoxBlurWindow::update_drag()
733 {
734         drag->drag_x = plugin->config.box_x;
735         drag->drag_y = plugin->config.box_y;
736         drag->drag_w = plugin->config.box_w;
737         drag->drag_h = plugin->config.box_h;
738         plugin->send_configure_change();
739 }
740
741 BoxBlurReset::BoxBlurReset(BoxBlurWindow *gui, int x, int y)
742  : BC_GenericButton(x, y, _("Reset"))
743 {
744         this->gui = gui;
745 }
746
747 int BoxBlurReset::calculate_w(BoxBlurWindow *gui)
748 {
749         return BC_GenericButton::calculate_w(gui,_("Reset"));
750 }
751
752 int BoxBlurReset::handle_event()
753 {
754         BoxBlurEffect *plugin = gui->plugin;
755         plugin->config.reset();
756         gui->drag->update(0);
757         gui->drag->drag_deactivate();
758         gui->update_gui();
759         gui->update_drag();
760         return 1;
761 }
762
763 BoxBlurPreset::BoxBlurPreset(BoxBlurWindow *gui, int x, int y)
764  : BC_GenericButton(x, y, _("Default"))
765 {
766         this->gui = gui;
767 }
768
769 int BoxBlurPreset::calculate_w(BoxBlurWindow *gui)
770 {
771         return BC_GenericButton::calculate_w(gui,_("Default"));
772 }
773
774 int BoxBlurPreset::handle_event()
775 {
776         BoxBlurEffect *plugin = gui->plugin;
777         plugin->config.preset();
778         gui->drag->update(0);
779         gui->drag->drag_deactivate();
780         gui->update_gui();
781         gui->update_drag();
782         return 1;
783 }
784