Files
rawTherapee/rtgui/controlspotpanel.cc
Lawrence Lee c5bb1f093e Fix issues found by AddressSanitizer
Fix memcpy overlap in TIFF reader.
Fix memory leaks of SpotRows in control spot panel.
Fix memory leaks of SpotRows in locallab.
Fix memory leak of Glib::ThreadPool in file browser entry.
Fix memory leak of Glib::ThreadPool in thumbnail image updater.
2023-11-11 16:56:34 -08:00

2886 lines
96 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"), 2, 150, 1, 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"), 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, 10.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.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("rawtherapee-logo-16.png")), Gtk::manage(new RTImage("circle-white-small.png"))))),
balanh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALANH"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("rawtherapee-logo-16.png")), Gtk::manage(new RTImage("circle-red-green-small.png"))))),
colorde_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORDE"), -15, 15, 2, 5, Gtk::manage(new RTImage("circle-blue-yellow-small.png")), Gtk::manage(new RTImage("circle-gray-green-small.png"))))),
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.png")), Gtk::manage(new RTImage("circle-gray-small.png")) ))),
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())),
ctboxshapemethod(Gtk::manage(new Gtk::Box())),
ctboxgamut(Gtk::manage(new Gtk::Box())),
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_);
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::Box* const ctboxspotmethod = Gtk::manage(new Gtk::Box());
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_->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_);
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_->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(*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;
std::unique_ptr<SpotRow> const 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;
std::unique_ptr<SpotRow> const 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;
std::unique_ptr<SpotRow> const 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;
std::unique_ptr<SpotRow> const 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()
{
// 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();
// 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
if (oldSpotMethod == 2) {
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
if (oldSpotMethod == 2) {
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) { // Full image 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();
}
// 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();
}
// 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) {//full image
excluFrame->hide();
}
/*
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
*/
if (!hishow_->get_active()) { // Normal case
expTransGrad_->hide();
expShapeDetect_->hide();
expSpecCases_->hide();
expMaskMerge_->hide();
circrad_->hide();
ctboxshape->hide();
} else { // Excluding case
expTransGrad_->show();
expShapeDetect_->show();
expSpecCases_->show();
expMaskMerge_->show();
circrad_->show();
ctboxshape->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_->getIntValue();
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();
if (!hishow_->get_active()) { // 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) {
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);
}
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();
}