crikey rework, KP4 fix, added Shift-KPx, valgrind cleanups, hex eye-dropper, resize...
[goodguy/history.git] / cinelerra-5.1 / plugins / crikey / crikeywindow.C
index 9b7bd82e69463275397080f9f2534eea48af5686..3f72f3ded74ccf5aa1f3b56189a6e6661ab1ca98 100644 (file)
@@ -23,6 +23,7 @@
 #include "clip.h"
 #include "crikey.h"
 #include "crikeywindow.h"
+#include "cstrdup.h"
 #include "cwindow.h"
 #include "cwindowgui.h"
 #include "edl.h"
 #define COLOR_W 50
 #define COLOR_H 30
 
-CriKeyNum::CriKeyNum(CriKeyWindow *gui, int x, int y, float &output)
- : BC_TumbleTextBox(gui, output, -32767.0f, 32767.0f, x, y, 80)
+CriKeyNum::CriKeyNum(CriKeyWindow *gui, int x, int y, float output)
+ : BC_TumbleTextBox(gui, output, -32767.0f, 32767.0f, x, y, 120)
 {
        this->gui = gui;
-       this->output = &output;
        set_increment(1);
        set_precision(1);
 }
@@ -50,9 +50,31 @@ CriKeyNum::~CriKeyNum()
 {
 }
 
-int CriKeyNum::handle_event()
+int CriKeyPointX::handle_event()
 {
-       *output = atof(get_text());
+       if( !CriKeyNum::handle_event() ) return 0;
+       CriKeyPoints *points = gui->points;
+       int hot_point = points->get_selection_number(0, 0);
+       if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+               float v = atof(get_text());
+               gui->plugin->config.points[hot_point]->x = v;
+               points->set_point(hot_point, PT_X, v);
+       }
+       points->update_list();
+       gui->plugin->send_configure_change();
+       return 1;
+}
+int CriKeyPointY::handle_event()
+{
+       if( !CriKeyNum::handle_event() ) return 0;
+       CriKeyPoints *points = gui->points;
+       int hot_point = points->get_selection_number(0, 0);
+       if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+               float v = atof(get_text());
+               gui->plugin->config.points[hot_point]->y = v;
+               points->set_point(hot_point, PT_Y, v);
+       }
+       points->update_list();
        gui->plugin->send_configure_change();
        return 1;
 }
@@ -86,35 +108,6 @@ void CriKeyDrawMode::update(int mode, int send)
        if( send ) gui->plugin->send_configure_change();
 }
 
