tweak boxblur layout
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / boxblur / boxblur.C
index b141fe6c83083638f9d9b761ba0235f24b50357d..8408bc3396494bd9c923a33287915b37d841ef16 100644 (file)
 
 #include "guicast.h"
 #include "boxblur.h"
+#include "dragcheckbox.h"
+#include "edl.h"
 #include "filexml.h"
 #include "language.h"
+#include "mainerror.h"
+#include "plugin.h"
+#include "pluginserver.h"
 #include "pluginvclient.h"
+#include "track.h"
+#include "tracks.h"
 #include "theme.h"
 
 #include <stdint.h>
 #include <string.h>
 
 class BoxBlurConfig;
+class BoxBlurNumISlider;
+class BoxBlurNumIText;
+class BoxBlurNumClear;
+class BoxBlurNum;
 class BoxBlurRadius;
 class BoxBlurPower;
+class BoxBlurDrag;
+class BoxBlurReset;
+class BoxBlurX;
+class BoxBlurY;
+class BoxBlurW;
+class BoxBlurH;
 class BoxBlurWindow;
 class BoxBlurEffect;
 
@@ -43,30 +60,141 @@ public:
        void copy_from(BoxBlurConfig &that);
        int equivalent(BoxBlurConfig &that);
        void interpolate(BoxBlurConfig &prev, BoxBlurConfig &next,
-               long prev_frame, long next_frame, long current_frame);
+               int64_t prev_frame, int64_t next_frame, int64_t current_frame);
+       void reset();
+       void preset();
 
        int horz_radius, vert_radius, power;
+       float box_x, box_y;
+       int box_w, box_h;
+       int drag;
 };
 
 
-class BoxBlurRadius : public BC_ISlider
+class BoxBlurNumISlider : public BC_ISlider
 {
 public:
-       BoxBlurRadius(BoxBlurWindow *gui, int x, int y, int w, int *radius);
+       BoxBlurNumISlider(BoxBlurNum *num, int x, int y);
        int handle_event();
+       BoxBlurNum *num;
+};
+
+class BoxBlurNumIText : public BC_TumbleTextBox
+{
+public:
+       BoxBlurNumIText(BoxBlurNum *num, int x, int y);
+       int handle_event();
+       BoxBlurNum *num;
+};
+
+class BoxBlurNumClear : public BC_Button
+{
+public:
+       BoxBlurNumClear(BoxBlurNum *num, int x, int y);
+       static int calculate_w(BoxBlurNum *num);
+       int handle_event();
+
+       BoxBlurNum *num;
+};
+
+class BoxBlurNum
+{
+public:
+       BoxBlurNum(BoxBlurWindow *gui, int x, int y, int w,
+               const char *name, int *iv, int imn, int imx);
+       ~BoxBlurNum();
+       void create_objects();
+       void update(int value);
+       int get_w();
+       int get_h();
 
        BoxBlurWindow *gui;
-       int *radius;
+       int x, y, w, h;
+       const char *name;
+       int imn, imx, *ivalue;
+       int title_w, text_w, slider_w;
+       BC_Title *title;
+       BoxBlurNumIText *text;
+       BoxBlurNumISlider *slider;
+       BoxBlurNumClear *clear;
+};
+
+
+class BoxBlurRadius : public BoxBlurNum
+{
+public:
+       BoxBlurRadius(BoxBlurWindow *gui, int x, int y, int w,
+                       const char *name, int *radius);
 };
 
