diff --git a/rtdata/languages/default b/rtdata/languages/default index 458d17a3f..6199d176f 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -851,8 +851,8 @@ HISTORY_MSG_600;Local - Soft Light enable HISTORY_MSG_601;Local - Soft Light strength HISTORY_MSG_602;Local - Soft Light scope HISTORY_MSG_603;Local - Sh Blur radius -HISTORY_MSG_605;Local - Color Modifications -HISTORY_MSG_606;Local - Exp Modifications +HISTORY_MSG_605;Local - Mask preview choice +HISTORY_MSG_606;Local Spot selected HISTORY_MSG_607;Local - Color Mask C HISTORY_MSG_608;Local - Color Mask L HISTORY_MSG_609;Local - Exp Mask C diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 1bda60307..6c30e6d35 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -873,13 +873,14 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . * 2017 2018 Jacques Desmis - * 2018 Pierre Cabrera + * 2019 Pierre Cabrera */ float **shbuffer = nullptr; int sca = 1; double huere, chromare, lumare, huerefblu, chromarefblu, lumarefblu, sobelre; float avge; + std::vector locallref; for (int sp = 0; sp < params->locallab.nbspot && sp < (int)params->locallab.spots.size(); sp++) { // Set local curves of current spot to LUT @@ -959,35 +960,26 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, avg, sca); - // Locallab mask curve references are only shown for selected spot - if (sp == params->locallab.selspot) { - if (locallListener) { - locallListener->refChanged(huer, lumar, chromar); - } - } + // Save Locallab mask curve references for current spot + LocallabListener::locallabRef spotref; + spotref.huer = huer; + spotref.lumar = lumar; + spotref.chromar = chromar; + locallref.push_back(spotref); // Locallab tools computation /* Notes: * - shbuffer is used as nullptr */ - // Locallab mask are only shown for selected spot - if (sp == params->locallab.selspot) { - ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, - locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, - locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, - locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, - locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, - locwavCurve, - LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, locallColorMask, locallExpMask, locallSHMask, locallcbMask, locallretiMask, locallsoftMask, localltmMask); - } else { - ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, - locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, - locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, - locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, - locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, - locwavCurve, - LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, 0, 0, 0, 0, 0, 0, 0); - } + // Locallab mask is only showed in detailed image + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, + locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, + locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, + locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, + locwavCurve, + LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, 0, 0, 0, 0, 0, 0, 0); + //recalculate references after if (params->locallab.spots.at(sp).spotMethod == "exc") { ipf.calc_ref(sp, reserv, reserv, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, avg); @@ -1025,6 +1017,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lochhmastmCurve.Reset(); } + + // Transmit Locallab reference values to LocallabListener + if (locallListener) { + locallListener->refChanged(locallref, params->locallab.selspot); + } } //************************************************************* diff --git a/rtengine/procevents.h b/rtengine/procevents.h index c294d27f4..1d54ed3f0 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -631,8 +631,8 @@ enum ProcEventCode { Evlocallabsensisf = 601, Evlocallabsharblur = 602, EvLocenalabregion = 603, - EvlocallabshowmaskcolMethod = 604, - EvlocallabshowmaskexpMethod = 605, + EvlocallabshowmaskMethod = 604, + EvLocallabSpotSelectedWithMask = 605, EvlocallabCCmaskshape = 606, EvlocallabLLmaskshape = 607, EvlocallabCCmaskexpshape = 608, @@ -662,7 +662,7 @@ enum ProcEventCode { Evlocallabsensihs = 632, Evlocallabradmaskcol = 633, Evlocallabradmaskexp = 634, - EvlocallabshowmaskSHMethod = 635, +// EvlocallabshowmaskSHMethod = 635, EvlocallabCCmaskSHshape = 636, EvlocallabLLmaskSHshape = 637, EvlocallabHHmaskSHshape = 638, @@ -700,7 +700,7 @@ enum ProcEventCode { EvlocallabLLmaskcbshape = 670, EvlocallabHHmaskcbshape = 671, EvLocallabEnacbMask = 672, - EvlocallabshowmaskcbMethod = 673, +// EvlocallabshowmaskcbMethod = 673, Evlocallabsoftradiustm = 674, EvLocallabSpotTransitgrad = 675, Evlocallabamount = 676, @@ -714,7 +714,7 @@ enum ProcEventCode { Evlocallabchromaskreti = 684, Evlocallabgammaskreti = 685, Evlocallabslomaskreti = 686, - EvlocallabshowmaskretiMethod = 687, +// EvlocallabshowmaskretiMethod = 687, EvLocallabEnaretiMasktmap = 688, Evlocallabscalereti = 689, Evlocallabdarkness = 690, @@ -726,7 +726,7 @@ enum ProcEventCode { Evlocallabequiltm = 696, Evlocallabfftwlc = 697, Evlocallabfftwreti = 698, - EvlocallabshowmasksoftMethod = 699, +// EvlocallabshowmasksoftMethod = 699, Evlocallabshadex = 700, EvlocallabexpMethod = 701, Evlocallablaplacexp = 702, @@ -741,7 +741,7 @@ enum ProcEventCode { Evlocallabchromasktm = 711, Evlocallabgammasktm = 712, Evlocallabslomasktm = 713, - EvlocallabshowmasktmMethod = 714, +// EvlocallabshowmasktmMethod = 714, EvlocallablocalcontMethod = 715, EvlocallabwavCurve = 716, Evlocallablevelwav = 717, diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 632f27075..cc8f67cc6 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -523,7 +523,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { 0, // unused LUMINANCECURVE, // EvLocallabSpotCreated LUMINANCECURVE, // EvLocallabSpotDeleted - LUMINANCECURVE, // EvLocallabSpotSelected + M_VOID, // EvLocallabSpotSelected M_VOID, // EvLocallabSpotName M_VOID, // EvLocallabSpotVisibility LUMINANCECURVE, // EvLocallabSpotShape @@ -631,8 +631,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvLocallabsensisf LUMINANCECURVE, // Evlocallabsharblur LUMINANCECURVE, // EvLocenalabregion - LUMINANCECURVE, // EvlocallabshowmaskcolMethod - LUMINANCECURVE, // EvlocallabshowmaskexpMethod + LUMINANCECURVE, // EvlocallabshowmaskMethod + LUMINANCECURVE, // EvLocallabSpotSelectedWithMask LUMINANCECURVE, // EvlocallabCCmaskshape LUMINANCECURVE, // EvlocallabLLmaskshape LUMINANCECURVE, // EvlocallabCCmaskexpshape diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 1dea2663b..dca2fba21 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -370,8 +370,14 @@ public: class LocallabListener { public: + struct locallabRef { + double huer; + double lumar; + double chromar; + }; + virtual ~LocallabListener() = default; - virtual void refChanged (double huer, double lumar, double chromar) = 0; + virtual void refChanged(const std::vector &ref, int selspot) = 0; }; class AutoColorTonListener diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index db9ed1cc4..6ea63ed77 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -56,7 +56,7 @@ ControlSpotPanel::ControlSpotPanel(): sensiexclu_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIEXCLU"), 0, 100, 1, 12))), structexclu_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUCCOL"), 0, 100, 1, 0))), - + struc_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRES"), 1.0, 12.0, 0.1, 4.0))), locX_(Gtk::manage(new Adjuster(M("TP_LOCAL_WIDTH"), 2, 3000, 1, 150))), locXL_(Gtk::manage(new Adjuster(M("TP_LOCAL_WIDTH_L"), 2, 3000, 1, 150))), @@ -80,9 +80,10 @@ ControlSpotPanel::ControlSpotPanel(): nameChanged_(false), visibilityChanged_(false), eventType(None), - excluFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_EXCLUF")))) + excluFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_EXCLUF")))), + maskPrevActive(false) { - bool showtooltip = options.showtooltip; + const bool showtooltip = options.showtooltip; Gtk::HBox* const hbox1_ = Gtk::manage(new Gtk::HBox(true, 4)); buttonaddconn_ = button_add_->signal_clicked().connect( @@ -90,7 +91,7 @@ ControlSpotPanel::ControlSpotPanel(): buttondeleteconn_ = button_delete_->signal_clicked().connect( sigc::mem_fun(*this, &ControlSpotPanel::on_button_delete)); buttonduplicateconn_ = button_duplicate_->signal_clicked().connect( - sigc::mem_fun(*this, &ControlSpotPanel::on_button_duplicate)); + sigc::mem_fun(*this, &ControlSpotPanel::on_button_duplicate)); hbox1_->pack_start(*button_add_); hbox1_->pack_start(*button_delete_); hbox1_->pack_start(*button_duplicate_); @@ -101,7 +102,11 @@ ControlSpotPanel::ControlSpotPanel(): sigc::mem_fun(*this, &ControlSpotPanel::on_button_rename)); buttonvisibilityconn_ = button_visibility_->signal_button_release_event().connect( sigc::mem_fun(*this, &ControlSpotPanel::on_button_visibility)); - if(showtooltip) button_visibility_->set_tooltip_markup(M("TP_LOCALLAB_VIS_TOOLTIP")); + + if (showtooltip) { + button_visibility_->set_tooltip_markup(M("TP_LOCALLAB_VIS_TOOLTIP")); + } + hbox2_->pack_start(*button_rename_); hbox2_->pack_start(*button_visibility_); pack_start(*hbox2_); @@ -116,8 +121,8 @@ ControlSpotPanel::ControlSpotPanel(): // Disable search to prevent hijacking keyboard shortcuts #5265 treeview_->set_enable_search(false); treeview_->signal_key_press_event().connect( - sigc::mem_fun( - *this, &ControlSpotPanel::blockTreeviewSearch), false); + sigc::mem_fun( + *this, &ControlSpotPanel::blockTreeviewSearch), false); auto cell = Gtk::manage(new Gtk::CellRendererText()); int cols_count = treeview_->append_column("ID", *cell); @@ -169,7 +174,11 @@ ControlSpotPanel::ControlSpotPanel(): Gtk::HBox* const ctboxspotmethod = Gtk::manage(new Gtk::HBox()); Gtk::Label* const labelspotmethod = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_EXCLUTYPE") + ":")); ctboxspotmethod->pack_start(*labelspotmethod, Gtk::PACK_SHRINK, 4); - if(showtooltip) ctboxspotmethod->set_tooltip_markup(M("TP_LOCALLAB_EXCLUTYPE_TOOLTIP")); + + if (showtooltip) { + ctboxspotmethod->set_tooltip_markup(M("TP_LOCALLAB_EXCLUTYPE_TOOLTIP")); + } + spotMethod_->append(M("TP_LOCALLAB_EXNORM")); spotMethod_->append(M("TP_LOCALLAB_EXECLU")); spotMethod_->set_active(0); @@ -180,9 +189,17 @@ ControlSpotPanel::ControlSpotPanel(): pack_start(*ctboxspotmethod); excluFrame->set_label_align(0.025, 0.5); - if(showtooltip) excluFrame->set_tooltip_text(M("TP_LOCALLAB_EXCLUF_TOOLTIP")); + + if (showtooltip) { + excluFrame->set_tooltip_text(M("TP_LOCALLAB_EXCLUF_TOOLTIP")); + } + ToolParamBlock* const excluBox = Gtk::manage(new ToolParamBlock()); - if(showtooltip) sensiexclu_->set_tooltip_text(M("TP_LOCALLAB_SENSIEXCLU_TOOLTIP")); + + if (showtooltip) { + sensiexclu_->set_tooltip_text(M("TP_LOCALLAB_SENSIEXCLU_TOOLTIP")); + } + sensiexclu_->setAdjusterListener(this); structexclu_->setAdjusterListener(this); excluBox->pack_start(*sensiexclu_); @@ -193,7 +210,11 @@ ControlSpotPanel::ControlSpotPanel(): Gtk::HBox* const ctboxshapemethod = Gtk::manage(new Gtk::HBox()); Gtk::Label* const labelshapemethod = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_STYPE") + ":")); ctboxshapemethod->pack_start(*labelshapemethod, Gtk::PACK_SHRINK, 4); - if(showtooltip) ctboxshapemethod->set_tooltip_markup(M("TP_LOCALLAB_STYPE_TOOLTIP")); + + if (showtooltip) { + ctboxshapemethod->set_tooltip_markup(M("TP_LOCALLAB_STYPE_TOOLTIP")); + } + shapeMethod_->append(M("TP_LOCALLAB_IND")); shapeMethod_->append(M("TP_LOCALLAB_SYM")); shapeMethod_->append(M("TP_LOCALLAB_INDSL")); @@ -229,7 +250,11 @@ ControlSpotPanel::ControlSpotPanel(): Gtk::HBox* const ctboxqualitymethod = Gtk::manage(new Gtk::HBox()); Gtk::Label* const labelqualitymethod = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_QUAL_METHOD") + ":")); ctboxqualitymethod->pack_start(*labelqualitymethod, Gtk::PACK_SHRINK, 4); - if(showtooltip) ctboxqualitymethod->set_tooltip_markup(M("TP_LOCALLAB_METHOD_TOOLTIP")); + + if (showtooltip) { + ctboxqualitymethod->set_tooltip_markup(M("TP_LOCALLAB_METHOD_TOOLTIP")); + } + qualityMethod_->append(M("TP_LOCALLAB_ENH")); qualityMethod_->append(M("TP_LOCALLAB_ENHDEN")); qualityMethod_->set_active(1); @@ -241,11 +266,25 @@ ControlSpotPanel::ControlSpotPanel(): Gtk::Frame* const transitFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_TRANSIT"))); transitFrame->set_label_align(0.025, 0.5); - if(showtooltip) transitFrame->set_tooltip_text(M("TP_LOCALLAB_TRANSIT_TOOLTIP")); + + if (showtooltip) { + transitFrame->set_tooltip_text(M("TP_LOCALLAB_TRANSIT_TOOLTIP")); + } + ToolParamBlock* const transitBox = Gtk::manage(new ToolParamBlock()); - if(showtooltip) transit_->set_tooltip_text(M("TP_LOCALLAB_TRANSIT_TOOLTIP")); - if(showtooltip) transitweak_->set_tooltip_text(M("TP_LOCALLAB_TRANSITWEAK_TOOLTIP")); - if(showtooltip) transitgrad_->set_tooltip_text(M("TP_LOCALLAB_TRANSITGRAD_TOOLTIP")); + + if (showtooltip) { + transit_->set_tooltip_text(M("TP_LOCALLAB_TRANSIT_TOOLTIP")); + } + + if (showtooltip) { + transitweak_->set_tooltip_text(M("TP_LOCALLAB_TRANSITWEAK_TOOLTIP")); + } + + if (showtooltip) { + transitgrad_->set_tooltip_text(M("TP_LOCALLAB_TRANSITGRAD_TOOLTIP")); + } + transit_->setAdjusterListener(this); transitweak_->setAdjusterListener(this); transitgrad_->setAdjusterListener(this); @@ -255,10 +294,14 @@ ControlSpotPanel::ControlSpotPanel(): transitBox->pack_start(*transitgrad_); transitFrame->add(*transitBox); pack_start(*transitFrame); - + Gtk::Frame* const artifFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_ARTIF"))); artifFrame->set_label_align(0.025, 0.5); - if(showtooltip) artifFrame->set_tooltip_text(M("TP_LOCALLAB_ARTIF_TOOLTIP")); + + if (showtooltip) { + artifFrame->set_tooltip_text(M("TP_LOCALLAB_ARTIF_TOOLTIP")); + } + ToolParamBlock* const artifBox = Gtk::manage(new ToolParamBlock()); thresh_->setAdjusterListener(this); struc_->setAdjusterListener(this); @@ -272,7 +315,7 @@ ControlSpotPanel::ControlSpotPanel(): pack_start(*artifFrame); avoidConn_ = avoid_->signal_toggled().connect( - sigc::mem_fun(*this, &ControlSpotPanel::avoidChanged)); + sigc::mem_fun(*this, &ControlSpotPanel::avoidChanged)); pack_start(*avoid_); show_all(); @@ -288,7 +331,7 @@ ControlSpotPanel::ControlSpotPanel(): colorMouseovertext.set_green(100. / 255.); colorMouseovertext.set_blue(0.); colorMouseovertext.set_alpha(0.5); - + // Nominal spot (transparent black) colorNominal.set_red(0.); colorNominal.set_green(0.); @@ -412,16 +455,18 @@ void ControlSpotPanel::on_button_duplicate() // Raise event const int selId = getSelectedSpot(); + if (selId == 0) { // No selected spot to duplicate return; } + nbSpotChanged_ = true; selSpotChanged_ = true; eventType = SpotDuplication; const int newId = getNewId(); listener->panelChanged(EvLocallabSpotCreated, "ID#" + std::to_string(newId) - + " (" + M("TP_LOCALLAB_EV_DUPL") + " ID#" - + std::to_string(selId) + ")"); + + " (" + M("TP_LOCALLAB_EV_DUPL") + " ID#" + + std::to_string(selId) + ")"); } void ControlSpotPanel::on_button_rename() @@ -451,6 +496,7 @@ void ControlSpotPanel::on_button_rename() // Update actual name and raise event if (status == RenameDialog::OkButton) { const Glib::ustring newname = d.get_new_name(); + if (newname != actualname) { // Event is only raised if name is updated nameChanged_ = true; row[spots_.name] = newname; @@ -592,7 +638,13 @@ void ControlSpotPanel::controlspotChanged() selSpotChanged_ = true; eventType = SpotSelection; const int selId = getSelectedSpot(); - listener->panelChanged(EvLocallabSpotSelected, "ID#" + std::to_string(selId)); + + // Image area shall be regenerated if mask preview was active when switching spot + if (maskPrevActive) { + listener->panelChanged(EvLocallabSpotSelectedWithMask, "ID#" + std::to_string(selId)); + } else { + listener->panelChanged(EvLocallabSpotSelected, "ID#" + std::to_string(selId)); + } } void ControlSpotPanel::shapeChanged() @@ -757,6 +809,7 @@ void ControlSpotPanel::updateParamVisibility() // Update Control Spot GUI according to shapeMethod_ combobox state (to be compliant with shapeMethodChanged function) const int method = shapeMethod_->get_active_row_number(); + if (!batchMode) { if (method == 1 || method == 3) { // Symmetrical cases locXL_->hide(); @@ -840,7 +893,7 @@ void ControlSpotPanel::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(Evlocallabstructexlu, structexclu_->getTextValue()); } } - + if (a == struc_) { row[spots_.struc] = struc_->getValue(); @@ -1361,9 +1414,10 @@ CursorShape ControlSpotPanel::getCursor(int objectID) const // When there is no control spot (i.e. no selected row), objectID can unexpectedly be different from -1 and produced not desired behavior const auto s = treeview_->get_selection(); + if (!s->count_selected_rows()) { - return CSHandOpen; - } + return CSHandOpen; + } const int rem_ = objectID % 7; @@ -1437,6 +1491,7 @@ bool ControlSpotPanel::mouseOver(int modifierKey) for (auto iter = children.begin(); iter != children.end(); iter++) { Gtk::TreeModel::Row row = *iter; + if (row[spots_.curveid] == curveId_ && *row != *selRow) { row[spots_.mouseover] = true; } else { @@ -1539,7 +1594,7 @@ bool ControlSpotPanel::button1Pressed(int modifierKey) } lastCoord_.set(provider->posImage.x + provider->deltaImage.x, provider->posImage.y + provider->deltaImage.y); - EditSubscriber::action = EditSubscriber::Action::DRAGGING; + EditSubscriber::action = EditSubscriber::Action::DRAGGING; return true; } diff --git a/rtgui/controlspotpanel.h b/rtgui/controlspotpanel.h index eb5bb5b74..d64c9e940 100644 --- a/rtgui/controlspotpanel.h +++ b/rtgui/controlspotpanel.h @@ -157,6 +157,15 @@ public: * @return True if a spot corresponding to the id has been selected */ bool setSelectedSpot(const int id); + /** + * Setter for mask preview active indicator + * + * @param ind True is mask preview is active + */ + void setMaskPrevActive(bool ind) + { + maskPrevActive = ind; + } // Control spot creation functions /** @@ -208,13 +217,6 @@ public: * @param pedited ParamsEdited containing default state values to set to the adjusters (not used because batch mode is deactivated for Locallab) */ void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr); - /** - * Variant of setDefaults function which only update adjuster default states - * - * @param pedited ParamsEdited containing default states to set to the adjusters - * @param id Spot id to consider to update adjusters default states - */ - // void updateDefaultsStates(const ParamsEdited* pedited, int id = 0); /** * Enable or disable the interactions with panel widgets * @@ -378,6 +380,7 @@ private: bool visibilityChanged_; int eventType; // 0 = No event, 1 = Spot creation event, 2 = Spot deletion event, 3 = Spot selection event, 4 = Spot duplication event Gtk::Frame* const excluFrame; + bool maskPrevActive; // Row background color Gdk::RGBA colorMouseover, colorNominal, colorMouseovertext; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 73b8d6119..210e90b9d 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -19,13 +19,13 @@ * 2017 Jacques Desmis * 2019 Pierre Cabrera */ - #include "locallab.h" -#include "../rtengine/rt_math.h" + #include "options.h" -#include "../rtengine/improcfun.h" +#include "../rtengine/procparams.h" using namespace rtengine; +using namespace procparams; extern Options options; @@ -83,7 +83,7 @@ Locallab::Locallab(): setParamEditable(false); } -void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) +void Locallab::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { // printf("Locallab read\n"); @@ -192,7 +192,7 @@ void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) // Note: No need to manage pedited as batch mode is deactivated for Locallab } -void Locallab::write(ProcParams* pp, ParamsEdited* pedited) +void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) { // Update Locallab activation state pp->locallab.enabled = getEnabled(); @@ -393,6 +393,17 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) enableListener(); + // Update locallab tools mask background + if (pp->locallab.selspot < (int)maskBackRef.size()) { + const double huer = maskBackRef.at(pp->locallab.selspot).huer; + const double lumar = maskBackRef.at(pp->locallab.selspot).lumar; + const double chromar = maskBackRef.at(pp->locallab.selspot).chromar; + + for (auto tool : locallabTools) { + tool->refChanged(huer, lumar, chromar); + } + } + // Update default values according to selected spot setDefaults(pp, pedited); @@ -602,8 +613,8 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) /* * Note: - * By default, this function is called when a new image is loaded (after read function). In this case, if there is - * at least one spot, default values are set to selected spot ones. + * By default, this function is called when a new image/profile is loaded (after read function). In this case, + * if there is at least one spot, default values are set to selected spot ones. * To keep having default values according to selected spot, this function shall also be called in the following * situations (after having called write function for controlspotpanel): * - After spot creation @@ -611,7 +622,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) * - After spot selection * - After spot duplication */ -void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pedited) +void Locallab::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) { // Set default values in spot panel control expsettings->setDefaults(defParams, pedited); @@ -635,47 +646,49 @@ void Locallab::setListener(ToolPanelListener* tpl) } } -void Locallab::refChanged(double huer, double lumar, double chromar) +void Locallab::refChanged(const std::vector &ref, int selspot) { + // Saving transmitted mask background data + maskBackRef = ref; + // Update locallab tools mask background - for (auto tool : locallabTools) { - tool->refChanged(huer, lumar, chromar); + if (selspot < (int)maskBackRef.size()) { + const double huer = maskBackRef.at(selspot).huer; + const double lumar = maskBackRef.at(selspot).lumar; + const double chromar = maskBackRef.at(selspot).chromar; + + for (auto tool : locallabTools) { + tool->refChanged(huer, lumar, chromar); + } } } -void Locallab::resetMaskVisibility() // TODO To keep ?? +void Locallab::resetMaskVisibility() { - // printf("resetMaskVisibility\n"); + // Indicate to spot control panel that no more mask preview is active + expsettings->setMaskPrevActive(false); - /* - disableListener(); - showmaskcolMethod->set_active(0); - showmaskexpMethod->set_active(0); - showmaskSHMethod->set_active(0); - showmaskcbMethod->set_active(0); - showmaskretiMethod->set_active(0); - showmasksoftMethod->set_active(0); - showmasktmMethod->set_active(0); - enableListener(); - */ + // Reset mask preview for all Locallab tools + for (auto tool : locallabTools) { + tool->resetMaskView(); + } } -Locallab::llMaskVisibility* Locallab::getMaskVisibility() // TODO To keep ?? +Locallab::llMaskVisibility Locallab::getMaskVisibility() const { - llMaskVisibility* maskStruct = new llMaskVisibility(); - /* - maskStruct->colorMask = showmaskcolMethod->get_active_row_number(); - maskStruct->expMask = showmaskexpMethod->get_active_row_number(); - maskStruct->SHMask = showmaskSHMethod->get_active_row_number(); - maskStruct->cbMask = showmaskcbMethod->get_active_row_number(); - maskStruct->retiMask = showmaskretiMethod->get_active_row_number(); - maskStruct->softMask = showmasksoftMethod->get_active_row_number(); - maskStruct->tmMask = showmasktmMethod->get_active_row_number(); - // printf("SHmask=%i \n", maskStruct->SHMask); - // printf("retimask=%i \n", maskStruct->retiMask); - */ + // Get mask preview from Locallab tools + int colorMask, expMask, SHMask, softMask, tmMask, retiMask, cbMask; - return maskStruct; + for (auto tool : locallabTools) { + tool->getMaskView(colorMask, expMask, SHMask, softMask, tmMask, retiMask, cbMask); + } + + // Indicate to spot control panel if one mask preview is active + const bool isMaskActive = (colorMask == 0) || (expMask == 0) || (SHMask == 0) || + (softMask == 0) || (tmMask == 0) || (retiMask == 0) || (cbMask == 0); + expsettings->setMaskPrevActive(isMaskActive); + + return {colorMask, expMask, SHMask, softMask, tmMask, retiMask, cbMask}; } void Locallab::setEditProvider(EditDataProvider * provider) diff --git a/rtgui/locallab.h b/rtgui/locallab.h index df2b05d85..eedb15d9e 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -24,9 +24,6 @@ #include "controlspotpanel.h" #include "locallabtools.h" -#include "toolpanel.h" -#include "editcallbacks.h" - class Locallab : public ToolParamBlock, @@ -54,6 +51,9 @@ private: std::vector locallabTools; + // Locallab tools mask background management data + std::vector maskBackRef; + public: Locallab(); @@ -64,7 +64,7 @@ public: void setListener(ToolPanelListener* tpl); // Locallab tools mask background management function - void refChanged(double huer, double lumar, double chromar); + void refChanged(const std::vector &ref, int selspot); // Mask visibility management functions struct llMaskVisibility { @@ -78,7 +78,7 @@ public: }; void resetMaskVisibility(); - llMaskVisibility* getMaskVisibility(); + llMaskVisibility getMaskVisibility() const; // EditProvider management function void setEditProvider(EditDataProvider* provider); diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index fce136ac8..aed72dee3 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -21,7 +21,6 @@ #include "locallabtools.h" #include "options.h" -#include "multilangmgr.h" #include "../rtengine/procparams.h" #include "locallab.h" @@ -207,7 +206,7 @@ void LocallabTool::resetMaskView() } } -void LocallabTool::refChanged(double huer, double lumar, double chromar) +void LocallabTool::refChanged(const double huer, const double lumar, const double chromar) { if (useMask) { // Hue reference normalization (between 0 and 1) @@ -507,6 +506,18 @@ LocallabColor::~LocallabColor() delete HCurveEditorG; } +void LocallabColor::setListener(ToolPanelListener* tpl) +{ + LocallabTool::setListener(tpl); + + labgrid->setListener(tpl); +} + +void LocallabColor::getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask) +{ + colorMask = showMaskMethod->get_active_row_number(); +} + void LocallabColor::colorForValue(double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) { LocallabTool::colorForValue(valX, valY, elemType, callerId, caller); // Mask curves @@ -528,13 +539,6 @@ void LocallabColor::colorForValue(double valX, double valY, enum ColorCaller::El } } -void LocallabColor::setListener(ToolPanelListener* tpl) -{ - LocallabTool::setListener(tpl); - - labgrid->setListener(tpl); -} - void LocallabColor::disableListener() { LocallabTool::disableListener(); @@ -895,7 +899,7 @@ void LocallabColor::showMaskMethodChanged() } if (listener) { - listener->panelChanged(EvlocallabshowmaskcolMethod, ""); // TODO Use generic event for mask preview + listener->panelChanged(EvlocallabshowmaskMethod, ""); } } @@ -1109,6 +1113,11 @@ LocallabExposure::~LocallabExposure() delete curveEditorG; } +void LocallabExposure::getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask) +{ + expMask = showMaskMethod->get_active_row_number(); +} + void LocallabExposure::disableListener() { LocallabTool::disableListener(); @@ -1485,7 +1494,7 @@ void LocallabExposure::showMaskMethodChanged() } if (listener) { - listener->panelChanged(EvlocallabshowmaskexpMethod, ""); // TODO Use generic event for mask preview + listener->panelChanged(EvlocallabshowmaskMethod, ""); } } @@ -1612,6 +1621,11 @@ LocallabShadow::LocallabShadow(): pack_start(*inverssh); } +void LocallabShadow::getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask) +{ + shMask = showMaskMethod->get_active_row_number(); +} + void LocallabShadow::disableListener() { LocallabTool::disableListener(); @@ -1872,7 +1886,7 @@ void LocallabShadow::showMaskMethodChanged() } if (listener) { - listener->panelChanged(EvlocallabshowmaskSHMethod, ""); // TODO Use generic event for mask preview + listener->panelChanged(EvlocallabshowmaskMethod, ""); } } @@ -2296,6 +2310,11 @@ LocallabSoft::LocallabSoft(): pack_start(*sensisf); } +void LocallabSoft::getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask) +{ + softMask = showmasksoftMethod->get_active_row_number(); +} + void LocallabSoft::disableListener() { LocallabTool::disableListener(); @@ -2451,7 +2470,7 @@ void LocallabSoft::showmasksoftMethodChanged() } if (listener) { - listener->panelChanged(EvlocallabshowmasksoftMethod, ""); // TODO Use generic event for mask preview + listener->panelChanged(EvlocallabshowmaskMethod, ""); } } diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 1e934bf8e..36dedb590 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -21,10 +21,8 @@ #ifndef _LOCALLABTOOLS_H_ #define _LOCALLABTOOLS_H_ -#include "toolpanel.h" #include "curveeditorgroup.h" #include "curveeditor.h" -#include "../rtengine/rtengine.h" #include "labgrid.h" #include "thresholdadjuster.h" @@ -45,8 +43,7 @@ class LocallabTool: public ToolPanel, public CurveListener, public ColorProvider, - public AdjusterListener, - public rtengine::LocallabListener + public AdjusterListener { protected: // Enumeration to manage mask type @@ -129,10 +126,11 @@ public: bool isLocallabToolAdded(); // Mask background management function - void refChanged(double huer, double lumar, double chromar); + void refChanged(const double huer, const double lumar, const double chromar); - // Mask preview reset function + // Mask preview functions void resetMaskView(); + virtual void getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask) {}; /* To be completed Notes: @@ -203,6 +201,8 @@ public: void setListener(ToolPanelListener* tpl); + void getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask); + void colorForValue(double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); void disableListener(); @@ -259,6 +259,8 @@ public: LocallabExposure(); ~LocallabExposure(); + void getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask); + void disableListener(); void enableListener(); void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); @@ -300,6 +302,8 @@ private: public: LocallabShadow(); + void getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask); + void disableListener(); void enableListener(); void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); @@ -383,6 +387,8 @@ private: public: LocallabSoft(); + void getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask); + void disableListener(); void enableListener(); void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); @@ -452,6 +458,8 @@ private: public: LocallabTone(); + void getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask); + void disableListener(); void enableListener(); void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); @@ -498,6 +506,8 @@ public: LocallabRetinex(); ~LocallabRetinex(); + void getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask); + void disableListener(); void enableListener(); void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); @@ -617,6 +627,8 @@ private: public: LocallabCBDL(); + void getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask); + void disableListener(); void enableListener(); void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 124840078..a73789623 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -21,7 +21,6 @@ #include "locallabtools.h" #include "options.h" -#include "multilangmgr.h" #include "../rtengine/procparams.h" #define MINCHRO 0. @@ -181,6 +180,11 @@ LocallabTone::LocallabTone(): pack_start(*sensitm); } +void LocallabTone::getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask) +{ + tmMask = showMaskMethod->get_active_row_number(); +} + void LocallabTone::disableListener() { LocallabTool::disableListener(); @@ -458,7 +462,7 @@ void LocallabTone::showMaskMethodChanged() } if (listener) { - listener->panelChanged(EvLocallabEnatmMask, ""); // TODO Use generic event for mask preview + listener->panelChanged(EvlocallabshowmaskMethod, ""); } } @@ -595,6 +599,11 @@ LocallabRetinex::~LocallabRetinex() delete LocalcurveEditorgainT; } +void LocallabRetinex::getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask) +{ + retiMask = showMaskMethod->get_active_row_number(); +} + void LocallabRetinex::disableListener() { LocallabTool::disableListener(); @@ -959,7 +968,7 @@ void LocallabRetinex::showMaskMethodChanged() } if (listener) { - listener->panelChanged(EvlocallabshowmaskretiMethod, ""); // TODO Use generic event for mask preview + listener->panelChanged(EvlocallabshowmaskMethod, ""); } } @@ -1663,6 +1672,11 @@ LocallabCBDL::LocallabCBDL(): pack_start(*sensicb); } +void LocallabCBDL::getMaskView(int &colorMask, int &expMask, int &shMask, int &softMask, int &tmMask, int &retiMask, int &cbMask) +{ + cbMask = showMaskMethod->get_active_row_number(); +} + void LocallabCBDL::disableListener() { LocallabTool::disableListener(); @@ -1950,7 +1964,7 @@ void LocallabCBDL::showMaskMethodChanged() } if (listener) { - listener->panelChanged(EvlocallabshowmaskcbMethod, ""); // TODO Use generic event for mask preview + listener->panelChanged(EvlocallabshowmaskMethod, ""); } } diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 20e9f976e..881880e57 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -473,10 +473,19 @@ void ToolPanelCoordinator::panelChanged(const rtengine::ProcEvent& event, const resize->write(params); } - // Manage Locallab mask visibility - if (event == rtengine::EvlocallabshowmaskcolMethod || event == rtengine::EvlocallabshowmaskexpMethod || event == rtengine::EvlocallabshowmaskSHMethod || event == rtengine::EvlocallabshowmasksoftMethod || event == rtengine::EvlocallabshowmaskcbMethod || event == rtengine::EvlocallabshowmaskretiMethod || event == rtengine::EvlocallabshowmasktmMethod) { - Locallab::llMaskVisibility* maskStruc = locallab->getMaskVisibility(); - ipc->setLocallabMaskVisibility(maskStruc->colorMask, maskStruc->expMask, maskStruc->SHMask, maskStruc->cbMask, maskStruc->retiMask, maskStruc->softMask, maskStruc->tmMask); + /* + * Manage Locallab mask visibility: + * - Mask preview is updated when choosing a mask preview method + * - Mask preview is stopped when creating, deleting or selecting a spot + */ + if (event == rtengine::EvlocallabshowmaskMethod) { + const Locallab::llMaskVisibility maskStruc = locallab->getMaskVisibility(); + ipc->setLocallabMaskVisibility(maskStruc.colorMask, maskStruc.expMask, + maskStruc.SHMask, maskStruc.cbMask, maskStruc.retiMask, + maskStruc.softMask, maskStruc.tmMask); + } else if (event == rtengine::EvLocallabSpotCreated || event == rtengine::EvLocallabSpotSelectedWithMask || event == rtengine::EvLocallabSpotDeleted) { + locallab->resetMaskVisibility(); + ipc->setLocallabMaskVisibility(0, 0, 0, 0, 0, 0, 0); } ipc->endUpdateParams(changeFlags); // starts the IPC processing @@ -581,11 +590,9 @@ void ToolPanelCoordinator::profileChange( gradient->updateGeometry(params->gradient.centerX, params->gradient.centerY, params->gradient.feather, params->gradient.degree, fw, fh); } - // Reset Locallab mask visibility when a picture is loaded - if (event == rtengine::EvPhotoLoaded) { - locallab->resetMaskVisibility(); - ipc->setLocallabMaskVisibility(0, 0, 0, 0, 0, 0, 0); - } + // Reset Locallab mask visibility + locallab->resetMaskVisibility(); + ipc->setLocallabMaskVisibility(0, 0, 0, 0, 0, 0, 0); // start the IPC processing if (filterRawRefresh) {