-int CriKeyKeyModeItem::handle_event()
-{
-       ((CriKeyKeyMode *)get_popup_menu())->update(id);
-       return 1;
-}
-CriKeyKeyMode::CriKeyKeyMode(CriKeyWindow *gui, int x, int y)
- : BC_PopupMenu(x, y, 100, "", 1)
-{
-       this->gui = gui;
-       key_modes[KEY_SEARCH]      = _("Search");
-       key_modes[KEY_SEARCH_ALL]  = _("Search all");
-       key_modes[KEY_POINT]       = _("Point");
-       this->mode = -1;
-}
-void CriKeyKeyMode::create_objects()
-{
-       for( int i=0; i<KEY_MODES; ++i )
-               add_item(new CriKeyKeyModeItem(key_modes[i], i));
-       update(gui->plugin->config.key_mode, 0);
-}
-void CriKeyKeyMode::update(int mode, int send)
-{
-       if( this->mode == mode ) return;
-       this->mode = mode;
-       set_text(key_modes[mode]);
-       gui->draw_key(mode);
-       if( send ) gui->plugin->send_configure_change();
-}
-
 CriKeyColorButton::CriKeyColorButton(CriKeyWindow *gui, int x, int y)
  : BC_GenericButton(x, y, _("Color"))
 {
@@ -134,19 +127,19 @@ CriKeyColorPicker::CriKeyColorPicker(CriKeyColorButton *color_button)
 
 void CriKeyColorPicker::start(int color)
 {
-       start_window(this->color = color, 0, 1);
+       orig_color = this->color = color;
+       start_window(color, 0, 1);
 }
 
 void CriKeyColorPicker::handle_done_event(int result)
 {
-       if( !result ) {
-               CriKeyWindow *gui = color_button->gui;
-               gui->lock_window("CriKeyColorPicker::handle_done_event");
-               gui->update_color(color);
-               gui->plugin->config.color = color;
-               gui->plugin->send_configure_change();
-               gui->unlock_window();
-       }
+       if( result ) color = orig_color;
+       CriKeyWindow *gui = color_button->gui;
+       gui->lock_window("CriKeyColorPicker::handle_done_event");
+       gui->update_color(color);
+       gui->plugin->config.color = color;
+       gui->plugin->send_configure_change();
+       gui->unlock_window();
 }
 
 int CriKeyColorPicker::handle_new_color(int color, int alpha)
@@ -173,19 +166,24 @@ void CriKeyWindow::start_color_thread()
 
 
 CriKeyWindow::CriKeyWindow(CriKey *plugin)
- : PluginClientWindow(plugin, 320, 220, 320, 220, 0)
+ : PluginClientWindow(plugin, 380, 360, 380, 360, 0)
 {
        this->plugin = plugin;
        this->color_button = 0;
        this->color_picker = 0;
-       this->title_x = 0;  this->point_x = 0;
-       this->title_y = 0;  this->point_y = 0;
-       this->dragging = 0; this->drag = 0;
+        this->title_x = 0;    this->point_x = 0;
+        this->title_y = 0;    this->point_y = 0;
+       this->new_point = 0;  this->del_point = 0;
+       this->point_up = 0;   this->point_dn = 0;
+       this->drag = 0;       this->dragging = 0;
+       this->last_x = 0;     this->last_y = 0;
+       this->points = 0;     this->cur_point = 0;
 }
 
 CriKeyWindow::~CriKeyWindow()
 {
        delete color_picker;
+       delete points;
 }
 
 void CriKeyWindow::create_objects()
@@ -197,46 +195,83 @@ void CriKeyWindow::create_objects()
        y += title->get_h() + margin;
        add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
        y += threshold->get_h() + margin;
+       add_subwindow(color_button = new CriKeyColorButton(this, x, y));
+       int x1 = x + color_button->get_w() + margin;
+       color_x = x1;  color_y = y;
+       update_color(plugin->config.color);
+       y += COLOR_H + 10 + margin ;
        add_subwindow(title = new BC_Title(x, y+5, _("Draw mode:")));
-       int x1 = x + title->get_w() + 10 + margin;
+       x1 = x + title->get_w() + 10 + margin;
        add_subwindow(draw_mode = new CriKeyDrawMode(this, x1, y));
        draw_mode->create_objects();
-       y += draw_mode->get_h() + margin;
-       add_subwindow(title = new BC_Title(x, y+5, _("Key mode:")));
-       add_subwindow(key_mode = new CriKeyKeyMode(this, x1, y));
-       y += key_mode->get_h() + margin;
-       key_x = x + 10 + margin;  key_y = y + 10 + margin;
-       key_mode->create_objects();
+       y += draw_mode->get_h() + 10 + margin;
+
+       CriKeyPoint *pt = plugin->config.points[plugin->config.selected];
+       add_subwindow(title_x = new BC_Title(x, y, _("X:")));
+       x1 = x + title_x->get_w() + margin;
+       point_x = new CriKeyPointX(this, x1, y, pt->x);
+       point_x->create_objects();
+       x1 += point_x->get_w() + margin;
+       add_subwindow(new_point = new CriKeyNewPoint(this, plugin, x1, y));
+       x1 += new_point->get_w() + margin;
+       add_subwindow(point_up = new CriKeyPointUp(this, x1, y));
+       y += point_x->get_h() + margin;
+       add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
+       x1 = x + title_y->get_w() + margin;
+       point_y = new CriKeyPointY(this, x1, y, pt->y);
+       point_y->create_objects();
+       x1 += point_y->get_w() + margin;
+       add_subwindow(del_point = new CriKeyDelPoint(this, plugin, x1, y));
+       x1 += del_point->get_w() + margin;
+       add_subwindow(point_dn = new CriKeyPointDn(this, x1, y));
+       y += point_y->get_h() + margin + 10;
+       add_subwindow(drag = new CriKeyDrag(this, x, y));
+       x1 = x + drag->get_w() + margin + 20;
+       add_subwindow(cur_point = new CriKeyCurPoint(this, plugin, x1, y+3));
+       cur_point->update(plugin->config.selected);
+       y += drag->get_h() + margin;
+       add_subwindow(points = new CriKeyPoints(this, plugin, x, y));
+       points->update(plugin->config.selected);
 
         if( plugin->config.drag )
                 grab(plugin->server->mwindow->cwindow->gui);
+
        show_window(1);
 }
 
 int CriKeyWindow::grab_event(XEvent *event)
 {
-       if( key_mode->mode != KEY_POINT ) return 0;
+       switch( event->type ) {
+       case ButtonPress: break;
+       case ButtonRelease: break;
+       case MotionNotify: break;
+       default: return 0;
+       }
 
        MWindow *mwindow = plugin->server->mwindow;
        CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
        CWindowCanvas *canvas = cwindow_gui->canvas;
-       int cx, cy;  canvas->get_canvas()->get_relative_cursor_xy(cx, cy);
-       if( cx < mwindow->theme->ccanvas_x ) return 0;
-       if( cx >= mwindow->theme->ccanvas_x+mwindow->theme->ccanvas_w ) return 0;
-       if( cy < mwindow->theme->ccanvas_y ) return 0;
-       if( cy >= mwindow->theme->ccanvas_y+mwindow->theme->ccanvas_h ) return 0;
+       int cx, cy;  cwindow_gui->get_relative_cursor_xy(cx, cy);
+       cx -= mwindow->theme->ccanvas_x;
+       cy -= mwindow->theme->ccanvas_y;
+
+       if( !dragging ) {
+               if( cx < 0 || cx >= mwindow->theme->ccanvas_w ) return 0;
+               if( cy < 0 || cy >= mwindow->theme->ccanvas_h ) return 0;
+       }
 
        switch( event->type ) {
        case ButtonPress:
                if( dragging ) return 0;
-               dragging = 1;
+               dragging = event->xbutton.state & ShiftMask ? -1 : 1;
                break;
        case ButtonRelease:
                if( !dragging ) return 0;
                dragging = 0;
                return 1;
        case MotionNotify:
-               if( dragging ) break;
+               if( !dragging ) return 0;
+               break;
        default:
                return 0;
        }
@@ -254,8 +289,70 @@ int CriKeyWindow::grab_event(XEvent *event)
        projector_y += mwindow->edl->session->output_h / 2;
        float output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
        float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
-       point_x->update((int64_t)(plugin->config.point_x = output_x));
-       point_y->update((int64_t)(plugin->config.point_y = output_y));
+       point_x->update((int64_t)(output_x));
+       point_y->update((int64_t)(output_y));
+
+       if( dragging > 0 ) {
+               switch( event->type ) {
+               case ButtonPress: {
+                       int hot_point = -1;
+                       int n = plugin->config.points.size();
+                       if( n > 0 ) {
+                               CriKeyPoint *pt = plugin->config.points[hot_point=0];
+                               double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
+                               for( int i=1; i<n; ++i ) {
+                                       pt = plugin->config.points[i];
+                                       double d = DISTANCE(output_x,output_y, pt->x,pt->y);
+                                       if( d >= dist ) continue;
+                                       dist = d;  hot_point = i;
+                               }
+                       }
+                       if( hot_point >= 0 ) {
+                               CriKeyPoint *pt = plugin->config.points[hot_point];
+                               if( pt->x == output_x && pt->y == output_y ) break;
+                               points->set_point(hot_point, PT_X, pt->x = output_x);
+                               points->set_point(hot_point, PT_Y, pt->y = output_y);
+                               plugin->config.selected = hot_point;
+                               points->set_selected(hot_point);
+                               points->update_list();
+                       }
+                       break; }
+               case MotionNotify: {
+                       int hot_point = points->get_selection_number(0, 0);
+                       if( hot_point >= 0 && hot_point < plugin->config.points.size() ) {
+                               CriKeyPoint *pt = plugin->config.points[hot_point];
+                               if( pt->x == output_x && pt->y == output_y ) break;
+                               points->set_point(hot_point, PT_X, pt->x = output_x);
+                               points->set_point(hot_point, PT_Y, pt->y = output_y);
+                               point_x->update(pt->x);
+                               point_y->update(pt->y);
+                               points->update_list();
+                       }
+                       break; }
+               }
+       }
+       else {
+               switch( event->type ) {
+               case MotionNotify: {
+                       float dx = output_x - last_x, dy = output_y - last_y;
+                       int n = plugin->config.points.size();
+                       for( int i=0; i<n; ++i ) {
+                               CriKeyPoint *pt = plugin->config.points[i];
+                               points->set_point(i, PT_X, pt->x += dx);
+                               points->set_point(i, PT_Y, pt->y += dy);
+                       }
+                       int hot_point = points->get_selection_number(0, 0);
+                       if( hot_point >= 0 && hot_point < n ) {
+                               CriKeyPoint *pt = plugin->config.points[hot_point];
+                               point_x->update(pt->x);
+                               point_y->update(pt->y);
+                               points->update_list();
+                       }
+                       break; }
+               }
+       }
+
+       last_x = output_x;  last_y = output_y;
        plugin->send_configure_change();
        return 1;
 }
