dragcheckbox rework, boxblur create can grab
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / crikey / crikeywindow.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2014 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include "automation.h"
22 #include "bcdisplayinfo.h"
23 #include "clip.h"
24 #include "crikey.h"
25 #include "crikeywindow.h"
26 #include "cstrdup.h"
27 #include "cwindow.h"
28 #include "cwindowgui.h"
29 #include "edl.h"
30 #include "edlsession.h"
31 #include "language.h"
32 #include "mainerror.h"
33 #include "mwindow.h"
34 #include "plugin.h"
35 #include "pluginserver.h"
36 #include "theme.h"
37 #include "track.h"
38
39 #define COLOR_W xS(50)
40 #define COLOR_H yS(30)
41
42 CriKeyNum::CriKeyNum(CriKeyWindow *gui, int x, int y, float output)
43  : BC_TumbleTextBox(gui, output, -32767.0f, 32767.0f, x, y, xS(120))
44 {
45         this->gui = gui;
46         set_increment(1);
47         set_precision(1);
48 }
49
50 CriKeyNum::~CriKeyNum()
51 {
52 }
53
54 int CriKeyPointX::handle_event()
55 {
56         if( !CriKeyNum::handle_event() ) return 0;
57         CriKeyPointList *point_list = gui->point_list;
58         int hot_point = point_list->get_selection_number(0, 0);
59         CriKeyPoints &points = gui->plugin->config.points;
60         int sz = points.size();
61         if( hot_point >= 0 && hot_point < sz ) {
62                 float v = atof(get_text());
63                 points[hot_point]->x = v;
64                 point_list->set_point(hot_point, PT_X, v);
65         }
66         point_list->update_list(hot_point);
67         gui->send_configure_change();
68         return 1;
69 }
70 int CriKeyPointY::handle_event()
71 {
72         if( !CriKeyNum::handle_event() ) return 0;
73         CriKeyPointList *point_list = gui->point_list;
74         int hot_point = point_list->get_selection_number(0, 0);
75         CriKeyPoints &points = gui->plugin->config.points;
76         int sz = points.size();
77         if( hot_point >= 0 && hot_point < sz ) {
78                 float v = atof(get_text());
79                 points[hot_point]->y = v;
80                 point_list->set_point(hot_point, PT_Y, v);
81         }
82         point_list->update_list(hot_point);
83         gui->send_configure_change();
84         return 1;
85 }
86
87 int CriKeyDrawModeItem::handle_event()
88 {
89         ((CriKeyDrawMode *)get_popup_menu())->update(id);
90         return 1;
91 }
92 CriKeyDrawMode::CriKeyDrawMode(CriKeyWindow *gui, int x, int y)
93  : BC_PopupMenu(x, y, xS(100), "", 1)
94 {
95         this->gui = gui;
96         draw_modes[DRAW_ALPHA]     = _("Alpha");
97         draw_modes[DRAW_EDGE]      = _("Edge");
98         draw_modes[DRAW_MASK]      = _("Mask");
99         mode = -1;
100 }
101 void CriKeyDrawMode::create_objects()
102 {
103         for( int i=0; i<DRAW_MODES; ++i )
104                 add_item(new CriKeyDrawModeItem(draw_modes[i], i));
105         update(gui->plugin->config.draw_mode, 0);
106 }
107 void CriKeyDrawMode::update(int mode, int send)
108 {
109         if( this->mode == mode ) return;
110         this->mode = mode;
111         set_text(draw_modes[mode]);
112         gui->plugin->config.draw_mode = mode;
113         if( send ) gui->send_configure_change();
114 }
115
116
117 CriKeyWindow::CriKeyWindow(CriKey *plugin)
118  : PluginClientWindow(plugin, xS(380), yS(400), xS(380), yS(400), 0)
119 {
120         this->plugin = plugin;
121         this->title_x = 0;    this->point_x = 0;
122         this->title_y = 0;    this->point_y = 0;
123         this->new_point = 0;  this->del_point = 0;
124         this->point_up = 0;   this->point_dn = 0;
125         this->drag = 0;       this->dragging = 0;
126         this->last_x = 0;     this->last_y = 0;
127         this->point_list = 0; this->pending_config = 0;
128 }
129
130 CriKeyWindow::~CriKeyWindow()
131 {
132         delete point_x;
133         delete point_y;
134 }
135
136 void CriKeyWindow::create_objects()
137 {
138         int xs10 = xS(10), xs32 = xS(32);
139         int ys5 = yS(5), ys10 = yS(10);
140         int x = 10, y = 10;
141         int margin = plugin->get_theme()->widget_border;
142         BC_Title *title;
143         add_subwindow(title = new BC_Title(x, y+ys5, _("Draw mode:")));
144         int x1 = x + title->get_w() + xs10 + margin;
145         add_subwindow(draw_mode = new CriKeyDrawMode(this, x1, y));
146         draw_mode->create_objects();
147         y += draw_mode->get_h() + ys10 + margin;
148
149         CriKeyPoint *pt = plugin->config.points[plugin->config.selected];
150         add_subwindow(title_x = new BC_Title(x, y, _("X:")));
151         x1 = x + title_x->get_w() + margin;
152         point_x = new CriKeyPointX(this, x1, y, pt->x);
153         point_x->create_objects();
154         x1 += point_x->get_w() + margin;
155         add_subwindow(new_point = new CriKeyNewPoint(this, plugin, x1, y));
156         x1 += new_point->get_w() + margin;
157         add_subwindow(point_up = new CriKeyPointUp(this, x1, y));
158         y += point_x->get_h() + margin;
159         add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
160         x1 = x + title_y->get_w() + margin;
161         point_y = new CriKeyPointY(this, x1, y, pt->y);
162         point_y->create_objects();
163         x1 += point_y->get_w() + margin;
164         add_subwindow(del_point = new CriKeyDelPoint(this, plugin, x1, y));
165         x1 += del_point->get_w() + margin;
166         add_subwindow(point_dn = new CriKeyPointDn(this, x1, y));
167         y += point_y->get_h() + margin + ys10;
168         add_subwindow(title = new BC_Title(x, y, _("Threshold:")));
169         y += title->get_h() + margin;
170         add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
171         y += threshold->get_h() + margin;
172
173         add_subwindow(drag = new CriKeyDrag(this, x, y));
174         if( plugin->config.drag ) {
175                 if( !grab(plugin->server->mwindow->cwindow->gui) )
176                         eprintf("drag enabled, but compositor already grabbed\n");
177         }
178         x1 = x + drag->get_w() + margin + xs32;
179         add_subwindow(reset = new CriKeyReset(this, plugin, x1, y+yS(3)));
180         y += drag->get_h() + margin;
181
182         add_subwindow(point_list = new CriKeyPointList(this, plugin, x, y));
183         point_list->update(plugin->config.selected);
184
185         y += point_list->get_h() + ys10;
186         add_subwindow(notes = new BC_Title(x, y,
187                  _("Right click in composer: create new point\n"
188                    "Shift-left click in Enable field:\n"
189                    "  if any off, turns all on\n"
190                    "  if all on, turns rest off.")));
191         show_window(1);
192 }
193
194 void CriKeyWindow::send_configure_change()
195 {
196         pending_config = 0;
197         plugin->send_configure_change();
198 }
199
200 int CriKeyWindow::grab_event(XEvent *event)
201 {
202         int ret = do_grab_event(event);
203         if( pending_config && !grab_event_count() )
204                 send_configure_change();
205         return ret;
206 }
207
208 int CriKeyWindow::do_grab_event(XEvent *event)
209 {
210         switch( event->type ) {
211         case ButtonPress: break;
212         case ButtonRelease: break;
213         case MotionNotify: break;
214         default:
215                 return 0;
216         }
217
218         MWindow *mwindow = plugin->server->mwindow;
219         CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
220         CWindowCanvas *canvas = cwindow_gui->canvas;
221         int cursor_x, cursor_y;
222         cwindow_gui->get_relative_cursor(cursor_x, cursor_y);
223         float output_x = cursor_x - canvas->view_x;
224         float output_y = cursor_y - canvas->view_y;
225
226         if( !dragging ) {
227                 if( output_x < 0 || output_x >= canvas->view_w ||
228                     output_y < 0 || output_y >= canvas->view_h )
229                         return 0;
230         }
231
232         switch( event->type ) {
233         case ButtonPress:
234                 if( dragging ) return 0;
235                 if( event->xbutton.button == WHEEL_UP )  return threshold->wheel_event(1);
236                 if( event->xbutton.button == WHEEL_DOWN ) return threshold->wheel_event(-1);
237                 dragging = event->xbutton.state & ShiftMask ? -1 : 1;
238                 break;
239         case ButtonRelease:
240                 if( !dragging ) return 0;
241                 dragging = 0;
242                 return 1;
243         case MotionNotify:
244                 if( !dragging ) return 0;
245                 break;
246         default:
247                 return 0;
248         }
249
250         float track_x, track_y;
251         canvas->canvas_to_output(mwindow->edl, 0, output_x, output_y);
252         plugin->output_to_track(output_x, output_y, track_x, track_y);
253         point_x->update((int64_t)track_x);
254         point_y->update((int64_t)track_y);
255         CriKeyPoints &points = plugin->config.points;
256
257         if( dragging > 0 ) {
258                 switch( event->type ) {
259                 case ButtonPress: {
260                         int button_no = event->xbutton.button;
261                         int hot_point = -1;
262                         if( button_no == RIGHT_BUTTON ) {
263                                 hot_point = plugin->new_point();
264                                 CriKeyPoint *pt = points[hot_point];
265                                 pt->x = track_x;  pt->y = track_y;
266                                 point_list->update(hot_point);
267                                 break;
268                         }
269                         int sz = points.size();
270                         if( hot_point < 0 && sz > 0 ) {
271                                 CriKeyPoint *pt = points[hot_point=0];
272                                 double dist = DISTANCE(track_x,track_y, pt->x,pt->y);
273                                 for( int i=1; i<sz; ++i ) {
274                                         pt = points[i];
275                                         double d = DISTANCE(track_x,track_y, pt->x,pt->y);
276                                         if( d >= dist ) continue;
277                                         dist = d;  hot_point = i;
278                                 }
279                                 pt = points[hot_point];
280                                 float cx, cy;
281                                 plugin->track_to_output(pt->x, pt->y, cx, cy);
282                                 canvas->output_to_canvas(mwindow->edl, 0, cx, cy);
283                                 cx += canvas->view_x;  cy += canvas->view_y;
284                                 dist = DISTANCE(cx,cy, cursor_x,cursor_y);
285                                 if( dist >= HANDLE_W )
286                                         hot_point = -1;
287                         }
288                         if( hot_point >= 0 && sz > 0 ) {
289                                 CriKeyPoint *pt = points[hot_point];
290                                 point_list->set_point(hot_point, PT_X, pt->x = track_x);
291                                 point_list->set_point(hot_point, PT_Y, pt->y = track_y);
292                                 for( int i=0; i<sz; ++i ) {
293                                         pt = points[i];
294                                         pt->e = i==hot_point ? !pt->e : 0;
295                                         point_list->set_point(i, PT_E, pt->e ? "*" : "");
296                                 }
297                                 point_list->update_list(hot_point);
298                         }
299                         break; }
300                 case MotionNotify: {
301                         int hot_point = point_list->get_selection_number(0, 0);
302                         if( hot_point >= 0 && hot_point < points.size() ) {
303                                 CriKeyPoint *pt = points[hot_point];
304                                 if( pt->x == track_x && pt->y == track_y ) break;
305                                 point_list->set_point(hot_point, PT_X, pt->x = track_x);
306                                 point_list->set_point(hot_point, PT_Y, pt->y = track_y);
307                                 point_x->update(pt->x);
308                                 point_y->update(pt->y);
309                                 point_list->update_list(hot_point);
310                         }
311                         break; }
312                 }
313         }
314         else {
315                 switch( event->type ) {
316                 case MotionNotify: {
317                         float dx = track_x - last_x, dy = track_y - last_y;
318                         int sz = points.size();
319                         for( int i=0; i<sz; ++i ) {
320                                 CriKeyPoint *pt = points[i];
321                                 point_list->set_point(i, PT_X, pt->x += dx);
322                                 point_list->set_point(i, PT_Y, pt->y += dy);
323                         }
324                         int hot_point = point_list->get_selection_number(0, 0);
325                         if( hot_point >= 0 && hot_point < sz ) {
326                                 CriKeyPoint *pt = points[hot_point];
327                                 point_x->update(pt->x);
328                                 point_y->update(pt->y);
329                                 point_list->update_list(hot_point);
330                         }
331                         break; }
332                 }
333         }
334
335         last_x = track_x;  last_y = track_y;
336         pending_config = 1;
337         return 1;
338 }
339
340 void CriKeyWindow::done_event(int result)
341 {
342         ungrab(client->server->mwindow->cwindow->gui);
343 }
344
345 CriKeyPointList::CriKeyPointList(CriKeyWindow *gui, CriKey *plugin, int x, int y)
346  : BC_ListBox(x, y, xS(360), yS(130), LISTBOX_TEXT)
347 {
348         this->gui = gui;
349         this->plugin = plugin;
350         titles[PT_E] = _("E");    widths[PT_E] = xS(50);
351         titles[PT_X] = _("X");    widths[PT_X] = xS(90);
352         titles[PT_Y] = _("Y");    widths[PT_Y] = xS(90);
353         titles[PT_T] = _("T");    widths[PT_T] = xS(70);
354         titles[PT_TAG] = _("Tag");  widths[PT_TAG] = xS(50);
355 }
356 CriKeyPointList::~CriKeyPointList()
357 {
358         clear();
359 }
360 void CriKeyPointList::clear()
361 {
362         for( int i=PT_SZ; --i>=0; )
363                 cols[i].remove_all_objects();
364 }
365
366 int CriKeyPointList::column_resize_event()
367 {
368         for( int i=PT_SZ; --i>=0; )
369                 widths[i] = get_column_width(i);
370         return 1;
371 }
372
373 int CriKeyPointList::handle_event()
374 {
375         int hot_point = get_selection_number(0, 0);
376         const char *x_text = "", *y_text = "";
377         float t = plugin->config.threshold;
378         CriKeyPoints &points = plugin->config.points;
379
380         int sz = points.size();
381         if( hot_point >= 0 && sz > 0 ) {
382                 if( get_cursor_x() < widths[0] ) {
383                         if( shift_down() ) {
384                                 int all_on = points[0]->e;
385                                 for( int i=1; i<sz && all_on; ++i ) all_on = points[i]->e;
386                                 int e = !all_on ? 1 : 0;
387                                 for( int i=0; i<sz; ++i ) points[i]->e = e;
388                                 points[hot_point]->e = 1;
389                         }
390                         else
391                                 points[hot_point]->e = !points[hot_point]->e;
392                 }
393                 x_text = gui->point_list->cols[PT_X].get(hot_point)->get_text();
394                 y_text = gui->point_list->cols[PT_Y].get(hot_point)->get_text();
395                 t = points[hot_point]->t;
396         }
397         gui->point_x->update(x_text);
398         gui->point_y->update(y_text);
399         gui->threshold->update(t);
400         update(hot_point);
401         gui->send_configure_change();
402         return 1;
403 }
404
405 int CriKeyPointList::selection_changed()
406 {
407         handle_event();
408         return 1;
409 }
410
411 void CriKeyPointList::new_point(const char *ep, const char *xp, const char *yp,
412                 const char *tp, const char *tag)
413 {
414         cols[PT_E].append(new BC_ListBoxItem(ep));
415         cols[PT_X].append(new BC_ListBoxItem(xp));
416         cols[PT_Y].append(new BC_ListBoxItem(yp));
417         cols[PT_T].append(new BC_ListBoxItem(tp));
418         cols[PT_TAG].append(new BC_ListBoxItem(tag));
419 }
420
421 void CriKeyPointList::del_point(int i)
422 {
423         for( int sz1=cols[0].size()-1, c=PT_SZ; --c>=0; )
424                 cols[c].remove_object_number(sz1-i);
425 }
426
427 void CriKeyPointList::set_point(int i, int c, float v)
428 {
429         char s[BCSTRLEN]; sprintf(s,"%0.4f",v);
430         set_point(i,c,s);
431 }
432 void CriKeyPointList::set_point(int i, int c, const char *cp)
433 {
434         cols[c].get(i)->set_text(cp);
435 }
436
437 int CriKeyPointList::set_selected(int k)
438 {
439         CriKeyPoints &points = plugin->config.points;
440         int sz = points.size();
441         if( !sz ) return -1;
442         bclamp(k, 0, sz-1);
443         for( int i=0; i<sz; ++i ) points[i]->e = 0;
444         points[k]->e = 1;
445         update_selection(&cols[0], k);
446         return k;
447 }
448 void CriKeyPointList::update_list(int k)
449 {
450         int xpos = get_xposition(), ypos = get_yposition();
451         if( k < 0 ) k = get_selection_number(0, 0);
452         update_selection(&cols[0], k);
453         BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
454         center_selection();
455 }
456 void CriKeyPointList::update(int k)
457 {
458         clear();
459         CriKeyPoints &points = plugin->config.points;
460         int sz = points.size();
461         for( int i=0; i<sz; ++i ) {
462                 CriKeyPoint *pt = points[i];
463                 char etxt[BCSTRLEN];  sprintf(etxt,"%s", pt->e ? "*" : "");
464                 char xtxt[BCSTRLEN];  sprintf(xtxt,"%0.4f", pt->x);
465                 char ytxt[BCSTRLEN];  sprintf(ytxt,"%0.4f", pt->y);
466                 char ttxt[BCSTRLEN];  sprintf(ttxt,"%0.4f", pt->t);
467                 char ttag[BCSTRLEN];  sprintf(ttag,"%d", pt->tag);
468                 new_point(etxt, xtxt, ytxt, ttxt, ttag);
469         }
470         if( k >= 0 && k < sz ) {
471                 gui->point_x->update(gui->point_list->cols[PT_X].get(k)->get_text());
472                 gui->point_y->update(gui->point_list->cols[PT_Y].get(k)->get_text());
473                 plugin->config.selected = k;
474         }
475
476         update_list(k);
477 }
478
479 void CriKeyWindow::update_gui()
480 {
481         draw_mode->update(plugin->config.draw_mode);
482         threshold->update(plugin->config.threshold);
483         drag->update(plugin->config.drag);
484         point_list->update(-1);
485 }
486
487
488 CriKeyThreshold::CriKeyThreshold(CriKeyWindow *gui, int x, int y, int w)
489  : BC_FSlider(x, y, 0, w, w, 0, 1, gui->plugin->config.threshold, 0)
490 {
491         this->gui = gui;
492         set_precision(0.005);
493         set_pagination(0.01, 0.1);
494 }
495
496 int CriKeyThreshold::wheel_event(int v)
497 {
498         if( v > 0 ) increase_value();
499         else if( v < 0 ) decrease_value();
500         handle_event();
501         enable();
502         return 1;
503 }
504
505 int CriKeyThreshold::handle_event()
506 {
507         float v = get_value();
508         gui->plugin->config.threshold = v;
509         int hot_point = gui->point_list->get_selection_number(0, 0);
510         if( hot_point >= 0 ) {
511                 CriKeyPoints &points = gui->plugin->config.points;
512                 CriKeyPoint *pt = points[hot_point];
513                 pt->t = v;  pt->e = 1;
514                 gui->point_list->update(hot_point);
515         }
516         gui->send_configure_change();
517         return 1;
518 }
519
520
521 CriKeyPointUp::CriKeyPointUp(CriKeyWindow *gui, int x, int y)
522  : BC_GenericButton(x, y, _("Up"))
523 {
524         this->gui = gui;
525 }
526 CriKeyPointUp::~CriKeyPointUp()
527 {
528 }
529
530 int CriKeyPointUp::handle_event()
531 {
532         CriKeyPoints &points = gui->plugin->config.points;
533         int sz = points.size();
534         int hot_point = gui->point_list->get_selection_number(0, 0);
535
536         if( sz > 1 && hot_point > 0 ) {
537                 CriKeyPoint *&pt0 = points[hot_point];
538                 CriKeyPoint *&pt1 = points[--hot_point];
539                 CriKeyPoint *t = pt0;  pt0 = pt1;  pt1 = t;
540                 gui->point_list->update(hot_point);
541         }
542         gui->send_configure_change();
543         return 1;
544 }
545
546 CriKeyPointDn::CriKeyPointDn(CriKeyWindow *gui, int x, int y)
547  : BC_GenericButton(x, y, _("Dn"))
548 {
549         this->gui = gui;
550 }
551 CriKeyPointDn::~CriKeyPointDn()
552 {
553 }
554
555 int CriKeyPointDn::handle_event()
556 {
557         CriKeyPoints &points = gui->plugin->config.points;
558         int sz = points.size();
559         int hot_point = gui->point_list->get_selection_number(0, 0);
560         if( sz > 1 && hot_point < sz-1 ) {
561                 CriKeyPoint *&pt0 = points[hot_point];
562                 CriKeyPoint *&pt1 = points[++hot_point];
563                 CriKeyPoint *t = pt0;  pt0 = pt1;  pt1 = t;
564                 gui->point_list->update(hot_point);
565         }
566         gui->send_configure_change();
567         return 1;
568 }
569
570 CriKeyDrag::CriKeyDrag(CriKeyWindow *gui, int x, int y)
571  : BC_CheckBox(x, y, gui->plugin->config.drag, _("Drag"))
572 {
573         this->gui = gui;
574 }
575 int CriKeyDrag::handle_event()
576 {
577         CWindowGUI *cwindow_gui = gui->plugin->server->mwindow->cwindow->gui;
578         int value = get_value();
579         if( value ) {
580                 if( !gui->grab(cwindow_gui) ) {
581                         update(value = 0);
582                         flicker(10,50);
583                 }
584         }
585         else
586                 gui->ungrab(cwindow_gui);
587         gui->plugin->config.drag = value;
588         gui->send_configure_change();
589         return 1;
590 }
591 int CriKeyWindow::handle_ungrab()
592 {
593         CWindowGUI *cwindow_gui = plugin->server->mwindow->cwindow->gui;
594         int ret = ungrab(cwindow_gui);
595         if( ret ) {
596                 drag->update(0);
597                 plugin->config.drag = 0;
598                 send_configure_change();
599         }
600         return ret;
601 }
602
603 CriKeyNewPoint::CriKeyNewPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
604  : BC_GenericButton(x, y, xS(80), _("New"))
605 {
606         this->gui = gui;
607         this->plugin = plugin;
608 }
609 CriKeyNewPoint::~CriKeyNewPoint()
610 {
611 }
612 int CriKeyNewPoint::handle_event()
613 {
614         int k = plugin->new_point();
615         gui->point_list->update(k);
616         gui->send_configure_change();
617         return 1;
618 }
619
620 CriKeyDelPoint::CriKeyDelPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
621  : BC_GenericButton(x, y, xS(80), C_("Del"))
622 {
623         this->gui = gui;
624         this->plugin = plugin;
625 }
626 CriKeyDelPoint::~CriKeyDelPoint()
627 {
628 }
629 int CriKeyDelPoint::handle_event()
630 {
631         int hot_point = gui->point_list->get_selection_number(0, 0);
632         CriKeyPoints &points = plugin->config.points;
633         if( hot_point >= 0 && hot_point < points.size() ) {
634                 plugin->config.del_point(hot_point);
635                 if( !points.size() ) plugin->new_point();
636                 int sz = points.size();
637                 if( hot_point >= sz && hot_point > 0 ) --hot_point;
638                 gui->point_list->update(hot_point);
639                 gui->send_configure_change();
640         }
641         return 1;
642 }
643
644 CriKeyReset::CriKeyReset(CriKeyWindow *gui, CriKey *plugin, int x, int y)
645  : BC_GenericButton(x, y, _("Reset"))
646 {
647         this->gui = gui;
648         this->plugin = plugin;
649 }
650 CriKeyReset::~CriKeyReset()
651 {
652 }
653 int CriKeyReset::handle_event()
654 {
655         CriKeyPoints &points = plugin->config.points;
656         points.remove_all_objects();
657         plugin->new_point();
658         gui->point_list->update(0);
659         gui->send_configure_change();
660         return 1;
661 }
662