From e1d0a0025da020611aa04b19a509044685a4b801 Mon Sep 17 00:00:00 2001 From: michael Date: Sat, 24 Dec 2011 12:04:22 -0500 Subject: [PATCH] Preview modes: R,B,G channels and Luminosity (issue 1167) --- rtdata/languages/default | 6 ++ rtgui/CMakeLists.txt | 2 +- rtgui/cropwindow.cc | 65 +++++++++++++----- rtgui/editorpanel.cc | 5 +- rtgui/imagearea.cc | 1 + rtgui/imagearea.h | 2 + rtgui/indclippedpanel.cc | 6 +- rtgui/previewmodepanel.cc | 141 ++++++++++++++++++++++++++++++++++++++ rtgui/previewmodepanel.h | 55 +++++++++++++++ 9 files changed, 262 insertions(+), 21 deletions(-) create mode 100644 rtgui/previewmodepanel.cc create mode 100644 rtgui/previewmodepanel.h diff --git a/rtdata/languages/default b/rtdata/languages/default index 7ded1c447..ba2b2b277 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -475,6 +475,11 @@ MAIN_TOOLTIP_HIDEFP;Show/hide the bottom panel (directory and file browser) F MAIN_TOOLTIP_HIDEHP;Show/hide the left panel (including the history) l MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication (Key <) MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication (Key >) +MAIN_TOOLTIP_PREVIEWB;Preview Blue channel +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview Focus Mask +MAIN_TOOLTIP_PREVIEWG;Preview Green channel +MAIN_TOOLTIP_PREVIEWR;Preview Red channel +MAIN_TOOLTIP_PREVIEWL;Preview Luminosity\n0.299*R + 0.587*G + 0.114*B MAIN_TOOLTIP_PREFERENCES;Set preferences MAIN_TOOLTIP_QINFO;Quick info on the image I MAIN_TOOLTIP_SAVEAS;Save image to a selected folder @@ -483,6 +488,7 @@ MAIN_TOOLTIP_SHOWHIDELP1;Show/hide the left panel l MAIN_TOOLTIP_SHOWHIDERP1;Show/hide the right panel Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Show/hide the top panel Shift-l MAIN_TOOLTIP_TOGGLE;Toggle before/after view B +MAIN_TOOLTIP_THRESHOLD;Threshold NAVIGATOR_B_NA;B = n/a NAVIGATOR_B_VALUE;B = %1 NAVIGATOR_G_NA;G = n/a diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index ad9dd0a06..748b3ab08 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -1,6 +1,6 @@ set (BASESOURCEFILES - editwindow.cc batchtoolpanelcoord.cc paramsedited.cc cropwindow.cc previewhandler.cc previewwindow.cc navigator.cc indclippedpanel.cc filterpanel.cc + editwindow.cc batchtoolpanelcoord.cc paramsedited.cc cropwindow.cc previewhandler.cc previewwindow.cc navigator.cc indclippedpanel.cc previewmodepanel.cc filterpanel.cc cursormanager.cc rtwindow.cc renamedlg.cc recentbrowser.cc placesbrowser.cc filepanel.cc editorpanel.cc batchqueuepanel.cc ilabel.cc thumbbrowserbase.cc adjuster.cc filebrowserentry.cc filebrowser.cc filethumbnailbuttonset.cc cachemanager.cc cacheimagedata.cc shcselector.cc perspective.cc diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index af45eb3ae..b256da072 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -677,6 +677,16 @@ void CropWindow::expose (Cairo::RefPtr cr) { //t3.set (); bool showcs = iarea->indClippedPanel->showClippedShadows(); bool showch = iarea->indClippedPanel->showClippedHighlights(); + bool showR = iarea->previewModePanel->showR(); + bool showG = iarea->previewModePanel->showG(); + bool showB = iarea->previewModePanel->showB(); + bool showL = iarea->previewModePanel->showL(); + bool showFocusMask = iarea->previewModePanel->showFocusMask(); + // additional flags to control clipping indicators for individual channels and across all channels + bool showclippedAll = (!showR && !showG && !showB && !showL); + bool showclippedR = showR || showL || showclippedAll; + bool showclippedG = showG || showL || showclippedAll; + bool showclippedB = showB || showL || showclippedAll; // If ALT was pressed, auto-enable highlight and shadow // TODO: Add linux/MacOS specific functions for alternative @@ -686,7 +696,7 @@ void CropWindow::expose (Cairo::RefPtr cr) { } #endif - if (showcs || showch) { + if (showcs || showch || showR || showG || showB || showL /*|| showFocusMask*/) { Glib::RefPtr tmp = cropHandler.cropPixbuf->copy (); guint8* pix = tmp->get_pixels(); guint8* pixWrkSpace = cropHandler.cropPixbuftrue->get_pixels(); @@ -704,36 +714,59 @@ void CropWindow::expose (Cairo::RefPtr cr) { guint8* curr = pix + i*pixRowStride; guint8* currWS = pixWrkSpace + i*pixWSRowStride; - int delta; bool changed; + int delta; bool changedHL; bool changedSH; for (int j=0; jget_width(); j++) { // we must compare clippings in working space, since the cropPixbuf is in sRGB, with mon profile + changedHL=false; + changedSH=false; + if (showch) { - delta=0; changed=false; + delta=0; changedHL=false; - if (currWS[0]>=options.highlightThreshold) { delta += 255-currWS[0]; changed=true; } - if (currWS[1]>=options.highlightThreshold) { delta += 255-currWS[1]; changed=true; } - if (currWS[2]>=options.highlightThreshold) { delta += 255-currWS[2]; changed=true; } + if (currWS[0]>=options.highlightThreshold && showclippedR) { delta += 255-currWS[0]; changedHL=true; } + if (currWS[1]>=options.highlightThreshold && showclippedG) { delta += 255-currWS[1]; changedHL=true; } + if (currWS[2]>=options.highlightThreshold && showclippedB) { delta += 255-currWS[2]; changedHL=true; } - if (changed) { + if (changedHL) { delta *= HighlightFac; - curr[0]=curr[1]=curr[2]=delta; + if (showclippedAll) curr[0]=curr[1]=curr[2]=delta; // indicate clipped highlights in gray + else {curr[0]=255; curr[1]=curr[2]=delta;} // indicate clipped highlights in red } } if (showcs) { - delta=0; changed=false; - - if (currWS[0]<=options.shadowThreshold) { delta += currWS[0]; changed=true; } - if (currWS[1]<=options.shadowThreshold) { delta += currWS[1]; changed=true; } - if (currWS[2]<=options.shadowThreshold) { delta += currWS[2]; changed=true; } + delta=0; changedSH=false; + if (currWS[0]<=options.shadowThreshold && showclippedR) { delta += currWS[0]; changedSH=true; } + if (currWS[1]<=options.shadowThreshold && showclippedG) { delta += currWS[1]; changedSH=true; } + if (currWS[2]<=options.shadowThreshold && showclippedB) { delta += currWS[2]; changedSH=true; } - if (changed) { - delta = 255 - (delta * ShawdowFac); - curr[0]=curr[1]=curr[2]=delta; + if (changedSH) { + if (showclippedAll) { + delta = 255 - (delta * ShawdowFac); + curr[0]=curr[1]=curr[2]=delta; // indicate clipped shadows in gray + } + else { + delta *= ShawdowFac; + curr[2]=255; curr[0]=curr[1]=delta; // indicate clipped shadows in blue + } + } + } //if (showcs) + + // modulate the preview of channels & L; + if (!changedHL && !changedSH){ //This condition allows clipping indicators for RGB channels to remain in color + if (showR) curr[1]=curr[2]=curr[0]; //Red channel in grayscale + if (showG) curr[0]=curr[2]=curr[1]; //Green channel in grayscale + if (showB) curr[0]=curr[1]=curr[2]; //Blue channel in grayscale + if (showL) { //Luminosity + // see http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness for more info + //int L = (int)(0.212671*curr[0]+0.715160*curr[1]+0.072169*curr[2]); + int L = (int)(0.299*curr[0]+0.587*curr[1]+0.114*curr[2]); //Lightness - this matches Luminance mode in Photoshop CS5 + curr[0]=curr[1]=curr[2]=L; } } + //if (showFocusMask){}; TODO add display of focus mask here /* if (showch && (currWS[0]>=options.highlightThreshold || currWS[1]>=options.highlightThreshold || currWS[2]>=options.highlightThreshold)) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index af7f4390b..34bb4fd8d 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -126,6 +126,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) Gtk::VSeparator* vsepcl = Gtk::manage (new Gtk::VSeparator ()); Gtk::VSeparator* vsepz2 = Gtk::manage (new Gtk::VSeparator ()); Gtk::VSeparator* vsepz3 = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepz4 = Gtk::manage (new Gtk::VSeparator ()); iarea = new ImageAreaPanel (); @@ -144,6 +145,8 @@ EditorPanel::EditorPanel (FilePanel* filePanel) toolBarPanel->pack_end (*vsepcl, Gtk::PACK_SHRINK, 2); toolBarPanel->pack_end (*iarea->imageArea->indClippedPanel, Gtk::PACK_SHRINK, 0); toolBarPanel->pack_end (*vsepz, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_end (*iarea->imageArea->previewModePanel, Gtk::PACK_SHRINK, 0); + toolBarPanel->pack_end (*vsepz4, Gtk::PACK_SHRINK, 2); afterBox = Gtk::manage (new Gtk::VBox ()); afterBox->pack_start (*iarea); @@ -849,7 +852,7 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) { case GDK_greater: iarea->imageArea->indClippedPanel->toggleClipped(false); return true; - +//TODO add shortcuts for previewModePanel buttons case GDK_F5: openThm->openDefaultViewer(event->state & GDK_SHIFT_MASK ? 2 : 1); return true; diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 498a84136..477084fd6 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -42,6 +42,7 @@ ImageArea::ImageArea (ImageAreaPanel* p) : parent(p) { zoomPanel = Gtk::manage (new ZoomPanel (this)); indClippedPanel = Gtk::manage (new IndicateClippedPanel (this)); + previewModePanel = Gtk::manage (new PreviewModePanel (this)); signal_style_changed().connect( sigc::mem_fun(*this, &ImageArea::styleChanged) ); signal_size_allocate().connect( sigc::mem_fun(*this, &ImageArea::on_resized) ); diff --git a/rtgui/imagearea.h b/rtgui/imagearea.h index 4f6447228..45f975e6b 100644 --- a/rtgui/imagearea.h +++ b/rtgui/imagearea.h @@ -29,6 +29,7 @@ #include "cropwindow.h" #include "zoompanel.h" #include "indclippedpanel.h" +#include "previewmodepanel.h" class ImageAreaPanel; class ImageArea : public Gtk::DrawingArea, public CropWindowListener { @@ -64,6 +65,7 @@ class ImageArea : public Gtk::DrawingArea, public CropWindowListener { CropWindow* mainCropWindow; ZoomPanel* zoomPanel; IndicateClippedPanel* indClippedPanel; + PreviewModePanel* previewModePanel; ImageArea (ImageAreaPanel* p); ~ImageArea (); diff --git a/rtgui/indclippedpanel.cc b/rtgui/indclippedpanel.cc index 8fed6a8f4..5865e60fb 100644 --- a/rtgui/indclippedpanel.cc +++ b/rtgui/indclippedpanel.cc @@ -28,14 +28,14 @@ IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : imageArea(ia) { indclippedh = Gtk::manage (new Gtk::ToggleButton ()); indclippedh->set_relief(Gtk::RELIEF_NONE); indclippedh->add (*Gtk::manage (new RTImage ("warnhl.png"))); - tt = M("MAIN_TOOLTIP_INDCLIPPEDH"); + tt = Glib::ustring::compose("%1\n%2 = %3",M("MAIN_TOOLTIP_INDCLIPPEDH"),M("MAIN_TOOLTIP_THRESHOLD"),options.highlightThreshold); if (tt.find("<") == Glib::ustring::npos && tt.find(">") == Glib::ustring::npos) indclippedh->set_tooltip_text (tt); else indclippedh->set_tooltip_markup (tt); indclippeds = Gtk::manage (new Gtk::ToggleButton ()); indclippeds->set_relief(Gtk::RELIEF_NONE); - indclippeds->add (*Gtk::manage (new RTImage ("warnsh.png"))); - tt = M("MAIN_TOOLTIP_INDCLIPPEDS"); + indclippeds->add (*Gtk::manage (new RTImage ("warnsh.png"))); + tt = Glib::ustring::compose("%1\n%2 = %3",M("MAIN_TOOLTIP_INDCLIPPEDS"),M("MAIN_TOOLTIP_THRESHOLD"),options.shadowThreshold); if (tt.find("<") == Glib::ustring::npos && tt.find(">") == Glib::ustring::npos) indclippeds->set_tooltip_text (tt); else indclippeds->set_tooltip_markup (tt); diff --git a/rtgui/previewmodepanel.cc b/rtgui/previewmodepanel.cc new file mode 100644 index 000000000..2c90439c5 --- /dev/null +++ b/rtgui/previewmodepanel.cc @@ -0,0 +1,141 @@ +/* + * This file is part of RawTherapee. + * + * + * RawTherapee 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 3 of the License, or + * (at your option) any later version. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include "previewmodepanel.h" +#include "options.h" +#include "multilangmgr.h" +#include "imagearea.h" +#include "rtimage.h" + +PreviewModePanel::PreviewModePanel (ImageArea* ia) : imageArea(ia) { + + previewR = Gtk::manage (new Gtk::ToggleButton ("R")); + previewR->set_relief(Gtk::RELIEF_NONE); + previewR->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWR")); + + previewG = Gtk::manage (new Gtk::ToggleButton ("G")); + previewG->set_relief(Gtk::RELIEF_NONE); + previewG->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWG")); + + previewB = Gtk::manage (new Gtk::ToggleButton ("B")); + previewB->set_relief(Gtk::RELIEF_NONE); + previewB->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWB")); + + previewL = Gtk::manage (new Gtk::ToggleButton ("L")); + previewL->set_relief(Gtk::RELIEF_NONE); + previewL->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWL")); + + previewFocusMask = Gtk::manage (new Gtk::ToggleButton ("F")); + previewFocusMask->set_relief(Gtk::RELIEF_NONE); + previewFocusMask->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWFOCUSMASK")); + previewFocusMask->hide();//TODO re-enable when Focus Mask is developed + + previewR->set_active (false); + previewG->set_active (false); + previewB->set_active (false); + previewL->set_active (false); + previewFocusMask->set_active (false); + + pack_start (*previewR, Gtk::PACK_SHRINK, 0); + pack_start (*previewG, Gtk::PACK_SHRINK, 0); + pack_start (*previewB, Gtk::PACK_SHRINK, 0); + pack_start (*previewL, Gtk::PACK_SHRINK, 0); + //pack_start (*previewFocusMask, Gtk::PACK_SHRINK, 0); //TODO re-enable when Focus Mask is developed + + connR = previewR->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled),previewR) ); + connG = previewG->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled),previewG) ); + connB = previewB->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled),previewB) ); + connL = previewL->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled),previewL) ); + connFocusMask = previewFocusMask->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled),previewFocusMask) ); + + //show_all (); +} + +//TODO: use functions below for shortcuts +void PreviewModePanel::toggleR () { + +} +void PreviewModePanel::toggleG () { + +} +void PreviewModePanel::toggleB () { + +} +void PreviewModePanel::toggleL () { + +} +void PreviewModePanel::toggleFocusMask () { + +} + +void PreviewModePanel::buttonToggled (Gtk::ToggleButton* tbpreview) { + // only 0 or 1 button at a time can remain pressed + + connR.block(true); + connG.block(true); + connB.block(true); + connL.block(true); + connFocusMask.block(true); + + if (tbpreview==previewR){ + // + previewG->set_active(false); + previewB->set_active(false); + previewL->set_active(false); + previewFocusMask->set_active(false); + } + + if (tbpreview==previewG){ + previewR->set_active(false); + // + previewB->set_active(false); + previewL->set_active(false); + previewFocusMask->set_active(false); + } + + if (tbpreview==previewB){ + previewR->set_active(false); + previewG->set_active(false); + // + previewL->set_active(false); + previewFocusMask->set_active(false); + } + + if (tbpreview==previewL){ + previewR->set_active(false); + previewG->set_active(false); + previewB->set_active(false); + // + previewFocusMask->set_active(false); + } + + if (tbpreview==previewFocusMask){ + previewR->set_active(false); + previewG->set_active(false); + previewB->set_active(false); + previewL->set_active(false); + // + } + + connR.block(false); + connG.block(false); + connB.block(false); + connL.block(false); + connFocusMask.block(false); + + imageArea->queue_draw (); +} diff --git a/rtgui/previewmodepanel.h b/rtgui/previewmodepanel.h new file mode 100644 index 000000000..d7f10a1ba --- /dev/null +++ b/rtgui/previewmodepanel.h @@ -0,0 +1,55 @@ +/* + * This file is part of RawTherapee. + * + * + * RawTherapee 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 3 of the License, or + * (at your option) any later version. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PREVIEWMODEPANEL_ +#define _PREVIEWMODEPANEL_ + +#include + +class ImageArea; +class PreviewModePanel : public Gtk::HBox { + + protected: + Gtk::ToggleButton* previewR; + Gtk::ToggleButton* previewG; + Gtk::ToggleButton* previewB; + Gtk::ToggleButton* previewL; + Gtk::ToggleButton* previewFocusMask; + ImageArea* imageArea; + + public: + PreviewModePanel (ImageArea* ia); + + void toggleR (); + void toggleG (); + void toggleB (); + void toggleL (); + void toggleFocusMask (); + + sigc::connection connR, connB, connG, connL, connFocusMask; + + void buttonToggled(Gtk::ToggleButton* tbpreview); + + bool showR () { return previewR->get_active (); } + bool showG () { return previewG->get_active (); } + bool showB () { return previewB->get_active (); } + bool showL () { return previewL->get_active (); } + bool showFocusMask () { return previewFocusMask->get_active (); } + +}; + +#endif