r1032: Make threshold low, mid, high colors configurable.
[cinelerra_cv.git] / plugins / threshold / thresholdwindow.C
blob0c10a7717dcdd09f748abfdb565c13dcab35a588
1 #include "bcdisplayinfo.h"
2 #include "histogramengine.h"
3 #include "language.h"
4 #include "threshold.h"
5 #include "thresholdwindow.h"
7 #define COLOR_W 100
8 #define COLOR_H 30
13 ThresholdMin::ThresholdMin(ThresholdMain *plugin,
14         ThresholdWindow *gui,
15         int x,
16         int y,
17         int w)
18  : BC_TumbleTextBox(gui, 
19         plugin->config.min,
20         HISTOGRAM_MIN,
21         HISTOGRAM_MAX,
22         x, 
23         y, 
24         w)
26         this->plugin = plugin;
27         this->gui = gui;
31 int ThresholdMin::handle_event()
33         plugin->config.min = atof(get_text());
34         gui->canvas->draw();
35         plugin->send_configure_change();
36         return 1;
47 ThresholdMax::ThresholdMax(ThresholdMain *plugin,
48         ThresholdWindow *gui,
49         int x,
50         int y,
51         int w)
52  : BC_TumbleTextBox(gui, 
53         plugin->config.max,
54         HISTOGRAM_MIN,
55         HISTOGRAM_MAX,
56         x, 
57         y, 
58         w)
60         this->plugin = plugin;
61         this->gui = gui;
64 int ThresholdMax::handle_event()
66         plugin->config.max = atof(get_text());
67         gui->canvas->draw();
68         plugin->send_configure_change();
69         return 1;
78 ThresholdPlot::ThresholdPlot(ThresholdMain *plugin,
79         int x,
80         int y)
81  : BC_CheckBox(x, y, plugin->config.plot, _("Plot histogram"))
83         this->plugin = plugin;
86 int ThresholdPlot::handle_event()
88         plugin->config.plot = get_value();
89         
90         plugin->send_configure_change();
91         return 1;
99 ThresholdCanvas::ThresholdCanvas(ThresholdMain *plugin,
100         ThresholdWindow *gui,
101         int x,
102         int y,
103         int w,
104         int h)
105  : BC_SubWindow(x, y, w, h)
107         this->plugin = plugin;
108         this->gui = gui;
109         state = NO_OPERATION;
112 int ThresholdCanvas::button_press_event()
114         if(is_event_win() && cursor_inside())
115         {
116                 activate();
117                 state = DRAG_SELECTION;
118                 if(shift_down())
119                 {
120                         x1 = (int)((plugin->config.min - HISTOGRAM_MIN) / 
121                                 (HISTOGRAM_MAX - HISTOGRAM_MIN) * 
122                                 get_w());
123                         x2 = (int)((plugin->config.max - HISTOGRAM_MIN) /
124                                 (HISTOGRAM_MAX - HISTOGRAM_MIN) *
125                                 get_w());
126                         center_x = (x2 + x1) / 2;
127                         if(abs(get_cursor_x() - x1) < abs(get_cursor_x() - x2))
128                         {
129                                 x1 = get_cursor_x();
130                                 center_x = x2;
131                         }
132                         else
133                         {
134                                 x2 = get_cursor_x();
135                                 center_x = x1;
136                         }
137                 }
138                 else
139                 {
140                         x1 = x2 = center_x = get_cursor_x();
141                 }
143                 plugin->config.min = x1 * 
144                         (HISTOGRAM_MAX - HISTOGRAM_MIN) / 
145                         get_w() + 
146                         HISTOGRAM_MIN;
147                 plugin->config.max = x2 * 
148                         (HISTOGRAM_MAX - HISTOGRAM_MIN) / 
149                         get_w() + 
150                         HISTOGRAM_MIN;
152                 draw();
153                 return 1;
154         }
155         return 0;
158 int ThresholdCanvas::button_release_event()
160         if(state == DRAG_SELECTION)
161         {
162                 state = NO_OPERATION;
163                 return 1;
164         }
165         return 0;
168 int ThresholdCanvas::cursor_motion_event()
170         if(state == DRAG_SELECTION)
171         {
172                 if(get_cursor_x() > center_x)
173                 {
174                         x1 = center_x;
175                         x2 = get_cursor_x();
176                 }
177                 else
178                 {
179                         x1 = get_cursor_x();
180                         x2 = center_x;
181                 }
183                 plugin->config.min = x1 * 
184                         (HISTOGRAM_MAX - HISTOGRAM_MIN) / 
185                         get_w() + 
186                         HISTOGRAM_MIN;
188                 plugin->config.max = x2 * 
189                         (HISTOGRAM_MAX - HISTOGRAM_MIN) / 
190                         get_w() + 
191                         HISTOGRAM_MIN;
193                 gui->min->update(plugin->config.min);
194                 gui->max->update(plugin->config.max);
195                 draw();
196                 plugin->send_configure_change();
197                 return 1;
198         }
199         return 0;
202 void ThresholdCanvas::draw()
204         int max = 0;
205         set_color(WHITE);
206         draw_box(0, 0, get_w(), get_h());
207         int border_x1 = (int)((0 - HISTOGRAM_MIN) / 
208                 (HISTOGRAM_MAX - HISTOGRAM_MIN) *
209                 get_w());
210         int border_x2 = (int)((1.0 - HISTOGRAM_MIN) / 
211                 (HISTOGRAM_MAX - HISTOGRAM_MIN) *
212                 get_w());
214         int x1 = (int)((plugin->config.min - HISTOGRAM_MIN) / 
215                 (HISTOGRAM_MAX - HISTOGRAM_MIN) * 
216                 get_w());
217         int x2 = (int)((plugin->config.max - HISTOGRAM_MIN) /
218                 (HISTOGRAM_MAX - HISTOGRAM_MIN) *
219                 get_w());
221         if(plugin->engine)
222         {
223                 int64_t *array = plugin->engine->accum[HISTOGRAM_VALUE];
226 // Get normalizing factor
227                 for(int i = 0; i < get_w(); i++)
228                 {
229                         int division1 = i * HISTOGRAM_RANGE / get_w();
230                         int division2 = (i + 1) * HISTOGRAM_RANGE / get_w();
231                         int total = 0;
232                         for(int j = division1; j < division2; j++)
233                         {
234                                 total += array[j];
235                         }
236                         if(total > max) max = total;
237                 }
239                 for(int i = 0; i < get_w(); i++)
240                 {
241                         int division1 = i * HISTOGRAM_RANGE / get_w();
242                         int division2 = (i + 1) * HISTOGRAM_RANGE / get_w();
243                         int total = 0;
244                         for(int j = division1; j < division2; j++)
245                         {
246                                 total += array[j];
247                         }
249                         int pixels;
250                         if(max)
251                                 pixels = total * get_h() / max;
252                         else
253                                 pixels = 0;
254                         if(i >= x1 && i < x2)
255                         {
256                                 set_color(BLUE);
257                                 draw_line(i, 0, i, get_h() - pixels);
258                                 set_color(WHITE);
259                                 draw_line(i, get_h(), i, get_h() - pixels);
260                         }
261                         else
262                         {
263                                 set_color(BLACK);
264                                 draw_line(i, get_h(), i, get_h() - pixels);
265                         }
266                 }
267         }
268         else
269         {
272                 set_color(BLUE);
273                 draw_box(x1, 0, x2 - x1, get_h());
274         }
276         set_color(RED);
277         draw_line(border_x1, 0, border_x1, get_h());
278         draw_line(border_x2, 0, border_x2, get_h());
280         flash(1);
288 ThresholdLowColorButton::ThresholdLowColorButton(ThresholdMain *plugin, ThresholdWindow *window, int x, int y)
289  : BC_GenericButton(x, y, _("Low Color"))
291         this->plugin = plugin;
292         this->window = window;
295 int ThresholdLowColorButton::handle_event()
297         RGBA & color = plugin->config.low_color;
298         window->low_color_thread->start_window(
299                 color.getRGB(),
300                 color.a);
301         return 1;
308 ThresholdMidColorButton::ThresholdMidColorButton(ThresholdMain *plugin, ThresholdWindow *window, int x, int y)
309  : BC_GenericButton(x, y, _("Mid Color"))
311         this->plugin = plugin;
312         this->window = window;
315 int ThresholdMidColorButton::handle_event()
317         RGBA & color = plugin->config.mid_color;
318         window->mid_color_thread->start_window(
319                 color.getRGB(),
320                 color.a);
321         return 1;
328 ThresholdHighColorButton::ThresholdHighColorButton(ThresholdMain *plugin, ThresholdWindow *window, int x, int y)
329  : BC_GenericButton(x, y, _("High Color"))
331         this->plugin = plugin;
332         this->window = window;
335 int ThresholdHighColorButton::handle_event()
337         RGBA & color = plugin->config.high_color;
338         window->high_color_thread->start_window(
339                 color.getRGB(),
340                 color.a);
341         return 1;
348 ThresholdLowColorThread::ThresholdLowColorThread(ThresholdMain *plugin, ThresholdWindow *window)
349  : ColorThread(1, _("Low color"))
351         this->plugin = plugin;
352         this->window = window;
355 int ThresholdLowColorThread::handle_new_color(int output, int alpha)
357         plugin->config.low_color.set(output, alpha);
358         window->update_low_color();
359         window->flush();
360         plugin->send_configure_change();
367 ThresholdMidColorThread::ThresholdMidColorThread(ThresholdMain *plugin, ThresholdWindow *window)
368  : ColorThread(1, _("Mid color"))
370         this->plugin = plugin;
371         this->window = window;
374 int ThresholdMidColorThread::handle_new_color(int output, int alpha)
376         plugin->config.mid_color.set(output, alpha);
377         window->update_mid_color();
378         window->flush();
379         plugin->send_configure_change();
386 ThresholdHighColorThread::ThresholdHighColorThread(ThresholdMain *plugin, ThresholdWindow *window)
387  : ColorThread(1, _("High color"))
389         this->plugin = plugin;
390         this->window = window;
393 int ThresholdHighColorThread::handle_new_color(int output, int alpha)
395         plugin->config.high_color.set(output, alpha);
396         window->update_high_color();
397         window->flush();
398         plugin->send_configure_change();
406 ThresholdWindow::ThresholdWindow(ThresholdMain *plugin, int x, int y)
407 : BC_Window(plugin->gui_string, x, y, 450, 450, 450, 450, 0, 1)
409         this->plugin = plugin;
410         this->min = 0;
411         this->max = 0;
412         this->canvas = 0;
413         this->plot = 0;
414         this->low_color = 0;
415         this->mid_color = 0;
416         this->high_color = 0;
417         this->low_color_thread = 0;
418         this->mid_color_thread = 0;
419         this->high_color_thread = 0;
422 ThresholdWindow::~ThresholdWindow()
426 int ThresholdWindow::create_objects()
428         int x = 10;
429         int y = 10;
430         add_subwindow(canvas = new ThresholdCanvas(plugin,
431                 this,
432                 x,
433                 y,
434                 get_w() - x - 10,
435                 get_h() - 160));
436         canvas->draw();
437         y += canvas->get_h() + 10;
439         add_subwindow(plot = new ThresholdPlot(plugin, x, y));
440         y += plot->get_h() + 10;
443         add_subwindow(low_color = new ThresholdLowColorButton(plugin, this, x, y));
444         low_color_x = x + 10;
445         low_color_y = y + low_color->get_h() + 10;
446         x += low_color->get_w() + 10;
448         add_subwindow(mid_color = new ThresholdMidColorButton(plugin, this, x, y));
449         mid_color_x = x + 10;
450         mid_color_y = y + mid_color->get_h() + 10;
451         x += mid_color->get_w() + 10;
453         add_subwindow(high_color = new ThresholdHighColorButton(plugin, this, x, y));
454         high_color_x = x + 10;
455         high_color_y = y + high_color->get_h() + 10;
457         y += low_color->get_h() + COLOR_H + 10 + 10;
459         x = 30;
460         BC_Title * min_title;
461         add_subwindow(min_title = new BC_Title(x, y, _("Min:")));
462         x += min_title->get_w() + 10;
463         min = new ThresholdMin(plugin,
464                 this,
465                 x,
466                 y,
467                 100);
468         min->create_objects();
469         min->set_increment(0.1);
472         x = mid_color->get_x() + mid_color->get_w() / 2;
473         BC_Title * max_title;
474         add_subwindow(max_title = new BC_Title(x, y, _("Max:")));
475         x += max_title->get_w() + 10;
476         max = new ThresholdMax(plugin,
477                 this,
478                 x,
479                 y,
480                 100);
481         max->create_objects();
482         max->set_increment(0.1);
485         low_color_thread  = new ThresholdLowColorThread(plugin, this);
486         mid_color_thread  = new ThresholdMidColorThread(plugin, this);
487         high_color_thread = new ThresholdHighColorThread(plugin, this);
488         update_low_color();
489         update_mid_color();
490         update_high_color();
492         show_window(1);
495 void ThresholdWindow::update_low_color()
497         set_color(plugin->config.low_color.getRGB());
498         draw_box(low_color_x, low_color_y, COLOR_W, COLOR_H);
499         flash(low_color_x, low_color_y, COLOR_W, COLOR_H);
502 void ThresholdWindow::update_mid_color()
504         set_color(plugin->config.mid_color.getRGB());
505         draw_box(mid_color_x, mid_color_y, COLOR_W, COLOR_H);
506         flash(mid_color_x, mid_color_y, COLOR_W, COLOR_H);
509 void ThresholdWindow::update_high_color()
511         set_color(plugin->config.high_color.getRGB());
512         draw_box(high_color_x, high_color_y, COLOR_W, COLOR_H);
513         flash(high_color_x, high_color_y, COLOR_W, COLOR_H);
518 WINDOW_CLOSE_EVENT(ThresholdWindow)
523 PLUGIN_THREAD_OBJECT(ThresholdMain, ThresholdThread, ThresholdWindow)