rawTherapee/rtgui/controlspotpanel.cc
Desmis a578423378
Abstract Profile - Contrast enhancement -- Selective Editing Cam16 and JzCzHz - improvments (#7111)
* Init levels trc GUI

* Levels TRC

* Complete with gamma based attenuation

* Limit RGB channel Slope with checkbox

* Improve GUI and code channel TRC

* Change default values - compexity levels RGB channels

* Relative gamma mode RGB channel TRC

* Change label and ponderation rolloff

* Change rolloff level

* Threshold attenuation

* Threshold attenuation 2 part

* GUI Link R G B

* Linked RGB with Green slope - RGB channels

* Set Freeman TM functions with ImProcFunctions

* First GUI Abstract profile highlight attenuation

* GUI AP part 2

* Restore olg GUI AP

* Expander AP primaries adn illuminant

* Disable RGB channel TRC

* Expander contrast AP

* Slider attenuation response

* Save work GUI local contrast

* Save GUI part 2 AP curve

* Local contrast GUI Abstract Profile

* Move Abstract profile in toolpanel and ICMpanel

* rtengine variable contrast

* Variable contrast 2

* Variable contrast engine 3

* Variable contrast engine 4

* Variable contrast engine

* Detail levels pyramid

* Engine residual contrast

* Residual contrast

* Change settings detail levels

* Expander refinement - new tooltips - low resid contrast

* Change contrast profile and labels

* Remove warning message GUI Gtk

* Gamutcontrol code - disabled

* Improve with calceffect

* Other improvement variable contrast

* Offset variable contrast

* Range offset - comment code

* Parametric inva fot lut

* Clean cmakelist.txt

* Change contrast profiles

* Comment code ipwavelet

* Added orthogonal Daubechies scaling D20

* Change strenght curve - tooltip Daubechies

* Forgotten changes

* Comment code

* Move variable in process - take into account highlight attenuation

* Display label maximum preview and preset selection

* Remove console message

* harmonize levels wavelets iplocallab

* Tooltips contrast enhancement

* Change tooltip Contrast profile

* Chnage tooltip Contrast

* Message warning preview size

* Change gamma TRC values in GUI

* Remove itanium architecture support for windows as PR 7105

* Change windows.yml and appimage.yml

* Windows.yml apseimprov

* Clean and comment ipwavelet

* Clean comment icmpanel.cc

* Harmonize local contrast wavelet Selective editing with Abstract profile

* Harmonize with AP - offset

* vanishing moment D20 - Selective editing wavelet

* Offset only in advanced mode

* GUI expander contrast enable and pyrwavtrc

* Clean and comment code

* merge with dev

* Prepare sigmoid based

* Contrast sigmoid GUI

* Skew sigmoid GUI

* Sigmoid tone mapper in iplocallab

* Change GUI settings

* White-point and black-point auto

* Change EvDCP to ALLNORAW as others events DCP

* Change default skew

* Change settings - enable scale Yb

* Display white point - advanced mode

* Improve GUI

* Clean unused variable

* new sigmoid Q in cam16

* Change tooltips and default sigmoid Q settings

* Sigmoid Jz

* Clean code Jz and sigmoid

* Harmonize Sigmoid Q and Sigmoid RGB

* Harmonize Sigmoid Jz

* Clean code

* Improve labels wit cd/m2

* Slope base Q methode first

* GUI slope based Q

* Change default settings and tooltips

* Change tooltips

* Clean code - change default setting

* Change default local contrast & wavelet to wavelet & basic mode

* Fixed bad assignation slopesmoq

* Improve sigmoid and slope based Q - GUI for Log encoding Color appearance

* Remove wrong change

* various small improvments

* Allows black and white AP and SDA in basic mode

* Change  the writing of wGamma and wSlope - attenuates the effect of the first 2 AP contrast profiles

* Clean code wgamma wslope

* Set curve Cam16 in basic mode

* Change position curve in GUI cam16

* Enable tonecurve1 in colorappearance & lighting in standard mode

* Fixed bug scale yb scene - ciecam curve - change default contrast enhancement

* not reset curve shape ciecam in strandard

* Change label Tone mapping operators and tooltips

* Change some labels and tooltips - Appearance - Mask and Mofifications - Recovery Based On Luminance Mask

* Forgotten changes

* Clean locallabtools2.cc

* Maxlevel wavelet minimum to 5

* Reset mask and modifications in SE wavelet and all tools in Global

* Show modified areas SE wavelet

* Tooltip show wavelets decomposition

* Fixed another bad behavior in Global - changes also in color & light for merge file

* Change behavior fullimage - global as in PR GHS

* Disable all mask and modifications in Global but remain active in fullimage and normal

* Set expander expanded = true

* Chane contrast enhancement coef

* Replace VBox trcWavVBox by ToolParamBlock trcWavFBox

* Forgotten code in icmpanel read pedited opacityShapeWLI - hope solve batch mode

* Change RGB Slope behavior with link

* No access to last level contrast enhancement

* Move Abstract Profile tooltip to title

The tooltip was popping up when the cursor was over almost any part of
the tool which was inconvenient. Now, the tooltip only appears when
hovering over the title.

* Improve Color Management expanders behavior

By default, collapse Abstract Profile and leave it's sub-expanders
expanded.

Keep the expanded state of all the sub-expanders during the editing
session.

Fix the right-click behavior. The clicked expander should be expanded
and all siblings, if any, should be collapsed.

* Fix RGB slope tone mapping RGB linkage

Synchronize the red, green, and blue values before updating the preview
to avoid using incorrect values to generate the preview.

* Fix SE CAM tone mapping slider defocus

Avoid unnecessarily hiding then showing the adjusters in tone mapping so
that focus is not lost while adjusting the adjusters.

* Delete history kslopesmo - remove IcmOpacityCurveWL

* change the tooltips as suggested by Lawrence

* Review L37 - change strengthjz strengthlc - MIDDLE_GREY MIDDLE_GREYjz - artifacts ciecam

* Change name Tone map freeman functions

* Remove gamutcont - rename localcont - change allocation memory wdspot

* Clean procparams

* remove sigmoidsenscie - logcieq

* Added * to three labels 'sigmoid' - change tooltip which shows the incompatibility with 5.11

* Forgotten correction suggested by Lawrence

* Compatibility 5.11 log encoding - sigmoid part 1

* Compatibility 5.11 part 2

* Compatibility 5.11 - step 3

* Compatibility 5.11 - step 4

* Compatibility 5.11 step xx

* Compatibility 5.11 - combobox operators Q and J

* Compatibility 5.11 Cam16 GUI first part

* Improve GUI Cam16 sigmoid compatibility

* Compatibility 5.11 Jz - sigmoid - step 1

* Compatibility 5.11 Jz gui step 2

* Compatibility 5.11 Jz GUI step x

* Compatibility 5.11 Jz - history - etc.

* Various change labels - history ...

* Improve GUI - hide show 5.11 5.12

* Jz 5.11 in iplocallab - step 1

* Compatibility 5.11 iplocallab cam16 step 1

* Improve GUI hide show 511 512

* Solved - I hope - GUI problem with tone mapper Q and J 5.11 and 5.12

* Compatibility 5.11 iplocallab Cam16 step 2

* Improve GUI compatibility 5.11 labels tooltips

* Small improvments GUI - labels - history...

* Fixed typo in paramsedited.cc clcurve issue 7283

* Change tooltips method 5.12 - 5.11 for cam16 and Jz  brightness Q or J

* Clean and refine code

* Various change dafult language  and CAM16 CAM02 replace by Cam16 Cam02

* Change modeQJ method for 5.11 in function ppversion

* Change labels as suggested by Wayne PR 7111

* Others changes suggested for label

* Change tooltips as suggested in PR

* Use unique pointer instead of manual management

* Update rtdata/languages/default

Co-authored-by: Lawrence37 <45837045+Lawrence37@users.noreply.github.com>

* Change all Cam16 references to CAM16

* Change convention uppercase and lowercase in frame - checkbox

* Improve tooltips for Tone Mapping Operators

* Another change CIECAM and uppercase lowercase in checkbox

* Remove appimage and windows yml

---------

Co-authored-by: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com>
2025-01-19 07:52:32 +01:00

3047 lines
102 KiB
C++

/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <http://www.gnu.org/licenses/>.
* 2018 Pierre Cabrera <pierre.cab@gmail.com>
*/
#include "rtengine/rt_math.h"
#include "controlspotpanel.h"
#include "editwidgets.h"
#include "options.h"
#include "rtengine/procparams.h"
#include "rtimage.h"
#include "eventmapper.h"
using namespace rtengine;
using namespace procparams;
extern Options options;
//-----------------------------------------------------------------------------
// ControlSpotPanel
//-----------------------------------------------------------------------------
ControlSpotPanel::ControlSpotPanel():
EditSubscriber(ET_OBJECTS),
FoldableToolPanel(this, "controlspotpanel", M("TP_LOCALLAB_SETTINGS")),
scrolledwindow_(Gtk::manage(new Gtk::ScrolledWindow())),
treeview_(Gtk::manage(new Gtk::TreeView())),
button_add_(Gtk::manage(new Gtk::Button(M("TP_LOCALLAB_BUTTON_ADD")))),
button_delete_(Gtk::manage(new Gtk::Button(M("TP_LOCALLAB_BUTTON_DEL")))),
button_duplicate_(Gtk::manage(new Gtk::Button(M("TP_LOCALLAB_BUTTON_DUPL")))),
button_rename_(Gtk::manage(new Gtk::Button(M("TP_LOCALLAB_BUTTON_REN")))),
button_visibility_(Gtk::manage(new Gtk::Button(M("TP_LOCALLAB_BUTTON_VIS")))),
prevMethod_(Gtk::manage(new MyComboBoxText())),
shape_(Gtk::manage(new MyComboBoxText())),
spotMethod_(Gtk::manage(new MyComboBoxText())),
shapeMethod_(Gtk::manage(new MyComboBoxText())),
qualityMethod_(Gtk::manage(new MyComboBoxText())),
//complexMethod_(Gtk::manage(new MyComboBoxText())),
wavMethod_(Gtk::manage(new MyComboBoxText())),
avoidgamutMethod_(Gtk::manage(new MyComboBoxText())),
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))),
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))),
locY_(Gtk::manage(new Adjuster(M("TP_LOCAL_HEIGHT"), 2, 3000, 1, 150))),
locYT_(Gtk::manage(new Adjuster(M("TP_LOCAL_HEIGHT_T"), 2, 3000, 1, 150))),
centerX_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CENTER_X"), -1000, 1000, 1, 0))),
centerY_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CENTER_Y"), -1000, 1000, 1, 0))),
circrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CIRCRADIUS"), 1.5, 150., 0.5, 18.))),
transit_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITVALUE"), 2., 100., 0.1, 60.))),
transitweak_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITWEAK"), 0.5, 25.0, 0.1, 1.0))),
transitgrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITGRAD"), -1.0, 1.0, 0.01, 0.0))),
feather_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE_MASK"), 10., 100., 0.1, 25.))),
struc_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRES"), 1.0, 12.0, 0.1, 4.0))),
thresh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRESDELTAE"), 0.0, 15.0, 0.1, 2.0))),
iter_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_PROXI"), 0.2, 10.0, 0.1, 2.0))),
// balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.05, 2.5, 0.05, 1.0, Gtk::manage(new RTImage("rawtherapee-logo-16")), Gtk::manage(new RTImage("circle-white-small"))))),
balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.05, 2.5, 0.05, 1.0, Gtk::manage(new RTImage("circle-yellow-small")), Gtk::manage(new RTImage("circle-white-small"))))),
balanh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALANH"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("circle-multicolor-small")), Gtk::manage(new RTImage("circle-red-green-small"))))),
colorde_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORDE"), -15, 15, 2, 5, Gtk::manage(new RTImage("circle-blue-yellow-small")), Gtk::manage(new RTImage("circle-gray-green-small"))))),
colorscope_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORSCOPE"), 0., 100.0, 1., 30.))),
avoidrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_AVOIDRAD"), 0., 30.0, 0.1, 0.))),
scopemask_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SCOPEMASK"), 0, 100, 1, 60))),
denoichmask_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DENOIMASK"), 0., 100., 0.5, 0))),
lumask_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LUMASK"), -50, 30, 1, 10, Gtk::manage(new RTImage("circle-yellow-small")), Gtk::manage(new RTImage("circle-gray-small")) ))),
hishow_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_PREVSHOW")))),
activ_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ACTIVSPOT")))),
blwh_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_BLWH")))),
recurs_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_RECURS")))),
laplac_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LAPLACC")))),
deltae_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_DELTAEC")))),
shortc_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SHORTC")))),
//savrest_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SAVREST")))),
expTransGrad_(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_TRANSIT")))),
expShapeDetect_(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_ARTIF")))),
expSpecCases_(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SPECCASE")))),
expMaskMerge_(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_MASFRAME")))),
preview_(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))),
ctboxshape(Gtk::manage(new Gtk::Box())),
ctboxactivmethod(Gtk::manage(new Gtk::Box())),
ctboxspotmethod(Gtk::manage(new Gtk::Box())),
ctboxshapemethod(Gtk::manage(new Gtk::Box())),
ctboxgamut(Gtk::manage(new Gtk::Box())),
artifBox2(Gtk::manage(new ToolParamBlock())),
controlPanelListener(nullptr),
lastObject_(-1),
nbSpotChanged_(false),
selSpotChanged_(false),
nameChanged_(false),
visibilityChanged_(false),
eventType(None),
excluFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_EXCLUF")))),
maskPrevActive(false)
{
auto m = ProcEventMapper::getInstance();
EvLocallabavoidgamutMethod = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GAMUTMUNSEL");
const bool showtooltip = options.showtooltip;
// pack_start(*hishow_);
Gtk::Box* const ctboxprevmethod = Gtk::manage(new Gtk::Box());
prevMethod_->append(M("TP_LOCALLAB_PREVHIDE"));
prevMethod_->append(M("TP_LOCALLAB_PREVSHOW"));
prevMethod_->set_active(0);
prevMethodconn_ = prevMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::prevMethodChanged));
// ctboxprevmethod->pack_start(*prevMethod_);
pack_start(*ctboxprevmethod);
Gtk::Box* const hbox1_ = Gtk::manage(new Gtk::Box());
hbox1_->set_spacing(4);
hbox1_->set_homogeneous(true);
buttonaddconn_ = button_add_->signal_clicked().connect(
sigc::mem_fun(*this, &ControlSpotPanel::on_button_add));
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));
hbox1_->pack_start(*button_add_);
hbox1_->pack_start(*button_delete_);
hbox1_->pack_start(*button_duplicate_);
pack_start(*hbox1_);
Gtk::Box* const hbox2_ = Gtk::manage(new Gtk::Box());
hbox2_->set_spacing(4);
hbox2_->set_homogeneous(true);
buttonrenameconn_ = button_rename_->signal_clicked().connect(
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"));
}
hbox2_->pack_start(*button_rename_);
hbox2_->pack_start(*button_visibility_);
pack_start(*hbox2_);
treemodel_ = Gtk::ListStore::create(spots_);
treeview_->set_model(treemodel_);
treeviewconn_ = treeview_->get_selection()->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::controlspotChanged));
treeview_->set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_VERTICAL);
// 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);
// Avoid situation where no spot is selected (Ctrl+click on treeview)
treeview_->signal_button_press_event().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::onSpotSelectionEvent), false);
auto cell = Gtk::manage(new Gtk::CellRendererText());
int cols_count = treeview_->append_column(M("TP_LOCALLAB_COL_NAME"), *cell);
auto col = treeview_->get_column(cols_count - 1);
if (col) {
col->set_cell_data_func(
*cell, sigc::mem_fun(
*this, &ControlSpotPanel::render_name));
}
cell = Gtk::manage(new Gtk::CellRendererText());
cols_count = treeview_->append_column(M("TP_LOCALLAB_COL_VIS"), *cell);
col = treeview_->get_column(cols_count - 1);
if (col) {
col->set_cell_data_func(
*cell, sigc::mem_fun(
*this, &ControlSpotPanel::render_isvisible));
}
scrolledwindow_->add(*treeview_);
scrolledwindow_->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
scrolledwindow_->set_min_content_height(150);
pack_start(*scrolledwindow_);
pack_start(*hishow_);
// Gtk::Box* const ctboxactivmethod = Gtk::manage(new Gtk::Box());
ctboxactivmethod->pack_start(*activ_);
pack_start(*ctboxactivmethod);
Gtk::Label* const labelshape = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_SHAPETYPE") + ":"));
ctboxshape->pack_start(*labelshape, Gtk::PACK_SHRINK, 4);
shape_->append(M("TP_LOCALLAB_ELI"));
shape_->append(M("TP_LOCALLAB_RECT"));
shape_->set_active(0);
shapeconn_ = shape_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::shapeChanged));
ctboxshape->pack_start(*shape_);
pack_start(*ctboxshape);
if (showtooltip) {
shape_->set_tooltip_text(M("TP_LOCALLAB_SHAPE_TOOLTIP"));
}
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"));
}
spotMethod_->append(M("TP_LOCALLAB_EXNORM"));
spotMethod_->append(M("TP_LOCALLAB_EXECLU"));
spotMethod_->append(M("TP_LOCALLAB_EXFULL"));
spotMethod_->append(M("TP_LOCALLAB_EXMAIN"));//new choice Global
spotMethod_->set_active(0);
spotMethodconn_ = spotMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::spotMethodChanged));
ctboxspotmethod->pack_start(*spotMethod_);
pack_start(*ctboxspotmethod);
excluFrame->set_label_align(0.025, 0.5);
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"));
}
sensiexclu_->setAdjusterListener(this);
structexclu_->setAdjusterListener(this);
structexclu_->setLogScale(10, 0);
excluBox->pack_start(*sensiexclu_);
excluBox->pack_start(*structexclu_);
excluFrame->add(*excluBox);
pack_start(*excluFrame);
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"));
}
shapeMethod_->append(M("TP_LOCALLAB_IND"));
shapeMethod_->append(M("TP_LOCALLAB_SYM"));
shapeMethod_->append(M("TP_LOCALLAB_INDSL"));
shapeMethod_->append(M("TP_LOCALLAB_SYMSL"));
shapeMethod_->set_active(0);
shapeMethodconn_ = shapeMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::shapeMethodChanged));
ctboxshapemethod->pack_start(*shapeMethod_);
// pack_start(*ctboxshapemethod);
pack_start(*locX_);
locX_->setAdjusterListener(this);
pack_start(*locXL_);
locXL_->setAdjusterListener(this);
pack_start(*locY_);
locY_->setAdjusterListener(this);
pack_start(*locYT_);
locYT_->setAdjusterListener(this);
pack_start(*centerX_);
centerX_->setAdjusterListener(this);
pack_start(*centerY_);
centerY_->setAdjusterListener(this);
pack_start(*circrad_);
circrad_->setAdjusterListener(this);
if (showtooltip) {
circrad_->set_tooltip_text(M("TP_LOCALLAB_CIRCRAD_TOOLTIP"));
}
Gtk::Box* const ctboxqualitymethod = Gtk::manage(new Gtk::Box());
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"));
}
qualityMethod_->append(M("TP_LOCALLAB_ENH"));
qualityMethod_->append(M("TP_LOCALLAB_ENHDEN"));
qualityMethod_->set_active(1);
qualityMethodconn_ = qualityMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::qualityMethodChanged));
ctboxqualitymethod->pack_start(*qualityMethod_);
if (showtooltip) {
expTransGrad_->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"));
transitweak_->set_tooltip_text(M("TP_LOCALLAB_TRANSITWEAK_TOOLTIP"));
feather_->set_tooltip_text(M("TP_LOCALLAB_FEATH_TOOLTIP"));
transitgrad_->set_tooltip_text(M("TP_LOCALLAB_TRANSITGRAD_TOOLTIP"));
scopemask_->set_tooltip_text(M("TP_LOCALLAB_SCOPEMASK_TOOLTIP"));
denoichmask_->set_tooltip_text(M("TP_LOCALLAB_DENOIMASK_TOOLTIP"));
}
transit_->setAdjusterListener(this);
transitweak_->setAdjusterListener(this);
transitgrad_->setAdjusterListener(this);
feather_->setAdjusterListener(this);
scopemask_->setAdjusterListener(this);
denoichmask_->setAdjusterListener(this);
transitBox->pack_start(*transit_);
transitBox->pack_start(*transitweak_);
transitBox->pack_start(*transitgrad_);
//transitBox->pack_start(*feather_);
expTransGrad_->add(*transitBox, false);
pack_start(*expTransGrad_, false, false);
if (showtooltip) {
expShapeDetect_->set_tooltip_text(M("TP_LOCALLAB_ARTIF_TOOLTIP"));
}
ToolParamBlock* const artifBox = Gtk::manage(new ToolParamBlock());
struc_->setAdjusterListener(this);
thresh_->setAdjusterListener(this);
iter_->setAdjusterListener(this);
balan_->setAdjusterListener(this);
balanh_->setAdjusterListener(this);
colorde_->setAdjusterListener(this);
colorscope_->setAdjusterListener(this);
avoidrad_->setAdjusterListener(this);
preview_->set_active(false);
previewConn_ = preview_->signal_clicked().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::previewChanged));
if (showtooltip) {
balan_->set_tooltip_text(M("TP_LOCALLAB_BALAN_TOOLTIP"));
balanh_->set_tooltip_text(M("TP_LOCALLAB_BALAN_TOOLTIP"));
colorde_->set_tooltip_text(M("TP_LOCALLAB_COLORDE_TOOLTIP"));
colorscope_->set_tooltip_text(M("TP_LOCALLAB_COLORSCOPE_TOOLTIP"));
preview_->set_tooltip_text(M("TP_LOCALLAB_COLORDEPREV_TOOLTIP"));
}
// artifBox->pack_start(*struc_);
artifBox->pack_start(*thresh_);
artifBox->pack_start(*iter_);
artifBox->pack_start(*balan_);
artifBox->pack_start(*balanh_);
artifBox->pack_start(*colorde_);
// artifBox->pack_start(*preview_);
// artifBox->pack_start(*colorscope_);
expShapeDetect_->add(*artifBox, false);
pack_start(*expShapeDetect_, false, false);
// ToolParamBlock* const artifBox2 = Gtk::manage(new ToolParamBlock());
artifBox2->pack_start(*preview_);
artifBox2->pack_start(*colorscope_);//unused with contrlspotpanel since 17 / 01 : 2024 but data used in color, vibrance, sh
colorscope_->hide();
pack_start(*artifBox2);
ToolParamBlock* const specCaseBox = Gtk::manage(new ToolParamBlock());
hishowconn_ = hishow_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::hishowChanged));
activConn_ = activ_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::activChanged));
Gtk::Label* const labelgamut = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_AVOID") + ":"));
ctboxgamut->pack_start(*labelgamut, Gtk::PACK_SHRINK, 4);
avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTNON"));
avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTLABRELA"));
avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTXYZABSO"));
avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTXYZRELA"));
avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTMUNSELL"));
avoidgamutMethod_->set_active(4);
avoidgamutconn_ = avoidgamutMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::avoidgamutMethodChanged));
ctboxgamut->pack_start(*avoidgamutMethod_);
if (showtooltip) {
ctboxgamut->set_tooltip_text(M("TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP"));
}
Gtk::Frame* const avFrame = Gtk::manage(new Gtk::Frame());
ToolParamBlock* const avbox = Gtk::manage(new ToolParamBlock());
avFrame->set_label_align(0.025, 0.5);
avbox->pack_start(*ctboxgamut);
avbox->pack_start(*avoidrad_);
avFrame->add(*avbox);
specCaseBox->pack_start(*avFrame);
blwhConn_ = blwh_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::blwhChanged));
if (showtooltip) {
blwh_->set_tooltip_text(M("TP_LOCALLAB_BLWH_TOOLTIP"));
}
specCaseBox->pack_start(*blwh_);
recursConn_ = recurs_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::recursChanged));
if (showtooltip) {
recurs_->set_tooltip_text(M("TP_LOCALLAB_RECURS_TOOLTIP"));
}
specCaseBox->pack_start(*recurs_);
specCaseBox->pack_start(*ctboxshapemethod);
Gtk::Box* const ctboxwavmethod = Gtk::manage(new Gtk::Box());
Gtk::Label* const labelwavmethod = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DAUBLOCAL") + ":"));
ctboxwavmethod->pack_start(*labelwavmethod, Gtk::PACK_SHRINK, 4);
if (showtooltip) {
ctboxwavmethod->set_tooltip_markup(M("TP_WAVELET_DAUB_TOOLTIP"));
}
wavMethod_->append(M("TP_WAVELET_DAUB2"));
wavMethod_->append(M("TP_WAVELET_DAUB4"));
wavMethod_->append(M("TP_WAVELET_DAUB6"));
wavMethod_->append(M("TP_WAVELET_DAUB10"));
wavMethod_->append(M("TP_WAVELET_DAUB14"));
wavMethod_->append(M("TP_WAVELET_DAUB20"));
wavMethod_->set_active(1);
wavMethodconn_ = wavMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::wavMethodChanged));
ctboxwavmethod->pack_start(*wavMethod_);
specCaseBox->pack_start(*ctboxwavmethod);
expSpecCases_->add(*specCaseBox, false);
pack_start(*expSpecCases_, false, false);
if (showtooltip) {
expMaskMerge_->set_tooltip_text(M("TP_LOCALLAB_MASFRAME_TOOLTIP"));
}
ToolParamBlock* const maskBox = Gtk::manage(new ToolParamBlock());
laplacConn_ = laplac_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::laplacChanged));
deltaeConn_ = deltae_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::deltaeChanged));
shortcConn_ = shortc_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::shortcChanged));
if (showtooltip) {
shortc_->set_tooltip_text(M("TP_LOCALLAB_SHORTCMASK_TOOLTIP"));
}
lumask_->setAdjusterListener(this);
//savrestConn_ = savrest_->signal_toggled().connect(
// sigc::mem_fun(*this, &ControlSpotPanel::savrestChanged));
if (showtooltip) {
//savrest_->set_tooltip_text(M("TP_LOCALLAB_SAVREST_TOOLTIP"));
lumask_->set_tooltip_text(M("TP_LOCALLAB_LUMASK_TOOLTIP"));
laplac_->set_tooltip_text(M("TP_LOCALLAB_LAP_MASK_TOOLTIP"));
}
// maskBox->pack_start(*laplac_);
maskBox->pack_start(*deltae_);
maskBox->pack_start(*scopemask_);
maskBox->pack_start(*denoichmask_);
maskBox->pack_start(*feather_);
// maskBox->pack_start(*shortc_);
maskBox->pack_start(*lumask_);
// maskBox->pack_start(*savrest_);
expMaskMerge_->add(*maskBox, false);
pack_start(*expMaskMerge_, false, false);
Gtk::Separator *separatormet = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL));
pack_start(*separatormet, Gtk::PACK_SHRINK, 2);
//Gtk::Box* const ctboxcomplexmethod = Gtk::manage(new Gtk::Box());
//if (showtooltip) {
// ctboxcomplexmethod->set_tooltip_markup(M("TP_LOCALLAB_COMPLEXMETHOD_TOOLTIP"));
//}
//Gtk::Label* const labelcomplexmethod = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_COMPLEX_METHOD") + ":"));
//ctboxcomplexmethod->pack_start(*labelcomplexmethod, Gtk::PACK_SHRINK, 4);
//if (showtooltip) {
// complexMethod_->set_tooltip_markup(M("TP_LOCALLAB_COMPLEX_TOOLTIP"));
//}
//complexMethod_->append(M("TP_LOCALLAB_SIM"));
//complexMethod_->append(M("TP_LOCALLAB_MED"));
//complexMethod_->append(M("TP_LOCALLAB_ALL"));
//complexMethod_->set_active(1);
//complexMethodconn_ = complexMethod_->signal_changed().connect(
// sigc::mem_fun(
// *this, &ControlSpotPanel::complexMethodChanged));
//ctboxcomplexmethod->pack_start(*complexMethod_);
// pack_start(*ctboxcomplexmethod);
/*
Gtk::Box* const ctboxwavmethod = Gtk::manage(new Gtk::Box());
Gtk::Label* const labelwavmethod = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DAUBLOCAL") + ":"));
ctboxwavmethod->pack_start(*labelwavmethod, Gtk::PACK_SHRINK, 4);
if (showtooltip) {
ctboxwavmethod->set_tooltip_markup(M("TP_WAVELET_DAUB_TOOLTIP"));
}
wavMethod_->append(M("TP_WAVELET_DAUB2"));
wavMethod_->append(M("TP_WAVELET_DAUB4"));
wavMethod_->append(M("TP_WAVELET_DAUB6"));
wavMethod_->append(M("TP_WAVELET_DAUB10"));
wavMethod_->append(M("TP_WAVELET_DAUB14"));
wavMethod_->set_active(1);
wavMethodconn_ = wavMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::wavMethodChanged));
ctboxwavmethod->pack_start(*wavMethod_);
pack_start(*ctboxwavmethod);
*/
show_all();
// Define row background color
// Mouseovered spot (opaque orange)
colorMouseover.set_red(1.);
colorMouseover.set_green(100. / 255.);
colorMouseover.set_blue(0.);
colorMouseover.set_alpha(1.);
colorMouseovertext.set_red(0.6);
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.);
colorNominal.set_blue(0.);
colorNominal.set_alpha(0.);
}
ControlSpotPanel::~ControlSpotPanel()
{
// visibleGeometry
for (auto i = EditSubscriber::visibleGeometry.begin(); i != EditSubscriber::visibleGeometry.end(); ++i) {
delete *i;
}
// mouseOverGeometry
for (auto i = EditSubscriber::mouseOverGeometry.begin(); i != EditSubscriber::mouseOverGeometry.end(); ++i) {
delete *i;
}
}
void ControlSpotPanel::setEditProvider(EditDataProvider* provider)
{
EditSubscriber::setEditProvider(provider);
}
void ControlSpotPanel::render_name(
Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter)
{
auto row = *iter;
Gtk::CellRendererText *ct = static_cast<Gtk::CellRendererText *>(cell);
// Render cell text
ct->property_text() = row[spots_.name];
// Render cell background color
if (row[spots_.mouseover]) {
ct->property_background_rgba() = colorMouseovertext;
} else {
ct->property_background_rgba() = colorNominal;
}
}
void ControlSpotPanel::render_isvisible(
Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter)
{
auto row = *iter;
Gtk::CellRendererText *ct = static_cast<Gtk::CellRendererText *>(cell);
// Render cell text
if (row[spots_.isvisible]) {
ct->property_text() = M("TP_LOCALLAB_ROW_VIS");
} else {
ct->property_text() = M("TP_LOCALLAB_ROW_NVIS");
}
// Render cell background color
if (row[spots_.mouseover]) {
ct->property_background_rgba() = colorMouseovertext;
} else {
ct->property_background_rgba() = colorNominal;
}
}
void ControlSpotPanel::on_button_add()
{
// printf("on_button_add\n");
if (!listener) {
return;
}
// Raise event
nbSpotChanged_ = true;
selSpotChanged_ = true;
eventType = SpotCreation;
listener->panelChanged(EvLocallabSpotCreated, "-");
}
void ControlSpotPanel::on_button_delete()
{
// printf("on_button_delete\n");
if (!listener) {
return;
}
// Raise event
const int selIndex = getSelectedSpot();
if (selIndex == -1) { // No selected spot to remove
return;
}
nbSpotChanged_ = true;
selSpotChanged_ = true;
eventType = SpotDeletion;
const std::unique_ptr<SpotRow> delSpotRow = getSpot(selIndex);
listener->panelChanged(EvLocallabSpotDeleted, delSpotRow->name);
}
void ControlSpotPanel::on_button_duplicate()
{
// printf("on_button_duplicate\n");
if (!listener) {
return;
}
// Raise event
const int selIndex = getSelectedSpot();
if (selIndex == -1) { // No selected spot to duplicate
return;
}
nbSpotChanged_ = true;
selSpotChanged_ = true;
eventType = SpotDuplication;
const std::unique_ptr<SpotRow> duplSpotRow = getSpot(selIndex);
listener->panelChanged(EvLocallabSpotCreated, M("TP_LOCALLAB_EV_DUPL") + " "
+ duplSpotRow->name);
}
void ControlSpotPanel::on_button_rename()
{
// printf("on_button_rename\n");
if (!listener) {
return;
}
// Get actual control spot name
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
const Gtk::TreeModel::Row row = *iter;
const Glib::ustring actualname = row[spots_.name];
// Launch windows to update spot name
RenameDialog d(actualname,
static_cast<Gtk::Window &>(*get_toplevel()));
int status = d.run();
// 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;
treeview_->columns_autosize();
listener->panelChanged(EvLocallabSpotName, newname);
if (controlPanelListener) {
controlPanelListener->spotNameChanged(newname);
}
}
}
}
bool ControlSpotPanel::on_button_visibility(GdkEventButton* event)
{
// printf("on_button_visibility\n");
if (!listener) {
return true;
}
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return true;
}
const auto iter = s->get_selected();
const Gtk::TreeModel::Row row = *iter;
const int ctrl = event->state & GDK_CONTROL_MASK;
if (event->button == 1) { // Left click on button
if (ctrl) { // Ctrl+click case: all spots are shown/hidden
// Get visibility of selected spot
const bool selVisibility = row[spots_.isvisible];
// Update visibility of all spot
const Gtk::TreeModel::Children children = treemodel_->children();
for (auto i = children.begin(); i != children.end(); i++) {
Gtk::TreeModel::Row r = *i;
r[spots_.isvisible] = !selVisibility;
updateControlSpotCurve(r);
}
// Raise event
visibilityChanged_ = true;
eventType = SpotAllVisibilityChanged;
if (!selVisibility) {
listener->panelChanged(EvLocallabSpotVisibility, M("TP_LOCALLAB_EV_VIS_ALL"));
} else {
listener->panelChanged(EvLocallabSpotVisibility, M("TP_LOCALLAB_EV_NVIS_ALL"));
}
return true;
} else { // Click case: only selected spot is shown/hidden
// Update visibility for selected spot only
row[spots_.isvisible] = !row[spots_.isvisible];
updateControlSpotCurve(row);
// Raise event
visibilityChanged_ = true;
const std::unique_ptr<SpotRow> spotRow = getSpot(getSelectedSpot());
if (row[spots_.isvisible]) {
listener->panelChanged(EvLocallabSpotVisibility, M("TP_LOCALLAB_EV_VIS") + " (" + spotRow->name + ")");
} else {
listener->panelChanged(EvLocallabSpotVisibility, M("TP_LOCALLAB_EV_NVIS") + " (" + spotRow->name + ")");
}
return true;
}
}
return false;
}
bool ControlSpotPanel::blockTreeviewSearch(GdkEventKey* event)
{
// printf("blockTreeviewSearch\n");
if (event->state & Gdk::CONTROL_MASK) { // Ctrl
if (event->keyval == GDK_KEY_f || event->keyval == GDK_KEY_F) {
// No action is performed to avoid activating treeview search
return true;
}
}
// Otherwise key action is transferred to treeview widget
return false;
}
bool ControlSpotPanel::onSpotSelectionEvent(GdkEventButton* event)
{
if (event->state & Gdk::CONTROL_MASK) { // Ctrl
// No action is performed to avoid a situation where no spot is selected
return true;
}
// Otherwise selection action is transferred to treeview widget
return false;
}
void ControlSpotPanel::load_ControlSpot_param()
{
// printf("load_ControlSpot_param\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
const Gtk::TreeModel::Row row = *iter;
// Load param in selected control spot
prevMethod_->set_active(row[spots_.prevMethod]);
shape_->set_active(row[spots_.shape]);
spotMethod_->set_active(row[spots_.spotMethod]);
sensiexclu_->setValue((double)row[spots_.sensiexclu]);
structexclu_->setValue((double)row[spots_.structexclu]);
shapeMethod_->set_active(row[spots_.shapeMethod]);
locX_->setValue((double)row[spots_.locX]);
locXL_->setValue((double)row[spots_.locXL]);
locY_->setValue((double)row[spots_.locY]);
locYT_->setValue((double)row[spots_.locYT]);
centerX_->setValue((double)row[spots_.centerX]);
centerY_->setValue((double)row[spots_.centerY]);
circrad_->setValue((double)row[spots_.circrad]);
qualityMethod_->set_active(row[spots_.qualityMethod]);
transit_->setValue((double)row[spots_.transit]);
transitweak_->setValue((double)row[spots_.transitweak]);
transitgrad_->setValue((double)row[spots_.transitgrad]);
feather_->setValue((double)row[spots_.feather]);
struc_->setValue((double)row[spots_.struc]);
thresh_->setValue((double)row[spots_.thresh]);
iter_->setValue((double)row[spots_.iter]);
balan_->setValue((double)row[spots_.balan]);
balanh_->setValue((double)row[spots_.balanh]);
colorde_->setValue((double)row[spots_.colorde]);
colorscope_->setValue((double)row[spots_.colorscope]);
avoidrad_->setValue((double)row[spots_.avoidrad]);
hishow_->set_active(row[spots_.hishow]);
activ_->set_active(row[spots_.activ]);
blwh_->set_active(row[spots_.blwh]);
recurs_->set_active(row[spots_.recurs]);
// laplac_->set_active(row[spots_.laplac]);
laplac_->set_active(true);
deltae_->set_active(row[spots_.deltae]);
scopemask_->setValue((double)row[spots_.scopemask]);
denoichmask_->setValue(row[spots_.denoichmask]);
shortc_->set_active(row[spots_.shortc]);
lumask_->setValue((double)row[spots_.lumask]);
//savrest_->set_active(row[spots_.savrest]);
//complexMethod_->set_active(row[spots_.complexMethod]);
wavMethod_->set_active(row[spots_.wavMethod]);
avoidgamutMethod_->set_active(row[spots_.avoidgamutMethod]);
}
void ControlSpotPanel::controlspotChanged()
{
// printf("controlspotChanged\n");
if (!listener) {
return;
}
// Raise event
const int selIndex = getSelectedSpot();
if (selIndex == -1) { // No selected spot
return;
}
selSpotChanged_ = true;
eventType = SpotSelection;
const std::unique_ptr<SpotRow> spotRow = getSpot(selIndex);
// Image area shall be regenerated if mask or deltaE preview was active when switching spot
if (maskPrevActive || preview_->get_active()) {
listener->panelChanged(EvLocallabSpotSelectedWithMask, spotRow->name);
} else {
listener->panelChanged(EvLocallabSpotSelected, spotRow->name);
}
}
void ControlSpotPanel::shapeChanged()
{
// printf("shapeChanged\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.shape] = shape_->get_active_row_number();
updateControlSpotCurve(row);
// Raise event
if (listener) {
listener->panelChanged(EvLocallabSpotShape, shape_->get_active_text());
}
}
void ControlSpotPanel::prevMethodChanged()
{
// printf("prevMethodChanged\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.prevMethod] = prevMethod_->get_active_row_number();
/*
// Update Control Spot GUI according to spotMethod_ combobox state (to be compliant with updateParamVisibility function)
if (multiImage && prevMethod_->get_active_text() == M("GENERAL_UNCHANGED")) {
expTransGrad_->show();
expShapeDetect_->show();
expSpecCases_->show();
expMaskMerge_->show();
circrad_->show();
ctboxshape->show();
} else if (prevMethod_->get_active_row_number() == 0) { // Normal case
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
circrad_->hide();
ctboxshape->hide();
shapeMethod_->set_active(0);
} else { // Excluding case
expTransGrad_->show();
expShapeDetect_->show();
expSpecCases_->show();
expMaskMerge_->show();
circrad_->show();
ctboxshape->show();
}
*/
// Raise event
if (listener) {
// listener->panelChanged(EvLocallabSpotprevMethod, prevMethod_->get_active_text());
}
}
void ControlSpotPanel::spotMethodChanged()
{
//01 2024 take into account new problems linked to Global spotmethod
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
const int oldSpotMethod = row[spots_.spotMethod];
row[spots_.spotMethod] = spotMethod_->get_active_row_number();
//ctboxspotmethod->show();
hishow_->show();
ctboxshape->show();
artifBox2->show();
colorscope_->hide();
// Update Control Spot GUI according to spotMethod_ combobox state (to be compliant with updateParamVisibility function)
if (multiImage && spotMethod_->get_active_text() == M("GENERAL_UNCHANGED")) {
excluFrame->show();
} else if (spotMethod_->get_active_row_number() == 0) { // Normal case
excluFrame->hide();
// Reset spot shape only if previous spotMethod is Full image or Global
if (oldSpotMethod == 2 || oldSpotMethod == 3) {
disableParamlistener(true);
locX_->setValue(150.);
row[spots_.locX] = locX_->getIntValue();
locXL_->setValue(150.);
row[spots_.locXL] = locXL_->getIntValue();
locY_->setValue(150.);
row[spots_.locY] = locY_->getIntValue();
locYT_->setValue(150.);
row[spots_.locYT] = locYT_->getIntValue();
shape_->set_active(0);
row[spots_.shape] = shape_->get_active_row_number();
transit_->setValue(60.);
row[spots_.transit] = transit_->getValue();
disableParamlistener(false);
updateControlSpotCurve(row);
}
} else if (spotMethod_->get_active_row_number() == 1) { // Excluding case
excluFrame->show();
// Reset spot shape only if previous spotMethod is Full image or Global
if (oldSpotMethod == 2 || oldSpotMethod == 3) {
disableParamlistener(true);
locX_->setValue(150.);
row[spots_.locX] = locX_->getIntValue();
locXL_->setValue(150.);
row[spots_.locXL] = locXL_->getIntValue();
locY_->setValue(150.);
row[spots_.locY] = locY_->getIntValue();
locYT_->setValue(150.);
row[spots_.locYT] = locYT_->getIntValue();
shape_->set_active(0);
row[spots_.shape] = shape_->get_active_row_number();
transit_->setValue(60.);
row[spots_.transit] = transit_->getValue();
disableParamlistener(false);
updateControlSpotCurve(row);
}
} else if (spotMethod_->get_active_row_number() == 2 || spotMethod_->get_active_row_number() == 3) { // Full image or Global case
excluFrame->hide();
shape_->set_active(0);
locX_->setValue(3000.);
row[spots_.locX] = locX_->getIntValue();
locXL_->setValue(3000.);
row[spots_.locXL] = locXL_->getIntValue();
locY_->setValue(3000.);
row[spots_.locY] = locY_->getIntValue();
locYT_->setValue(3000.);
row[spots_.locYT] = locYT_->getIntValue();
shape_->set_active(1);
row[spots_.shape] = shape_->get_active_row_number();
transit_->setValue(100.);
row[spots_.transit] = transit_->getValue();
if(spotMethod_->get_active_row_number() == 3) { //global
ctboxshape->hide();
artifBox2->hide();
hishow_->hide();
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
circrad_->hide();
ctboxshape->hide();
} else {
ctboxshape->show();
circrad_->show();
artifBox2->show();
colorscope_->hide();
hishow_->show();
if(hishow_->get_active()) {
expTransGrad_->show();
expShapeDetect_->show();
expSpecCases_->show();
expMaskMerge_->show();
}
}
}
// Raise event
if (listener) {
listener->panelChanged(EvLocallabSpotSpotMethod, spotMethod_->get_active_text());
}
}
void ControlSpotPanel::avoidgamutMethodChanged()
{
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const int meth = avoidgamutMethod_->get_active_row_number();
avoidrad_->show();
if(meth == 2 || meth == 3 || meth == 4) {
avoidrad_->hide();
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.avoidgamutMethod] = avoidgamutMethod_->get_active_row_number();
// Raise event
if (listener) {
listener->panelChanged(EvLocallabavoidgamutMethod, avoidgamutMethod_->get_active_text());
}
}
void ControlSpotPanel::shapeMethodChanged()
{
// printf("shapeMethodChanged\n");
const int method = shapeMethod_->get_active_row_number();
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
if (!batchMode && (method == 1 || method == 3)) { // Symmetrical cases
disableParamlistener(true);
locXL_->setValue(locX_->getValue());
locYT_->setValue(locY_->getValue());
disableParamlistener(false);
row[spots_.shapeMethod] = shapeMethod_->get_active_row_number();
row[spots_.locXL] = locX_->getIntValue();
row[spots_.locYT] = locY_->getIntValue();
updateControlSpotCurve(row);
} else { // In batch mode, sliders are always independent
row[spots_.shapeMethod] = shapeMethod_->get_active_row_number();
}
// Update Control Spot GUI according to shapeMethod_ combobox state (to be compliant with updateParamVisibility function)
if (!batchMode) {
if (method == 1 || method == 3) { // Symmetrical cases
locXL_->hide();
locYT_->hide();
if (method == 1) { // 1 = Symmetrical (mouse)
locX_->hide();
locY_->hide();
centerX_->hide();
centerY_->hide();
} else { // 3 = Symmetrical (mouse + sliders)
locX_->show();
locY_->show();
centerX_->show();
centerY_->show();
}
} else { // Independent cases
if (method == 0) { // 0 = Independent (mouse)
locX_->hide();
locXL_->hide();
locY_->hide();
locYT_->hide();
centerX_->hide();
centerY_->hide();
} else { // 2 = Independent (mouse + sliders)
locX_->show();
locXL_->show();
locY_->show();
locYT_->show();
centerX_->show();
centerY_->show();
}
}
} else { // In batch mode, sliders are necessary shown
locX_->show();
locXL_->show();
locY_->show();
locYT_->show();
centerX_->show();
centerY_->show();
}
// Raise event
if (listener) {
listener->panelChanged(EvLocallabSpotShapeMethod, shapeMethod_->get_active_text());
}
}
void ControlSpotPanel::qualityMethodChanged()
{
// printf("qualityMethodChanged\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.qualityMethod] = qualityMethod_->get_active_row_number();
// Raise event
if (listener) {
listener->panelChanged(EvLocallabSpotQualityMethod, qualityMethod_->get_active_text());
}
}
//void ControlSpotPanel::complexMethodChanged()
//{
// // printf("qualityMethodChanged\n");
//
// // Get selected control spot
// const auto s = treeview_->get_selection();
//
// if (!s->count_selected_rows()) {
// return;
// }
//
// const auto iter = s->get_selected();
// Gtk::TreeModel::Row row = *iter;
//
// row[spots_.complexMethod] = complexMethod_->get_active_row_number();
//
// if (multiImage && complexMethod_->get_active_text() == M("GENERAL_UNCHANGED")) {
// // excluFrame->show();
// } else if (complexMethod_->get_active_row_number() == 0) { //sim
// // excluFrame->hide();
// } else if (complexMethod_->get_active_row_number() == 1) { // mod
// // excluFrame->show();
// } else if (complexMethod_->get_active_row_number() == 2) { // all
// // excluFrame->show();
// }
//
// // Raise event
// if (listener) {
// listener->panelChanged(EvLocallabSpotcomplexMethod, complexMethod_->get_active_text());
// }
//}
void ControlSpotPanel::wavMethodChanged()
{
// printf("qualityMethodChanged\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.wavMethod] = wavMethod_->get_active_row_number();
// Raise event
if (listener) {
listener->panelChanged(EvLocallabSpotwavMethod, wavMethod_->get_active_text());
}
}
void ControlSpotPanel::updateParamVisibility()
{
// printf("updateParamVisibility\n");
// Update Control Spot GUI according to shapeMethod_ combobox state (to be compliant with shapeMethodChanged function)
const int method = shapeMethod_->get_active_row_number();
const int meth = avoidgamutMethod_->get_active_row_number();
if (!batchMode) {
if (method == 1 || method == 3) { // Symmetrical cases
locXL_->hide();
locYT_->hide();
if (method == 1) { // 1 = Symmetrical (mouse)
locX_->hide();
locY_->hide();
centerX_->hide();
centerY_->hide();
} else { // 3 = Symmetrical (mouse + sliders)
locX_->show();
locY_->show();
centerX_->show();
centerY_->show();
}
} else { // Independent cases
if (method == 0) { // 0 = Independent (mouse)
locX_->hide();
locXL_->hide();
locY_->hide();
locYT_->hide();
centerX_->hide();
centerY_->hide();
} else { // 2 = Independent (mouse + sliders)
locX_->show();
locXL_->show();
locY_->show();
locYT_->show();
centerX_->show();
centerY_->show();
}
}
} else { // In batch mode, sliders are necessary shown
locX_->show();
locXL_->show();
locY_->show();
locYT_->show();
centerX_->show();
centerY_->show();
}
if(meth == 1) {
avoidrad_->show();
} else {
avoidrad_->hide();
}
// ctboxspotmethod->show();
hishow_->show();
artifBox2->show();
ctboxshape->show();
colorscope_->hide();
// Update Control Spot GUI according to spotMethod_ combobox state (to be compliant with spotMethodChanged function)
if (multiImage && spotMethod_->get_active_text() == M("GENERAL_UNCHANGED")) {
excluFrame->show();
} else if (spotMethod_->get_active_row_number() == 0) { // Normal case
excluFrame->hide();
} else if (spotMethod_->get_active_row_number() == 1) { // Excluding case
excluFrame->show();
} else if (spotMethod_->get_active_row_number() == 2 || spotMethod_->get_active_row_number() == 3) {//full image or global
excluFrame->hide();
if(spotMethod_->get_active_row_number() == 3) {
artifBox2->hide();
hishow_->hide();
hishow_->set_active(false);
ctboxshape->hide();
circrad_->hide();
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
} else {
artifBox2->show();
colorscope_->hide();
hishow_->show();
ctboxshape->show();
circrad_->show();
if(hishow_->get_active()) {
expTransGrad_->show();
expShapeDetect_->show();
expSpecCases_->show();
expMaskMerge_->show();
}
}
}
/*
if (multiImage && prevMethod_->get_active_text() == M("GENERAL_UNCHANGED")) {
expTransGrad_->show();
expShapeDetect_->show();
expSpecCases_->show();
expMaskMerge_->show();
circrad_->show();
ctboxshape->show();
} else if (prevMethod_->get_active_row_number() == 0) { // Normal case
*/
//ctboxshape->show();
// artifBox2->show();
if (!hishow_->get_active() || spotMethod_->get_active_row_number() == 3) { // Normal case or Global
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
circrad_->hide();
ctboxshape->hide();
if(spotMethod_->get_active_row_number() == 3) {
artifBox2->hide();
hishow_->hide();
ctboxshape->hide();
circrad_->hide();
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
} else {
hishow_->show();
artifBox2->show();
colorscope_->hide();
hishow_->show();
ctboxshape->show();
circrad_->show();
}
} else { // Excluding case
expTransGrad_->show();
expShapeDetect_->show();
expSpecCases_->show();
expMaskMerge_->show();
circrad_->show();
ctboxshape->show();
hishow_->show();
}
}
void ControlSpotPanel::adjusterChanged(Adjuster* a, double newval)
{
// printf("adjusterChanged\n");
const int method = shapeMethod_->get_active_row_number();
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
if (a == sensiexclu_) {
row[spots_.sensiexclu] = sensiexclu_->getIntValue();
if (listener) {
listener->panelChanged(EvLocallabSpotSensiexclu, sensiexclu_->getTextValue());
}
}
if (a == structexclu_) {
row[spots_.structexclu] = structexclu_->getIntValue();
if (listener) {
listener->panelChanged(Evlocallabstructexlu, structexclu_->getTextValue());
}
}
if (a == locX_) {
row[spots_.locX] = locX_->getIntValue();
if (!batchMode && (method == 1 || method == 3)) { // Symmetrical cases (in batch mode, sliders are always independent)
disableParamlistener(true);
locXL_->setValue(locX_->getValue());
disableParamlistener(false);
row[spots_.locXL] = locXL_->getIntValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocX, locX_->getTextValue());
}
}
if (a == locXL_) {
row[spots_.locXL] = locXL_->getIntValue();
if (!batchMode && (method == 1 || method == 3)) { // Symmetrical cases (in batch mode, sliders are always independent)
disableParamlistener(true);
locX_->setValue(locXL_->getValue());
disableParamlistener(false);
row[spots_.locX] = locX_->getIntValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocXL, locXL_->getTextValue());
}
}
if (a == locY_) {
row[spots_.locY] = locY_->getIntValue();
if (!batchMode && (method == 1 || method == 3)) { // Symmetrical cases (in batch mode, sliders are always independent)
disableParamlistener(true);
locYT_->setValue(locY_->getValue());
disableParamlistener(false);
row[spots_.locYT] = locYT_->getIntValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocY, locY_->getTextValue());
}
}
if (a == locYT_) {
row[spots_.locYT] = locYT_->getIntValue();
if (!batchMode && (method == 1 || method == 3)) { // Symmetrical cases (in batch mode, sliders are always independent)
disableParamlistener(true);
locY_->setValue(locYT_->getValue());
disableParamlistener(false);
row[spots_.locY] = locY_->getIntValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocYT, locYT_->getTextValue());
}
}
if (a == centerX_ || a == centerY_) {
row[spots_.centerX] = centerX_->getIntValue();
row[spots_.centerY] = centerY_->getIntValue();
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotCenter, "X=" + centerX_->getTextValue() + ", Y=" + centerY_->getTextValue());
}
}
if (a == circrad_) {
row[spots_.circrad] = circrad_->getValue();
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotCircrad, circrad_->getTextValue());
}
}
if (a == transit_) {
row[spots_.transit] = transit_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotTransit, transit_->getTextValue());
}
}
if (a == transitweak_) {
row[spots_.transitweak] = transitweak_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotTransitweak, transitweak_->getTextValue());
}
}
if (a == transitgrad_) {
row[spots_.transitgrad] = transitgrad_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotTransitgrad, transitgrad_->getTextValue());
}
}
if (a == feather_) {
row[spots_.feather] = feather_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotfeather, feather_->getTextValue());
}
}
if (a == struc_) {
row[spots_.struc] = struc_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotStruc, struc_->getTextValue());
}
}
if (a == thresh_) {
row[spots_.thresh] = thresh_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotThresh, thresh_->getTextValue());
}
}
if (a == iter_) {
row[spots_.iter] = iter_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotIter, iter_->getTextValue());
}
}
if (a == balan_) {
row[spots_.balan] = balan_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotbalan, balan_->getTextValue());
}
}
if (a == balanh_) {
row[spots_.balanh] = balanh_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotbalanh, balanh_->getTextValue());
}
}
if (a == colorde_) {
row[spots_.colorde] = colorde_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotcolorde, colorde_->getTextValue());
}
}
if (a == colorscope_) {
row[spots_.colorscope] = colorscope_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotcolorscope, colorscope_->getTextValue());
}
}
if (a == avoidrad_) {
row[spots_.avoidrad] = avoidrad_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotavoidrad, avoidrad_->getTextValue());
}
}
if (a == scopemask_) {
row[spots_.scopemask] = scopemask_->getIntValue();
if (listener) {
listener->panelChanged(EvLocallabSpotscopemask, scopemask_->getTextValue());
}
}
if (a == denoichmask_) {
row[spots_.denoichmask] = denoichmask_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotdenoichmask, denoichmask_->getTextValue());
}
}
if (a == lumask_) {
row[spots_.lumask] = lumask_->getIntValue();
if (listener) {
listener->panelChanged(EvLocallabSpotlumask, lumask_->getTextValue());
}
}
}
void ControlSpotPanel::hishowChanged()
{
// printf("avoidChanged\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.hishow] = hishow_->get_active();
ctboxshape->show();
if (!hishow_->get_active() || spotMethod_->get_active_row_number() == 3) { // Normal case or Global
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
circrad_->hide();
ctboxshape->hide();
shapeMethod_->set_active(0);
if(spotMethod_->get_active_row_number() == 3) {
hishow_->hide();
hishow_->set_active(false);
circrad_->hide();
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
} else {
hishow_->show();
circrad_->show();
}
} else { // Excluding case
expTransGrad_->show();
expShapeDetect_->show();
expSpecCases_->show();
expMaskMerge_->show();
circrad_->show();
ctboxshape->show();
hishow_->show();
}
// Raise event
if (listener) {
if (hishow_->get_active()) {
listener->panelChanged(Evlocallabhishow, M("GENERAL_ENABLED"));
} else {
listener->panelChanged(Evlocallabhishow, M("GENERAL_DISABLED"));
}
}
}
void ControlSpotPanel::activChanged()
{
// printf("activChanged\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.activ] = activ_->get_active();
// Raise event
if (listener) {
if (activ_->get_active()) {
listener->panelChanged(Evlocallabactiv, M("GENERAL_ENABLED"));
} else {
listener->panelChanged(Evlocallabactiv, M("GENERAL_DISABLED"));
}
}
}
void ControlSpotPanel::blwhChanged()
{
// printf("blwhChanged\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.blwh] = blwh_->get_active();
// Raise event
if (listener) {
if (blwh_->get_active()) {
listener->panelChanged(Evlocallabblwh, M("GENERAL_ENABLED"));
} else {
listener->panelChanged(Evlocallabblwh, M("GENERAL_DISABLED"));
}
}
}
void ControlSpotPanel::recursChanged()
{
// printf("recursChanged\n");
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.recurs] = recurs_->get_active();
// Raise event
if (listener) {
if (recurs_->get_active()) {
listener->panelChanged(Evlocallabrecurs, M("GENERAL_ENABLED"));
} else {
listener->panelChanged(Evlocallabrecurs, M("GENERAL_DISABLED"));
}
}
}
void ControlSpotPanel::laplacChanged()
{
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.laplac] = laplac_->get_active();
// Raise event
if (listener) {
if (laplac_->get_active()) {
listener->panelChanged(Evlocallablaplac, M("GENERAL_ENABLED"));
} else {
listener->panelChanged(Evlocallablaplac, M("GENERAL_DISABLED"));
}
}
}
void ControlSpotPanel::deltaeChanged()
{
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.deltae] = deltae_->get_active();
// Raise event
if (listener) {
if (deltae_->get_active()) {
listener->panelChanged(Evlocallabdeltae, M("GENERAL_ENABLED"));
} else {
listener->panelChanged(Evlocallabdeltae, M("GENERAL_DISABLED"));
}
}
}
void ControlSpotPanel::shortcChanged()
{
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.shortc] = shortc_->get_active();
// Raise event
if (listener) {
if (shortc_->get_active()) {
listener->panelChanged(Evlocallabshortc, M("GENERAL_ENABLED"));
} else {
listener->panelChanged(Evlocallabshortc, M("GENERAL_DISABLED"));
}
}
}
//void ControlSpotPanel::savrestChanged()
//{
// // Get selected control spot
// const auto s = treeview_->get_selection();
//
// if (!s->count_selected_rows()) {
// return;
// }
//
// const auto iter = s->get_selected();
// Gtk::TreeModel::Row row = *iter;
// row[spots_.savrest] = savrest_->get_active();
//
// // Raise event
// if (listener) {
// if (savrest_->get_active()) {
// listener->panelChanged(Evlocallabsavrest, M("GENERAL_ENABLED"));
// } else {
// listener->panelChanged(Evlocallabsavrest, M("GENERAL_DISABLED"));
// }
// }
//}
void ControlSpotPanel::previewChanged()
{
// If deltaE preview is activated, deactivate all other tool mask preview
if (controlPanelListener) {
controlPanelListener->resetToolMaskView();
}
if (listener) {
listener->panelChanged(EvlocallabshowmaskMethod, "");
}
}
void ControlSpotPanel::disableParamlistener(bool cond)
{
// printf("disableParamlistener: %d\n", cond);
treeviewconn_.block(cond);
buttonaddconn_.block(cond);
buttondeleteconn_.block(cond);
buttonduplicateconn_.block(cond);
buttonrenameconn_.block(cond);
buttonvisibilityconn_.block(cond);
prevMethodconn_.block(cond);
shapeconn_.block(cond);
spotMethodconn_.block(cond);
sensiexclu_->block(cond);
structexclu_->block(cond);
shapeMethodconn_.block(cond);
locX_->block(cond);
locXL_->block(cond);
locY_->block(cond);
locYT_->block(cond);
centerX_->block(cond);
centerY_->block(cond);
circrad_->block(cond);
qualityMethodconn_.block(cond);
transit_->block(cond);
transitweak_->block(cond);
transitgrad_->block(cond);
feather_->block(cond);
struc_->block(cond);
thresh_->block(cond);
iter_->block(cond);
balan_->block(cond);
balanh_->block(cond);
colorde_->block(cond);
colorscope_->block(cond);
avoidrad_->block(cond);
hishowconn_.block(cond);
activConn_.block(cond);
blwhConn_.block(cond);
recursConn_.block(cond);
laplacConn_.block(cond);
deltaeConn_.block(cond);
scopemask_->block(cond);
denoichmask_->block(cond);
shortcConn_.block(cond);
lumask_->block(cond);
//savrestConn_.block(cond);
//complexMethodconn_.block(cond);
wavMethodconn_.block(cond);
avoidgamutconn_.block(cond);
}
void ControlSpotPanel::setParamEditable(bool cond)
{
// printf("setParamEditable: %d\n", cond);
prevMethod_->set_sensitive(cond);
shape_->set_sensitive(cond);
spotMethod_->set_sensitive(cond);
sensiexclu_->set_sensitive(cond);
structexclu_->set_sensitive(cond);
shapeMethod_->set_sensitive(cond);
locX_->set_sensitive(cond);
locXL_->set_sensitive(cond);
locY_->set_sensitive(cond);
locYT_->set_sensitive(cond);
centerX_->set_sensitive(cond);
centerY_->set_sensitive(cond);
circrad_->set_sensitive(cond);
qualityMethod_->set_sensitive(cond);
transit_->set_sensitive(cond);
transitweak_->set_sensitive(cond);
transitgrad_->set_sensitive(cond);
feather_->set_sensitive(cond);
struc_->set_sensitive(cond);
thresh_->set_sensitive(cond);
iter_->set_sensitive(cond);
balan_->set_sensitive(cond);
balanh_->set_sensitive(cond);
colorde_->set_sensitive(cond);
colorscope_->set_sensitive(cond);
avoidrad_->set_sensitive(cond);
hishow_->set_sensitive(cond);
activ_->set_sensitive(cond);
blwh_->set_sensitive(cond);
recurs_->set_sensitive(cond);
laplac_->set_sensitive(cond);
deltae_->set_sensitive(cond);
scopemask_->set_sensitive(cond);
denoichmask_->set_sensitive(cond);
shortc_->set_sensitive(cond);
lumask_->set_sensitive(cond);
//savrest_->set_sensitive(cond);
//complexMethod_->set_sensitive(cond);
wavMethod_->set_sensitive(cond);
preview_->set_sensitive(cond);
avoidgamutMethod_->set_sensitive(cond);
if (!cond) {
// Reset complex parameters visibility to default state
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
circrad_->hide();
ctboxshape->hide();
excluFrame->hide();
// ctboxshapemethod->hide();
locX_->hide();
locXL_->hide();
locY_->hide();
locYT_->hide();
centerX_->hide();
centerY_->hide();
}
}
void ControlSpotPanel::setDefaultExpanderVisibility()
{
expTransGrad_->set_expanded(false);
expShapeDetect_->set_expanded(false);
expSpecCases_->set_expanded(false);
expMaskMerge_->set_expanded(false);
}
void ControlSpotPanel::addControlSpotCurve(Gtk::TreeModel::Row& row)
{
// printf("addControlSpotCurve\n");
if (row[spots_.curveid] > 0) { // Row has already an associated curve
return;
}
// Creation of visibleGeometry
Circle* cirX;
cirX = new Circle();
cirX->radius = 4.;
cirX->filled = true;
cirX->datum = Geometry::IMAGE;
Circle* cirXL;
cirXL = new Circle();
cirXL->radius = 4.;
cirXL->filled = true;
cirXL->datum = Geometry::IMAGE;
Circle* cirY;
cirY = new Circle();
cirY->radius = 4.;
cirY->filled = true;
cirY->datum = Geometry::IMAGE;
Circle* cirYT;
cirYT = new Circle();
cirYT->radius = 4.;
cirYT->filled = true;
cirYT->datum = Geometry::IMAGE;
Circle* centerCircle;
centerCircle = new Circle();
centerCircle->datum = Geometry::IMAGE;
centerCircle->radiusInImageSpace = true;
Ellipse* shape_ellipse;
shape_ellipse = new Ellipse();
shape_ellipse->datum = Geometry::IMAGE;
shape_ellipse->radiusInImageSpace = true;
EditRectangle* shape_rectangle;
shape_rectangle = new EditRectangle();
shape_rectangle->datum = Geometry::IMAGE;
EditSubscriber::visibleGeometry.push_back(centerCircle); // (curveid - 1) * 7
EditSubscriber::visibleGeometry.push_back(shape_ellipse); // (curveid - 1) * 7 + 1
EditSubscriber::visibleGeometry.push_back(shape_rectangle); // (curveid - 1) * 7 + 2
EditSubscriber::visibleGeometry.push_back(cirX); // (curveid - 1) * 7 + 3
EditSubscriber::visibleGeometry.push_back(cirXL); // (curveid - 1) * 7 + 4
EditSubscriber::visibleGeometry.push_back(cirY); // (curveid - 1) * 7 + 5
EditSubscriber::visibleGeometry.push_back(cirYT); // (curveid - 1) * 7 + 6
// Creation of mouseOverGeometry
cirX = new Circle();
cirX->radius = 4.;
cirX->filled = true;
cirX->datum = Geometry::IMAGE;
cirXL = new Circle();
cirXL->radius = 4.;
cirXL->filled = true;
cirXL->datum = Geometry::IMAGE;
cirY = new Circle();
cirY->radius = 4.;
cirY->filled = true;
cirY->datum = Geometry::IMAGE;
cirYT = new Circle();
cirYT->radius = 4.;
cirYT->filled = true;
cirYT->datum = Geometry::IMAGE;
centerCircle = new Circle();
centerCircle->filled = true;
centerCircle->datum = Geometry::IMAGE;
centerCircle->radiusInImageSpace = true;
shape_ellipse = new Ellipse();
shape_ellipse->datum = Geometry::IMAGE;
shape_ellipse->radiusInImageSpace = true;
shape_rectangle = new EditRectangle();
shape_rectangle->datum = Geometry::IMAGE;
EditSubscriber::mouseOverGeometry.push_back(centerCircle); // (curveid - 1) * 7
EditSubscriber::mouseOverGeometry.push_back(shape_ellipse); // (curveid - 1) * 7 + 1
EditSubscriber::mouseOverGeometry.push_back(shape_rectangle); // (curveid - 1) * 7 + 2
EditSubscriber::mouseOverGeometry.push_back(cirX); // (curveid - 1) * 7 + 3
EditSubscriber::mouseOverGeometry.push_back(cirXL); // (curveid - 1) * 7 + 4
EditSubscriber::mouseOverGeometry.push_back(cirY); // (curveid - 1) * 7 + 5
EditSubscriber::mouseOverGeometry.push_back(cirYT); // (curveid - 1) * 7 + 6
row[spots_.curveid] = EditSubscriber::visibleGeometry.size() / 7;
}
void ControlSpotPanel::updateControlSpotCurve(const Gtk::TreeModel::Row& row)
{
const int curveid_ = row[spots_.curveid];
EditDataProvider* const dataProvider = getEditProvider();
// printf("updateControlSpotCurve: %d\n", curveid_);
if (curveid_ == 0 || !dataProvider) { // Row has no associated curve or there is no EditProvider
return;
}
int imW = 0;
int imH = 0;
dataProvider->getImageSize(imW, imH);
if (!imW || !imH) { // No image loaded
return;
}
const int centerX_ = row[spots_.centerX];
const int centerY_ = row[spots_.centerY];
const int circrad_ = row[spots_.circrad];
const int locX_ = row[spots_.locX];
const int locXL_ = row[spots_.locXL];
const int locY_ = row[spots_.locY];
const int locYT_ = row[spots_.locYT];
const int shape_ = row[spots_.shape];
const bool isvisible_ = row[spots_.isvisible];
const int decayX = (double)locX_ * (double)imW / 2000.;
const int decayXL = (double)locXL_ * (double)imW / 2000.;
const int decayY = (double)locY_ * (double)imH / 2000.;
const int decayYT = (double)locYT_ * (double)imH / 2000.;
const rtengine::Coord origin((double)imW / 2. + (double)centerX_ * (double)imW / 2000., (double)imH / 2. + (double)centerY_ * (double)imH / 2000.);
const auto updateSelectionCircle = [&](Geometry * geometry, const int offsetX, const int offsetY) {
const auto cir = static_cast<Circle*>(geometry);
cir->center.x = origin.x + offsetX;
cir->center.y = origin.y + offsetY;
};
const auto updateCenterCircle = [&](Geometry * geometry) {
const auto circle = static_cast<Circle*>(geometry);
circle->center = origin;
circle->radius = circrad_;
};
const auto updateEllipse = [&](Geometry * geometry) {
const auto ellipse = static_cast<Ellipse*>(geometry);
ellipse->center = origin;
ellipse->radX = decayX;
ellipse->radXL = decayXL;
ellipse->radY = decayY;
ellipse->radYT = decayYT;
};
const auto updateRectangle = [&](Geometry * geometry) {
const auto rectangle = static_cast<EditRectangle*>(geometry);
rectangle->bottomRight.x = origin.x + decayX;
rectangle->bottomRight.y = origin.y + decayY;
rectangle->topLeft.x = origin.x - decayXL;
rectangle->topLeft.y = origin.y - decayYT;
};
updateCenterCircle(visibleGeometry.at((curveid_ - 1) * 7));
updateCenterCircle(mouseOverGeometry.at((curveid_ - 1) * 7));
updateEllipse(visibleGeometry.at((curveid_ - 1) * 7 + 1));
updateEllipse(mouseOverGeometry.at((curveid_ - 1) * 7 + 1));
updateRectangle(visibleGeometry.at((curveid_ - 1) * 7 + 2));
updateRectangle(mouseOverGeometry.at((curveid_ - 1) * 7 + 2));
updateSelectionCircle(visibleGeometry.at((curveid_ - 1) * 7 + 3), decayX, 0.);
updateSelectionCircle(mouseOverGeometry.at((curveid_ - 1) * 7 + 3), decayX, 0.);
updateSelectionCircle(visibleGeometry.at((curveid_ - 1) * 7 + 4), -decayXL, 0.);
updateSelectionCircle(mouseOverGeometry.at((curveid_ - 1) * 7 + 4), -decayXL, 0.);
updateSelectionCircle(visibleGeometry.at((curveid_ - 1) * 7 + 5), 0., decayY);
updateSelectionCircle(mouseOverGeometry.at((curveid_ - 1) * 7 + 5), 0., decayY);
updateSelectionCircle(visibleGeometry.at((curveid_ - 1) * 7 + 6), 0., -decayYT);
updateSelectionCircle(mouseOverGeometry.at((curveid_ - 1) * 7 + 6), 0., -decayYT);
// Update Arcellipse/Rectangle visibility according to shape and visibility
if (isvisible_) {
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7)->setActive(true); // centerCircle
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 3)->setActive(true); // cirX
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 4)->setActive(true); // cirXL
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 5)->setActive(true); // cirY
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 6)->setActive(true); // cirYT
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7)->setActive(true); // centerCircle
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 3)->setActive(true); // cirX
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 4)->setActive(true); // cirXL
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 5)->setActive(true); // cirY
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 6)->setActive(true); // cirYT
if (shape_ == 0) { // 0 = Ellipse
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 1)->setActive(true); // shape_ellipse
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 2)->setActive(false); // shape_rectangle
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 1)->setActive(true); // shape_ellipse
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 2)->setActive(false); // shape_rectangle
} else { // 1 = Rectangle
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 1)->setActive(false); // shape_ellipse
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 2)->setActive(true); // shape_rectangle
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 1)->setActive(false); // shape_ellipse
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 2)->setActive(true); // shape_rectangle
}
} else {
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7)->setActive(false); // centerCircle
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 1)->setActive(false); // shape_ellipse
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 2)->setActive(false); // shape_rectangle
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 3)->setActive(false); // cirX
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 4)->setActive(false); // cirXL
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 5)->setActive(false); // cirY
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 7 + 6)->setActive(false); // cirYT
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7)->setActive(false); // centerCircle
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 1)->setActive(false); // shape_ellipse
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 2)->setActive(false); // shape_rectangle
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 3)->setActive(false); // cirX
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 4)->setActive(false); // cirXL
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 5)->setActive(false); // cirY
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 7 + 6)->setActive(false); // cirYT
}
}
void ControlSpotPanel::deleteControlSpotCurve(Gtk::TreeModel::Row& row)
{
const int curveid_ = row[spots_.curveid];
// printf("deleteControlSpotCurve: %d\n", curveid_);
if (curveid_ == 0) { // Row has no associated curve
return;
}
// visibleGeometry
for (int i = 6; i >= 0; i--) {
delete *(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 7 + i);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 7 + i);
}
// mouseOverGeometry
for (int i = 6; i >= 0; i--) {
delete *(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 7 + i);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 7 + i);
}
row[spots_.curveid] = 0; // Reset associated curve id
// Reordering curve id
const Gtk::TreeModel::Children children = treemodel_->children();
for (auto iter = children.begin(); iter != children.end(); iter++) {
Gtk::TreeModel::Row r = *iter;
if (r[spots_.curveid] > curveid_) {
r[spots_.curveid] = r[spots_.curveid] - 1;
}
}
}
void ControlSpotPanel::updateCurveOpacity(const Gtk::TreeModel::Row& selectedRow)
{
const int curveid_ = selectedRow[spots_.curveid];
// printf("updateCurveOpacity: %d\n", curveid_);
if (curveid_ == 0) { // Row has no associated curve
return;
}
for (int it_ = 0; it_ < (int) EditSubscriber::visibleGeometry.size(); it_++) {
if ((it_ < ((curveid_ - 1) * 7)) || (it_ > ((curveid_ - 1) * 7) + 6)) { // it_ does not belong to selected curve
EditSubscriber::visibleGeometry.at(it_)->opacity = 25.;
} else {
EditSubscriber::visibleGeometry.at(it_)->opacity = 75.;
}
}
}
CursorShape ControlSpotPanel::getCursor(int objectID, int xPos, int yPos) const
{
// printf("Object ID: %d\n", objectID);
// 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;
}
const int rem_ = objectID % 7;
switch (rem_) {
case (0): // centerCircle: (curveid_ - 1) * 7
return CSMove2D;
case (1): // shape_ellipse: (curveid_ - 1) * 7 + 1
return CSMove2D;
case (2): // shape_rectangle: (curveid_ - 1) * 7 + 2
return CSMove2D;
case (3): // cirX: (curveid_ - 1) * 7 + 3
return CSMove1DH;
case (4): // cirXL: (curveid_ - 1) * 7 + 4
return CSMove1DH;
case (5): // cirY: (curveid_ - 1) * 7 + 5
return CSMove1DV;
case (6): // cirYT: (curveid_ - 1) * 7 + 6
return CSMove1DV;
default:
return CSHandOpen;
}
}
bool ControlSpotPanel::mouseOver(int modifierKey)
{
EditDataProvider* editProvider_ = getEditProvider();
const auto s = treeview_->get_selection();
if (!editProvider_ || !s->count_selected_rows()) { // When there is no control spot (i.e. no selected row), objectID can unexpectedly be different from -1 and produced not desired behavior
return false;
}
// Get selected row
const auto selIter = s->get_selected();
const Gtk::TreeModel::Row selRow = *selIter;
const int object_ = editProvider_->object;
if (object_ != lastObject_) {
if (object_ == -1) {
// Reset mouseOver preview for visibleGeometry
for (size_t it_ = 0; it_ < EditSubscriber::visibleGeometry.size(); it_++) {
EditSubscriber::visibleGeometry.at(it_)->state = Geometry::NORMAL;
}
// Reset mouseOver preview for TreeView
const Gtk::TreeModel::Children children = treemodel_->children();
for (auto iter = children.begin(); iter != children.end(); iter++) {
Gtk::TreeModel::Row row = *iter;
row[spots_.mouseover] = false;
}
// Actualize lastObject_
lastObject_ = object_;
return false;
}
const int curveId_ = object_ / 7 + 1;
const int rem = object_ % 7;
// Manage mouseOver preview for TreeView
const Gtk::TreeModel::Children children = treemodel_->children();
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 {
row[spots_.mouseover] = false;
}
}
for (int it_ = 0; it_ < (int) EditSubscriber::visibleGeometry.size(); it_++) {
if ((it_ < ((curveId_ - 1) * 7)) || (it_ > ((curveId_ - 1) * 7) + 6)) { // it_ does not belong to cursor pointed curve
EditSubscriber::visibleGeometry.at(it_)->state = Geometry::NORMAL;
}
}
const int method = shapeMethod_->get_active_row_number();
// Circle, Arcellipses and Rectangle
if (rem >= 0 && rem < 3) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 1)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 2)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 3)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 4)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 5)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 6)->state = Geometry::PRELIGHT;
} else {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 2)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 3)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 4)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 4)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 5)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 6)->state = Geometry::NORMAL;
}
// cirX
if (rem == 3) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 3)->state = Geometry::PRELIGHT;
if (method == 1 || method == 3) { // Symmetrical cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 4)->state = Geometry::PRELIGHT;
}
}
// cirXL
if (rem == 4) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 4)->state = Geometry::PRELIGHT;
if (method == 1 || method == 3) { // Symmetrical cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 3)->state = Geometry::PRELIGHT;
}
}
// cirY
if (rem == 5) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 5)->state = Geometry::PRELIGHT;
if (method == 1 || method == 3) { // Symmetrical cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 6)->state = Geometry::PRELIGHT;
}
}
// cirYT
if (rem == 6) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 6)->state = Geometry::PRELIGHT;
if (method == 1 || method == 3) { // Symmetrical cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 7 + 5)->state = Geometry::PRELIGHT;
}
}
lastObject_ = object_;
return true;
}
return false;
}
bool ControlSpotPanel::button1Pressed(int modifierKey)
{
// printf("button1Pressed\n");
EditDataProvider *provider = getEditProvider();
const auto s = treeview_->get_selection();
if (!provider || lastObject_ == -1 || !s->count_selected_rows()) { // When there is no control spot (i.e. no selected row), objectID can unexpectedly be different from -1 and produced not desired behavior
return false;
}
// Select associated control spot
const int curveId_ = lastObject_ / 7 + 1;
Gtk::TreeModel::Children children = treemodel_->children();
for (auto iter = children.begin(); iter != children.end(); iter++) {
const Gtk::TreeModel::Row r = *iter;
if (r[spots_.curveid] == curveId_) {
treeview_->set_cursor(treemodel_->get_path(r));
break;
}
}
lastCoord_.set(provider->posImage.x + provider->deltaImage.x, provider->posImage.y + provider->deltaImage.y);
EditSubscriber::action = EditSubscriber::Action::DRAGGING;
return true;
}
bool ControlSpotPanel::button1Released()
{
// printf("button1Released\n");
EditSubscriber::action = EditSubscriber::Action::NONE;
return true;
}
bool ControlSpotPanel::drag1(int modifierKey)
{
// printf("drag1\n");
EditDataProvider *provider = getEditProvider();
const auto s = treeview_->get_selection();
if (!provider || lastObject_ == -1 || !s->count_selected_rows()) { // When there is no control spot (i.e. no selected row), objectID can unexpectedly be different from -1 and produced not desired behavior
return false;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
int imW, imH;
provider->getImageSize(imW, imH);
const int rem = lastObject_ % 7;
const int method = shapeMethod_->get_active_row_number();
Coord newCoord = Coord(provider->posImage.x + provider->deltaImage.x, provider->posImage.y + provider->deltaImage.y);
// Circle, Ellipses and Rectangle
if (rem >= 0 && rem < 3) {
double deltaX = (double (newCoord.x) - double (lastCoord_.x)) * 2000. / double (imW);
double deltaY = (double (newCoord.y) - double (lastCoord_.y)) * 2000. / double (imH);
centerX_->setValue(centerX_->getValue() + deltaX);
centerY_->setValue(centerY_->getValue() + deltaY);
row[spots_.centerX] = centerX_->getIntValue();
row[spots_.centerY] = centerY_->getIntValue();
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotCenter, "X=" + centerX_->getTextValue() + ", Y=" + centerY_->getTextValue());
}
}
// cirX
if (rem == 3) {
double deltaX = (double (newCoord.x) - double (lastCoord_.x)) * 2000. / double (imW);
locX_->setValue(locX_->getValue() + deltaX);
row[spots_.locX] = locX_->getIntValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locXL_->setValue(locX_->getValue());
disableParamlistener(false);
row[spots_.locXL] = locXL_->getIntValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocX, locX_->getTextValue());
}
}
// cirXL
if (rem == 4) {
double deltaXL = (double (lastCoord_.x) - double (newCoord.x)) * 2000. / double (imW);
locXL_->setValue(locXL_->getValue() + deltaXL);
row[spots_.locXL] = locXL_->getIntValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locX_->setValue(locXL_->getValue());
disableParamlistener(false);
row[spots_.locX] = locX_->getIntValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocXL, locXL_->getTextValue());
}
}
// cirY
if (rem == 5) {
double deltaY = (double (newCoord.y) - double (lastCoord_.y)) * 2000. / double (imH);
locY_->setValue(locY_->getValue() + deltaY);
row[spots_.locY] = locY_->getIntValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locYT_->setValue(locY_->getValue());
disableParamlistener(false);
row[spots_.locYT] = locYT_->getIntValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocY, locY_->getTextValue());
}
}
// cirYT
if (rem == 6) {
double deltaYT = (double (lastCoord_.y) - double (newCoord.y)) * 2000. / double (imH);
locYT_->setValue(locYT_->getValue() + deltaYT);
row[spots_.locYT] = locYT_->getIntValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locY_->setValue(locYT_->getValue());
disableParamlistener(false);
row[spots_.locY] = locY_->getIntValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocYT, locYT_->getTextValue());
}
}
lastCoord_.set(newCoord.x, newCoord.y);
return true;
}
int ControlSpotPanel::getEventType()
{
const int tmp = eventType;
eventType = None; // Re-initialization at "None" if event type gotten
return tmp;
}
std::unique_ptr<ControlSpotPanel::SpotRow> ControlSpotPanel::getSpot(const int index)
{
// TODO: Return an std::optional<ControlSpotPanel::SpotRow> after upgrading
// to C++17.
// printf("getSpot: %d\n", index);
MyMutex::MyLock lock(mTreeview);
std::unique_ptr<SpotRow> r(new SpotRow());
int i = -1;
for (auto &row : treemodel_->children()) {
i++;
if (i == index) {
r->name = row[spots_.name];
r->isvisible = row[spots_.isvisible];
r->prevMethod = row[spots_.prevMethod];
r->shape = row[spots_.shape];
r->spotMethod = row[spots_.spotMethod];
// r->mergeMethod = row[spots_.mergeMethod];
r->sensiexclu = row[spots_.sensiexclu];
r->structexclu = row[spots_.structexclu];
r->struc = row[spots_.struc];
r->shapeMethod = row[spots_.shapeMethod];
r->locX = row[spots_.locX];
r->locXL = row[spots_.locXL];
r->locY = row[spots_.locY];
r->locYT = row[spots_.locYT];
r->centerX = row[spots_.centerX];
r->centerY = row[spots_.centerY];
r->circrad = row[spots_.circrad];
r->qualityMethod = row[spots_.qualityMethod];
r->complexMethod = row[spots_.complexMethod];
r->transit = row[spots_.transit];
r->feather = row[spots_.feather];
r->thresh = row[spots_.thresh];
r->iter = row[spots_.iter];
r->balan = row[spots_.balan];
r->balanh = row[spots_.balanh];
r->colorde = row[spots_.colorde];
r->colorscope = row[spots_.colorscope];
r->avoidrad = row[spots_.avoidrad];
r->transitweak = row[spots_.transitweak];
r->transitgrad = row[spots_.transitgrad];
r->scopemask = row[spots_.scopemask];
r->denoichmask = row[spots_.denoichmask];
r->lumask = row[spots_.lumask];
r->hishow = row[spots_.hishow];
r->activ = row[spots_.activ];
r->blwh = row[spots_.blwh];
r->recurs = row[spots_.recurs];
r->laplac = row[spots_.laplac];
r->deltae = row[spots_.deltae];
r->shortc = row[spots_.shortc];
//r->savrest = row[spots_.savrest];
r->wavMethod = row[spots_.wavMethod];
r->avoidgamutMethod = row[spots_.avoidgamutMethod];
return r;
}
}
return nullptr;
}
int ControlSpotPanel::getSpotNumber()
{
// printf("getSpotNumber\n");
return (int)treemodel_->children().size();
}
int ControlSpotPanel::getSelectedSpot()
{
// printf("getSelectedSpot\n");
MyMutex::MyLock lock(mTreeview);
const auto s = treeview_->get_selection();
// Check if treeview has row, otherwise return 0
if (!s->count_selected_rows()) {
return -1;
}
const auto selRow = s->get_selected();
// Get selected spot index
int index = -1;
for (auto i : treemodel_->children()) {
index++;
if (selRow == i) {
return index;
}
}
return -1;
}
bool ControlSpotPanel::setSelectedSpot(const int index)
{
// printf("setSelectedSpot: %d\n", index);
MyMutex::MyLock lock(mTreeview);
int i = -1;
for (auto &row : treemodel_->children()) {
i++;
if (i == index) {
disableParamlistener(true);
treeview_->set_cursor(treemodel_->get_path(row));
load_ControlSpot_param();
updateParamVisibility();
updateCurveOpacity(row);
disableParamlistener(false);
return true;
}
}
return false;
}
bool ControlSpotPanel::isDeltaEPrevActive()
{
return (preview_->get_active());
}
void ControlSpotPanel::resetDeltaEPreview()
{
previewConn_.block(true);
preview_->set_active(false);
previewConn_.block(false);
}
void ControlSpotPanel::addControlSpot(const SpotRow &newSpot)
{
// printf("addControlSpot: %d\n", newSpot.name);
MyMutex::MyLock lock(mTreeview);
disableParamlistener(true);
Gtk::TreeModel::Row row = *(treemodel_->append());
row[spots_.mouseover] = false;
row[spots_.name] = newSpot.name;
row[spots_.isvisible] = newSpot.isvisible;
row[spots_.curveid] = 0; // No associated curve
row[spots_.prevMethod] = newSpot.prevMethod;
row[spots_.shape] = newSpot.shape;
row[spots_.spotMethod] = newSpot.spotMethod;
row[spots_.sensiexclu] = newSpot.sensiexclu;
row[spots_.structexclu] = newSpot.structexclu;
row[spots_.shapeMethod] = newSpot.shapeMethod;
row[spots_.locX] = newSpot.locX;
row[spots_.locXL] = newSpot.locXL;
row[spots_.locY] = newSpot.locY;
row[spots_.locYT] = newSpot.locYT;
row[spots_.centerX] = newSpot.centerX;
row[spots_.centerY] = newSpot.centerY;
row[spots_.circrad] = newSpot.circrad;
row[spots_.qualityMethod] = newSpot.qualityMethod;
row[spots_.transit] = newSpot.transit;
row[spots_.transitweak] = newSpot.transitweak;
row[spots_.transitgrad] = newSpot.transitgrad;
row[spots_.feather] = newSpot.feather;
row[spots_.struc] = newSpot.struc;
row[spots_.thresh] = newSpot.thresh;
row[spots_.iter] = newSpot.iter;
row[spots_.balan] = newSpot.balan;
row[spots_.balanh] = newSpot.balanh;
row[spots_.colorde] = newSpot.colorde;
row[spots_.colorscope] = newSpot.colorscope;
row[spots_.avoidrad] = newSpot.avoidrad;
row[spots_.hishow] = newSpot.hishow;
row[spots_.activ] = newSpot.activ;
row[spots_.blwh] = newSpot.blwh;
row[spots_.recurs] = newSpot.recurs;
row[spots_.laplac] = newSpot.laplac;
row[spots_.deltae] = newSpot.deltae;
row[spots_.scopemask] = newSpot.scopemask;
row[spots_.denoichmask] = newSpot.denoichmask;
row[spots_.shortc] = newSpot.shortc;
row[spots_.lumask] = newSpot.lumask;
//row[spots_.savrest] = newSpot.savrest;
row[spots_.complexMethod] = newSpot.complexMethod;
row[spots_.wavMethod] = newSpot.wavMethod;
row[spots_.avoidgamutMethod] = newSpot.avoidgamutMethod;
updateParamVisibility();
disableParamlistener(false);
// Add associated control spot curve
addControlSpotCurve(row);
updateControlSpotCurve(row);
}
void ControlSpotPanel::deleteControlSpot(const int index)
{
// printf("deleteControlSpot: %d\n", index);
MyMutex::MyLock lock(mTreeview);
disableParamlistener(true);
int i = -1;
for (auto iter : treemodel_->children()) {
i++;
if (i == index) {
Gtk::TreeModel::Row row = *iter;
deleteControlSpotCurve(row);
treemodel_->erase(*row);
break;
}
}
disableParamlistener(false);
}
//new function linked to Global and options
void ControlSpotPanel::updateguiset(int spottype, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie)
{
{ //with this function we can 1) activate Settings SpotMethod
// also if need GUI for mask , todo...
idle_register.add(
[this, spottype, iscolor, issh , isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, iscie]() -> bool {
GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected
// Update GUI fullimage or main
disableListener();
if(spottype >= 2 && options.spotmet >= 2) {//optimize update
spotMethodChanged();
}
if((iscolor || issh || isvib || isexpos || istom || iscont || islog || ismas || iscie)
&& !issharp && !issoft && !isret && !isblur & !iscbdl) {
preview_->hide();
} else if (issoft || isblur || isret || issharp || iscbdl) {
preview_->show();
}
enableListener();
return false;
}
);
}
}
//new function linked to change scope
void ControlSpotPanel::updateguiscopeset(int scope)
{
{ //with this function we can disabled old values scope
idle_register.add(
[this, scope]() -> bool {
GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected
disableListener();
colorscope_->setValue(scope);
adjusterChanged(colorscope_, 0.);
enableListener();
return false;
}
);
}
}
void ControlSpotPanel::setDefaults(const rtengine::procparams::ProcParams * defParams, const ParamsEdited * pedited)
{
const int index = defParams->locallab.selspot;
if (index < (int)defParams->locallab.spots.size()) {
const LocallabParams::LocallabSpot defSpot = defParams->locallab.spots.at(index);
// Set default values for adjuster widgets
sensiexclu_->setDefault((double)defSpot.sensiexclu);
structexclu_->setDefault((double)defSpot.structexclu);
locX_->setDefault((double)defSpot.loc.at(0));
locXL_->setDefault((double)defSpot.loc.at(1));
locY_->setDefault((double)defSpot.loc.at(2));
locYT_->setDefault((double)defSpot.loc.at(3));
centerX_->setDefault((double)defSpot.centerX);
centerY_->setDefault((double)defSpot.centerY);
circrad_->setDefault((double)defSpot.circrad);
transit_->setDefault(defSpot.transit);
transitweak_->setDefault(defSpot.transitweak);
transitgrad_->setDefault(defSpot.transitgrad);
feather_->setDefault(defSpot.feather);
struc_->setDefault(defSpot.struc);
thresh_->setDefault(defSpot.thresh);
iter_->setDefault(defSpot.iter);
balan_->setDefault(defSpot.balan);
balanh_->setDefault(defSpot.balanh);
colorde_->setDefault(defSpot.colorde);
colorscope_->setDefault(defSpot.colorscope);
avoidrad_->setDefault(defSpot.avoidrad);
scopemask_->setDefault((double)defSpot.scopemask);
denoichmask_->setDefault((double)defSpot.denoichmask);
lumask_->setDefault((double)defSpot.lumask);
}
// Note: No need to manage pedited as batch mode is deactivated for Locallab
}
//-----------------------------------------------------------------------------
// ControlSpots
//-----------------------------------------------------------------------------
ControlSpotPanel::ControlSpots::ControlSpots()
{
add(mouseover);
add(name);
add(isvisible);
add(curveid);
add(prevMethod);
add(shape);
add(spotMethod);
add(sensiexclu);
add(structexclu);
add(shapeMethod);
add(locX);
add(locXL);
add(locYT);
add(locY);
add(centerX);
add(centerY);
add(circrad);
add(qualityMethod);
add(transit);
add(transitweak);
add(transitgrad);
add(feather);
add(struc);
add(thresh);
add(iter);
add(balan);
add(balanh);
add(colorde);
add(colorscope);
add(avoidrad);
add(hishow);
add(activ);
add(blwh);
add(recurs);
add(laplac);
add(deltae);
add(scopemask);
add(denoichmask);
add(shortc);
add(lumask);
//add(savrest);
add(complexMethod);
add(wavMethod);
add(avoidgamutMethod);
}
//-----------------------------------------------------------------------------
// RenameDialog
//-----------------------------------------------------------------------------
ControlSpotPanel::RenameDialog::RenameDialog(const Glib::ustring &actualname, Gtk::Window &parent):
Gtk::Dialog(M("TP_LOCALLAB_REN_DIALOG_NAME"), parent),
newname_(Gtk::manage(new Gtk::Entry()))
{
// Entry widget
Gtk::Box* const hb = Gtk::manage(new Gtk::Box());
hb->pack_start(*Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_REN_DIALOG_LAB"))), false, false, 4);
newname_->set_text(actualname);
hb->pack_start(*newname_);
get_content_area()->pack_start(*hb, Gtk::PACK_SHRINK, 4);
// OK/CANCEL buttons
add_button(M("GENERAL_OK"), OkButton);
add_button(M("GENERAL_CANCEL"), CancelButton);
// Set OK button as default one when pressing enter
newname_->set_activates_default();
set_default_response(OkButton);
show_all_children();
}
Glib::ustring ControlSpotPanel::RenameDialog::get_new_name()
{
return newname_->get_text();
}