--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "bcdisplayinfo.h"
+#include "histogramengine.h"
+#include "language.h"
+#include "threshold.h"
+#include "thresholdwindow.h"
+
+#define COLOR_W 100
+#define COLOR_H 30
+
+
+
+
+ThresholdMin::ThresholdMin(ThresholdMain *plugin,
+ ThresholdWindow *gui,
+ int x,
+ int y,
+ int w)
+ : BC_TumbleTextBox(gui,
+ plugin->config.min,
+ HISTOGRAM_MIN,
+ HISTOGRAM_MAX,
+ x,
+ y,
+ w)
+{
+ this->plugin = plugin;
+ this->gui = gui;
+}
+
+
+int ThresholdMin::handle_event()
+{
+ plugin->config.min = atof(get_text());
+ gui->canvas->draw();
+ plugin->send_configure_change();
+ return 1;
+}
+
+
+
+
+
+
+
+
+
+ThresholdMax::ThresholdMax(ThresholdMain *plugin,
+ ThresholdWindow *gui,
+ int x,
+ int y,
+ int w)
+ : BC_TumbleTextBox(gui,
+ plugin->config.max,
+ HISTOGRAM_MIN,
+ HISTOGRAM_MAX,
+ x,
+ y,
+ w)
+{
+ this->plugin = plugin;
+ this->gui = gui;
+}
+
+int ThresholdMax::handle_event()
+{
+ plugin->config.max = atof(get_text());
+ gui->canvas->draw();
+ plugin->send_configure_change();
+ return 1;
+}
+
+
+
+
+
+
+
+ThresholdPlot::ThresholdPlot(ThresholdMain *plugin,
+ int x,
+ int y)
+ : BC_CheckBox(x, y, plugin->config.plot, _("Plot histogram"))
+{
+ this->plugin = plugin;
+}
+
+int ThresholdPlot::handle_event()
+{
+ plugin->config.plot = get_value();
+
+ plugin->send_configure_change();
+ return 1;
+}
+
+
+
+
+
+
+ThresholdCanvas::ThresholdCanvas(ThresholdMain *plugin,
+ ThresholdWindow *gui,
+ int x,
+ int y,
+ int w,
+ int h)
+ : BC_SubWindow(x, y, w, h)
+{
+ this->plugin = plugin;
+ this->gui = gui;
+ state = NO_OPERATION;
+}
+
+int ThresholdCanvas::button_press_event()
+{
+ if(is_event_win() && cursor_inside())
+ {
+ activate();
+ state = DRAG_SELECTION;
+ if(shift_down())
+ {
+ x1 = (int)((plugin->config.min - HISTOGRAM_MIN) /
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) *
+ get_w());
+ x2 = (int)((plugin->config.max - HISTOGRAM_MIN) /
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) *
+ get_w());
+ center_x = (x2 + x1) / 2;
+ if(abs(get_cursor_x() - x1) < abs(get_cursor_x() - x2))
+ {
+ x1 = get_cursor_x();
+ center_x = x2;
+ }
+ else
+ {
+ x2 = get_cursor_x();
+ center_x = x1;
+ }
+ }
+ else
+ {
+ x1 = x2 = center_x = get_cursor_x();
+ }
+
+ plugin->config.min = x1 *
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) /
+ get_w() +
+ HISTOGRAM_MIN;
+ plugin->config.max = x2 *
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) /
+ get_w() +
+ HISTOGRAM_MIN;
+
+ draw();
+ return 1;
+ }
+ return 0;
+}
+
+int ThresholdCanvas::button_release_event()
+{
+ if(state == DRAG_SELECTION)
+ {
+ state = NO_OPERATION;
+ return 1;
+ }
+ return 0;
+}
+
+int ThresholdCanvas::cursor_motion_event()
+{
+ if(state == DRAG_SELECTION)
+ {
+ if(get_cursor_x() > center_x)
+ {
+ x1 = center_x;
+ x2 = get_cursor_x();
+ }
+ else
+ {
+ x1 = get_cursor_x();
+ x2 = center_x;
+ }
+
+ plugin->config.min = x1 *
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) /
+ get_w() +
+ HISTOGRAM_MIN;
+
+ plugin->config.max = x2 *
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) /
+ get_w() +
+ HISTOGRAM_MIN;
+
+ gui->min->update(plugin->config.min);
+ gui->max->update(plugin->config.max);
+ draw();
+ plugin->send_configure_change();
+ return 1;
+ }
+ return 0;
+}
+
+void ThresholdCanvas::draw()
+{
+ int max = 0;
+ set_color(WHITE);
+ draw_box(0, 0, get_w(), get_h());
+ int border_x1 = (int)((0 - HISTOGRAM_MIN) /
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) *
+ get_w());
+ int border_x2 = (int)((1.0 - HISTOGRAM_MIN) /
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) *
+ get_w());
+
+ int x1 = (int)((plugin->config.min - HISTOGRAM_MIN) /
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) *
+ get_w());
+ int x2 = (int)((plugin->config.max - HISTOGRAM_MIN) /
+ (HISTOGRAM_MAX - HISTOGRAM_MIN) *
+ get_w());
+
+ if(plugin->engine)
+ {
+ int64_t *array = plugin->engine->accum[HISTOGRAM_VALUE];
+
+
+// Get normalizing factor
+ for(int i = 0; i < get_w(); i++)
+ {
+ int division1 = i * HISTOGRAM_RANGE / get_w();
+ int division2 = (i + 1) * HISTOGRAM_RANGE / get_w();
+ int total = 0;
+ for(int j = division1; j < division2; j++)
+ {
+ total += array[j];
+ }
+ if(total > max) max = total;
+ }
+
+ for(int i = 0; i < get_w(); i++)
+ {
+ int division1 = i * HISTOGRAM_RANGE / get_w();
+ int division2 = (i + 1) * HISTOGRAM_RANGE / get_w();
+ int total = 0;
+ for(int j = division1; j < division2; j++)
+ {
+ total += array[j];
+ }
+
+ int pixels;
+ if(max)
+ pixels = total * get_h() / max;
+ else
+ pixels = 0;
+ if(i >= x1 && i < x2)
+ {
+ set_color(BLUE);
+ draw_line(i, 0, i, get_h() - pixels);
+ set_color(WHITE);
+ draw_line(i, get_h(), i, get_h() - pixels);
+ }
+ else
+ {
+ set_color(BLACK);
+ draw_line(i, get_h(), i, get_h() - pixels);
+ }
+ }
+ }
+ else
+ {
+
+
+ set_color(BLUE);
+ draw_box(x1, 0, x2 - x1, get_h());
+ }
+
+ set_color(RED);
+ draw_line(border_x1, 0, border_x1, get_h());
+ draw_line(border_x2, 0, border_x2, get_h());
+
+ flash(1);
+}
+
+
+
+
+
+
+ThresholdLowColorButton::ThresholdLowColorButton(ThresholdMain *plugin, ThresholdWindow *window, int x, int y)
+ : BC_GenericButton(x, y, _("Low Color"))
+{
+ this->plugin = plugin;
+ this->window = window;
+}
+
+int ThresholdLowColorButton::handle_event()
+{
+ RGBA & color = plugin->config.low_color;
+ window->low_color_thread->start_window(
+ color.getRGB(),
+ color.a);
+ return 1;
+}
+
+
+
+
+
+ThresholdMidColorButton::ThresholdMidColorButton(ThresholdMain *plugin, ThresholdWindow *window, int x, int y)
+ : BC_GenericButton(x, y, _("Mid Color"))
+{
+ this->plugin = plugin;
+ this->window = window;
+}
+
+int ThresholdMidColorButton::handle_event()
+{
+ RGBA & color = plugin->config.mid_color;
+ window->mid_color_thread->start_window(
+ color.getRGB(),
+ color.a);
+ return 1;
+}
+
+
+
+
+
+ThresholdHighColorButton::ThresholdHighColorButton(ThresholdMain *plugin, ThresholdWindow *window, int x, int y)
+ : BC_GenericButton(x, y, _("High Color"))
+{
+ this->plugin = plugin;
+ this->window = window;
+}
+
+int ThresholdHighColorButton::handle_event()
+{
+ RGBA & color = plugin->config.high_color;
+ window->high_color_thread->start_window(
+ color.getRGB(),
+ color.a);
+ return 1;
+}
+
+
+
+
+
+ThresholdLowColorThread::ThresholdLowColorThread(ThresholdMain *plugin, ThresholdWindow *window)
+ : ColorThread(1, _("Low color"))
+{
+ this->plugin = plugin;
+ this->window = window;
+}
+
+int ThresholdLowColorThread::handle_new_color(int output, int alpha)
+{
+ plugin->config.low_color.set(output, alpha);
+ window->update_low_color();
+ window->flush();
+ plugin->send_configure_change();
+ return 1;
+}
+
+
+
+
+
+ThresholdMidColorThread::ThresholdMidColorThread(ThresholdMain *plugin, ThresholdWindow *window)
+ : ColorThread(1, _("Mid color"))
+{
+ this->plugin = plugin;
+ this->window = window;
+}
+
+int ThresholdMidColorThread::handle_new_color(int output, int alpha)
+{
+ plugin->config.mid_color.set(output, alpha);
+ window->update_mid_color();
+ window->flush();
+ plugin->send_configure_change();
+ return 1;
+}
+
+
+
+
+
+ThresholdHighColorThread::ThresholdHighColorThread(ThresholdMain *plugin, ThresholdWindow *window)
+ : ColorThread(1, _("High color"))
+{
+ this->plugin = plugin;
+ this->window = window;
+}
+
+int ThresholdHighColorThread::handle_new_color(int output, int alpha)
+{
+ plugin->config.high_color.set(output, alpha);
+ window->update_high_color();
+ window->flush();
+ plugin->send_configure_change();
+ return 1;
+}
+
+
+
+
+
+
+ThresholdWindow::ThresholdWindow(ThresholdMain *plugin)
+: PluginClientWindow(plugin, 450, 450, 450, 450, 1)
+{
+ this->plugin = plugin;
+ this->min = 0;
+ this->max = 0;
+ this->canvas = 0;
+ this->plot = 0;
+ this->low_color = 0;
+ this->mid_color = 0;
+ this->high_color = 0;
+ this->low_color_thread = 0;
+ this->mid_color_thread = 0;
+ this->high_color_thread = 0;
+}
+
+ThresholdWindow::~ThresholdWindow()
+{
+}
+
+void ThresholdWindow::create_objects()
+{
+ int x = 10;
+ int y = 10;
+ add_subwindow(canvas = new ThresholdCanvas(plugin,
+ this,
+ x,
+ y,
+ get_w() - x - 10,
+ get_h() - 160));
+ canvas->draw();
+ y += canvas->get_h() + 10;
+
+ add_subwindow(plot = new ThresholdPlot(plugin, x, y));
+ y += plot->get_h() + 10;
+
+
+ add_subwindow(low_color = new ThresholdLowColorButton(plugin, this, x, y));
+ low_color_x = x + 10;
+ low_color_y = y + low_color->get_h() + 10;
+ x += low_color->get_w() + 10;
+
+ add_subwindow(mid_color = new ThresholdMidColorButton(plugin, this, x, y));
+ mid_color_x = x + 10;
+ mid_color_y = y + mid_color->get_h() + 10;
+ x += mid_color->get_w() + 10;
+
+ add_subwindow(high_color = new ThresholdHighColorButton(plugin, this, x, y));
+ high_color_x = x + 10;
+ high_color_y = y + high_color->get_h() + 10;
+
+ y += low_color->get_h() + COLOR_H + 10 + 10;
+
+ x = 30;
+ BC_Title * min_title;
+ add_subwindow(min_title = new BC_Title(x, y, _("Min:")));
+ x += min_title->get_w() + 10;
+ min = new ThresholdMin(plugin,
+ this,
+ x,
+ y,
+ 100);
+ min->create_objects();
+ min->set_increment(0.1);
+
+
+ x = mid_color->get_x() + mid_color->get_w() / 2;
+ BC_Title * max_title;
+ add_subwindow(max_title = new BC_Title(x, y, _("Max:")));
+ x += max_title->get_w() + 10;
+ max = new ThresholdMax(plugin,
+ this,
+ x,
+ y,
+ 100);
+ max->create_objects();
+ max->set_increment(0.1);
+
+
+ low_color_thread = new ThresholdLowColorThread(plugin, this);
+ mid_color_thread = new ThresholdMidColorThread(plugin, this);
+ high_color_thread = new ThresholdHighColorThread(plugin, this);
+ update_low_color();
+ update_mid_color();
+ update_high_color();
+
+ show_window(1);
+}
+
+void ThresholdWindow::update_low_color()
+{
+ set_color(plugin->config.low_color.getRGB());
+ draw_box(low_color_x, low_color_y, COLOR_W, COLOR_H);
+ flash(low_color_x, low_color_y, COLOR_W, COLOR_H);
+}
+
+void ThresholdWindow::update_mid_color()
+{
+ set_color(plugin->config.mid_color.getRGB());
+ draw_box(mid_color_x, mid_color_y, COLOR_W, COLOR_H);
+ flash(mid_color_x, mid_color_y, COLOR_W, COLOR_H);
+}
+
+void ThresholdWindow::update_high_color()
+{
+ set_color(plugin->config.high_color.getRGB());
+ draw_box(high_color_x, high_color_y, COLOR_W, COLOR_H);
+ flash(high_color_x, high_color_y, COLOR_W, COLOR_H);
+}
+
+
+