-class BoxBlurPower : public BC_ISlider
+class BoxBlurPower : public BoxBlurNum
 {
 public:
-       BoxBlurPower(BoxBlurWindow *gui, int x, int y, int w, int *power);
+       BoxBlurPower(BoxBlurWindow *gui, int x, int y, int w,
+                       const char *name, int *power);
+};
+
+class BoxBlurX : public BC_TumbleTextBox
+{
+public:
+       BoxBlurX(BoxBlurWindow *gui, int x, int y);
+       int handle_event();
+       BoxBlurWindow *gui;
+};
+class BoxBlurY : public BC_TumbleTextBox
+{
+public:
+       BoxBlurY(BoxBlurWindow *gui, int x, int y);
+       int handle_event();
+       BoxBlurWindow *gui;
+};
+class BoxBlurW : public BC_TumbleTextBox
+{
+public:
+       BoxBlurW(BoxBlurWindow *gui, int x, int y);
+       int handle_event();
+       BoxBlurWindow *gui;
+};
+class BoxBlurH : public BC_TumbleTextBox
+{
+public:
+       BoxBlurH(BoxBlurWindow *gui, int x, int y);
+       int handle_event();
+       BoxBlurWindow *gui;
+};
+
+class BoxBlurDrag : public DragCheckBox
+{
+public:
+       BoxBlurDrag(BoxBlurWindow *gui, BoxBlurEffect *plugin, int x, int y);
        int handle_event();
+       void update_gui();
+       Track *get_drag_track();
+       int64_t get_drag_position();
+       static int calculate_w(BoxBlurWindow *gui);
+
+       BoxBlurWindow *gui;
+       BoxBlurEffect *plugin;
+};
+
+class BoxBlurReset : public BC_GenericButton
+{
+public:
+       BoxBlurReset(BoxBlurWindow *gui, int x, int y);
+       int handle_event();
+       static int calculate_w(BoxBlurWindow *gui);
+
+       BoxBlurWindow *gui;
+};
+
+class BoxBlurPreset : public BC_GenericButton
+{
+public:
+       BoxBlurPreset(BoxBlurWindow *gui, int x, int y);
+       int handle_event();
+       static int calculate_w(BoxBlurWindow *gui);
 
        BoxBlurWindow *gui;
-       int *power;
 };
 
 class BoxBlurWindow : public PluginClientWindow
@@ -75,15 +203,23 @@ public:
        BoxBlurWindow(BoxBlurEffect *plugin);
        ~BoxBlurWindow();
        void create_objects();
+       void update_gui();
+       void update_drag();
 
        BoxBlurEffect *plugin;
+       BoxBlurReset *reset;
+       BoxBlurPreset *preset;
        BoxBlurRadius *blur_horz;
        BoxBlurRadius *blur_vert;
        BoxBlurPower *blur_power;
+       BoxBlurDrag *drag;
+       BoxBlurX *box_x;
+       BoxBlurY *box_y;
+       BoxBlurW *box_w;
+       BoxBlurH *box_h;
 };
 
 
-
 class BoxBlurEffect : public PluginVClient
 {
 public:
@@ -96,16 +232,37 @@ public:
        int is_realtime();
        void save_data(KeyFrame *keyframe);
        void read_data(KeyFrame *keyframe);
+       void draw_boundry();
 
+       VFrame *input, *output;
        BoxBlur *box_blur;
 };
 
 
-BoxBlurConfig::BoxBlurConfig()
+void BoxBlurConfig::reset()
+{
+       horz_radius = 0;
+       vert_radius = 0;
+       power = 1;
+       drag = 0;
+       box_x = box_y = 0.0;
+       box_w = box_h = 0;
+}
+
+void BoxBlurConfig::preset()
 {
        horz_radius = 2;
        vert_radius = 2;
        power = 2;
+       drag = 0;
+       box_x = box_y = 0.0;
+       box_w = box_h = 0;
+}
+
+
+BoxBlurConfig::BoxBlurConfig()
+{
+       preset();
 }
 
 void BoxBlurConfig::copy_from(BoxBlurConfig &that)
@@ -113,13 +270,18 @@ void BoxBlurConfig::copy_from(BoxBlurConfig &that)
        horz_radius = that.horz_radius;
        vert_radius = that.vert_radius;
        power = that.power;
