3f72f3ded74ccf5aa1f3b56189a6e6661ab1ca98
[goodguy/history.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 "mwindow.h"
33 #include "plugin.h"
34 #include "pluginserver.h"
35 #include "theme.h"
36 #include "track.h"
37
38 #define COLOR_W 50
39 #define COLOR_H 30
40
41 CriKeyNum::CriKeyNum(CriKeyWindow *gui, int x, int y, float output)
42  : BC_TumbleTextBox(gui, output, -32767.0f, 32767.0f, x, y, 120)
43 {
44         this->gui = gui;
45         set_increment(1);
46         set_precision(1);
47 }
48
49 CriKeyNum::~CriKeyNum()
50 {
51 }
52
53 int CriKeyPointX::handle_event()
54 {
55         if( !CriKeyNum::handle_event() ) return 0;
56         CriKeyPoints *points = gui->points;
57         int hot_point = points->get_selection_number(0, 0);
58         if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
59                 float v = atof(get_text());
60                 gui->plugin->config.points[hot_point]->x = v;
61                 points->set_point(hot_point, PT_X, v);
62         }
63         points->update_list();
64         gui->plugin->send_configure_change();
65         return 1;
66 }
67 int CriKeyPointY::handle_event()
68 {
69         if( !CriKeyNum::handle_event() ) return 0;
70         CriKeyPoints *points = gui->points;
71         int hot_point = points->get_selection_number(0, 0);
72         if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
73                 float v = atof(get_text());
74                 gui->plugin->config.points[hot_point]->y = v;
75                 points->set_point(hot_point, PT_Y, v);
76         }
77         points->update_list();
78         gui->plugin->send_configure_change();
79         return 1;
80 }
81
82 int CriKeyDrawModeItem::handle_event()
83 {
84         ((CriKeyDrawMode *)get_popup_menu())->update(id);
85         return 1;
86 }
87 CriKeyDrawMode::CriKeyDrawMode(CriKeyWindow *gui, int x, int y)
88  : BC_PopupMenu(x, y, 100, "", 1)
89 {
90         this->gui = gui;
91         draw_modes[DRAW_ALPHA]     = _("Alpha");
92         draw_modes[DRAW_EDGE]      = _("Edge");
93         draw_modes[DRAW_MASK]      = _("Mask");
94         mode = -1;
95 }
96 void CriKeyDrawMode::create_objects()
97 {
98         for( int i=0; i<DRAW_MODES; ++i )
99                 add_item(new CriKeyDrawModeItem(draw_modes[i], i));
100         update(gui->plugin->config.draw_mode, 0);
101 }
102 void CriKeyDrawMode::update(int mode, int send)
103 {
104         if( this->mode == mode ) return;
105         this->mode = mode;
106         set_text(draw_modes[mode]);
107         gui->plugin->config.draw_mode = mode;
108         if( send ) gui->plugin->send_configure_change();
109 }
110
111 CriKeyColorButton::CriKeyColorButton(CriKeyWindow *gui, int x, int y)
112  : BC_GenericButton(x, y, _("Color"))
113 {
114         this->gui = gui;
115 }
116 int CriKeyColorButton::handle_event()
117 {
118         gui->start_color_thread();
119         return 1;
120 }
121
122 CriKeyColorPicker::CriKeyColorPicker(CriKeyColorButton *color_button)
123  : ColorPicker(0, _("Color"))
124 {
125         this->color_button = color_button;
126 }
127
128 void CriKeyColorPicker::start(int color)
129 {
130         orig_color = this->color = color;
131         start_window(color, 0, 1);
132 }
133
134 void CriKeyColorPicker::handle_done_event(int result)
135 {
136         if( result ) color = orig_color;
137         CriKeyWindow *gui = color_button->gui;
138         gui->lock_window("CriKeyColorPicker::handle_done_event");
139         gui->update_color(color);
140         gui->plugin->config.color = color;
141         gui->plugin->send_configure_change();
142         gui->unlock_window();
143 }
144
145 int CriKeyColorPicker::handle_new_color(int color, int alpha)
146 {
147         CriKeyWindow *gui = color_button->gui;
148         gui->lock_window("CriKeyColorPicker::handle_new_color");
149         gui->update_color(this->color = color);
150         gui->flush();
151         gui->plugin->config.color = color;
152         gui->plugin->send_configure_change();
153         gui->unlock_window();
154         return 1;
155 }
156
157
158 void CriKeyWindow::start_color_thread()
159 {
160         unlock_window();
161         delete color_picker;
162         color_picker = new CriKeyColorPicker(color_button);
163         color_picker->start(plugin->config.color);
164         lock_window("CriKeyWindow::start_color_thread");
165 }
166
167
168 CriKeyWindow::CriKeyWindow(CriKey *plugin)
169  : PluginClientWindow(plugin, 380, 360, 380, 360, 0)
170 {
171         this->plugin = plugin;
172         this->color_button = 0;
173         this->color_picker = 0;
174         this->title_x = 0;    this->point_x = 0;
175         this->title_y = 0;    this->point_y = 0;
176         this->new_point = 0;  this->del_point = 0;
177         this->point_up = 0;   this->point_dn = 0;
178         this->drag = 0;       this->dragging = 0;
179         this->last_x = 0;     this->last_y = 0;
180         this->points = 0;     this->cur_point = 0;
181 }
182
183 CriKeyWindow::~CriKeyWindow()
184 {
185         delete color_picker;
186         delete points;
187 }
188
189 void CriKeyWindow::create_objects()
190 {
191         int x = 10, y = 10;
192         int margin = plugin->get_theme()->widget_border;
193         BC_Title *title;
194         add_subwindow(title = new BC_Title(x, y, _("Threshold:")));
195         y += title->get_h() + margin;
196         add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
197         y += threshold->get_h() + margin;
198         add_subwindow(color_button = new CriKeyColorButton(this, x, y));
199         int x1 = x + color_button->get_w() + margin;
200         color_x = x1;  color_y = y;
201         update_color(plugin->config.color);
202         y += COLOR_H + 10 + margin ;
203         add_subwindow(title = new BC_Title(x, y+5, _("Draw mode:")));
204         x1 = x + title->get_w() + 10 + margin;
205         add_subwindow(draw_mode = new CriKeyDrawMode(this, x1, y));
206         draw_mode->create_objects();
207         y += draw_mode->get_h() + 10 + margin;
208
209         CriKeyPoint *pt = plugin->config.points[plugin->config.selected];
210         add_subwindow(title_x = new BC_Title(x, y, _("X:")));
211         x1 = x + title_x->get_w() + margin;
212         point_x = new CriKeyPointX(this, x1, y, pt->x);
213         point_x->create_objects();
214         x1 += point_x->get_w() + margin;
215         add_subwindow(new_point = new CriKeyNewPoint(this, plugin, x1, y));
216         x1 += new_point->get_w() + margin;
217         add_subwindow(point_up = new CriKeyPointUp(this, x1, y));
218         y += point_x->get_h() + margin;
219         add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
220         x1 = x + title_y->get_w() + margin;
221         point_y = new CriKeyPointY(this, x1, y, pt->y);
222         point_y->create_objects();
223         x1 += point_y->get_w() + margin;
224         add_subwindow(del_point = new CriKeyDelPoint(this, plugin, x1, y));
225         x1 += del_point->get_w() + margin;
226         add_subwindow(point_dn = new CriKeyPointDn(this, x1, y));
227         y += point_y->get_h() + margin + 10;
228         add_subwindow(drag = new CriKeyDrag(this, x, y));
229         x1 = x + drag->get_w() + margin + 20;
230         add_subwindow(cur_point = new CriKeyCurPoint(this, plugin, x1, y+3));
231         cur_point->update(plugin->config.selected);
232         y += drag->get_h() + margin;
233         add_subwindow(points = new CriKeyPoints(this, plugin, x, y));
234         points->update(plugin->config.selected);
235
236         if( plugin->config.drag )
237                 grab(plugin->server->mwindow->cwindow->gui);
238
239         show_window(1);
240 }
241
242 int CriKeyWindow::grab_event(XEvent *event)
243 {
244         switch( event->type ) {
245         case ButtonPress: break;
246         case ButtonRelease: break;
247         case MotionNotify: break;
248         default: return 0;
249         }
250
251         MWindow *mwindow = plugin->server->mwindow;
252         CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
253         CWindowCanvas *canvas = cwindow_gui->canvas;
254         int cx, cy;  cwindow_gui->get_relative_cursor_xy(cx, cy);
255         cx -= mwindow->theme->ccanvas_x;
256         cy -= mwindow->theme->ccanvas_y;
257
258         if( !dragging ) {
259                 if( cx < 0 || cx >= mwindow->theme->ccanvas_w ) return 0;
260                 if( cy < 0 || cy >= mwindow->theme->ccanvas_h ) return 0;
261         }
262
263         switch( event->type ) {
264         case ButtonPress:
265                 if( dragging ) return 0;
266                 dragging = event->xbutton.state & ShiftMask ? -1 : 1;
267                 break;
268         case ButtonRelease:
269                 if( !dragging ) return 0;
270                 dragging = 0;
271                 return 1;
272         case MotionNotify:
273                 if( !dragging ) return 0;
274                 break;
275         default:
276                 return 0;
277         }
278
279         float cursor_x = cx, cursor_y = cy;
280         canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
281         int64_t position = plugin->get_source_position();
282         float projector_x, projector_y, projector_z;
283         Track *track = plugin->server->plugin->track;
284         int track_w = track->track_w, track_h = track->track_h;
285         track->automation->get_projector(
286                 &projector_x, &projector_y, &projector_z,
287                 position, PLAY_FORWARD);
288         projector_x += mwindow->edl->session->output_w / 2;
289         projector_y += mwindow->edl->session->output_h / 2;
290         float output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
291         float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
292         point_x->update((int64_t)(output_x));
293         point_y->update((int64_t)(output_y));
294
295         if( dragging > 0 ) {
296                 switch( event->type ) {
297                 case ButtonPress: {
298                         int hot_point = -1;
299                         int n = plugin->config.points.size();
300                         if( n > 0 ) {
301                                 CriKeyPoint *pt = plugin->config.points[hot_point=0];
302                                 double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
303                                 for( int i=1; i<n; ++i ) {
304                                         pt = plugin->config.points[i];
305                                         double d = DISTANCE(output_x,output_y, pt->x,pt->y);
306                                         if( d >= dist ) continue;
307                                         dist = d;  hot_point = i;
308                                 }
309                         }
310                         if( hot_point >= 0 ) {
311                                 CriKeyPoint *pt = plugin->config.points[hot_point];
312                                 if( pt->x == output_x && pt->y == output_y ) break;
313                                 points->set_point(hot_point, PT_X, pt->x = output_x);
314                                 points->set_point(hot_point, PT_Y, pt->y = output_y);
315                                 plugin->config.selected = hot_point;
316                                 points->set_selected(hot_point);
317                                 points->update_list();
318                         }
319                         break; }
320                 case MotionNotify: {
321                         int hot_point = points->get_selection_number(0, 0);
322                         if( hot_point >= 0 && hot_point < plugin->config.points.size() ) {
323                                 CriKeyPoint *pt = plugin->config.points[hot_point];
324                                 if( pt->x == output_x && pt->y == output_y ) break;
325                                 points->set_point(hot_point, PT_X, pt->x = output_x);
326                                 points->set_point(hot_point, PT_Y, pt->y = output_y);
327                                 point_x->update(pt->x);
328                                 point_y->update(pt->y);
329                                 points->update_list();
330                         }
331                         break; }
332                 }
333         }
334         else {
335                 switch( event->type ) {
336                 case MotionNotify: {
337                         float dx = output_x - last_x, dy = output_y - last_y;
338                         int n = plugin->config.points.size();
339                         for( int i=0; i<n; ++i ) {
340                                 CriKeyPoint *pt = plugin->config.points[i];
341                                 points->set_point(i, PT_X, pt->x += dx);
342                                 points->set_point(i, PT_Y, pt->y += dy);
343                         }
344                         int hot_point = points->get_selection_number(0, 0);
345                         if( hot_point >= 0 && hot_point < n ) {
346                                 CriKeyPoint *pt = plugin->config.points[hot_point];
347                                 point_x->update(pt->x);
348                                 point_y->update(pt->y);
349                                 points->update_list();
350                         }
351                         break; }
352                 }
353         }
354
355         last_x = output_x;  last_y = output_y;
356         plugin->send_configure_change();
357         return 1;
358 }
359
360 void CriKeyWindow::done_event(int result)
361 {
362         ungrab(client->server->mwindow->cwindow->gui);
363         if( color_picker ) color_picker->close_window();
364 }
365
366 CriKeyPoints::CriKeyPoints(CriKeyWindow *gui, CriKey *plugin, int x, int y)
367  : BC_ListBox(x, y, 360, 130, LISTBOX_TEXT)
368 {
369         this->gui = gui;
370         this->plugin = plugin;
371         titles[PT_E] = _("E");    widths[PT_E] = 40;
372         titles[PT_X] = _("X");    widths[PT_X] = 120;
373         titles[PT_Y] = _("Y");    widths[PT_Y] = 120;
374         titles[PT_T] = _("Tag");  widths[PT_T] = 60;
375 }
376 CriKeyPoints::~CriKeyPoints()
377 {
378         clear();
379 }
380 void CriKeyPoints::clear()
381 {
382         for( int i=PT_SZ; --i>=0; )
383                 cols[i].remove_all_objects();
384 }
385
386 int CriKeyPoints::column_resize_event()
387 {
388         for( int i=PT_SZ; --i>=0; )
389                 widths[i] = get_column_width(i);
390         return 1;
391 }
392
393 int CriKeyPoints::handle_event()
394 {
395         int hot_point = get_selection_number(0, 0);
396         const char *x_text = "", *y_text = "";
397         if( hot_point >= 0 && hot_point < plugin->config.points.size() ) {
398                 if( get_cursor_x() < widths[0] ) {
399                         plugin->config.points[hot_point]->e =
400                                 !plugin->config.points[hot_point]->e;
401                 }
402                 x_text = gui->points->cols[PT_X].get(hot_point)->get_text();
403                 y_text = gui->points->cols[PT_Y].get(hot_point)->get_text();
404         }
405         else
406                 hot_point = 0;
407         gui->point_x->update(x_text);
408         gui->point_y->update(y_text);
409         plugin->config.selected = hot_point;
410         update(hot_point);
411         gui->plugin->send_configure_change();
412         return 1;
413 }
414
415 int CriKeyPoints::selection_changed()
416 {
417         handle_event();
418         return 1;
419 }
420
421 void CriKeyPoints::new_point(const char *ep, const char *xp, const char *yp, const char *tp)
422 {
423         cols[PT_E].append(new BC_ListBoxItem(ep));
424         cols[PT_X].append(new BC_ListBoxItem(xp));
425         cols[PT_Y].append(new BC_ListBoxItem(yp));
426         cols[PT_T].append(new BC_ListBoxItem(tp));
427 }
428
429 void CriKeyPoints::del_point(int i)
430 {
431         for( int n=cols[0].size()-1, c=PT_SZ; --c>=0; )
432                 cols[c].remove_object_number(n-i);
433 }
434
435 void CriKeyPoints::set_point(int i, int c, float v)
436 {
437         char s[BCSTRLEN]; sprintf(s,"%0.4f",v);
438         set_point(i,c,s);
439 }
440 void CriKeyPoints::set_point(int i, int c, const char *cp)
441 {
442         cols[c].get(i)->set_text(cp);
443 }
444
445 int CriKeyPoints::set_selected(int k)
446 {
447         int sz = gui->plugin->config.points.size();
448         if( !sz ) return -1;
449         bclamp(k, 0, sz-1);
450         int n = gui->points->get_selection_number(0, 0);
451         if( n >= 0 ) {
452                 for( int i=0; i<PT_SZ; ++i )
453                         cols[i].get(n)->set_selected(0);
454         }
455         for( int i=0; i<PT_SZ; ++i )
456                 cols[i].get(k)->set_selected(1);
457         gui->cur_point->update(k);
458         return k;
459 }
460 void CriKeyPoints::update_list()
461 {
462         int xpos = get_xposition(), ypos = get_xposition();
463         int k =  get_selection_number(0, 0);
464         BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
465 }
466 void CriKeyPoints::update(int k)
467 {
468         if( k < 0 ) k = get_selection_number(0, 0);
469         gui->cur_point->update(k);
470         int xpos = get_xposition(), ypos = get_xposition();
471
472         clear();
473         ArrayList<CriKeyPoint*> &points = plugin->config.points;
474         int n = points.size();
475         for( int i=0; i<n; ++i ) {
476                 CriKeyPoint *pt = points[i];
477                 char etxt[BCSTRLEN];  sprintf(etxt,"%s", pt->e ? "*" : "");
478                 char xtxt[BCSTRLEN];  sprintf(xtxt,"%0.4f", pt->x);
479                 char ytxt[BCSTRLEN];  sprintf(ytxt,"%0.4f", pt->y);
480                 char ttxt[BCSTRLEN];  sprintf(ttxt,"%d", pt->t);
481                 new_point(etxt, xtxt, ytxt, ttxt);
482         }
483         if( k < n ) {
484                 for( int i=PT_SZ; --i>=0; )
485                         cols[i].get(k)->set_selected(1);
486                 gui->point_x->update(gui->points->cols[PT_X].get(k)->get_text());
487                 gui->point_y->update(gui->points->cols[PT_Y].get(k)->get_text());
488         }
489
490         BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
491 }
492
493 void CriKeyWindow::update_color(int color)
494 {
495         set_color(color);
496         draw_box(color_x, color_y, COLOR_W, COLOR_H);
497         set_color(BLACK);
498         draw_rectangle(color_x, color_y, COLOR_W, COLOR_H);
499         flash(color_x, color_y, COLOR_W, COLOR_H);
500 }
501
502 void CriKeyWindow::update_gui()
503 {
504         draw_mode->update(plugin->config.draw_mode);
505         update_color(plugin->config.color);
506         threshold->update(plugin->config.threshold);
507         cur_point->update(plugin->config.selected);
508         drag->update(plugin->config.drag);
509         points->update(plugin->config.selected);
510 }
511
512
513 CriKeyThreshold::CriKeyThreshold(CriKeyWindow *gui, int x, int y, int w)
514  : BC_FSlider(x, y, 0, w, w, 0, 1, gui->plugin->config.threshold, 0)
515 {
516         this->gui = gui;
517         set_precision(0.005);
518 }
519
520 int CriKeyThreshold::handle_event()
521 {
522         float v = get_value();
523         gui->plugin->config.threshold = v;
524         gui->plugin->send_configure_change();
525         return 1;
526 }
527
528
529 CriKeyPointUp::CriKeyPointUp(CriKeyWindow *gui, int x, int y)
530  : BC_GenericButton(x, y, _("Up"))
531 {
532         this->gui = gui;
533 }
534 CriKeyPointUp::~CriKeyPointUp()
535 {
536 }
537
538 int CriKeyPointUp::handle_event()
539 {
540         int n = gui->plugin->config.points.size();
541         int hot_point = gui->points->get_selection_number(0, 0);
542
543         if( n > 1 && hot_point > 0 ) {
544                 CriKeyPoint *&pt0 = gui->plugin->config.points[hot_point];
545                 CriKeyPoint *&pt1 = gui->plugin->config.points[--hot_point];
546                 CriKeyPoint *t = pt0;  pt0 = pt1;  pt1 = t;
547                 gui->plugin->config.selected = hot_point;
548                 gui->points->update(hot_point);
549         }
550         gui->plugin->send_configure_change();
551         return 1;
552 }
553
554 CriKeyPointDn::CriKeyPointDn(CriKeyWindow *gui, int x, int y)
555  : BC_GenericButton(x, y, _("Dn"))
556 {
557         this->gui = gui;
558 }
559 CriKeyPointDn::~CriKeyPointDn()
560 {
561 }
562
563 int CriKeyPointDn::handle_event()
564 {
565         int n = gui->plugin->config.points.size();
566         int hot_point = gui->points->get_selection_number(0, 0);
567         if( n > 1 && hot_point < n-1 ) {
568                 CriKeyPoint *&pt0 = gui->plugin->config.points[hot_point];
569                 CriKeyPoint *&pt1 = gui->plugin->config.points[++hot_point];
570                 CriKeyPoint *t = pt0;  pt0 = pt1;  pt1 = t;
571                 gui->plugin->config.selected = hot_point;
572                 gui->points->update(hot_point);
573         }
574         gui->plugin->send_configure_change();
575         return 1;
576 }
577
578 CriKeyDrag::CriKeyDrag(CriKeyWindow *gui, int x, int y)
579  : BC_CheckBox(x, y, gui->plugin->config.drag, _("Drag"))
580 {
581         this->gui = gui;
582 }
583 int CriKeyDrag::handle_event()
584 {
585         int value = get_value();
586         gui->plugin->config.drag = value;
587         CWindowGUI *cwindow_gui = gui->plugin->server->mwindow->cwindow->gui;
588         if( value )
589                 gui->grab(cwindow_gui);
590         else
591                 gui->ungrab(cwindow_gui);
592         gui->plugin->send_configure_change();
593         return 1;
594 }
595
596 CriKeyNewPoint::CriKeyNewPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
597  : BC_GenericButton(x, y, 80, _("New"))
598 {
599         this->gui = gui;
600         this->plugin = plugin;
601 }
602 CriKeyNewPoint::~CriKeyNewPoint()
603 {
604 }
605 int CriKeyNewPoint::handle_event()
606 {
607         int k = plugin->new_point();
608         gui->points->update(k);
609         gui->plugin->send_configure_change();
610         return 1;
611 }
612
613 CriKeyDelPoint::CriKeyDelPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
614  : BC_GenericButton(x, y, 80, _("Del"))
615 {
616         this->gui = gui;
617         this->plugin = plugin;
618 }
619 CriKeyDelPoint::~CriKeyDelPoint()
620 {
621 }
622 int CriKeyDelPoint::handle_event()
623 {
624         int hot_point = gui->points->get_selection_number(0, 0);
625         if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
626                 plugin->config.del_point(hot_point);
627                 if( !plugin->config.points.size() ) plugin->new_point();
628                 int n = gui->plugin->config.points.size();
629                 if( hot_point >= n && hot_point > 0 ) --hot_point;
630                 gui->plugin->config.selected = hot_point;
631                 gui->points->update(hot_point);
632                 gui->plugin->send_configure_change();
633         }
634         return 1;
635 }
636
637 CriKeyCurPoint::CriKeyCurPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
638  : BC_Title(x, y, "")
639 {
640         this->gui = gui;
641         this->plugin = plugin;
642 }
643 CriKeyCurPoint::~CriKeyCurPoint()
644 {
645 }
646 void CriKeyCurPoint::update(int n)
647 {
648         char string[BCSTRLEN];
649         sprintf(string, _("Selected: %d   "), n);
650         BC_Title::update(string);
651 }
652