diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 318f1e05e..7a43bac14 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -835,12 +835,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, cont, lumar, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, avg, sca); - - if (locallListener) { - locallListener->refChanged(huer, lumar, chromar); + if (sp == params.locallab.selspot) { + if (locallListener) { + locallListener->refChanged(huer, lumar, chromar); + } } - // Locallab tools computation /* Notes: * - shbuffer is used as nullptr diff --git a/rtgui/curveeditor.cc b/rtgui/curveeditor.cc index 3d1223bdf..795378d7c 100644 --- a/rtgui/curveeditor.cc +++ b/rtgui/curveeditor.cc @@ -247,6 +247,7 @@ CurveEditor::CurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEd { bgHistValid = false; + locallabRef = 0.0; remoteDrag = false; selected = DCT_Linear; bottomBarCP = nullptr; @@ -321,6 +322,19 @@ void CurveEditor::updateBackgroundHistogram(const LUTu& hist) subGroup->updateBackgroundHistogram(this); } +/* + * Update Locallab reference value displayed in the background + */ +void CurveEditor::updateLocallabBackground(double ref) +{ + // Copy Locallab reference value in the curve editor cache + locallabRef = ref; + + // Then call the curve editor group to eventually update the histogram + subGroup->updateLocallabBackground(this); +} + + // Open up the curve if it has modifications and it's not already opened // Returns: true if curve was non linear and opened bool CurveEditor::openIfNonlinear() diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h index 4cf49a377..64dfce9c9 100644 --- a/rtgui/curveeditor.h +++ b/rtgui/curveeditor.h @@ -58,7 +58,7 @@ protected: PopUpToggleButton* curveType; LUTu histogram; // histogram values bool bgHistValid; - + double locallabRef; // Locallab reference value bool remoteDrag; int selected; @@ -94,7 +94,7 @@ public: bool isUnChanged (); void setUnChanged (bool uc); void updateBackgroundHistogram(const LUTu& hist); - + void updateLocallabBackground(double ref); void setLeftBarColorProvider(ColorProvider* cp, int callerId); void setBottomBarColorProvider(ColorProvider* cp, int callerId); void setCurveColorProvider(ColorProvider* cp, int callerId); diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index 4e5f038d6..2ef44a211 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -269,6 +269,7 @@ void CurveEditorGroup::curveTypeToggled(CurveEditor* ce) if (ct < ce->subGroup->valUnchanged) { ce->subGroup->restoreDisplayedHistogram(); + ce->subGroup->restoreLocallabBackground(); } } else { // The button is now released, so we have to hide this CurveEditor diff --git a/rtgui/curveeditorgroup.h b/rtgui/curveeditorgroup.h index 80a1a95a4..721e71d02 100644 --- a/rtgui/curveeditorgroup.h +++ b/rtgui/curveeditorgroup.h @@ -136,6 +136,7 @@ public: } void updateEditButton(CurveEditor* curve, Gtk::ToggleButton *button, sigc::connection &connection); virtual void updateBackgroundHistogram (CurveEditor* ce) {} + virtual void updateLocallabBackground(CurveEditor* ce) {}; virtual void switchGUI() = 0; virtual void refresh(CurveEditor *curveToRefresh) = 0; virtual void editModeSwitchedOff() = 0; @@ -165,6 +166,7 @@ protected: virtual void storeCurveValues (CurveEditor* ce, const std::vector& p) = 0; virtual void storeDisplayedCurve () = 0; virtual void restoreDisplayedHistogram() {}; + virtual void restoreLocallabBackground() {}; virtual void removeEditor () = 0; virtual const std::vector getCurveFromGUI (int type) = 0; diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 376bb55c2..a6b9416d7 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -554,6 +554,13 @@ void FlatCurveEditorSubGroup::restoreDisplayedHistogram() } +void FlatCurveEditorSubGroup::restoreLocallabBackground() +{ + if (parent->displayedCurve) { + CPointsCurve->updateLocallabBackground(parent->displayedCurve->locallabRef); + } +} + void FlatCurveEditorSubGroup::storeCurveValues (CurveEditor* ce, const std::vector& p) { if (!p.empty()) { @@ -627,6 +634,13 @@ bool FlatCurveEditorSubGroup::curveReset(CurveEditor *ce) return true; } +void FlatCurveEditorSubGroup::updateLocallabBackground(CurveEditor* ce) +{ + if (ce == parent->displayedCurve) { + CPointsCurve->updateLocallabBackground(ce->locallabRef); + } +} + /*void FlatCurveEditorSubGroup::updateBackgroundHistogram (CurveEditor* ce) { CurveEditor* fce = (CurveEditor*)ce; if (fce==displayedCurve) { diff --git a/rtgui/flatcurveeditorsubgroup.h b/rtgui/flatcurveeditorsubgroup.h index ab2abedfb..f31ad5bbc 100644 --- a/rtgui/flatcurveeditorsubgroup.h +++ b/rtgui/flatcurveeditorsubgroup.h @@ -50,6 +50,7 @@ public: FlatCurveEditor* addCurve(Glib::ustring curveLabel = "", bool periodic = true); //virtual void updateBackgroundHistogram (CurveEditor* ce); + void updateLocallabBackground(CurveEditor* ce) override; void switchGUI() override; void refresh(CurveEditor *curveToRefresh) override; void editModeSwitchedOff() override; @@ -66,6 +67,7 @@ protected: void storeCurveValues (CurveEditor* ce, const std::vector& p) override; void storeDisplayedCurve () override; void restoreDisplayedHistogram () override; + void restoreLocallabBackground() override; void savePressed (); void loadPressed (); void copyPressed (); diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 5d4116683..bbc61719e 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -53,11 +53,11 @@ Locallab::Locallab(): expsoft(new MyExpander(true, M("TP_LOCALLAB_SOFT"))), expblur(new MyExpander(true, M("TP_LOCALLAB_BLUFR"))), exptonemap(new MyExpander(true, M("TP_LOCALLAB_TM"))), - expreti(new MyExpander(true, M("TP_LOCALLAB_RETI"))), - expsharp(new MyExpander(true, M("TP_LOCALLAB_SHARP"))), + expreti(new MyExpander(true, new Gtk::HBox())), + expsharp(new MyExpander(true, new Gtk::HBox())), expcontrast(new MyExpander(true, M("TP_LOCALLAB_LOC_CONTRAST"))), - expcbdl(new MyExpander(true, M("TP_LOCALLAB_CBDL"))), - expdenoi(new MyExpander(true, M("TP_LOCALLAB_DENOIS"))), + expcbdl(new MyExpander(true, new Gtk::HBox())), + expdenoi(new MyExpander(true, new Gtk::HBox())), // CurveEditorGroup widgets @@ -201,8 +201,6 @@ Locallab::Locallab(): lumacontrastMinusButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS")))), lumaneutralButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMANEUTRAL")))), lumacontrastPlusButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS")))), - transLabels(Gtk::manage(new Gtk::Label("---"))), - transLabels2(Gtk::manage(new Gtk::Label("---"))), maskcolFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHOW")))), maskexpFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHOW")))), gridFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LABGRID")))), @@ -210,10 +208,7 @@ Locallab::Locallab(): // Others defparams(nullptr), defpedited(nullptr), - pe(nullptr), - nexthuer(0.), - nextlumar(0.), - nextchromar(0.) + pe(nullptr) { ToolVBox* const panel = Gtk::manage(new ToolVBox()); @@ -389,8 +384,9 @@ Locallab::Locallab(): colorBox->pack_start(*invers); maskcolFrame->set_label_align(0.025, 0.5); ToolParamBlock* const maskcolBox = Gtk::manage(new ToolParamBlock()); - maskcolBox->pack_start(*transLabels, Gtk::PACK_SHRINK, 4); - maskcolBox->pack_start(*showmaskcolMethod, Gtk::PACK_SHRINK, 0); +// maskcolBox->pack_start(*transLabels, Gtk::PACK_SHRINK, 4); +// maskcolBox->pack_start(*showmaskcolMethod, Gtk::PACK_SHRINK, 0); + maskcolBox->pack_start(*showmaskcolMethod, Gtk::PACK_SHRINK, 4); maskcolBox->pack_start(*enaColorMask, Gtk::PACK_SHRINK, 0); maskcolBox->pack_start(*maskCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor maskcolBox->pack_start(*blendmaskcol, Gtk::PACK_SHRINK, 0); @@ -495,8 +491,9 @@ Locallab::Locallab(): exposeBox->pack_start(*inversex); maskexpFrame->set_label_align(0.025, 0.5); ToolParamBlock* const maskexpBox = Gtk::manage(new ToolParamBlock()); - maskexpBox->pack_start(*transLabels2, Gtk::PACK_SHRINK, 4); - maskexpBox->pack_start(*showmaskexpMethod, Gtk::PACK_SHRINK, 0); + maskexpBox->pack_start(*showmaskexpMethod, Gtk::PACK_SHRINK, 4); +// maskexpBox->pack_start(*transLabels2, Gtk::PACK_SHRINK, 4); +// maskexpBox->pack_start(*showmaskexpMethod, Gtk::PACK_SHRINK, 0); maskexpBox->pack_start(*enaExpMask, Gtk::PACK_SHRINK, 0); maskexpBox->pack_start(*maskexpCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor maskexpBox->pack_start(*blendmaskexp, Gtk::PACK_SHRINK, 0); @@ -663,9 +660,18 @@ Locallab::Locallab(): exptonemap->add(*tmBox); exptonemap->setLevel(2); - // panel->pack_start(*exptonemap, false, false); +// panel->pack_start(*exptonemap, false, false); // Retinex + Gtk::HBox* const retiTitleHBox = Gtk::manage(new Gtk::HBox()); + Gtk::Label* const retiLabel = Gtk::manage(new Gtk::Label()); + retiLabel->set_markup(Glib::ustring("") + escapeHtmlChars(M("TP_LOCALLAB_RETI")) + Glib::ustring("")); + retiLabel->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + retiTitleHBox->pack_start(*retiLabel, Gtk::PACK_EXPAND_WIDGET, 0); + RTImage *retiImage = Gtk::manage (new RTImage("one-to-one-small.png")); + retiImage->set_tooltip_text(M("TP_GENERAL_11SCALE_TOOLTIP")); + retiTitleHBox->pack_end(*retiImage, Gtk::PACK_SHRINK, 0); + expreti->setLabel(retiTitleHBox); expreti->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expreti)); enableretiConn = expreti->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expreti)); @@ -716,6 +722,16 @@ Locallab::Locallab(): panel->pack_start(*expreti, false, false); // Sharpening + Gtk::HBox* const sharpTitleHBox = Gtk::manage(new Gtk::HBox()); + Gtk::Label* const sharpLabel = Gtk::manage(new Gtk::Label()); + sharpLabel->set_markup(Glib::ustring("") + escapeHtmlChars(M("TP_LOCALLAB_SHARP")) + Glib::ustring("")); + sharpLabel->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + sharpTitleHBox->pack_start(*sharpLabel, Gtk::PACK_EXPAND_WIDGET, 0); + RTImage *sharpImage = Gtk::manage (new RTImage("one-to-one-small.png")); + sharpImage->set_tooltip_text(M("TP_GENERAL_11SCALE_TOOLTIP")); + sharpTitleHBox->pack_end(*sharpImage, Gtk::PACK_SHRINK, 0); + expsharp->setLabel(sharpTitleHBox); + expsharp->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expsharp)); enablesharpConn = expsharp->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expsharp)); @@ -776,6 +792,15 @@ Locallab::Locallab(): panel->pack_start(*expcontrast, false, false); // Contrast by detail levels + Gtk::HBox* const cbdlTitleHBox = Gtk::manage(new Gtk::HBox()); + Gtk::Label* const cbdlLabel = Gtk::manage(new Gtk::Label()); + cbdlLabel->set_markup(Glib::ustring("") + escapeHtmlChars(M("TP_LOCALLAB_CBDL")) + Glib::ustring("")); + cbdlLabel->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + cbdlTitleHBox->pack_start(*cbdlLabel, Gtk::PACK_EXPAND_WIDGET, 0); + RTImage *cbdlImage = Gtk::manage (new RTImage("one-to-one-small.png")); + cbdlImage->set_tooltip_text(M("TP_GENERAL_11SCALE_TOOLTIP")); + cbdlTitleHBox->pack_end(*cbdlImage, Gtk::PACK_SHRINK, 0); + expcbdl->setLabel(cbdlTitleHBox); expcbdl->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expcbdl)); enablecbdlConn = expcbdl->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expcbdl)); expcbdl->set_tooltip_text(M("TP_LOCALLAB_EXPCBDL_TOOLTIP")); @@ -827,6 +852,15 @@ Locallab::Locallab(): panel->pack_start(*expcbdl, false, false); // Denoise + Gtk::HBox* const denoiTitleHBox = Gtk::manage(new Gtk::HBox()); + Gtk::Label* const denoiLabel = Gtk::manage(new Gtk::Label()); + denoiLabel->set_markup(Glib::ustring("") + escapeHtmlChars(M("TP_LOCALLAB_DENOIS")) + Glib::ustring("")); + denoiLabel->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + denoiTitleHBox->pack_start(*denoiLabel, Gtk::PACK_EXPAND_WIDGET, 0); + RTImage *denoiImage = Gtk::manage (new RTImage("one-to-one-small.png")); + denoiImage->set_tooltip_text(M("TP_GENERAL_11SCALE_TOOLTIP")); + denoiTitleHBox->pack_end(*denoiImage, Gtk::PACK_SHRINK, 0); + expdenoi->setLabel(denoiTitleHBox); expdenoi->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expdenoi)); enabledenoiConn = expdenoi->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expdenoi)); @@ -998,59 +1032,44 @@ void Locallab::writeOptions(std::vector &tpOpen) } -void Locallab::refChanged(double huer, double lumar, double chromar) -{ - nexthuer = huer; - nextlumar = lumar / 100.f; - nextchromar = chromar / 137.4f; - float h = Color::huelab_to_huehsv2(nexthuer); - h += 1.f / 6.f; - - if (h > 1.f) { - h -= 1.f; - } - - nexthuer = h; - //printf("nh=%f nl=%f nc=%f\n", nexthuer, nextlumar, nextchromar); - - - idle_register.add( - [this]() -> bool { - GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected - // FIXME: The above can't be true?! - disableListener(); - enableListener(); - updateLabel(); - return false; - } - ); - - -} - - -void Locallab::updateLabel() +void Locallab::refChanged (double huer, double lumar, double chromar) { if (!batchMode) { - float nX, nY, nZ; - - nY = nextlumar; - nX = nextchromar; - nZ = nexthuer; - { - transLabels->set_text( - Glib::ustring::compose(M("TP_LOCALLAB_REFLABEL"), - Glib::ustring::format(std::fixed, std::setprecision(3), nX), - Glib::ustring::format(std::fixed, std::setprecision(3), nY), - Glib::ustring::format(std::fixed, std::setprecision(3), nZ)) - ); - transLabels2->set_text( - Glib::ustring::compose(M("TP_LOCALLAB_REFLABEL"), - Glib::ustring::format(std::fixed, std::setprecision(3), nX), - Glib::ustring::format(std::fixed, std::setprecision(3), nY), - Glib::ustring::format(std::fixed, std::setprecision(3), nZ)) - ); + // Hue reference normalization (between 0 and 1) + double normHuer = huer; + float h = Color::huelab_to_huehsv2(normHuer); + h += 1.f/6.f; + if (h > 1.f) { + h -= 1.f; } + normHuer = h; + + // Luma reference normalization (between 0 and 1) + double normLumar = lumar / 100.f; + + // Chroma reference normalization (between 0 and 1) + double normChromar = chromar / 137.4f; + + // printf("nh=%f nl=%f nc=%f\n", normHuer, normLumar, normChromar); + + idle_register.add( + [this, normHuer, normLumar, normChromar]() -> bool + { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update Color & Light mask background + CCmaskshape->updateLocallabBackground(normChromar); + LLmaskshape->updateLocallabBackground(normLumar); + HHmaskshape->updateLocallabBackground(normHuer); + + // Update Exposure mask background + CCmaskexpshape->updateLocallabBackground(normChromar); + LLmaskexpshape->updateLocallabBackground(normLumar); + HHmaskexpshape->updateLocallabBackground(normHuer); + + return false; + } + ); } } @@ -1091,7 +1110,7 @@ void Locallab::lumacontrastPlusPressed() for (int i = 0; i < 5; i++) { float inc = (5 - i); - multiplier[i]->setValue(multiplier[i]->getValue() + 0.01f * inc ); + multiplier[i]->setValue(multiplier[i]->getValue() + 0.01f * inc); } // Raise event (only for first multiplier because associated event concerns all multipliers) @@ -3198,6 +3217,7 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) } } + // Vibrance if (a == pastels && pastSatTog->get_active() && !(multiImage && pastSatTog->get_inconsistent())) { saturated->setValue(newval); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 1b3e32bbe..79b7d7fbc 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -232,8 +232,8 @@ private: Gtk::Button* const lumaneutralButton; Gtk::Button* const lumacontrastPlusButton; sigc::connection lumacontrastMinusPressedConn, lumaneutralPressedConn, lumacontrastPlusPressedConn; - Gtk::Label* transLabels; - Gtk::Label* transLabels2; +// Gtk::Label* transLabels; +// Gtk::Label* transLabels2; Gtk::Frame* maskcolFrame; Gtk::Frame* maskexpFrame; Gtk::Frame* gridFrame; @@ -301,9 +301,6 @@ private: void updateLocallabGUI(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited, int index); void updateSpecificGUIState(); void setParamEditable(bool cond); - double nexthuer; - double nextlumar; - double nextchromar; public: @@ -323,7 +320,6 @@ public: void writeOptions(std::vector &tpOpen); void updateToolState(std::vector &tpOpen); void refChanged(double huer, double lumar, double chromar); - void updateLabel(); // Mask visibility management functions struct llMaskVisibility { diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index 9b64ee516..dd2478da9 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -39,7 +39,8 @@ MyFlatCurve::MyFlatCurve () : deletedPointX(0.0), leftTanHandle({0.0, 0.0}), rightTanHandle({0.0, 0.0}), - draggingElement(false) + draggingElement(false), + locallabRef(0.0) { graphW = get_allocation().get_width() - RADIUS * 2; @@ -164,6 +165,19 @@ void MyFlatCurve::draw () Gdk::RGBA c; +// Draw Locallab reference value in the background + if (locallabRef > 0.0) { + cr->set_line_width(1.0); + cr->move_to(double(graphX + 1), double(graphY - 1)); + c = style->get_color(state); + cr->set_source_rgba(c.get_red(), c.get_green(), c.get_blue(), 0.2); + cr->line_to(double(graphX + 1), double(graphY - 1) - double(graphH - 2)); + cr->line_to(double(graphX) + 1.5 + locallabRef*double(graphW -2), double(graphY - 1) - double(graphH - 2)); + cr->line_to(double(graphX) + 1.5 + locallabRef*double(graphW -2), double(graphY - 1)); + cr->close_path(); + cr->fill(); + cr->stroke(); + } cr->set_line_width (1.0); // draw f(x)=0.5 line @@ -1872,6 +1886,35 @@ void MyFlatCurve::stopNumericalAdjustment() } } +void MyFlatCurve::updateLocallabBackground(double ref) +{ + locallabRef = ref; + + mcih->pending++; + + idle_register.add( + [this]() -> bool + { + if (mcih->destroyed) { + if (mcih->pending == 1) { + delete mcih; + } else { + --mcih->pending; + } + + return false; + } + + mcih->clearPixmap(); + mcih->myCurve->queue_draw(); + + --mcih->pending; + + return false; + } + ); +} + void MyFlatCurve::setType (FlatCurveType t) { diff --git a/rtgui/myflatcurve.h b/rtgui/myflatcurve.h index c0223bfcf..da7d8905f 100644 --- a/rtgui/myflatcurve.h +++ b/rtgui/myflatcurve.h @@ -76,6 +76,8 @@ public: class MyFlatCurve : public MyCurve { +private: + IdleRegister idle_register; protected: FlatCurveDescr curve; @@ -103,6 +105,7 @@ protected: enum EditedHandle editedHandle; bool draggingElement; enum MouseOverAreas area; + double locallabRef; // Locallab reference value to display in the background void draw (); void movePoint(bool moveX, bool moveY, bool pipetteDrag = false); @@ -137,6 +140,7 @@ public: void setPos(double pos, int chanIdx) override; void stopNumericalAdjustment() override; + void updateLocallabBackground(double ref); }; #endif