+       drag = that.drag;
+       box_x = that.box_x;  box_y = that.box_y;
+       box_w = that.box_w;  box_h = that.box_h;
 }
 
 int BoxBlurConfig::equivalent(BoxBlurConfig &that)
 {
        return horz_radius == that.horz_radius &&
                vert_radius == that.vert_radius &&
-               power == that.power;
+               power == that.power && // drag == that.drag &&
+               EQUIV(box_x, that.box_x) && EQUIV(box_y, that.box_y) &&
+               box_w == that.box_w && box_h == that.box_h;
 }
 
 void BoxBlurConfig::interpolate(BoxBlurConfig &prev, BoxBlurConfig &next,
@@ -130,66 +292,227 @@ void BoxBlurConfig::interpolate(BoxBlurConfig &prev, BoxBlurConfig &next,
        this->horz_radius = u*prev.horz_radius + v*next.horz_radius;
        this->vert_radius = u*prev.vert_radius + v*next.vert_radius;
        this->power = u*prev.power + v*next.power;
+       this->drag = prev.drag;
+       this->box_x = u*prev.box_x + v*next.box_x;
+       this->box_y = u*prev.box_y + v*next.box_y;
+       this->box_w = u*prev.box_w + v*next.box_w;
+       this->box_h = u*prev.box_h + v*next.box_h;
 }
 
 
-BoxBlurRadius::BoxBlurRadius(BoxBlurWindow *gui, int x, int y, int w, int *radius)
- : BC_ISlider(x, y, 0, w, w, 0, 100, *radius)
+int BoxBlurNum::get_w() { return w; }
+int BoxBlurNum::get_h() { return h; }
+
+BoxBlurNumISlider::BoxBlurNumISlider(BoxBlurNum *num, int x, int y)
+ : BC_ISlider(x, y, 0, num->slider_w, num->slider_w,
+               num->imn, num->imx, *num->ivalue)
 {
-       this->gui = gui;
-       this->radius = radius;
+       this->num = num;
 }
-int BoxBlurRadius::handle_event()
+
+int BoxBlurNumISlider::handle_event()
 {
-       *radius = get_value();
-       gui->plugin->send_configure_change();
+       int iv = get_value();
+       num->update(iv);
        return 1;
 }
 
-BoxBlurPower::BoxBlurPower(BoxBlurWindow *gui, int x, int y, int w, int *power)
- : BC_ISlider(x, y, 0, w, w, 1, 10, *power)
+BoxBlurNumIText::BoxBlurNumIText(BoxBlurNum *num, int x, int y)
+ : BC_TumbleTextBox(num->gui, *num->ivalue, num->imn, num->imx,
+                       x, y, num->text_w)
 {
-       this->gui = gui;
-       this->power = power;
+       this->num = num;
+}
+
+int BoxBlurNumIText::handle_event()
+{
+       int iv = atoi(get_text());
+       num->update(iv);
+       return 1;
+}
+
+BoxBlurNumClear::BoxBlurNumClear(BoxBlurNum *num, int x, int y)
+ : BC_Button(x, y, num->gui->plugin->get_theme()->get_image_set("reset_button"))
+{
+       this->num = num;
 }
-int BoxBlurPower::handle_event()
+
+int BoxBlurNumClear::calculate_w(BoxBlurNum *num)
+{
+       VFrame **imgs = num->gui->plugin->get_theme()->get_image_set("reset_button");
+       return imgs[0]->get_w();
+}
+
+int BoxBlurNumClear::handle_event()
 {
-       *power = get_value();
-       gui->plugin->send_configure_change();
+       int v = num->imn;
+       num->update(v);
        return 1;
 }
 
+BoxBlurNum::BoxBlurNum(BoxBlurWindow *gui, int x, int y, int w,
+                const char *name, int *iv, int imn, int imx)
+{
+       this->gui = gui;
+       this->x = x;
+       this->y = y;
+       this->w = w;
+       this->h = 0;
+       this->name = name;
+       this->ivalue = iv;
+       this->imn = imn;
+       this->imx = imx;
+       int margin = gui->plugin->get_theme()->widget_border;
+       int clear_w = BoxBlurNumClear::calculate_w(this);
+       int tumble_w = BC_Tumbler::calculate_w();
+       int len = w - 2*margin - clear_w - tumble_w;
+       this->title_w = xS(60);
+       this->text_w = xS(60) - tumble_w;
+       this->slider_w = len - title_w - text_w - 2*margin;
+
+       title = 0;
+       text = 0;
+       slider = 0;
+       clear = 0;
+}
+
+BoxBlurNum::~BoxBlurNum()
+{
+       delete text;
+}
+
+void BoxBlurNum::create_objects()
+{
+       int x1 = this->x;
+       gui->add_subwindow(title = new BC_Title(x1, y, name));
+       int margin = gui->plugin->get_theme()->widget_border;
+       x1 += title_w + margin;
+       text = new BoxBlurNumIText(this, x1, y);
+       text->create_objects();
+       x1 += text_w + BC_Tumbler::calculate_w() + margin;
+       gui->add_subwindow(slider = new BoxBlurNumISlider(this, x1, y));
+       x1 += slider_w + 2*margin;
+       gui->add_subwindow(clear = new BoxBlurNumClear(this, x1, y));
+       h = bmax(title->get_h(), bmax(text->get_h(),
+               bmax(slider->get_h(), clear->get_h())));
+}
+
+void BoxBlurNum::update(int value)
+{
+       text->update((int64_t)value);
+       slider->update(value);
+       *ivalue = value;
+       gui->update_drag();
+}
+
+
+BoxBlurRadius::BoxBlurRadius(BoxBlurWindow *gui, int x, int y, int w,
+               const char *name, int *radius)
+ : BoxBlurNum(gui, x, y, w, name, radius, 0, 100)
+{
+}
+
+BoxBlurPower::BoxBlurPower(BoxBlurWindow *gui, int x, int y, int w,
+               const char *name, int *power)
+ : BoxBlurNum(gui, x, y, w, name, power, 1, 10)
+{
+}
+
 BoxBlurWindow::BoxBlurWindow(BoxBlurEffect *plugin)
- : PluginClientWindow(plugin, xS(200), yS(120), xS(200), yS(120), 0)
+ : PluginClientWindow(plugin, xS(360), yS(240), xS(360), yS(240), 0)
 {
        this->plugin = plugin;
+       blur_horz = 0;
+       blur_vert = 0;
+       blur_power = 0;
+       box_x = 0;  box_y = 0;
+       box_w = 0;  box_h = 0;
 }
 
 BoxBlurWindow::~BoxBlurWindow()
 {
+       delete blur_horz;
+       delete blur_vert;
+       delete blur_power;
+       delete box_x;
+       delete box_y;
+       delete box_w;
+       delete box_h;
 }
 
 void BoxBlurWindow::create_objects()
 {
        int x = xS(10), y = yS(10);
-       int x1 = xS(70), margin = plugin->get_theme()->widget_border;
+       int t1 = x, t2 = t1+xS(24), t3 = t2+xS(100), t4 = t3+xS(24);
+       int ww = get_w() - 2*x, bar_o = xS(30), bar_m = xS(15);
+       int margin = plugin->get_theme()->widget_border;
+
+        BC_TitleBar *tbar;
+        add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Position & Size")));
+        y += tbar->get_h() + margin;
+       int x1 = ww - BoxBlurDrag::calculate_w(this) - margin;
+       add_subwindow(drag = new BoxBlurDrag(this, plugin, x1, y));
+       drag->create_objects();
+       if( plugin->config.drag && drag->drag_activate() )
+               eprintf("drag enabled, but compositor already grabbed\n");
+
        BC_Title *title;
-       add_subwindow(title = new BC_Title(x, y, _("Box Blur"), MEDIUMFONT, YELLOW));
-       y += title->get_h() + 2*margin;
-       add_subwindow(title = new BC_Title(x, y, _("Horz:")));
-       add_subwindow(blur_horz = new BoxBlurRadius(this, x1, y, xS(120),
-               &plugin->config.horz_radius));
+       add_subwindow(title = new BC_Title(t1, y, _("X:")));
+       box_x = new BoxBlurX(this, t2, y);
+       box_x->create_objects();
+       add_subwindow(title = new BC_Title(t3, y, _("W:")));
+       box_w = new BoxBlurW(this, t4, y);
+       box_w->create_objects();
+       y += bmax(title->get_h(), box_w->get_h()) + margin;
+       add_subwindow(title = new BC_Title(t1, y, _("Y:")));
+       box_y = new BoxBlurY(this, t2, y);
+       box_y->create_objects();
+       add_subwindow(title = new BC_Title(t3, y, _("H:")));
+       box_h = new BoxBlurH(this, t4, y);
+       box_h->create_objects();
+       y += bmax(title->get_h(), box_h->get_h()) + 2*margin;
+
+       add_subwindow(tbar = new BC_TitleBar(x, y, ww, bar_o, bar_m, _("Blur")));
+       y += tbar->get_h() + margin;
+       blur_horz = new BoxBlurRadius(this, x, y, ww, _("Horz:"),
+                       &plugin->config.horz_radius);
+       blur_horz->create_objects();
        y += blur_horz->get_h() + margin;
-       add_subwindow(title = new BC_Title(x, y, _("Vert:")));
-       add_subwindow(blur_vert = new BoxBlurRadius(this, x1, y, xS(120),
-               &plugin->config.vert_radius));
+       blur_vert = new BoxBlurRadius(this, x, y, ww, _("Vert:"),
+                       &plugin->config.vert_radius);
+       blur_vert->create_objects();
        y += blur_vert->get_h() + margin;
-       add_subwindow(title = new BC_Title(x, y, _("Power:")));
-       add_subwindow(blur_power = new BoxBlurPower(this, x1, y, xS(120),
-               &plugin->config.power));
+       blur_power = new BoxBlurPower(this, x, y, ww, _("Power:"),
+                       &plugin->config.power);
+       blur_power->create_objects();
+       y += blur_power->get_h() + margin;
+       BC_Bar *bar;
+       add_subwindow(bar = new BC_Bar(x, y, ww));
+       y += bar->get_h() + 2*margin;
+
+       add_subwindow(reset = new BoxBlurReset(this, x, y));
+       x1 = x + ww - BoxBlurPreset::calculate_w(this);
+       add_subwindow(preset = new BoxBlurPreset(this, x1, y));
+       y += bmax(title->get_h(), reset->get_h()) + 2*margin;
        show_window(1);
 }
 
+void BoxBlurWindow::update_gui()
+{
+       BoxBlurConfig &config = plugin->config;
+       blur_horz->update(config.horz_radius);
+       blur_vert->update(config.vert_radius);
+       blur_power->update(config.power);
+       box_x->update(config.box_x);
+       box_y->update(config.box_y);
+       box_w->update((int64_t)config.box_w);
+       box_h->update((int64_t)config.box_h);
+       drag->drag_x = config.box_x;
+       drag->drag_y = config.box_y;
+       drag->drag_w = config.box_w;
+       drag->drag_h = config.box_h;
+}
+
 
 REGISTER_PLUGIN(BoxBlurEffect)
 NEW_WINDOW_MACRO(BoxBlurEffect, BoxBlurWindow)
@@ -219,6 +542,11 @@ void BoxBlurEffect::save_data(KeyFrame *keyframe)
        output.tag.set_property("HORZ_RADIUS", config.horz_radius);
        output.tag.set_property("VERT_RADIUS", config.vert_radius);
        output.tag.set_property("POWER", config.power);
+       output.tag.set_property("DRAG", config.drag);
+       output.tag.set_property("BOX_X", config.box_x);
+       output.tag.set_property("BOX_Y", config.box_y);
+       output.tag.set_property("BOX_W", config.box_w);
+       output.tag.set_property("BOX_H", config.box_h);
        output.append_tag();
        output.tag.set_title("/BOXBLUR");
        output.append_tag();
@@ -237,23 +565,51 @@ void BoxBlurEffect::read_data(KeyFrame *keyframe)
                        config.horz_radius = input.tag.get_property("HORZ_RADIUS", config.horz_radius);
                        config.vert_radius = input.tag.get_property("VERT_RADIUS", config.vert_radius);
                        config.power = input.tag.get_property("POWER", config.power);
+                       config.drag = input.tag.get_property("DRAG", config.drag);
+                       config.box_x = input.tag.get_property("BOX_X", config.box_x);
+                       config.box_y = input.tag.get_property("BOX_Y", config.box_y);
+                       config.box_w = input.tag.get_property("BOX_W", config.box_w);
+                       config.box_h = input.tag.get_property("BOX_H", config.box_h);
                }
        }
 }
 
