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