Fixed initialisation of tf in file_open(). Without setting the memory to 0,
[cinelerra_cv/mob.git] / plugins / histogram / histogramwindow.C
blob3f2819265ca1430adaa7acab984f7ac1a4132eac
1 #include "bcdisplayinfo.h"
2 #include "bcsignals.h"
3 #include "cursors.h"
4 #include "histogram.h"
5 #include "histogramconfig.h"
6 #include "histogramwindow.h"
7 #include "keys.h"
8 #include "language.h"
11 #include <unistd.h>
13 PLUGIN_THREAD_OBJECT(HistogramMain, HistogramThread, HistogramWindow)
17 HistogramWindow::HistogramWindow(HistogramMain *plugin, int x, int y)
18  : BC_Window(plugin->gui_string, 
19         x,
20         y,
21         440, 
22         500, 
23         440, 
24         500, 
25         0, 
26         1,
27         1)
29         this->plugin = plugin; 
32 HistogramWindow::~HistogramWindow()
36 #include "max_picon_png.h"
37 #include "mid_picon_png.h"
38 #include "min_picon_png.h"
39 static VFrame max_picon_image(max_picon_png);
40 static VFrame mid_picon_image(mid_picon_png);
41 static VFrame min_picon_image(min_picon_png);
43 int HistogramWindow::create_objects()
45         int x = 10, y = 10, x1 = 10;
46         BC_Title *title = 0;
48         max_picon = new BC_Pixmap(this, &max_picon_image);
49         mid_picon = new BC_Pixmap(this, &mid_picon_image);
50         min_picon = new BC_Pixmap(this, &min_picon_image);
51         add_subwindow(mode_v = new HistogramMode(plugin, 
52                 x, 
53                 y,
54                 HISTOGRAM_VALUE,
55                 _("Value")));
56         x += 70;
57         add_subwindow(mode_r = new HistogramMode(plugin, 
58                 x, 
59                 y,
60                 HISTOGRAM_RED,
61                 _("Red")));
62         x += 70;
63         add_subwindow(mode_g = new HistogramMode(plugin, 
64                 x, 
65                 y,
66                 HISTOGRAM_GREEN,
67                 _("Green")));
68         x += 70;
69         add_subwindow(mode_b = new HistogramMode(plugin, 
70                 x, 
71                 y,
72                 HISTOGRAM_BLUE,
73                 _("Blue")));
74 //      x += 70;
75 //      add_subwindow(mode_a = new HistogramMode(plugin, 
76 //              x, 
77 //              y,
78 //              HISTOGRAM_ALPHA,
79 //              _("Alpha")));
81         x = x1;
82         y += 30;
83         add_subwindow(title = new BC_Title(x, y, _("Input X:")));
84         x += title->get_w() + 10;
85         input_x = new HistogramInputText(plugin,
86                 this,
87                 x,
88                 y,
89                 1);
90         input_x->create_objects();
92         x += input_x->get_w() + 10;
93         add_subwindow(title = new BC_Title(x, y, _("Input Y:")));
94         x += title->get_w() + 10;
95         input_y = new HistogramInputText(plugin,
96                 this,
97                 x,
98                 y,
99                 0);
100         input_y->create_objects();
102         y += 30;
103         x = x1;
105         canvas_w = get_w() - x - x;
106         canvas_h = get_h() - y - 190;
107         title1_x = x;
108         title2_x = x + (int)(canvas_w * -MIN_INPUT / FLOAT_RANGE);
109         title3_x = x + (int)(canvas_w * (1.0 - MIN_INPUT) / FLOAT_RANGE);
110         title4_x = x + (int)(canvas_w);
111         add_subwindow(canvas = new HistogramCanvas(plugin,
112                 this,
113                 x, 
114                 y, 
115                 canvas_w, 
116                 canvas_h));
117 // Calculate output curve with no value function
118         plugin->tabulate_curve(plugin->mode, 0);
119         draw_canvas_overlay();
120         canvas->flash();
122         y += canvas->get_h() + 1;
123         add_subwindow(new BC_Title(title1_x, 
124                 y, 
125                 "-10%"));
126         add_subwindow(new BC_Title(title2_x,
127                 y,
128                 "0%"));
129         add_subwindow(new BC_Title(title3_x - get_text_width(MEDIUMFONT, "100"),
130                 y,
131                 "100%"));
132         add_subwindow(new BC_Title(title4_x - get_text_width(MEDIUMFONT, "110"),
133                 y,
134                 "110%"));
136         y += 20;
137         add_subwindow(title = new BC_Title(x, y, _("Output min:")));
138         x += title->get_w() + 10;
139         output_min = new HistogramOutputText(plugin,
140                 this,
141                 x,
142                 y,
143                 &plugin->config.output_min[plugin->mode]);
144         output_min->create_objects();
145         x += output_min->get_w() + 10;
146         add_subwindow(new BC_Title(x, y, _("Output Max:")));
147         x += title->get_w() + 10;
148         output_max = new HistogramOutputText(plugin,
149                 this,
150                 x,
151                 y,
152                 &plugin->config.output_max[plugin->mode]);
153         output_max->create_objects();
155         x = x1;
156         y += 30;
158         add_subwindow(output = new HistogramSlider(plugin, 
159                 this,
160                 x, 
161                 y, 
162                 get_w() - 20,
163                 30,
164                 0));
165         output->update();
166         y += 40;
169         add_subwindow(automatic = new HistogramAuto(plugin, 
170                 x, 
171                 y));
173         x += 120;
174         add_subwindow(new HistogramReset(plugin, 
175                 x, 
176                 y));
177         x += 100;
178         add_subwindow(new BC_Title(x, y, _("Threshold:")));
179         x += 100;
180         threshold = new HistogramOutputText(plugin,
181                 this,
182                 x,
183                 y,
184                 &plugin->config.threshold);
185         threshold->create_objects();
187         x = x1;
188         y += 30;
189         add_subwindow(plot = new HistogramPlot(plugin, 
190                 x, 
191                 y));
193         y += plot->get_h() + 5;
194         add_subwindow(split = new HistogramSplit(plugin, 
195                 x, 
196                 y));
199         show_window();
201         return 0;
204 WINDOW_CLOSE_EVENT(HistogramWindow)
206 int HistogramWindow::keypress_event()
208         int result = 0;
209         if(get_keypress() == BACKSPACE ||
210                 get_keypress() == DELETE)
211         {
212                 if(plugin->current_point >= 0)
213                 {
214                         HistogramPoint *current = 
215                                 plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
216                         delete current;
217                         plugin->current_point = -1;
218                         update_input();
219                         update_canvas();
220                         plugin->send_configure_change();
221                         result = 1;
222                 }
223         }
224         return result;
227 void HistogramWindow::update(int do_input)
229         automatic->update(plugin->config.automatic);
230         threshold->update(plugin->config.threshold);
231         update_mode();
233         if(do_input) update_input();
234         update_output();
237 void HistogramWindow::update_input()
239         input_x->update();
240         input_y->update();
243 void HistogramWindow::update_output()
245         output->update();
246         output_min->update(plugin->config.output_min[plugin->mode]);
247         output_max->update(plugin->config.output_max[plugin->mode]);
250 void HistogramWindow::update_mode()
252         mode_v->update(plugin->mode == HISTOGRAM_VALUE ? 1 : 0);
253         mode_r->update(plugin->mode == HISTOGRAM_RED ? 1 : 0);
254         mode_g->update(plugin->mode == HISTOGRAM_GREEN ? 1 : 0);
255         mode_b->update(plugin->mode == HISTOGRAM_BLUE ? 1 : 0);
256         output_min->output = &plugin->config.output_min[plugin->mode];
257         output_max->output = &plugin->config.output_max[plugin->mode];
258         plot->update(plugin->config.plot);
259         split->update(plugin->config.split);
262 void HistogramWindow::draw_canvas_overlay()
264         canvas->set_color(0x00ff00);
265         int y1;
268 // Draw output line
269         for(int i = 0; i < canvas_w; i++)
270         {
271                 float input = (float)i / 
272                                 canvas_w * 
273                                 FLOAT_RANGE + 
274                                 MIN_INPUT;
275                 float output = plugin->calculate_smooth(input, plugin->mode);
277                 int y2 = canvas_h - (int)(output * canvas_h);
278                 if(i > 0)
279                 {
280                         canvas->draw_line(i - 1, y1, i, y2);
281                 }
282                 y1 = y2;
283         }
285 // Draw output points
286         HistogramPoint *current = plugin->config.points[plugin->mode].first;
287         int number = 0;
288         while(current)
289         {
290                 int x1;
291                 int y1;
292                 int x2;
293                 int y2;
294                 int x;
295                 int y;
296                 get_point_extents(current,
297                         &x1, 
298                         &y1, 
299                         &x2, 
300                         &y2,
301                         &x,
302                         &y);
304                 if(number == plugin->current_point)
305                         canvas->draw_box(x1, y1, x2 - x1, y2 - y1);
306                 else
307                         canvas->draw_rectangle(x1, y1, x2 - x1, y2 - y1);
308                 current = NEXT;
309                 number++;
310         }
313 // Draw 0 and 100% lines.
314         canvas->set_color(0xff0000);
315         canvas->draw_line(title2_x - canvas->get_x(), 
316                 0, 
317                 title2_x - canvas->get_x(), 
318                 canvas_h);
319         canvas->draw_line(title3_x - canvas->get_x(), 
320                 0, 
321                 title3_x - canvas->get_x(), 
322                 canvas_h);
325 void HistogramWindow::update_canvas()
327         int *accum = plugin->accum[plugin->mode];
328         int accum_per_canvas_i = HISTOGRAM_SLOTS / canvas_w + 1;
329         float accum_per_canvas_f = (float)HISTOGRAM_SLOTS / canvas_w;
330         int normalize = 0;
331         int max = 0;
333 // Calculate output curve with no value function
334         plugin->tabulate_curve(plugin->mode, 0);
336         for(int i = 0; i < HISTOGRAM_SLOTS; i++)
337         {
338                 if(accum && accum[i] > normalize) normalize = accum[i];
339         }
342         if(normalize)
343         {
344                 for(int i = 0; i < canvas_w; i++)
345                 {
346                         int accum_start = (int)(accum_per_canvas_f * i);
347                         int accum_end = accum_start + accum_per_canvas_i;
348                         max = 0;
349                         for(int j = accum_start; j < accum_end; j++)
350                         {
351                                 max = MAX(accum[j], max);
352                         }
354 //                      max = max * canvas_h / normalize;
355                         max = (int)(log(max) / log(normalize) * canvas_h);
357                         canvas->set_color(0xffffff);
358                         canvas->draw_line(i, 0, i, canvas_h - max);
359                         canvas->set_color(0x000000);
360                         canvas->draw_line(i, canvas_h - max, i, canvas_h);
361                 }
362         }
363         else
364         {
365                 canvas->set_color(0xffffff);
366                 canvas->draw_box(0, 0, canvas_w, canvas_h);
367         }
370         draw_canvas_overlay();
371         canvas->flash();
374 void HistogramWindow::get_point_extents(HistogramPoint *current,
375         int *x1, 
376         int *y1, 
377         int *x2, 
378         int *y2,
379         int *x,
380         int *y)
382         *x = (int)((current->x - MIN_INPUT) * canvas_w / FLOAT_RANGE);
383         *y = (int)(canvas_h - current->y * canvas_h);
384         *x1 = *x - BOX_SIZE / 2;
385         *y1 = *y - BOX_SIZE / 2;
386         *x2 = *x1 + BOX_SIZE;
387         *y2 = *y1 + BOX_SIZE;
396 HistogramCanvas::HistogramCanvas(HistogramMain *plugin,
397         HistogramWindow *gui,
398         int x,
399         int y,
400         int w,
401         int h)
402  : BC_SubWindow(x,
403         y,
404         w,
405         h,
406         0xffffff)
408         this->plugin = plugin;
409         this->gui = gui;
412 int HistogramCanvas::button_press_event()
414         int result = 0;
415         if(is_event_win() && cursor_inside())
416         {
417                 if(!plugin->dragging_point && 
418                         (!plugin->config.automatic || plugin->mode == HISTOGRAM_VALUE))
419                 {
420                         HistogramPoint *new_point = 0;
421                         gui->deactivate();
422 // Search for existing point under cursor
423                         HistogramPoint *current = plugin->config.points[plugin->mode].first;
424                         plugin->current_point = -1;
425                         while(current)
426                         {
427                                 int x = (int)((current->x - MIN_INPUT) * gui->canvas_w / FLOAT_RANGE);
428                                 int y = (int)(gui->canvas_h - current->y * gui->canvas_h);
430                                 if(get_cursor_x() >= x - BOX_SIZE / 2 &&
431                                         get_cursor_y() >= y - BOX_SIZE / 2 &&
432                                         get_cursor_x() < x + BOX_SIZE / 2 &&
433                                         get_cursor_y() < y + BOX_SIZE / 2)
434                                 {
435                                         plugin->current_point = 
436                                                 plugin->config.points[plugin->mode].number_of(current);
437                                         plugin->point_x_offset = get_cursor_x() - x;
438                                         plugin->point_y_offset = get_cursor_y() - y;
439                                         break;
440                                 }
441                                 current = NEXT;
442                         }
444                         if(plugin->current_point < 0)
445                         {
446 // Create new point under cursor
447                                 float current_x = (float)get_cursor_x() * 
448                                         FLOAT_RANGE / 
449                                         get_w() + 
450                                         MIN_INPUT;
451                                 float current_y = 1.0 - 
452                                         (float)get_cursor_y() / 
453                                         get_h();
454                                 new_point = 
455                                         plugin->config.points[plugin->mode].insert(current_x, current_y);
456                                 plugin->current_point = 
457                                         plugin->config.points[plugin->mode].number_of(new_point);
458                                 plugin->point_x_offset = 0;
459                                 plugin->point_y_offset = 0;
460                         }
462                         plugin->dragging_point = 1;
463                         result = 1;
465                         plugin->config.boundaries();
466                         gui->update_input();
467                         gui->update_canvas();
468                         if(new_point)
469                         {
470                                 plugin->send_configure_change();
471                         }
472                 }
473         }
474         return result;
477 int HistogramCanvas::cursor_motion_event()
479         if(plugin->dragging_point)
480         {
481                 float current_x = 
482                         (float)(get_cursor_x() - plugin->point_x_offset) * 
483                         FLOAT_RANGE / 
484                         get_w() + 
485                         MIN_INPUT;
486                 float current_y = 1.0 - 
487                         (float)(get_cursor_y() - plugin->point_y_offset) / 
488                         get_h();
489                 HistogramPoint *current_point = 
490                         plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
491                 current_point->x = current_x;
492                 current_point->y = current_y;
493                 plugin->config.boundaries();
494                 gui->update_input();
495                 gui->update_canvas();
496                 plugin->send_configure_change();
497                 return 1;
498         }
499         else
500         if(is_event_win() && cursor_inside())
501         {
502                 HistogramPoint *current = plugin->config.points[plugin->mode].first;
503                 int done = 0;
504                 while(current && !done)
505                 {
506                         int x1;
507                         int y1;
508                         int x2;
509                         int y2;
510                         int x;
511                         int y;
512                         gui->get_point_extents(current,
513                                 &x1, 
514                                 &y1, 
515                                 &x2, 
516                                 &y2,
517                                 &x,
518                                 &y);
519                         int new_cursor = ARROW_CURSOR;
520                         if(get_cursor_x() >= x1 && 
521                                 get_cursor_y() >= y1 &&
522                                 get_cursor_x() < x2 &&
523                                 get_cursor_y() < y2)
524                         {
525                                 new_cursor = UPRIGHT_ARROW_CURSOR;
526                                 done = 1;
527                         }
529                         if(new_cursor != get_cursor())
530                                 set_cursor(new_cursor);
533                         current = NEXT;
534                 }
535         }
536         return 0;
539 int HistogramCanvas::button_release_event()
541         if(plugin->dragging_point)
542         {
543 // Test for out of order points to delete.
544                 HistogramPoint *current = 
545                         plugin->config.points[plugin->mode].get_item_number(plugin->current_point);
546                 HistogramPoint *prev = PREVIOUS;
547                 HistogramPoint *next = NEXT;
549                 if((prev && prev->x >= current->x) ||
550                         (next && next->x <= current->x))
551                 {
552                         delete current;
553                         plugin->current_point = -1;
554                         plugin->config.boundaries();
555                         gui->update_input();
556                         gui->update_canvas();
557                         plugin->send_configure_change();
558                 }
560                 plugin->dragging_point = 0;
561         }
562         return 0;
571 HistogramReset::HistogramReset(HistogramMain *plugin, 
572         int x,
573         int y)
574  : BC_GenericButton(x, y, _("Reset"))
576         this->plugin = plugin;
578 int HistogramReset::handle_event()
580         plugin->config.reset(0);
581         plugin->thread->window->update(1);
582         plugin->thread->window->update_canvas();
583         plugin->send_configure_change();
584         return 1;
595 HistogramSlider::HistogramSlider(HistogramMain *plugin, 
596         HistogramWindow *gui,
597         int x, 
598         int y, 
599         int w,
600         int h,
601         int is_input)
602  : BC_SubWindow(x, y, w, h)
604         this->plugin = plugin;
605         this->gui = gui;
606         this->is_input = is_input;
607         operation = NONE;
610 int HistogramSlider::input_to_pixel(float input)
612         return (int)((input - MIN_INPUT) / FLOAT_RANGE * get_w());
615 int HistogramSlider::button_press_event()
617         if(is_event_win() && cursor_inside())
618         {
619                 int min;
620                 int max;
621                 int w = get_w();
622                 int h = get_h();
623                 int half_h = get_h() / 2;
625                 gui->deactivate();
627                 if(operation == NONE)
628                 {
629                         int x1 = input_to_pixel(plugin->config.output_min[plugin->mode]) - 
630                                 gui->mid_picon->get_w() / 2;
631                         int x2 = x1 + gui->mid_picon->get_w();
632                         if(get_cursor_x() >= x1 && get_cursor_x() < x2 &&
633                                 get_cursor_y() >= half_h && get_cursor_y() < h)
634                         {
635                                 operation = DRAG_MIN_OUTPUT;
636                         }
637                 }
639                 if(operation == NONE)
640                 {
641                         int x1 = input_to_pixel(plugin->config.output_max[plugin->mode]) - 
642                                 gui->mid_picon->get_w() / 2;
643                         int x2 = x1 + gui->mid_picon->get_w();
644                         if(get_cursor_x() >= x1 && get_cursor_x() < x2 &&
645                                 get_cursor_y() >= half_h && get_cursor_y() < h)
646                         {
647                                 operation = DRAG_MAX_OUTPUT;
648                         }
649                 }
650                 return 1;
651         }
652         return 0;
655 int HistogramSlider::button_release_event()
657         if(operation != NONE)
658         {
659                 operation = NONE;
660                 return 1;
661         }
662         return 0;
665 int HistogramSlider::cursor_motion_event()
667         if(operation != NONE)
668         {
669                 float value = (float)get_cursor_x() / get_w() * FLOAT_RANGE + MIN_INPUT;
670                 CLAMP(value, MIN_INPUT, MAX_INPUT);
672                 switch(operation)
673                 {
674                         case DRAG_MIN_OUTPUT:
675                                 value = MIN(plugin->config.output_max[plugin->mode], value);
676                                 plugin->config.output_min[plugin->mode] = value;
677                                 break;
678                         case DRAG_MAX_OUTPUT:
679                                 value = MAX(plugin->config.output_min[plugin->mode], value);
680                                 plugin->config.output_max[plugin->mode] = value;
681                                 break;
682                 }
683         
684                 plugin->config.boundaries();
685                 gui->update_output();
687                 plugin->send_configure_change();
688                 return 1;
689         }
690         return 0;
693 void HistogramSlider::update()
695         int w = get_w();
696         int h = get_h();
697         int half_h = get_h() / 2;
698         int quarter_h = get_h() / 4;
699         int mode = plugin->mode;
700         int r = 0xff;
701         int g = 0xff;
702         int b = 0xff;
704         clear_box(0, 0, w, h);
706         switch(mode)
707         {
708                 case HISTOGRAM_RED:
709                         g = b = 0x00;
710                         break;
711                 case HISTOGRAM_GREEN:
712                         r = b = 0x00;
713                         break;
714                 case HISTOGRAM_BLUE:
715                         r = g = 0x00;
716                         break;
717         }
719         for(int i = 0; i < w; i++)
720         {
721                 int color = (int)(i * 0xff / w);
722                 set_color(((r * color / 0xff) << 16) | 
723                         ((g * color / 0xff) << 8) | 
724                         (b * color / 0xff));
726                 draw_line(i, 0, i, half_h);
727         }
729         float min;
730         float max;
731         min = plugin->config.output_min[plugin->mode];
732         max = plugin->config.output_max[plugin->mode];
734         draw_pixmap(gui->min_picon,
735                 input_to_pixel(min) - gui->min_picon->get_w() / 2,
736                 half_h + 1);
737         draw_pixmap(gui->max_picon,
738                 input_to_pixel(max) - gui->max_picon->get_w() / 2,
739                 half_h + 1);
741         flash();
742         flush();
753 HistogramAuto::HistogramAuto(HistogramMain *plugin, 
754         int x, 
755         int y)
756  : BC_CheckBox(x, y, plugin->config.automatic, _("Automatic"))
758         this->plugin = plugin;
761 int HistogramAuto::handle_event()
763         plugin->config.automatic = get_value();
764         plugin->send_configure_change();
765         return 1;
771 HistogramPlot::HistogramPlot(HistogramMain *plugin, 
772         int x, 
773         int y)
774  : BC_CheckBox(x, y, plugin->config.plot, _("Plot histogram"))
776         this->plugin = plugin;
779 int HistogramPlot::handle_event()
781         plugin->config.plot = get_value();
782         plugin->send_configure_change();
783         return 1;
789 HistogramSplit::HistogramSplit(HistogramMain *plugin, 
790         int x, 
791         int y)
792  : BC_CheckBox(x, y, plugin->config.split, _("Split output"))
794         this->plugin = plugin;
797 int HistogramSplit::handle_event()
799         plugin->config.split = get_value();
800         plugin->send_configure_change();
801         return 1;
806 HistogramMode::HistogramMode(HistogramMain *plugin, 
807         int x, 
808         int y,
809         int value,
810         char *text)
811  : BC_Radial(x, y, plugin->mode == value, text)
813         this->plugin = plugin;
814         this->value = value;
816 int HistogramMode::handle_event()
818         plugin->mode = value;
819         plugin->current_point= -1;
820         plugin->thread->window->update_canvas();
821         plugin->thread->window->update_mode();
822         plugin->thread->window->update_input();
823         plugin->thread->window->update_canvas();
824         plugin->thread->window->update_output();
825         plugin->thread->window->output->update();
826 //      plugin->send_configure_change();
827         return 1;
838 HistogramOutputText::HistogramOutputText(HistogramMain *plugin,
839         HistogramWindow *gui,
840         int x,
841         int y,
842         float *output)
843  : BC_TumbleTextBox(gui, 
844                 output ? (float)*output : 0.0,
845                 (float)MIN_INPUT,
846                 (float)MAX_INPUT,
847                 x, 
848                 y, 
849                 60)
851         this->plugin = plugin;
852         this->output = output;
853         set_precision(DIGITS);
854         set_increment(PRECISION);
858 int HistogramOutputText::handle_event()
860         if(output)
861         {
862                 *output = atof(get_text());
863         }
865         plugin->thread->window->output->update();
866         plugin->send_configure_change();
867         return 1;
877 HistogramInputText::HistogramInputText(HistogramMain *plugin,
878         HistogramWindow *gui,
879         int x,
880         int y,
881         int do_x)
882  : BC_TumbleTextBox(gui, 
883                 0.0,
884                 (float)MIN_INPUT,
885                 (float)MAX_INPUT,
886                 x, 
887                 y, 
888                 60)
890         this->do_x = do_x;
891         this->plugin = plugin;
892         this->gui = gui;
893         set_precision(DIGITS);
894         set_increment(PRECISION);
898 int HistogramInputText::handle_event()
900         if(plugin->current_point >= 0 &&
901                 plugin->current_point < plugin->config.points[plugin->mode].total())
902         {
903                 HistogramPoint *point = 
904                         plugin->config.points[plugin->mode].get_item_number(
905                                 plugin->current_point);
907                 if(point)
908                 {
909                         if(do_x) 
910                                 point->x = atof(get_text());
911                         else
912                                 point->y = atof(get_text());
914                         plugin->config.boundaries();
915                         gui->update_canvas();
917                         plugin->thread->window->output->update();
918                         plugin->send_configure_change();
919                 }
920         }
921         return 1;
924 void HistogramInputText::update()
926         if(plugin->current_point >= 0 &&
927                 plugin->current_point < plugin->config.points[plugin->mode].total())
928         {
929                 HistogramPoint *point = 
931                         plugin->config.points[plugin->mode].get_item_number(
932                                 plugin->current_point);
934                 if(point)
935                 {
936                         if(do_x)
937                                 BC_TumbleTextBox::update(point->x);
938                         else
939                                 BC_TumbleTextBox::update(point->y);
940                 }
941                 else
942                 {
943                         BC_TumbleTextBox::update((float)0.0);
944                 }
945         }
946         else
947         {
948                 BC_TumbleTextBox::update((float)0.0);
949         }
950