+void BoxBlurEffect::draw_boundry()
+{
+       if( !gui_open() ) return;
+       int box_x = config.box_x, box_y = config.box_y;
+       int box_w = config.box_w ? config.box_w : input->get_w();
+       int box_h = config.box_h ? config.box_h : input->get_h();
+       DragCheckBox::draw_boundary(output, box_x, box_y, box_w, box_h);
+}
+
 int BoxBlurEffect::process_realtime(VFrame *input, VFrame *output)
 {
+       this->input = input;
+       this->output = output;
        load_configuration();
+       int out_w = output->get_w(), out_h = output->get_h();
+
        if( !box_blur ) {
-               int cpus = input->get_w()*input->get_h()/0x80000 + 1;
+               int cpus = (out_w * out_h)/0x80000 + 1;
                box_blur = new BoxBlur(cpus);
        }
+       int x = config.box_x, y = config.box_y;
+       int ow = config.box_w ? config.box_w : out_w;
+       int oh = config.box_h ? config.box_h : out_h;
        if( config.horz_radius ) {
-               box_blur->hblur(output, input, config.horz_radius, config.power);
+               box_blur->hblur(output, input, config.horz_radius, config.power,
+                       -1, x,y, ow, oh);
                input = output;
        }
-       if( config.vert_radius )
-               box_blur->vblur(output, input, config.vert_radius, config.power);
+       if( config.vert_radius ) {
+               box_blur->vblur(output, input, config.vert_radius, config.power,
+                       -1, x,y, ow, oh);
+       }
+
+       if( config.drag )
+               draw_boundry();
+
        return 1;
 }
 