@@ -266,44 +363,131 @@ void CriKeyWindow::done_event(int result)
        if( color_picker ) color_picker->close_window();
 }
 
-void CriKeyWindow::draw_key(int mode)
+CriKeyPoints::CriKeyPoints(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_ListBox(x, y, 360, 130, LISTBOX_TEXT)
 {
-       int margin = plugin->get_theme()->widget_border;
-       int x = key_x, y = key_y;
-       delete color_picker;  color_picker = 0;
-       delete color_button;  color_button = 0;
-       delete title_x;  title_x = 0;
-       delete point_x;  point_x = 0;
-       delete title_y;  title_y = 0;
-       delete point_y;  point_y = 0;
-       delete drag;     drag = 0;
-
-       clear_box(x,y, get_w()-x,get_h()-y);
-       flash(x,y, get_w()-x,get_h()-y);
-
-       switch( mode ) {
-       case KEY_SEARCH:
-       case KEY_SEARCH_ALL:
-               add_subwindow(color_button = new CriKeyColorButton(this, x, y));
-               x += color_button->get_w() + margin;
-               color_x = x;  color_y = y;
-               update_color(plugin->config.color);
-               break;
-       case KEY_POINT:
-               add_subwindow(title_x = new BC_Title(x, y, _("X:")));
-               int x1 = x + title_x->get_w() + margin, y1 = y;
-               point_x = new CriKeyNum(this, x1, y, plugin->config.point_x);
-               point_x->create_objects();
-               y += point_x->get_h() + margin;
-               add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
-               point_y = new CriKeyNum(this, x1, y, plugin->config.point_y);
-               point_y->create_objects();
-               x1 += point_x->get_w() + margin;
-               add_subwindow(drag = new CriKeyDrag(this, x1, y1));
-               break;
+       this->gui = gui;
+       this->plugin = plugin;
+       titles[PT_E] = _("E");    widths[PT_E] = 40;
+       titles[PT_X] = _("X");    widths[PT_X] = 120;
+       titles[PT_Y] = _("Y");    widths[PT_Y] = 120;
+       titles[PT_T] = _("Tag");  widths[PT_T] = 60;
+}
+CriKeyPoints::~CriKeyPoints()
+{
+       clear();
+}
+void CriKeyPoints::clear()
+{
+       for( int i=PT_SZ; --i>=0; )
+               cols[i].remove_all_objects();
+}
+
+int CriKeyPoints::column_resize_event()
+{
+       for( int i=PT_SZ; --i>=0; )
+               widths[i] = get_column_width(i);
+       return 1;
+}
+
+int CriKeyPoints::handle_event()
+{
+       int hot_point = get_selection_number(0, 0);
+       const char *x_text = "", *y_text = "";
+       if( hot_point >= 0 && hot_point < plugin->config.points.size() ) {
+               if( get_cursor_x() < widths[0] ) {
+                       plugin->config.points[hot_point]->e =
+                               !plugin->config.points[hot_point]->e;
+               }
+               x_text = gui->points->cols[PT_X].get(hot_point)->get_text();
+               y_text = gui->points->cols[PT_Y].get(hot_point)->get_text();
        }
-       plugin->config.key_mode = mode;
-       show_window(1);
+       else
+               hot_point = 0;
+       gui->point_x->update(x_text);
+       gui->point_y->update(y_text);
+       plugin->config.selected = hot_point;
+       update(hot_point);
+       gui->plugin->send_configure_change();
+       return 1;
+}
+
+int CriKeyPoints::selection_changed()
+{
+       handle_event();
+       return 1;
+}
+
+void CriKeyPoints::new_point(const char *ep, const char *xp, const char *yp, const char *tp)
+{
+       cols[PT_E].append(new BC_ListBoxItem(ep));
+       cols[PT_X].append(new BC_ListBoxItem(xp));
+       cols[PT_Y].append(new BC_ListBoxItem(yp));
+       cols[PT_T].append(new BC_ListBoxItem(tp));
+}
+
+void CriKeyPoints::del_point(int i)
+{
+       for( int n=cols[0].size()-1, c=PT_SZ; --c>=0; )
+               cols[c].remove_object_number(n-i);
+}
+
+void CriKeyPoints::set_point(int i, int c, float v)
+{
+       char s[BCSTRLEN]; sprintf(s,"%0.4f",v);
+       set_point(i,c,s);
+}
+void CriKeyPoints::set_point(int i, int c, const char *cp)
+{
+       cols[c].get(i)->set_text(cp);
+}
+
+int CriKeyPoints::set_selected(int k)
+{
+       int sz = gui->plugin->config.points.size();
+       if( !sz ) return -1;
+       bclamp(k, 0, sz-1);
+       int n = gui->points->get_selection_number(0, 0);
+       if( n >= 0 ) {
+               for( int i=0; i<PT_SZ; ++i )
+                       cols[i].get(n)->set_selected(0);
+       }
+       for( int i=0; i<PT_SZ; ++i )
+               cols[i].get(k)->set_selected(1);
+       gui->cur_point->update(k);
+       return k;
+}
+void CriKeyPoints::update_list()
+{
+       int xpos = get_xposition(), ypos = get_xposition();
+       int k =  get_selection_number(0, 0);
+       BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
+}
+void CriKeyPoints::update(int k)
+{
+       if( k < 0 ) k = get_selection_number(0, 0);
+       gui->cur_point->update(k);
+       int xpos = get_xposition(), ypos = get_xposition();
+
+       clear();
+       ArrayList<CriKeyPoint*> &points = plugin->config.points;
+       int n = points.size();
+       for( int i=0; i<n; ++i ) {
+               CriKeyPoint *pt = points[i];
+               char etxt[BCSTRLEN];  sprintf(etxt,"%s", pt->e ? "*" : "");
+               char xtxt[BCSTRLEN];  sprintf(xtxt,"%0.4f", pt->x);
+               char ytxt[BCSTRLEN];  sprintf(ytxt,"%0.4f", pt->y);
+               char ttxt[BCSTRLEN];  sprintf(ttxt,"%d", pt->t);
+               new_point(etxt, xtxt, ytxt, ttxt);
+       }
+       if( k < n ) {
+               for( int i=PT_SZ; --i>=0; )
+                       cols[i].get(k)->set_selected(1);
+               gui->point_x->update(gui->points->cols[PT_X].get(k)->get_text());
+               gui->point_y->update(gui->points->cols[PT_Y].get(k)->get_text());
+       }
+
+       BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
 }
 
 void CriKeyWindow::update_color(int color)
@@ -317,19 +501,12 @@ void CriKeyWindow::update_color(int color)
 
 void CriKeyWindow::update_gui()
 {
-       threshold->update(plugin->config.threshold);
        draw_mode->update(plugin->config.draw_mode);
-       key_mode->update(plugin->config.key_mode);
-       switch( plugin->config.key_mode ) {
-       case KEY_POINT:
-               point_x->update(plugin->config.point_x);
-               point_y->update(plugin->config.point_y);
-               break;
-       case KEY_SEARCH:
-       case KEY_SEARCH_ALL:
-               update_color(plugin->config.color);
-               break;
-       }
+       update_color(plugin->config.color);
+       threshold->update(plugin->config.threshold);
+       cur_point->update(plugin->config.selected);
+       drag->update(plugin->config.drag);
+       points->update(plugin->config.selected);
 }
 
 
@@ -342,11 +519,61 @@ CriKeyThreshold::CriKeyThreshold(CriKeyWindow *gui, int x, int y, int w)
 
 int CriKeyThreshold::handle_event()
 {
-       gui->plugin->config.threshold = get_value();
+       float v = get_value();
+       gui->plugin->config.threshold = v;
+       gui->plugin->send_configure_change();
+       return 1;
+}
+
+
+CriKeyPointUp::CriKeyPointUp(CriKeyWindow *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Up"))
+{
+       this->gui = gui;
+}
+CriKeyPointUp::~CriKeyPointUp()
+{
+}
+
+int CriKeyPointUp::handle_event()
+{
+       int n = gui->plugin->config.points.size();
+       int hot_point = gui->points->get_selection_number(0, 0);
+
+       if( n > 1 && hot_point > 0 ) {
+               CriKeyPoint *&pt0 = gui->plugin->config.points[hot_point];
+               CriKeyPoint *&pt1 = gui->plugin->config.points[--hot_point];
+               CriKeyPoint *t = pt0;  pt0 = pt1;  pt1 = t;
+               gui->plugin->config.selected = hot_point;
+               gui->points->update(hot_point);
+       }
        gui->plugin->send_configure_change();
        return 1;
 }
 
+CriKeyPointDn::CriKeyPointDn(CriKeyWindow *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Dn"))
+{
+       this->gui = gui;
+}
+CriKeyPointDn::~CriKeyPointDn()
+{
+}
+
+int CriKeyPointDn::handle_event()
+{
+       int n = gui->plugin->config.points.size();
+       int hot_point = gui->points->get_selection_number(0, 0);
+       if( n > 1 && hot_point < n-1 ) {
+               CriKeyPoint *&pt0 = gui->plugin->config.points[hot_point];
+               CriKeyPoint *&pt1 = gui->plugin->config.points[++hot_point];
+               CriKeyPoint *t = pt0;  pt0 = pt1;  pt1 = t;
+               gui->plugin->config.selected = hot_point;
+               gui->points->update(hot_point);
+       }
+       gui->plugin->send_configure_change();
+       return 1;
+}
 
 CriKeyDrag::CriKeyDrag(CriKeyWindow *gui, int x, int y)
  : BC_CheckBox(x, y, gui->plugin->config.drag, _("Drag"))
@@ -366,3 +593,60 @@ int CriKeyDrag::handle_event()
         return 1;
 }
 
+CriKeyNewPoint::CriKeyNewPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_GenericButton(x, y, 80, _("New"))
+{
+       this->gui = gui;
+       this->plugin = plugin;
+}
+CriKeyNewPoint::~CriKeyNewPoint()
+{
+}
+int CriKeyNewPoint::handle_event()
+{
+       int k = plugin->new_point();
+       gui->points->update(k);
+       gui->plugin->send_configure_change();
+       return 1;
+}
+
+CriKeyDelPoint::CriKeyDelPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_GenericButton(x, y, 80, _("Del"))
+{
+       this->gui = gui;
+       this->plugin = plugin;
+}
+CriKeyDelPoint::~CriKeyDelPoint()
+{
+}
+int CriKeyDelPoint::handle_event()
+{
+       int hot_point = gui->points->get_selection_number(0, 0);
+       if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+               plugin->config.del_point(hot_point);
+               if( !plugin->config.points.size() ) plugin->new_point();
+               int n = gui->plugin->config.points.size();
+               if( hot_point >= n && hot_point > 0 ) --hot_point;
+               gui->plugin->config.selected = hot_point;
+               gui->points->update(hot_point);
+               gui->plugin->send_configure_change();
+       }
+       return 1;
+}
+
+CriKeyCurPoint::CriKeyCurPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_Title(x, y, "")
+{
+       this->gui = gui;
+       this->plugin = plugin;
+}
+CriKeyCurPoint::~CriKeyCurPoint()
+{
+}
+void CriKeyCurPoint::update(int n)
+{
+       char string[BCSTRLEN];
+       sprintf(string, _("Selected: %d   "), n);
+       BC_Title::update(string);
+}
+