GUI enhancement: RGBV indicators below Histogram on behalf of Wolfgang K?hnel (see issue 683)
This commit is contained in:
@@ -21,69 +21,376 @@
|
||||
#include <string.h>
|
||||
#include <LUT.h>
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// HistogramPanel
|
||||
HistogramPanel::HistogramPanel () {
|
||||
|
||||
// Gtk::HBox* outer_hbox = Gtk::manage (new Gtk::HBox (false, 0));
|
||||
|
||||
histogramArea = Gtk::manage (new HistogramArea ());
|
||||
histogramRGBArea = Gtk::manage (new HistogramRGBArea ());
|
||||
|
||||
Gtk::VBox* left_vbox = Gtk::manage (new Gtk::VBox (false, 0));
|
||||
left_vbox->pack_start (*histogramArea, Gtk::PACK_EXPAND_WIDGET, 2);
|
||||
left_vbox->pack_start (*histogramRGBArea, Gtk::PACK_SHRINK, 2);
|
||||
set_size_request (-1, 170);
|
||||
histogramArea->set_size_request (-1, 150);
|
||||
histogramRGBArea->set_size_request(-1, 10);
|
||||
|
||||
showRed = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_R")));
|
||||
showGreen = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_G")));
|
||||
showBlue = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_B")));
|
||||
showValue = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_L")));
|
||||
showRAW = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_RAW")));
|
||||
Gtk::VBox* vbox = Gtk::manage (new Gtk::VBox (false, 0));
|
||||
|
||||
showRed->set_active (true);
|
||||
showGreen->set_active (true);
|
||||
showBlue->set_active (true);
|
||||
showValue->set_active (true);
|
||||
showRAW->set_active (false);
|
||||
vbox->pack_start (*showRed, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_start (*showGreen, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_start (*showBlue, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_start (*showValue, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_end (*showRAW, Gtk::PACK_SHRINK, 2);
|
||||
pack_start (*histogramArea);
|
||||
pack_end (*vbox, Gtk::PACK_SHRINK, 2);
|
||||
showBAR = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_BAR")));
|
||||
|
||||
showRed->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
|
||||
showGreen->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
|
||||
showBlue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
|
||||
showValue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
|
||||
showRAW->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
|
||||
|
||||
show_all ();
|
||||
showBAR->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
|
||||
|
||||
showRed->set_tooltip_text (M("HISTOGRAM_TOOLTIP_R"));
|
||||
showGreen->set_tooltip_text (M("HISTOGRAM_TOOLTIP_G"));
|
||||
showBlue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_B"));
|
||||
showValue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_L"));
|
||||
showRAW->set_tooltip_text (M("HISTOGRAM_TOOLTIP_RAW"));
|
||||
showBAR->set_tooltip_text (M("HISTOGRAM_TOOLTIP_BAR"));
|
||||
|
||||
rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &HistogramPanel::resized) );
|
||||
Gtk::VBox* vbox = Gtk::manage (new Gtk::VBox (false, 0));
|
||||
showRed->set_active (true);
|
||||
showGreen->set_active (true);
|
||||
showBlue->set_active (true);
|
||||
showValue->set_active (true);
|
||||
showRAW->set_active (false);
|
||||
showBAR->set_active (true);
|
||||
vbox->pack_start (*showRed, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_start (*showGreen, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_start (*showBlue, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_start (*showValue, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_start (*showRAW, Gtk::PACK_SHRINK, 2);
|
||||
vbox->pack_start (*showBAR, Gtk::PACK_SHRINK, 2);
|
||||
|
||||
pack_start (*left_vbox,Gtk::PACK_EXPAND_WIDGET, 2);
|
||||
pack_start (*vbox, Gtk::PACK_SHRINK, 2);
|
||||
|
||||
show_all ();
|
||||
|
||||
rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &HistogramPanel::resized) );
|
||||
}
|
||||
|
||||
void HistogramPanel::resized (Gtk::Allocation& req) {
|
||||
|
||||
rconn.block (true);
|
||||
|
||||
if (req.get_width()/2>150)
|
||||
set_size_request (req.get_width(), 150);
|
||||
else
|
||||
if (req.get_width()/2>150) {
|
||||
set_size_request (req.get_width(), 170);
|
||||
histogramArea->set_size_request (req.get_width(), 150);
|
||||
histogramRGBArea->set_size_request (req.get_width(), 10);
|
||||
|
||||
// Probably set R,G,B,V, RAW, and BAR button here to their original size if resizing below is implemented.
|
||||
}
|
||||
else {
|
||||
set_size_request (req.get_width(), req.get_width()/2);
|
||||
histogramArea->set_size_request (req.get_width(), req.get_width()/2);
|
||||
histogramRGBArea->set_size_request(req.get_width(),5);
|
||||
|
||||
// Probably reduce R,G,B,V, RAW, and BAR button here a to a half-sized version.
|
||||
}
|
||||
|
||||
rconn.block (false);
|
||||
|
||||
histogramArea->renderHistogram ();
|
||||
histogramArea->queue_draw ();
|
||||
|
||||
if (histogramRGBArea->getFreeze()==true) {
|
||||
histogramRGBArea->updateFreeze(false);
|
||||
// set histogramRGBArea invalid;
|
||||
histogramRGBArea->renderRGBMarks(-1, -1, -1);
|
||||
// re-set freeze to old state
|
||||
histogramRGBArea->updateFreeze(true);
|
||||
histogramRGBArea->queue_draw ();
|
||||
}
|
||||
else {
|
||||
// set histogramRGBArea invalid;
|
||||
histogramRGBArea->renderRGBMarks(-1, -1, -1);
|
||||
histogramRGBArea->queue_draw ();
|
||||
}
|
||||
}
|
||||
|
||||
void HistogramPanel::rgbv_toggled () {
|
||||
|
||||
// Update Display
|
||||
histogramArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showRAW->get_active());
|
||||
histogramArea->queue_draw ();
|
||||
|
||||
histogramRGBArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showRAW->get_active(), showBAR->get_active());
|
||||
histogramRGBArea->renderRGBMarks (0,0,0);
|
||||
histogramArea->queue_draw ();
|
||||
}
|
||||
|
||||
|
||||
void HistogramPanel::setHistRGBInvalid () {
|
||||
// do something to un-show vertical bars
|
||||
histogramRGBArea->renderRGBMarks(-1, -1, -1);
|
||||
histogramRGBArea->queue_draw ();
|
||||
}
|
||||
|
||||
// "Freeze" is not a button, but a RMB-click, so this is not in the RGBV-Toggle method
|
||||
void HistogramPanel::toggleFreeze () {
|
||||
if (histogramRGBArea->getFreeze()==true) { histogramRGBArea->updateFreeze(false); }
|
||||
else {
|
||||
if (histogramRGBArea->getShow()==true) {
|
||||
histogramRGBArea->updateFreeze(true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void HistogramPanel::pointerMoved (bool validPos, Glib::ustring profile, int x, int y, int r, int g, int b) {
|
||||
|
||||
if (!validPos) {
|
||||
// do something to un-show vertical bars
|
||||
histogramRGBArea->renderRGBMarks(-1, -1, -1);
|
||||
histogramRGBArea->queue_draw ();
|
||||
}
|
||||
else {
|
||||
// do something to show vertical bars
|
||||
histogramRGBArea->renderRGBMarks(r, g, b);
|
||||
histogramRGBArea->queue_draw ();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
// HistogramRGBArea
|
||||
HistogramRGBArea::HistogramRGBArea () :
|
||||
frozen(false), valid(false), showMode(true), rawMode(false), needLuma(true), needRed(true), needGreen(true), needBlue(true) {
|
||||
|
||||
harih = new HistogramRGBAreaIdleHelper;
|
||||
harih->harea = this;
|
||||
harih->destroyed = false;
|
||||
harih->pending = 0;
|
||||
|
||||
signal_style_changed().connect( sigc::mem_fun(*this, &HistogramRGBArea::styleChanged) );
|
||||
}
|
||||
|
||||
HistogramRGBArea::~HistogramRGBArea () {
|
||||
|
||||
if (harih->pending)
|
||||
harih->destroyed = true;
|
||||
else
|
||||
delete harih;
|
||||
}
|
||||
|
||||
bool HistogramRGBArea::getFreeze() {
|
||||
return(frozen);
|
||||
}
|
||||
|
||||
bool HistogramRGBArea::getShow() {
|
||||
return(showMode);
|
||||
}
|
||||
|
||||
void HistogramRGBArea::updateFreeze (bool f) {
|
||||
frozen = f;
|
||||
return;
|
||||
}
|
||||
|
||||
void HistogramRGBArea::renderRGBMarks (int r, int g, int b) {
|
||||
|
||||
if (!is_realized ())
|
||||
return;
|
||||
|
||||
if (frozen) {
|
||||
return;
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Window> window = get_window();
|
||||
int winx, winy, winw, winh, wind;
|
||||
window->get_geometry(winx, winy, winw, winh, wind);
|
||||
|
||||
overlay = Gdk::Pixmap::create (window, winw, winh, -1);
|
||||
Glib::RefPtr<Gdk::GC> ovrl = Gdk::GC::create(overlay);
|
||||
|
||||
Glib::RefPtr<Gtk::Style> style = get_style ();
|
||||
|
||||
if (!showMode) {
|
||||
ovrl->set_foreground (style->get_bg (Gtk::STATE_NORMAL));
|
||||
overlay->draw_rectangle (ovrl, true, 0, 0, winw, winh);
|
||||
if (rgbgc_ && overlay) {
|
||||
window->draw_drawable (rgbgc_, overlay, 0, 0, 0, 0, -1, -1); }
|
||||
return; }
|
||||
else {
|
||||
ovrl->set_foreground (style->get_fg (Gtk::STATE_NORMAL));
|
||||
overlay->draw_rectangle (ovrl, true, 0, 0, winw, winh);
|
||||
if (rgbgc_ && overlay) {
|
||||
window->draw_drawable (rgbgc_, overlay, 0, 0, 0, 0, -1, -1); }
|
||||
}
|
||||
|
||||
Cairo::RefPtr<Cairo::Context> cr = overlay->create_cairo_context();
|
||||
cr->set_line_width (1.0);
|
||||
|
||||
if ( r != -1 && g != -1 && b != -1 ) {
|
||||
if (needRed) {
|
||||
// Red
|
||||
cr->set_source_rgb(1.0, 0.0, 0.0);
|
||||
cr->move_to((int)(r*(winw/256.0)), 0);
|
||||
cr->line_to((int)(r*(winw/256.0)), winh-0);
|
||||
cr->stroke();
|
||||
}
|
||||
if (needGreen) {
|
||||
// Green
|
||||
cr->set_source_rgb(0.0, 1.0, 0.0);
|
||||
cr->move_to((int)(g*(winw/256.0)), 0);
|
||||
cr->line_to((int)(g*(winw/256.0)), winh-0);
|
||||
cr->stroke();
|
||||
}
|
||||
if (needBlue) {
|
||||
// Blue
|
||||
cr->set_source_rgb(0.0, 0.0, 1.0);
|
||||
cr->move_to((int)(b*(winw/256.0)), 0);
|
||||
cr->line_to((int)(b*(winw/256.0)), winh-0);
|
||||
cr->stroke();
|
||||
}
|
||||
if (needLuma) {
|
||||
// Luma
|
||||
cr->set_source_rgb(1.0, 1.0, 1.0);
|
||||
cr->move_to((int)((r+g+b)/3*(winw/256.0)), 0);
|
||||
cr->line_to((int)((r+g+b)/3*(winw/256.0)), winh-0);
|
||||
cr->stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int histrgbupdate (void* data) {
|
||||
|
||||
gdk_threads_enter ();
|
||||
|
||||
HistogramRGBAreaIdleHelper* harih = (HistogramRGBAreaIdleHelper*)data;
|
||||
|
||||
if (harih->destroyed) {
|
||||
if (harih->pending == 1)
|
||||
delete harih;
|
||||
else
|
||||
harih->pending--;
|
||||
gdk_threads_leave ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
harih->harea->renderRGBMarks(-1,-1,-1);
|
||||
harih->harea->queue_draw ();
|
||||
|
||||
harih->pending--;
|
||||
gdk_threads_leave ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HistogramRGBArea::update (int valh, int rh, int gh, int bh) {
|
||||
|
||||
if (valh) {
|
||||
val=valh;
|
||||
r=rh;
|
||||
g=gh;
|
||||
b=bh;
|
||||
valid = true;
|
||||
}
|
||||
else
|
||||
valid = false;
|
||||
|
||||
harih->pending++;
|
||||
g_idle_add (histrgbupdate, harih);
|
||||
}
|
||||
|
||||
void HistogramRGBArea::updateOptions (bool r, bool g, bool b, bool l, bool raw, bool show) {
|
||||
|
||||
needRed = r;
|
||||
needGreen = g;
|
||||
needBlue = b;
|
||||
needLuma = l;
|
||||
rawMode = raw;
|
||||
showMode = show;
|
||||
|
||||
// Histogram RGB BAR button logic goes here
|
||||
|
||||
// Disable bar button when RAW histogram is displayed
|
||||
if ( rawMode && showMode) {
|
||||
showMode = false;
|
||||
}
|
||||
|
||||
// When un-showing the bar, set the freeze state to off
|
||||
if (!showMode) {
|
||||
updateFreeze(false);
|
||||
}
|
||||
}
|
||||
|
||||
void HistogramRGBArea::on_realize () {
|
||||
|
||||
Gtk::DrawingArea::on_realize();
|
||||
Glib::RefPtr<Gdk::Window> window = get_window();
|
||||
rgbgc_ = Gdk::GC::create(window);
|
||||
add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK);
|
||||
|
||||
Glib::RefPtr<Gdk::Colormap> rgbcolormap = get_default_colormap();
|
||||
black = Gdk::Color ("black");
|
||||
red = Gdk::Color ("red");
|
||||
green = Gdk::Color ("green");
|
||||
blue = Gdk::Color ("blue");
|
||||
lgray = Gdk::Color ("gray75");
|
||||
mgray = Gdk::Color ("gray50");
|
||||
dgray = Gdk::Color ("gray25");
|
||||
rgbcolormap->alloc_color(black);
|
||||
rgbcolormap->alloc_color(white);
|
||||
rgbcolormap->alloc_color(red);
|
||||
rgbcolormap->alloc_color(green);
|
||||
rgbcolormap->alloc_color(blue);
|
||||
rgbcolormap->alloc_color(lgray);
|
||||
rgbcolormap->alloc_color(mgray);
|
||||
rgbcolormap->alloc_color(dgray);
|
||||
|
||||
}
|
||||
|
||||
bool HistogramRGBArea::on_expose_event(GdkEventExpose* event) {
|
||||
|
||||
Glib::RefPtr<Gdk::Window> window = get_window();
|
||||
|
||||
// on_realize & RenderRGBMarks have to be called before
|
||||
if (rgbgc_ && overlay) {
|
||||
window->draw_drawable (rgbgc_, overlay, 0, 0, 0, 0, -1, -1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HistogramRGBArea::on_button_press_event (GdkEventButton* event) {
|
||||
|
||||
if (event->type==GDK_2BUTTON_PRESS && event->button==1) {
|
||||
// do something. Maybe un-freeze ?
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HistogramRGBArea::styleChanged (const Glib::RefPtr<Gtk::Style>& style) {
|
||||
|
||||
white = get_style()->get_base(Gtk::STATE_NORMAL);
|
||||
queue_draw ();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
// HistogramArea
|
||||
HistogramArea::HistogramArea () :
|
||||
valid(false), showFull(true), oldwidth(-1), needLuma(true), needRed(true), needGreen(true), needBlue(true), rawMode(false) {
|
||||
|
||||
lhist(256);
|
||||
rhist(256);
|
||||
ghist(256);
|
||||
bhist(256);
|
||||
|
||||
haih = new HistogramAreaIdleHelper;
|
||||
haih->harea = this;
|
||||
haih->destroyed = false;
|
||||
@@ -350,4 +657,3 @@ bool HistogramArea::on_button_press_event (GdkEventButton* event) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user