@@ -263,9 +619,164 @@ void BoxBlurEffect::update_gui()
        load_configuration();
        thread->window->lock_window("BoxBlurEffect::update_gui");
        BoxBlurWindow *gui = (BoxBlurWindow *)thread->window;
-       gui->blur_horz->update(config.horz_radius);
-       gui->blur_vert->update(config.vert_radius);
-       gui->blur_power->update(config.power);
+       gui->update_gui();
        thread->window->unlock_window();
 }
 
+
+BoxBlurX::BoxBlurX(BoxBlurWindow *gui, int x, int y)
+ : BC_TumbleTextBox(gui, gui->plugin->config.box_x,
+               -32767.f, 32767.f, x, y, xS(64))
+{
+       this->gui = gui;
+       set_precision(1);
+}
+int BoxBlurX::handle_event()
+{
+       gui->plugin->config.box_x = atof(get_text());
+       gui->update_drag();
+       return 1;
+}
+
+BoxBlurY::BoxBlurY(BoxBlurWindow *gui, int x, int y)
+ : BC_TumbleTextBox(gui, gui->plugin->config.box_y,
+               -32767.f, 32767.f, x, y, xS(64))
+{
+       this->gui = gui;
+       set_precision(1);
+}
+int BoxBlurY::handle_event()
+{
+       gui->plugin->config.box_y = atof(get_text());
+       gui->update_drag();
+       return 1;
+}
+
+BoxBlurW::BoxBlurW(BoxBlurWindow *gui, int x, int y)
+ : BC_TumbleTextBox(gui, gui->plugin->config.box_w,
+               0, 32767, x, y, xS(64))
+{
+       this->gui = gui;
+}
+int BoxBlurW::handle_event()
+{
+       gui->plugin->config.box_w = atol(get_text());
+       gui->update_drag();
+       return 1;
+}
+
+BoxBlurH::BoxBlurH(BoxBlurWindow *gui, int x, int y)
+ : BC_TumbleTextBox(gui, gui->plugin->config.box_h,
+               0, 32767, x, y, xS(64))
+{
+       this->gui = gui;
+}
+int BoxBlurH::handle_event()
+{
+       gui->plugin->config.box_h = atol(get_text());
+       gui->update_drag();
+       return 1;
+}
+
+BoxBlurDrag::BoxBlurDrag(BoxBlurWindow *gui, BoxBlurEffect *plugin, int x, int y)
+ : DragCheckBox(plugin->server->mwindow, x, y, _("Drag"), &plugin->config.drag,
+               plugin->config.box_x, plugin->config.box_y,
+               plugin->config.box_w, plugin->config.box_h)
+{
+       this->plugin = plugin;
+       this->gui = gui;
+}
+
+int BoxBlurDrag::calculate_w(BoxBlurWindow *gui)
+{
+       int w, h;
+       calculate_extents(gui, &w, &h, _("Drag"));
+       return w;
+}
+
+Track *BoxBlurDrag::get_drag_track()
+{
+       PluginServer *server = plugin->server;
+       int plugin_id = server->plugin_id;
+       Plugin *plugin = server->edl->tracks->plugin_exists(plugin_id);
+       return !plugin ? 0 : plugin->track;
+}
+int64_t BoxBlurDrag::get_drag_position()
+{
+       return plugin->get_source_position();
+}
+
+void BoxBlurDrag::update_gui()
+{
+       plugin->config.drag = get_value();
+       plugin->config.box_x = drag_x;
+       plugin->config.box_y = drag_y;
+       plugin->config.box_w = drag_w+0.5;
+       plugin->config.box_h = drag_h+0.5;
+       gui->box_x->update((float)plugin->config.box_x);
+       gui->box_y->update((float)plugin->config.box_y);
+       gui->box_w->update((int64_t)plugin->config.box_w);
+       gui->box_h->update((int64_t)plugin->config.box_h);
+       plugin->send_configure_change();
+}
+
+int BoxBlurDrag::handle_event()
+{
+       int ret = DragCheckBox::handle_event();
+       plugin->send_configure_change();
+       return ret;
+}
+
+void BoxBlurWindow::update_drag()
+{
+       drag->drag_x = plugin->config.box_x;
+       drag->drag_y = plugin->config.box_y;
+       drag->drag_w = plugin->config.box_w;
+       drag->drag_h = plugin->config.box_h;
+       plugin->send_configure_change();
+}
+
+BoxBlurReset::BoxBlurReset(BoxBlurWindow *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Reset"))
+{
+       this->gui = gui;
+}
+
+int BoxBlurReset::calculate_w(BoxBlurWindow *gui)
+{
+       return BC_GenericButton::calculate_w(gui,_("Reset"));
+}
+
+int BoxBlurReset::handle_event()
+{
+       BoxBlurEffect *plugin = gui->plugin;
+       plugin->config.reset();
+       gui->drag->update(0);
+       gui->drag->drag_deactivate();
+       gui->update_gui();
+       gui->update_drag();
+       return 1;
+}
+
+BoxBlurPreset::BoxBlurPreset(BoxBlurWindow *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Default"))
+{
+       this->gui = gui;
+}
+
+int BoxBlurPreset::calculate_w(BoxBlurWindow *gui)
+{
+       return BC_GenericButton::calculate_w(gui,_("Default"));
+}
+
+int BoxBlurPreset::handle_event()
+{
+       BoxBlurEffect *plugin = gui->plugin;
+       plugin->config.preset();
+       gui->drag->update(0);
+       gui->drag->drag_deactivate();
+       gui->update_gui();
+       gui->update_drag();
+       return 1;
+}
+