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