a/v per track data height, boxblur power fix, add french expanders
[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 + 1e-6; // avoid truncation jitter
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 + 1e-6;
299         this->box_h = u*prev.box_h + v*next.box_h + 1e-6;
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(260), xS(360), yS(260), 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 ys10 = yS(10), ys20 = yS(20), ys30 = yS(30), ys40 = yS(40);
449         int t1 = x, t2 = t1+xS(24), t3 = t2+xS(100), t4 = t3+xS(24);
450         int ww = get_w() - 2*x, bar_o = xS(30), bar_m = xS(15);
451         int margin = plugin->get_theme()->widget_border;
452
453         BC_TitleBar *tbar;
454         add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Position & Size")));
455         y += ys20;
456         int x1 = ww - BoxBlurDrag::calculate_w(this) - margin;
457         add_subwindow(drag = new BoxBlurDrag(this, plugin, x1, y));
458         drag->create_objects();
459         if( plugin->config.drag && drag->drag_activate() )
460                 eprintf("drag enabled, but compositor already grabbed\n");
461
462         BC_Title *title;
463         add_subwindow(title = new BC_Title(t1, y, _("X:")));
464         box_x = new BoxBlurX(this, t2, y);
465         box_x->create_objects();
466         add_subwindow(title = new BC_Title(t3, y, _("W:")));
467         box_w = new BoxBlurW(this, t4, y);
468         box_w->create_objects();
469         y += ys30;
470         add_subwindow(title = new BC_Title(t1, y, _("Y:")));
471         box_y = new BoxBlurY(this, t2, y);
472         box_y->create_objects();
473         add_subwindow(title = new BC_Title(t3, y, _("H:")));
474         box_h = new BoxBlurH(this, t4, y);
475         box_h->create_objects();
476         y += ys40;
477
478         add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Blur")));
479         y += ys20;
480         blur_horz = new BoxBlurRadius(this, x, y, ww, _("Horz:"),
481                         &plugin->config.horz_radius);
482         blur_horz->create_objects();
483         y += ys30;
484         blur_vert = new BoxBlurRadius(this, x, y, ww, _("Vert:"),
485                         &plugin->config.vert_radius);
486         blur_vert->create_objects();
487         y += ys30;
488         blur_power = new BoxBlurPower(this, x, y, ww, _("Power:"),
489                         &plugin->config.power);
490         blur_power->create_objects();
491         y += ys40;
492         BC_Bar *bar;
493         add_subwindow(bar = new BC_Bar(x, y, ww));
494         y += ys10;
495
496         add_subwindow(reset = new BoxBlurReset(this, x, y));
497         x1 = x + ww - BoxBlurPreset::calculate_w(this);
498         add_subwindow(preset = new BoxBlurPreset(this, x1, y));
499         y += bmax(title->get_h(), reset->get_h()) + 2*margin;
500         show_window(1);
501 }
502
503 void BoxBlurWindow::update_gui()
504 {
505         BoxBlurConfig &config = plugin->config;
506         blur_horz->update(config.horz_radius);
507         blur_vert->update(config.vert_radius);
508         blur_power->update(config.power);
509         box_x->update(config.box_x);
510         box_y->update(config.box_y);
511         box_w->update((int64_t)config.box_w);
512         box_h->update((int64_t)config.box_h);
513         drag->drag_x = config.box_x;
514         drag->drag_y = config.box_y;
515         drag->drag_w = config.box_w;
516         drag->drag_h = config.box_h;
517 }
518
519
520 REGISTER_PLUGIN(BoxBlurEffect)
521 NEW_WINDOW_MACRO(BoxBlurEffect, BoxBlurWindow)
522 LOAD_CONFIGURATION_MACRO(BoxBlurEffect, BoxBlurConfig)
523
524
525 BoxBlurEffect::BoxBlurEffect(PluginServer *server)
526  : PluginVClient(server)
527 {
528         box_blur = 0;
529 }
530
531 BoxBlurEffect::~BoxBlurEffect()
532 {
533         delete box_blur;
534 }
535
536 const char* BoxBlurEffect::plugin_title() { return N_("BoxBlur"); }
537 int BoxBlurEffect::is_realtime() { return 1; }
538
539
540 void BoxBlurEffect::save_data(KeyFrame *keyframe)
541 {
542         FileXML output;
543         output.set_shared_output(keyframe->xbuf);
544         output.tag.set_title("BOXBLUR");
545         output.tag.set_property("HORZ_RADIUS", config.horz_radius);
546         output.tag.set_property("VERT_RADIUS", config.vert_radius);
547         output.tag.set_property("POWER", config.power);
548         output.tag.set_property("DRAG", config.drag);
549         output.tag.set_property("BOX_X", config.box_x);
550         output.tag.set_property("BOX_Y", config.box_y);
551         output.tag.set_property("BOX_W", config.box_w);
552         output.tag.set_property("BOX_H", config.box_h);
553         output.append_tag();
554         output.tag.set_title("/BOXBLUR");
555         output.append_tag();
556         output.append_newline();
557         output.terminate_string();
558 }
559
560 void BoxBlurEffect::read_data(KeyFrame *keyframe)
561 {
562         FileXML input;
563         input.set_shared_input(keyframe->xbuf);
564         int result = 0;
565
566         while( !(result = input.read_tag()) ) {
567                 if( input.tag.title_is("BOXBLUR") ) {
568                         config.horz_radius = input.tag.get_property("HORZ_RADIUS", config.horz_radius);
569                         config.vert_radius = input.tag.get_property("VERT_RADIUS", config.vert_radius);
570                         config.power = input.tag.get_property("POWER", config.power);
571                         config.drag = input.tag.get_property("DRAG", config.drag);
572                         config.box_x = input.tag.get_property("BOX_X", config.box_x);
573                         config.box_y = input.tag.get_property("BOX_Y", config.box_y);
574                         config.box_w = input.tag.get_property("BOX_W", config.box_w);
575                         config.box_h = input.tag.get_property("BOX_H", config.box_h);
576                 }
577         }
578 }
579
580 void BoxBlurEffect::draw_boundry()
581 {
582         if( !gui_open() ) return;
583         int box_x = config.box_x, box_y = config.box_y;
584         int box_w = config.box_w ? config.box_w : input->get_w();
585         int box_h = config.box_h ? config.box_h : input->get_h();
586         DragCheckBox::draw_boundary(output, box_x, box_y, box_w, box_h);
587 }
588
589 int BoxBlurEffect::process_realtime(VFrame *input, VFrame *output)
590 {
591         this->input = input;
592         this->output = output;
593         load_configuration();
594         int out_w = output->get_w(), out_h = output->get_h();
595
596         if( !box_blur ) {
597                 int cpus = (out_w * out_h)/0x80000 + 1;
598                 box_blur = new BoxBlur(cpus);
599         }
600         int x = config.box_x, y = config.box_y;
601         int ow = config.box_w ? config.box_w : out_w;
602         int oh = config.box_h ? config.box_h : out_h;
603         if( config.horz_radius ) {
604                 box_blur->hblur(output, input, config.horz_radius, config.power,
605                         -1, x,y, ow, oh);
606                 input = output;
607         }
608         if( config.vert_radius ) {
609                 box_blur->vblur(output, input, config.vert_radius, config.power,
610                         -1, x,y, ow, oh);
611         }
612
613         if( config.drag )
614                 draw_boundry();
615
616         return 1;
617 }
618
619 void BoxBlurEffect::update_gui()
620 {
621         if( !thread ) return;
622         load_configuration();
623         thread->window->lock_window("BoxBlurEffect::update_gui");
624         BoxBlurWindow *gui = (BoxBlurWindow *)thread->window;
625         gui->update_gui();
626         thread->window->unlock_window();
627 }
628
629
630 BoxBlurX::BoxBlurX(BoxBlurWindow *gui, int x, int y)
631  : BC_TumbleTextBox(gui, gui->plugin->config.box_x,
632                 -32767.f, 32767.f, x, y, xS(64))
633 {
634         this->gui = gui;
635         set_precision(1);
636 }
637 int BoxBlurX::handle_event()
638 {
639         gui->plugin->config.box_x = atof(get_text());
640         gui->update_drag();
641         return 1;
642 }
643
644 BoxBlurY::BoxBlurY(BoxBlurWindow *gui, int x, int y)
645  : BC_TumbleTextBox(gui, gui->plugin->config.box_y,
646                 -32767.f, 32767.f, x, y, xS(64))
647 {
648         this->gui = gui;
649         set_precision(1);
650 }
651 int BoxBlurY::handle_event()
652 {
653         gui->plugin->config.box_y = atof(get_text());
654         gui->update_drag();
655         return 1;
656 }
657
658 BoxBlurW::BoxBlurW(BoxBlurWindow *gui, int x, int y)
659  : BC_TumbleTextBox(gui, gui->plugin->config.box_w,
660                 0, 32767, x, y, xS(64))
661 {
662         this->gui = gui;
663 }
664 int BoxBlurW::handle_event()
665 {
666         gui->plugin->config.box_w = atol(get_text());
667         gui->update_drag();
668         return 1;
669 }
670
671 BoxBlurH::BoxBlurH(BoxBlurWindow *gui, int x, int y)
672  : BC_TumbleTextBox(gui, gui->plugin->config.box_h,
673                 0, 32767, x, y, xS(64))
674 {
675         this->gui = gui;
676 }
677 int BoxBlurH::handle_event()
678 {
679         gui->plugin->config.box_h = atol(get_text());
680         gui->update_drag();
681         return 1;
682 }
683
684 BoxBlurDrag::BoxBlurDrag(BoxBlurWindow *gui, BoxBlurEffect *plugin, int x, int y)
685  : DragCheckBox(plugin->server->mwindow, x, y, _("Drag"), &plugin->config.drag,
686                 plugin->config.box_x, plugin->config.box_y,
687                 plugin->config.box_w, plugin->config.box_h)
688 {
689         this->plugin = plugin;
690         this->gui = gui;
691 }
692
693 int BoxBlurDrag::calculate_w(BoxBlurWindow *gui)
694 {
695         int w, h;
696         calculate_extents(gui, &w, &h, _("Drag"));
697         return w;
698 }
699
700 Track *BoxBlurDrag::get_drag_track()
701 {
702         PluginServer *server = plugin->server;
703         int plugin_id = server->plugin_id;
704         Plugin *plugin = server->edl->tracks->plugin_exists(plugin_id);
705         return !plugin ? 0 : plugin->track;
706 }
707 int64_t BoxBlurDrag::get_drag_position()
708 {
709         return plugin->get_source_position();
710 }
711
712 void BoxBlurDrag::update_gui()
713 {
714         plugin->config.drag = get_value();
715         plugin->config.box_x = drag_x;
716         plugin->config.box_y = drag_y;
717         plugin->config.box_w = drag_w+0.5;
718         plugin->config.box_h = drag_h+0.5;
719         gui->box_x->update((float)plugin->config.box_x);
720         gui->box_y->update((float)plugin->config.box_y);
721         gui->box_w->update((int64_t)plugin->config.box_w);
722         gui->box_h->update((int64_t)plugin->config.box_h);
723         plugin->send_configure_change();
724 }
725
726 int BoxBlurDrag::handle_event()
727 {
728         int ret = DragCheckBox::handle_event();
729         plugin->send_configure_change();
730         return ret;
731 }
732
733 void BoxBlurWindow::update_drag()
734 {
735         drag->drag_x = plugin->config.box_x;
736         drag->drag_y = plugin->config.box_y;
737         drag->drag_w = plugin->config.box_w;
738         drag->drag_h = plugin->config.box_h;
739         plugin->send_configure_change();
740 }
741
742 BoxBlurReset::BoxBlurReset(BoxBlurWindow *gui, int x, int y)
743  : BC_GenericButton(x, y, _("Reset"))
744 {
745         this->gui = gui;
746 }
747
748 int BoxBlurReset::calculate_w(BoxBlurWindow *gui)
749 {
750         return BC_GenericButton::calculate_w(gui,_("Reset"));
751 }
752
753 int BoxBlurReset::handle_event()
754 {
755         BoxBlurEffect *plugin = gui->plugin;
756         plugin->config.reset();
757         gui->drag->update(0);
758         gui->drag->drag_deactivate();
759         gui->update_gui();
760         gui->update_drag();
761         return 1;
762 }
763
764 BoxBlurPreset::BoxBlurPreset(BoxBlurWindow *gui, int x, int y)
765  : BC_GenericButton(x, y, _("Default"))
766 {
767         this->gui = gui;
768 }
769
770 int BoxBlurPreset::calculate_w(BoxBlurWindow *gui)
771 {
772         return BC_GenericButton::calculate_w(gui,_("Default"));
773 }
774
775 int BoxBlurPreset::handle_event()
776 {
777         BoxBlurEffect *plugin = gui->plugin;
778         plugin->config.preset();
779         gui->drag->update(0);
780         gui->drag->drag_deactivate();
781         gui->update_gui();
782         gui->update_drag();
783         return 1;
784 }
785