Files
rawTherapee/rtgui/controlspotpanel.cc
Pandagrapher 39c53119eb Improve batch mode with Locallab
Batch mode is now correctly managed by Locallab. It works only if the
pictures have the same control spot number with coherent id

Other improvements:
- If there is no control spot, all Locallab tools are now disabled
2018-12-26 10:31:57 +01:00

1813 lines
64 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 "multilangmgr.h"
#include <iomanip>
using namespace rtengine;
//-----------------------------------------------------------------------------
// ControlSpotPanel
//-----------------------------------------------------------------------------
ControlSpotPanel::ControlSpotPanel():
EditSubscriber(ET_OBJECTS),
FoldableToolPanel(this, "controlspotpanel", M("TP_LOCALLAB_SETTINGS")),
button_add_("Add"),
button_delete_("Delete"),
button_rename_("Rename"),
shape_(Gtk::manage(new MyComboBoxText())),
spotMethod_(Gtk::manage(new MyComboBoxText())),
shapeMethod_(Gtk::manage(new MyComboBoxText())),
qualityMethod_(Gtk::manage(new MyComboBoxText())),
sensiexclu_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIEXCLU"), 0, 100, 1, 19))),
struc_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUC"), 0, 5, 1, 0))),
locX_(Gtk::manage(new Adjuster(M("TP_LOCAL_WIDTH"), 0, 2250, 1, 250))),
locXL_(Gtk::manage(new Adjuster(M("TP_LOCAL_WIDTH_L"), 0, 2250, 1, 250))),
locY_(Gtk::manage(new Adjuster(M("TP_LOCAL_HEIGHT"), 0, 2250, 1, 250))),
locYT_(Gtk::manage(new Adjuster(M("TP_LOCAL_HEIGHT_T"), 0, 2250, 1, 250))),
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_TRANSIT"), 5, 95, 1, 60))),
thresh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRES"), 1, 35, 1, 18))),
iter_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_PROXI"), 0, 60, 1, 0))),
lastObject_(-1),
lastCoord_(new Coord()),
nbSpotChanged_(false),
selSpotChanged_(false),
nameChanged_(false),
eventType(0)
{
treeview_.set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_VERTICAL);
scrolledwindow_.add(treeview_);
scrolledwindow_.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
scrolledwindow_.set_min_content_height(150);
pack_start(buttonbox_);
pack_start(scrolledwindow_);
buttonbox_.pack_start(button_add_, Gtk::PACK_SHRINK, 4);
buttonbox_.pack_start(button_delete_, Gtk::PACK_SHRINK, 4);
buttonbox_.pack_start(button_rename_);
buttonbox_.set_layout(Gtk::BUTTONBOX_START);
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));
buttonrenameconn_ = button_rename_.signal_clicked().connect(
sigc::mem_fun(*this, &ControlSpotPanel::on_button_rename));
treemodel_ = Gtk::ListStore::create(spots_);
treeview_.set_model(treemodel_);
treeviewconn_ = treeview_.get_selection()->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::controlspotChanged));
auto cell = Gtk::manage(new Gtk::CellRendererText());
int cols_count = treeview_.append_column("ID", *cell);
auto col = treeview_.get_column(cols_count - 1);
if (col) {
col->set_cell_data_func(
*cell, sigc::mem_fun(
*this, &ControlSpotPanel::render_id));
}
cell = Gtk::manage(new Gtk::CellRendererText());
cols_count = treeview_.append_column("Name", *cell);
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("Status", *cell);
col = treeview_.get_column(cols_count - 1);
if (col) {
col->set_cell_data_func(
*cell, sigc::mem_fun(
*this, &ControlSpotPanel::render_isvisible));
}
Gtk::HBox* const ctboxshape = Gtk::manage(new Gtk::HBox());
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);
Gtk::HBox* const ctboxspotmethod = Gtk::manage(new Gtk::HBox());
Gtk::Label* const labelspotmethod = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_EXCLUTYPE") + ":"));
ctboxspotmethod->pack_start(*labelspotmethod, Gtk::PACK_SHRINK, 4);
ctboxspotmethod->set_tooltip_markup(M("TP_LOCALLAB_EXCLUTYPE_TOOLTIP"));
spotMethod_->append(M("TP_LOCALLAB_EXNORM"));
spotMethod_->append(M("TP_LOCALLAB_EXECLU"));
spotMethod_->set_active(0);
spotMethodconn_ = spotMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::spotMethodChanged));
ctboxspotmethod->pack_start(*spotMethod_);
pack_start(*ctboxspotmethod);
Gtk::Frame* const excluFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_EXCLUF")));
excluFrame->set_label_align(0.025, 0.5);
excluFrame->set_tooltip_text(M("TP_LOCALLAB_EXCLUF_TOOLTIP"));
ToolParamBlock* const excluBox = Gtk::manage(new ToolParamBlock());
sensiexclu_->set_tooltip_text(M("TP_LOCALLAB_SENSIEXCLU_TOOLTIP"));
sensiexclu_->setAdjusterListener(this);
excluBox->pack_start(*sensiexclu_);
struc_->set_tooltip_text(M("TP_LOCALLAB_STRUC_TOOLTIP"));
struc_->setAdjusterListener(this);
// excluBox->pack_start(*struc_); // Uncomment this line to use the struc_ adjuster
excluFrame->add(*excluBox);
pack_start(*excluFrame);
Gtk::HBox* const ctboxshapemethod = Gtk::manage(new Gtk::HBox());
Gtk::Label* const labelshapemethod = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_STYPE") + ":"));
ctboxshapemethod->pack_start(*labelshapemethod, Gtk::PACK_SHRINK, 4);
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);
Gtk::HBox* const ctboxqualitymethod = Gtk::manage(new Gtk::HBox());
Gtk::Label* const labelqualitymethod = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_QUAL_METHOD") + ":"));
ctboxqualitymethod->pack_start(*labelqualitymethod, Gtk::PACK_SHRINK, 4);
ctboxqualitymethod->set_tooltip_markup(M("TP_LOCALLAB_METHOD_TOOLTIP"));
qualityMethod_->append(M("TP_LOCALLAB_STD"));
qualityMethod_->append(M("TP_LOCALLAB_ENH"));
qualityMethod_->append(M("TP_LOCALLAB_ENHDEN"));
qualityMethod_->set_active(0);
qualityMethodconn_ = qualityMethod_->signal_changed().connect(
sigc::mem_fun(
*this, &ControlSpotPanel::qualityMethodChanged));
ctboxqualitymethod->pack_start(*qualityMethod_);
pack_start(*ctboxqualitymethod);
pack_start(*transit_);
transit_->set_tooltip_text(M("TP_LOCALLAB_TRANSIT_TOOLTIP"));
transit_->setAdjusterListener(this);
Gtk::Frame* const artifFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_ARTIF")));
artifFrame->set_label_align(0.025, 0.5);
artifFrame->set_tooltip_text(M("TP_LOCALLAB_ARTIF_TOOLTIP"));
ToolParamBlock* const artifBox = Gtk::manage(new ToolParamBlock());
artifBox->pack_start(*thresh_);
thresh_->setAdjusterListener(this);
artifBox->pack_start(*iter_);
iter_->setAdjusterListener(this);
artifFrame->add(*artifBox);
pack_start(*artifFrame);
show_all();
}
void ControlSpotPanel::setEditProvider(EditDataProvider* provider)
{
EditSubscriber::setEditProvider(provider);
}
void ControlSpotPanel::render_id(
Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter)
{
auto row = *iter;
Gtk::CellRendererText *ct = static_cast<Gtk::CellRendererText *>(cell);
int value = row[spots_.id];
ct->property_text() = std::to_string(value);
}
void ControlSpotPanel::render_name(
Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter)
{
auto row = *iter;
Gtk::CellRendererText *ct = static_cast<Gtk::CellRendererText *>(cell);
auto value = row[spots_.name];
ct->property_text() = value;
}
void ControlSpotPanel::render_isvisible(
Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter)
{
auto row = *iter;
Gtk::CellRendererText *ct = static_cast<Gtk::CellRendererText *>(cell);
auto value = row[spots_.isvisible];
if (value) {
ct->property_text() = "Visible";
} else {
ct->property_text() = "Not visible";
}
}
void ControlSpotPanel::on_button_add()
{
printf("on_button_add\n");
if (!listener) {
return;
}
// Raise event
nbSpotChanged_ = true;
selSpotChanged_ = true;
eventType = 1; // 1 = Spot creation event
const int newId = getNewId();
listener->panelChanged(EvLocallabSpotCreated, "ID#" + std::to_string(newId));
}
void ControlSpotPanel::on_button_delete()
{
printf("on_button_delete\n");
if (!listener) {
return;
}
// Raise event
nbSpotChanged_ = true;
selSpotChanged_ = true;
eventType = 2; // 2 = Spot deletion event
const int delId = getSelectedSpot();
listener->panelChanged(EvLocallabSpotDeleted, "ID#" + std::to_string(delId));
}
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 == 1) {
nameChanged_ = true;
const auto newname = d.get_new_name();
row[spots_.name] = newname;
treeview_.columns_autosize();
listener->panelChanged(EvLocallabSpotName, newname);
}
}
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
shape_->set_active(row[spots_.shape]);
spotMethod_->set_active(row[spots_.spotMethod]);
sensiexclu_->setValue(static_cast<double>(row[spots_.sensiexclu]));
struc_->setValue(static_cast<double>(row[spots_.struc]));
shapeMethod_->set_active(row[spots_.shapeMethod]);
locX_->setValue(static_cast<double>(row[spots_.locX]));
locXL_->setValue(static_cast<double>(row[spots_.locXL]));
locY_->setValue(static_cast<double>(row[spots_.locY]));
locYT_->setValue(static_cast<double>(row[spots_.locYT]));
centerX_->setValue(static_cast<double>(row[spots_.centerX]));
centerY_->setValue(static_cast<double>(row[spots_.centerY]));
circrad_->setValue(static_cast<double>(row[spots_.circrad]));
qualityMethod_->set_active(row[spots_.qualityMethod]);
transit_->setValue(static_cast<double>(row[spots_.transit]));
thresh_->setValue(static_cast<double>(row[spots_.thresh]));
iter_->setValue(static_cast<double>(row[spots_.iter]));
}
void ControlSpotPanel::controlspotChanged()
{
printf("controlspotChanged\n");
if (!listener) {
return;
}
// Raise event
selSpotChanged_ = true;
eventType = 3; // 3 = Spot selection event
const int selId = getSelectedSpot();
listener->panelChanged(EvLocallabSpotSelected, "ID#" + std::to_string(selId));
}
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::spotMethodChanged()
{
printf("spotMethodChanged\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_.spotMethod] = spotMethod_->get_active_row_number();
// Raise event
if (listener) {
listener->panelChanged(EvLocallabSpotSpotMethod, spotMethod_->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 (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] = static_cast<int>(locX_->getValue());
row[spots_.locYT] = static_cast<int>(locY_->getValue());
updateControlSpotCurve(row);
} else {
row[spots_.shapeMethod] = shapeMethod_->get_active_row_number();
}
updateParamVisibility();
// 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::updateParamVisibility()
{
printf("updateParamVisibility\n");
const int method = shapeMethod_->get_active_row_number();
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();
}
}
}
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] = (int) sensiexclu_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotSensiexclu, sensiexclu_->getTextValue());
}
}
if (a == struc_) {
row[spots_.struc] = (int) struc_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotStruc, struc_->getTextValue());
}
}
if (a == locX_) {
row[spots_.locX] = (int) locX_->getValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locXL_->setValue(locX_->getValue());
disableParamlistener(false);
row[spots_.locXL] = (int) locXL_->getValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocX, locX_->getTextValue());
}
}
if (a == locXL_) {
row[spots_.locXL] = (int) locXL_->getValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locX_->setValue(locXL_->getValue());
disableParamlistener(false);
row[spots_.locX] = (int) locX_->getValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocXL, locXL_->getTextValue());
}
}
if (a == locY_) {
row[spots_.locY] = (int) locY_->getValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locYT_->setValue(locY_->getValue());
disableParamlistener(false);
row[spots_.locYT] = (int) locYT_->getValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocY, locY_->getTextValue());
}
}
if (a == locYT_) {
row[spots_.locYT] = (int) locYT_->getValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locY_->setValue(locYT_->getValue());
disableParamlistener(false);
row[spots_.locY] = (int) locY_->getValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocYT, locYT_->getTextValue());
}
}
if (a == centerX_ || a == centerY_) {
row[spots_.centerX] = (int) centerX_->getValue();
row[spots_.centerY] = (int) centerY_->getValue();
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotCenter, "X=" + centerX_->getTextValue() + ", Y=" + centerY_->getTextValue());
}
}
if (a == circrad_) {
row[spots_.circrad] = (int) circrad_->getValue();
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotCircrad, circrad_->getTextValue());
}
}
if (a == transit_) {
row[spots_.transit] = (int) transit_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotTransit, transit_->getTextValue());
}
}
if (a == thresh_) {
row[spots_.thresh] = (int) thresh_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotThresh, thresh_->getTextValue());
}
}
if (a == iter_) {
row[spots_.iter] = (int) iter_->getValue();
if (listener) {
listener->panelChanged(EvLocallabSpotIter, iter_->getTextValue());
}
}
}
void ControlSpotPanel::disableParamlistener(bool cond)
{
printf("disableParamlistener: %d\n", cond);
treeviewconn_.block(cond);
buttonaddconn_.block(cond);
buttondeleteconn_.block(cond);
buttonrenameconn_.block(cond);
shapeconn_.block(cond);
spotMethodconn_.block(cond);
sensiexclu_->block(cond);
struc_->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);
thresh_->block(cond);
iter_->block(cond);
}
void ControlSpotPanel::setParamEditable(bool cond)
{
// printf("setParamEditable: %d\n", cond);
shape_->set_sensitive(cond);
spotMethod_->set_sensitive(cond);
sensiexclu_->set_sensitive(cond);
struc_->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);
thresh_->set_sensitive(cond);
iter_->set_sensitive(cond);
}
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
Line* lineX;
lineX = new Line();
lineX->innerLineWidth = 2.5;
lineX->datum = Geometry::IMAGE;
Line* lineXL;
lineXL = new Line();
lineXL->innerLineWidth = 2.5;
lineXL->datum = Geometry::IMAGE;
Line* lineY;
lineY = new Line();
lineY->innerLineWidth = 2.5;
lineY->datum = Geometry::IMAGE;
Line* lineYT;
lineYT = new Line();
lineYT->innerLineWidth = 2.5;
lineYT->datum = Geometry::IMAGE;
Circle* centerCircle;
centerCircle = new Circle();
centerCircle->datum = Geometry::IMAGE;
centerCircle->radiusInImageSpace = true;
Arcellipse* arc1;
arc1 = new Arcellipse();
arc1->innerLineWidth = 0.7;
arc1->datum = Geometry::IMAGE;
arc1->radiusInImageSpace = true;
Arcellipse* arc2;
arc2 = new Arcellipse();
arc2->innerLineWidth = 0.7;
arc2->datum = Geometry::IMAGE;
arc2->radiusInImageSpace = true;
Arcellipse* arc3;
arc3 = new Arcellipse();
arc3->innerLineWidth = 0.7;
arc3->datum = Geometry::IMAGE;
arc3->radiusInImageSpace = true;
Arcellipse* arc4;
arc4 = new Arcellipse();
arc4->innerLineWidth = 0.7;
arc4->datum = Geometry::IMAGE;
arc4->radiusInImageSpace = true;
Rectangle* rec;
rec = new Rectangle();
rec->innerLineWidth = 0.7;
rec->datum = Geometry::IMAGE;
EditSubscriber::visibleGeometry.push_back(lineX); // (curveid - 1) * 10
EditSubscriber::visibleGeometry.push_back(lineXL); // (curveid - 1) * 10 + 1
EditSubscriber::visibleGeometry.push_back(lineY); // (curveid - 1) * 10 + 2
EditSubscriber::visibleGeometry.push_back(lineYT); // (curveid - 1) * 10 + 3
EditSubscriber::visibleGeometry.push_back(centerCircle); // (curveid - 1) * 10 + 4
EditSubscriber::visibleGeometry.push_back(arc1); // (curveid - 1) * 10 + 5
EditSubscriber::visibleGeometry.push_back(arc2); // (curveid - 1) * 10 + 6
EditSubscriber::visibleGeometry.push_back(arc3); // (curveid - 1) * 10 + 7
EditSubscriber::visibleGeometry.push_back(arc4); // (curveid - 1) * 10 + 8
EditSubscriber::visibleGeometry.push_back(rec); // (curveid - 1) * 10 + 9
// Creation of mouseOverGeometry
lineX = new Line();
lineX->innerLineWidth = 2.5;
lineX->datum = Geometry::IMAGE;
lineXL = new Line();
lineXL->innerLineWidth = 2.5;
lineXL->datum = Geometry::IMAGE;
lineY = new Line();
lineY->innerLineWidth = 2.5;
lineY->datum = Geometry::IMAGE;
lineYT = new Line();
lineYT->innerLineWidth = 2.5;
lineYT->datum = Geometry::IMAGE;
centerCircle = new Circle();
centerCircle->datum = Geometry::IMAGE;
centerCircle->radiusInImageSpace = true;
arc1 = new Arcellipse();
arc1->innerLineWidth = 0.7;
arc1->datum = Geometry::IMAGE;
arc1->radiusInImageSpace = true;
arc2 = new Arcellipse();
arc2->innerLineWidth = 0.7;
arc2->datum = Geometry::IMAGE;
arc2->radiusInImageSpace = true;
arc3 = new Arcellipse();
arc3->innerLineWidth = 0.7;
arc3->datum = Geometry::IMAGE;
arc3->radiusInImageSpace = true;
arc4 = new Arcellipse();
arc4->innerLineWidth = 0.7;
arc4->datum = Geometry::IMAGE;
arc4->radiusInImageSpace = true;
rec = new Rectangle();
rec->innerLineWidth = 0.7;
rec->datum = Geometry::IMAGE;
EditSubscriber::mouseOverGeometry.push_back(lineX); // (curveid - 1) * 10
EditSubscriber::mouseOverGeometry.push_back(lineXL); // (curveid - 1) * 10 + 1
EditSubscriber::mouseOverGeometry.push_back(lineY); // (curveid - 1) * 10 + 2
EditSubscriber::mouseOverGeometry.push_back(lineYT); // (curveid - 1) * 10 + 3
EditSubscriber::mouseOverGeometry.push_back(centerCircle); // (curveid - 1) * 10 + 4
EditSubscriber::mouseOverGeometry.push_back(arc1); // (curveid - 1) * 10 + 5
EditSubscriber::mouseOverGeometry.push_back(arc2); // (curveid - 1) * 10 + 6
EditSubscriber::mouseOverGeometry.push_back(arc3); // (curveid - 1) * 10 + 7
EditSubscriber::mouseOverGeometry.push_back(arc4); // (curveid - 1) * 10 + 8
EditSubscriber::mouseOverGeometry.push_back(rec); // (curveid - 1) * 10 + 9
row[spots_.curveid] = EditSubscriber::visibleGeometry.size() / 10;
}
void ControlSpotPanel::updateControlSpotCurve(Gtk::TreeModel::Row row)
{
const int curveid_ = static_cast<int>(row[spots_.curveid]);
if (curveid_ == 0) { // Row has no associated curve
return;
}
const int centerX_ = static_cast<int>(row[spots_.centerX]);
const int centerY_ = static_cast<int>(row[spots_.centerY]);
const int circrad_ = static_cast<int>(row[spots_.circrad]);
const int locX_ = static_cast<int>(row[spots_.locX]);
const int locXL_ = static_cast<int>(row[spots_.locXL]);
const int locY_ = static_cast<int>(row[spots_.locY]);
const int locYT_ = static_cast<int>(row[spots_.locYT]);
const int shape_ = static_cast<int>(row[spots_.shape]);
printf("updateControlSpotCurve: %d\n", curveid_);
EditDataProvider* dataProvider = getEditProvider();
if (!dataProvider) {
return;
}
int imW = 0;
int imH = 0;
dataProvider->getImageSize(imW, imH);
if (!imW || !imH) {
return;
}
const double decayX = (locX_) * (double (imW)) / 2000.;
const double decayXL = (locXL_) * (double (imW)) / 2000.;
const double decayY = (locY_) * double (imH) / 2000.;
const double decayYT = (locYT_) * double (imH) / 2000.;
rtengine::Coord origin(imW / 2 + centerX_ * imW / 2000.f, imH / 2 + centerY_ * imH / 2000.f);
const auto updateLineWithDecay = [&](Geometry * geometry, const float radius, const float decal, const float offSetAngle, const double decay) {
const auto line = static_cast<Line*>(geometry); // 180
line->begin = PolarCoord(radius, decal) + PolarCoord(decay, offSetAngle);
line->begin += origin; // 0
line->end = PolarCoord(radius, decal - 180) + PolarCoord(decay, offSetAngle);
line->end += origin;
};
const auto updateCircle = [&](Geometry * geometry) {
const auto circle = static_cast<Circle*>(geometry);
circle->center = origin;
circle->radius = circrad_;
};
const auto updateArcellipse = [&](Geometry * geometry, const double dRad_, const double dRad2_, const double begang_, const double endang_) {
const auto arcellipse = static_cast<Arcellipse*>(geometry);
arcellipse->center = origin;
arcellipse->begang = begang_;
arcellipse->endang = endang_;
arcellipse->radius = dRad_;
arcellipse->radius2 = dRad2_;
};
const auto updateRectangle = [&](Geometry * geometry) {
const auto rectangle = static_cast<Rectangle*>(geometry);
rectangle->bottomRight.x = origin.x + (int) decayX;
rectangle->bottomRight.y = origin.y + (int) decayY;
rectangle->topLeft.x = origin.x - (int) decayXL;
rectangle->topLeft.y = origin.y - (int) decayYT;
};
updateLineWithDecay(visibleGeometry.at((curveid_ - 1) * 10), 500., 90., 0., decayX);
updateLineWithDecay(mouseOverGeometry.at((curveid_ - 1) * 10), 500., 90., 0., decayX);
updateLineWithDecay(visibleGeometry.at((curveid_ - 1) * 10 + 1), 500., 90., 180., decayXL);
updateLineWithDecay(mouseOverGeometry.at((curveid_ - 1) * 10 + 1), 500., 90., 180., decayXL);
updateLineWithDecay(visibleGeometry.at((curveid_ - 1) * 10 + 2), 500., 180., 90., decayY);
updateLineWithDecay(mouseOverGeometry.at((curveid_ - 1) * 10 + 2), 500., 180., 90., decayY);
updateLineWithDecay(visibleGeometry.at((curveid_ - 1) * 10 + 3), 500., 180., 270., decayYT);
updateLineWithDecay(mouseOverGeometry.at((curveid_ - 1) * 10 + 3), 500., 180., 270., decayYT);
updateCircle(visibleGeometry.at((curveid_ - 1) * 10 + 4));
updateCircle(mouseOverGeometry.at((curveid_ - 1) * 10 + 4));
updateArcellipse(visibleGeometry.at((curveid_ - 1) * 10 + 5), decayX, decayYT, 3 * RT_PI_2, 2 * RT_PI);
updateArcellipse(visibleGeometry.at((curveid_ - 1) * 10 + 6), decayXL, decayYT, RT_PI, 3 * RT_PI_2);
updateArcellipse(visibleGeometry.at((curveid_ - 1) * 10 + 7), decayXL, decayY, RT_PI_2, RT_PI);
updateArcellipse(visibleGeometry.at((curveid_ - 1) * 10 + 8), decayX, decayY, 0., RT_PI_2);
updateArcellipse(mouseOverGeometry.at((curveid_ - 1) * 10 + 5), decayX, decayYT, 3 * RT_PI_2, 2 * RT_PI);
updateArcellipse(mouseOverGeometry.at((curveid_ - 1) * 10 + 6), decayXL, decayYT, RT_PI, 3 * RT_PI_2);
updateArcellipse(mouseOverGeometry.at((curveid_ - 1) * 10 + 7), decayXL, decayY, RT_PI_2, RT_PI);
updateArcellipse(mouseOverGeometry.at((curveid_ - 1) * 10 + 8), decayX, decayY, 0., RT_PI_2);
updateRectangle(visibleGeometry.at((curveid_ - 1) * 10 + 9));
updateRectangle(mouseOverGeometry.at((curveid_ - 1) * 10 + 9));
// Update Arcellipse/Rectangle visibility according to shape
if (shape_ == 0) { // 0 = Ellipse
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 5)->setActive(true); // arc1
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 6)->setActive(true); // arc2
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 7)->setActive(true); // arc3
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 8)->setActive(true); // arc4
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 9)->setActive(false); // rec
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 5)->setActive(true); // arc1
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 6)->setActive(true); // arc2
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 7)->setActive(true); // arc3
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 8)->setActive(true); // arc4
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 9)->setActive(false); // rec
} else { // 1 = Rectangle
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 5)->setActive(false); // arc1
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 6)->setActive(false); // arc2
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 7)->setActive(false); // arc3
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 8)->setActive(false); // arc4
EditSubscriber::visibleGeometry.at((curveid_ - 1) * 10 + 9)->setActive(true); // rec
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 5)->setActive(false); // arc1
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 6)->setActive(false); // arc2
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 7)->setActive(false); // arc3
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 8)->setActive(false); // arc4
EditSubscriber::mouseOverGeometry.at((curveid_ - 1) * 10 + 9)->setActive(true); // rec
}
}
void ControlSpotPanel::deleteControlSpotCurve(Gtk::TreeModel::Row row)
{
const int curveid_ = static_cast<int>(row[spots_.curveid]);
if (curveid_ == 0) { // Row has no associated curve
return;
}
printf("deleteControlSpotCurve: %d\n", curveid_);
// visibleGeometry
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 9);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 8);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 7);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 6);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 5);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 4);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 3);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 2);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10 + 1);
EditSubscriber::visibleGeometry.erase(EditSubscriber::visibleGeometry.begin() + (curveid_ - 1) * 10);
// mouseOverGeometry
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 9);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 8);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 7);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 6);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 5);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 4);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 3);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 2);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10 + 1);
EditSubscriber::mouseOverGeometry.erase(EditSubscriber::mouseOverGeometry.begin() + (curveid_ - 1) * 10);
row[spots_.curveid] = 0; // Reset associated curve id
// Reordering curve id
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;
}
}
}
CursorShape ControlSpotPanel::getCursor(int objectID)
{
printf("Object ID: %d\n", objectID);
int rem_ = objectID % 10;
switch (rem_) {
case (0): // LocX: (curveid_ - 1) * 10
return CSMove1DH;
case (1): // LocXL: (curveid_ - 1) * 10 + 1
return CSMove1DH;
case (2): // LocY: (curveid_ - 1) * 10 + 2
return CSMove1DV;
case (3): // LocYT: (curveid_ - 1) * 10 + 3
return CSMove1DV;
case (4): // centerCircle: (curveid_ - 1) * 10 + 4
return CSMove2D;
case (5): // arc1: (curveid_ - 1) * 10 + 5
return CSMove2D;
case (6): // arc2: (curveid_ - 1) * 10 + 6
return CSMove2D;
case (7): // arc3: (curveid_ - 1) * 10 + 7
return CSMove2D;
case (8): // arc4: (curveid_ - 1) * 10 + 8
return CSMove2D;
case (9): // rec: (curveid_ - 1) * 10 + 9
return CSMove2D;
default:
return CSHandOpen;
}
}
bool ControlSpotPanel::mouseOver(int modifierKey)
{
EditDataProvider* editProvider_ = getEditProvider();
if (!editProvider_) {
return false;
}
int object_ = editProvider_->object;
if (object_ != lastObject_) {
if (object_ == -1) {
for (int it_ = 0; it_ < (int) EditSubscriber::visibleGeometry.size(); it_++) {
EditSubscriber::visibleGeometry.at(it_)->state = Geometry::NORMAL;
}
lastObject_ = object_;
return false;
}
int curveId_ = object_ / 10 + 1;
int rem = object_ % 10;
for (int it_ = 0; it_ < (int) EditSubscriber::visibleGeometry.size(); it_++) {
if ((it_ < ((curveId_ - 1) * 10)) || (it_ > ((curveId_ - 1) * 10) + 9)) { // it_ does not belong to cursor pointed curve
EditSubscriber::visibleGeometry.at(it_)->state = Geometry::NORMAL;
}
}
const int method = shapeMethod_->get_active_row_number();
// LocX
if (rem == 0) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10)->state = Geometry::PRELIGHT;
if (method == 1 || method == 3) { // Symmetrical cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 1)->state = Geometry::PRELIGHT;
}
} else {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10)->state = Geometry::NORMAL;
}
// LocXL
if (rem == 1) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 1)->state = Geometry::PRELIGHT;
if (method == 1 || method == 3) { // Symmetrical cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10)->state = Geometry::PRELIGHT;
}
} else {
if (method == 0 || method == 2) { // Independent cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 1)->state = Geometry::NORMAL;
}
}
// LocY
if (rem == 2) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 2)->state = Geometry::PRELIGHT;
if (method == 1 || method == 3) { // Symmetrical cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 3)->state = Geometry::PRELIGHT;
}
} else {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 2)->state = Geometry::NORMAL;
}
// LocYT
if (rem == 3) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 3)->state = Geometry::PRELIGHT;
if (method == 1 || method == 3) { // Symmetrical cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 2)->state = Geometry::PRELIGHT;
}
} else {
if (method == 0 || method == 2) { // Independent cases
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 3)->state = Geometry::NORMAL;
}
}
// Circle, Arcellipses and Rectangle
if (rem >= 4) {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 4)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 5)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 6)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 7)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 8)->state = Geometry::PRELIGHT;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 9)->state = Geometry::PRELIGHT;
} else {
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 4)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 5)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 6)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 7)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 8)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at((curveId_ - 1) * 10 + 9)->state = Geometry::NORMAL;
}
lastObject_ = object_;
return true;
}
return false;
}
bool ControlSpotPanel::button1Pressed(int modifierKey)
{
printf("button1Pressed\n");
EditDataProvider *provider = getEditProvider();
if (!provider || lastObject_ == -1) {
return false;
}
// Select associated control spot
int curveId_ = lastObject_ / 10 + 1;
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_) {
treeview_.set_cursor(treemodel_->get_path(r));
break;
}
}
lastCoord_->set(provider->posImage.x + provider->deltaImage.x, provider->posImage.y + provider->deltaImage.y);
EditSubscriber::action = ES_ACTION_DRAGGING;
return true;
}
bool ControlSpotPanel::button1Released()
{
printf("button1Released\n");
EditSubscriber::action = ES_ACTION_NONE;
return true;
}
bool ControlSpotPanel::drag1(int modifierKey)
{
printf("drag1\n");
EditDataProvider *provider = getEditProvider();
if (!provider || lastObject_ == -1) {
return false;
}
// Get associated control spot
const auto s = treeview_.get_selection();
if (!s->count_selected_rows()) {
return false;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
int imW, imH;
provider->getImageSize(imW, imH);
int rem = lastObject_ % 10;
int method = shapeMethod_->get_active_row_number();
Coord* newCoord = new Coord(provider->posImage.x + provider->deltaImage.x, provider->posImage.y + provider->deltaImage.y);
// LocX
if (rem == 0) {
double deltaX = (double (newCoord->x) - double (lastCoord_->x)) * 2000. / double (imW);
locX_->setValue(locX_->getValue() + deltaX);
row[spots_.locX] = (int) locX_->getValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locXL_->setValue(locX_->getValue());
disableParamlistener(false);
row[spots_.locXL] = (int) locXL_->getValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocX, locX_->getTextValue());
}
}
// LocXL
if (rem == 1) {
double deltaXL = (double (lastCoord_->x) - double (newCoord->x)) * 2000. / double (imW);
locXL_->setValue(locXL_->getValue() + deltaXL);
row[spots_.locXL] = (int) locXL_->getValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locX_->setValue(locXL_->getValue());
disableParamlistener(false);
row[spots_.locX] = (int) locX_->getValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocXL, locXL_->getTextValue());
}
}
// LocY
if (rem == 2) {
double deltaY = (double (newCoord->y) - double (lastCoord_->y)) * 2000. / double (imH);
locY_->setValue(locY_->getValue() + deltaY);
row[spots_.locY] = (int) locY_->getValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locYT_->setValue(locY_->getValue());
disableParamlistener(false);
row[spots_.locYT] = (int) locYT_->getValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocY, locY_->getTextValue());
}
}
// LocYT
if (rem == 3) {
double deltaYT = (double (lastCoord_->y) - double (newCoord->y)) * 2000. / double (imH);
locYT_->setValue(locYT_->getValue() + deltaYT);
row[spots_.locYT] = (int) locYT_->getValue();
if (method == 1 || method == 3) { // Symmetrical cases
disableParamlistener(true);
locY_->setValue(locYT_->getValue());
disableParamlistener(false);
row[spots_.locY] = (int) locY_->getValue();
}
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotLocYT, locYT_->getTextValue());
}
}
// Circle, Arcellipses and Rectangle
if (rem >= 4) {
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] = (int) centerX_->getValue();
row[spots_.centerY] = (int) centerY_->getValue();
updateControlSpotCurve(row);
if (listener) {
listener->panelChanged(EvLocallabSpotCenter, "X=" + centerX_->getTextValue() + ", Y=" + centerY_->getTextValue());
}
}
lastCoord_->set(newCoord->x, newCoord->y);
return true;
}
int ControlSpotPanel::getEventType()
{
const int tmp = eventType;
eventType = 0; // Re-initialization at 0 if event type gotten
return tmp;
}
ControlSpotPanel::SpotRow* ControlSpotPanel::getSpot(int id)
{
printf("getSpot: %d\n", id);
SpotRow* r = new SpotRow();
Gtk::TreeModel::Children children = treemodel_->children();
Gtk::TreeModel::Children::iterator iter;
for (iter = children.begin(); iter != children.end(); iter++) {
Gtk::TreeModel::Row row = *iter;
if (row[spots_.id] == id) {
r->id = row[spots_.id];
r->name = row[spots_.name];
r->isvisible = row[spots_.isvisible];
r->shape = row[spots_.shape];
r->spotMethod = row[spots_.spotMethod];
r->sensiexclu = row[spots_.sensiexclu];
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->transit = row[spots_.transit];
r->thresh = row[spots_.thresh];
r->iter = row[spots_.iter];
return r;
}
}
return nullptr;
}
std::vector<int>* ControlSpotPanel::getSpotIdList()
{
std::vector<int>* r = new std::vector<int>();
Gtk::TreeModel::Children children = treemodel_->children();
Gtk::TreeModel::Children::iterator iter;
for (iter = children.begin(); iter != children.end(); iter++) {
Gtk::TreeModel::Row row = *iter;
r->push_back(row[spots_.id]);
}
return r;
}
int ControlSpotPanel::getSelectedSpot()
{
printf("getSelectedSpot\n");
const auto s = treeview_.get_selection();
// Check if treeview has row, otherwise return 0
if (!s->count_selected_rows()) {
return 0;
}
auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
int id = row[spots_.id];
return id;
}
void ControlSpotPanel::setSelectedSpot(int id)
{
printf("setSelectedSpot: %d\n", id);
disableParamlistener(true);
Gtk::TreeModel::Children children = treemodel_->children();
Gtk::TreeModel::Children::iterator iter;
for (iter = children.begin(); iter != children.end(); iter++) {
Gtk::TreeModel::Row row = *iter;
if (row[spots_.id] == id) {
treeview_.set_cursor(treemodel_->get_path(row));
load_ControlSpot_param();
updateParamVisibility();
}
}
disableParamlistener(false);
}
int ControlSpotPanel::getNewId()
{
// Looking for maximum used id
int max_row_id = 0;
Gtk::TreeModel::Children children = treemodel_->children();
Gtk::TreeModel::Children::iterator iter;
for (iter = children.begin(); iter != children.end(); iter++) {
Gtk::TreeModel::Row row = *iter;
int iter_id = row[spots_.id];
max_row_id = std::max(max_row_id, iter_id);
}
max_row_id++;
return max_row_id;
}
void ControlSpotPanel::addControlSpot(SpotRow* newSpot)
{
printf("addControlSpot: %d\n", newSpot->id);
disableParamlistener(true);
Gtk::TreeModel::Row row = * (treemodel_->append());
row[spots_.id] = newSpot->id;
row[spots_.name] = newSpot->name;
row[spots_.isvisible] = newSpot->isvisible;
row[spots_.curveid] = 0; // No associated curve
row[spots_.shape] = newSpot->shape;
row[spots_.spotMethod] = newSpot->spotMethod;
row[spots_.sensiexclu] = newSpot->sensiexclu;
row[spots_.struc] = newSpot->struc;
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_.thresh] = newSpot->thresh;
row[spots_.iter] = newSpot->iter;
updateParamVisibility();
disableParamlistener(false);
// Add associated control spot curve
addControlSpotCurve(row);
updateControlSpotCurve(row);
}
int ControlSpotPanel::updateControlSpot(SpotRow* spot)
{
printf("updateControlSpot: %d\n", spot->id);
disableParamlistener(true);
Gtk::TreeModel::Children children = treemodel_->children();
Gtk::TreeModel::Children::iterator iter;
for (iter = children.begin(); iter != children.end(); iter++) {
Gtk::TreeModel::Row row = *iter;
if (row[spots_.id] == spot->id) {
row[spots_.name] = spot->name;
row[spots_.isvisible] = spot->isvisible;
row[spots_.shape] = spot->shape;
row[spots_.spotMethod] = spot->spotMethod;
row[spots_.sensiexclu] = spot->sensiexclu;
row[spots_.struc] = spot->struc;
row[spots_.shapeMethod] = spot->shapeMethod;
row[spots_.locX] = spot->locX;
row[spots_.locXL] = spot->locXL;
row[spots_.locY] = spot->locY;
row[spots_.locYT] = spot->locYT;
row[spots_.centerX] = spot->centerX;
row[spots_.centerY] = spot->centerY;
row[spots_.circrad] = spot->circrad;
row[spots_.qualityMethod] = spot->qualityMethod;
row[spots_.transit] = spot->transit;
row[spots_.thresh] = spot->thresh;
row[spots_.iter] = spot->iter;
updateControlSpotCurve(row);
updateParamVisibility();
disableParamlistener(false);
return 1;
}
}
disableParamlistener(false);
return 0;
}
void ControlSpotPanel::deleteControlSpot(int id)
{
printf("deleteControlSpot: %d\n", id);
disableParamlistener(true);
Gtk::TreeModel::Children children = treemodel_->children();
Gtk::TreeModel::Children::iterator iter;
for (iter = children.begin(); iter != children.end(); iter++) {
Gtk::TreeModel::Row row = *iter;
if (row[spots_.id] == id) {
deleteControlSpotCurve(row);
treemodel_->erase(iter);
}
}
disableParamlistener(false);
}
ControlSpotPanel::SpotEdited* ControlSpotPanel::getEditedStates()
{
printf("getEditedStates\n");
SpotEdited* se = new SpotEdited();
if (nbSpotChanged_) {
se->nbspot = true;
// nbSpotChanged_ = false;
} else {
se->nbspot = false;
}
if (selSpotChanged_) {
se->selspot = true;
// selSpotChanged_ = false;
} else {
se->selspot = false;
}
if (nameChanged_) {
se->name = true;
// nameChanged_ = false;
} else {
se->name = false;
}
se->isvisible = false; // TODO isvisible
se->shape = shape_->get_active_row_number() != 2;
se->spotMethod = spotMethod_->get_active_row_number() != 2;
se->sensiexclu = sensiexclu_->getEditedState();
se->struc = struc_->getEditedState();
se->shapeMethod = shapeMethod_->get_active_row_number() != 4;
se->locX = locX_->getEditedState();
se->locXL = locXL_->getEditedState();
se->locY = locY_->getEditedState();
se->locYT = locYT_->getEditedState();
se->centerX = centerX_->getEditedState();
se-> centerY = centerY_->getEditedState();
se->circrad = circrad_->getEditedState();
se->qualityMethod = qualityMethod_->get_active_row_number() != 4;
se->transit = transit_->getEditedState();
se->thresh = thresh_->getEditedState();
se->iter = iter_->getEditedState();
return se;
}
void ControlSpotPanel::setEditedStates(SpotEdited* se)
{
printf("setEditedStates\n");
// Reset treeview edited states
nbSpotChanged_ = false;
selSpotChanged_ = false;
nameChanged_ = false;
// Disable params listeners
disableParamlistener(true);
// Set widgets edited states
if (!se->nbspot || !se->selspot) {
treeview_.set_sensitive(false);
button_add_.set_sensitive(false);
button_delete_.set_sensitive(false);
button_rename_.set_sensitive(false);
} else {
treeview_.set_sensitive(true);
button_add_.set_sensitive(true);
button_delete_.set_sensitive(true);
button_rename_.set_sensitive(se->name);
}
// TODO Add isvisible
if (!se->shape) {
shape_->set_active(2);
}
if (!se->spotMethod) {
spotMethod_->set_active(2);
}
sensiexclu_->setEditedState(se->sensiexclu ? Edited : UnEdited);
struc_->setEditedState(se->struc ? Edited : UnEdited);
if (!se->shapeMethod) {
shapeMethod_->set_active(4);
}
locX_->setEditedState(se->locX ? Edited : UnEdited);
locXL_->setEditedState(se->locXL ? Edited : UnEdited);
locY_->setEditedState(se->locY ? Edited : UnEdited);
locYT_->setEditedState(se->locYT ? Edited : UnEdited);
centerX_->setEditedState(se->centerX ? Edited : UnEdited);
centerY_->setEditedState(se->centerY ? Edited : UnEdited);
circrad_->setEditedState(se->circrad ? Edited : UnEdited);
if (!se->qualityMethod) {
qualityMethod_->set_active(4);
}
transit_->setEditedState(se->transit ? Edited : UnEdited);
thresh_->setEditedState(se->thresh ? Edited : UnEdited);
iter_->setEditedState(se->iter ? Edited : UnEdited);
// Enable params listeners
disableParamlistener(false);
}
void ControlSpotPanel::setDefaults(const ProcParams * defParams, const ParamsEdited * pedited, int id)
{
// Find vector index of given spot id (index = -1 if not found)
int index = -1;
for (int i = 0; i < (int)defParams->locallab.spots.size(); i++) {
printf("Test\n");
if (defParams->locallab.spots.at(i).id == id) {
index = i;
break;
}
}
printf("index: %d\n", index);
// Set default values for adjusters
const LocallabParams::LocallabSpot* defSpot = new LocallabParams::LocallabSpot();
if (index != -1 && index < (int)defParams->locallab.spots.size()) {
defSpot = &defParams->locallab.spots.at(index);
}
sensiexclu_->setDefault((double)defSpot->sensiexclu);
struc_->setDefault((double)defSpot->struc);
locX_->setDefault((double)defSpot->locX);
locXL_->setDefault((double)defSpot->locXL);
locY_->setDefault((double)defSpot->locY);
locYT_->setDefault((double)defSpot->locYT);
centerX_->setDefault((double)defSpot->centerX);
centerY_->setDefault((double)defSpot->centerY);
circrad_->setDefault((double)defSpot->circrad);
transit_->setDefault((double)defSpot->transit);
thresh_->setDefault((double)defSpot->thresh);
iter_->setDefault((double)defSpot->iter);
// Set default edited states for adjusters
if (!pedited) {
sensiexclu_->setDefaultEditedState(Irrelevant);
struc_->setDefaultEditedState(Irrelevant);
locX_->setDefaultEditedState(Irrelevant);
locXL_->setDefaultEditedState(Irrelevant);
locY_->setDefaultEditedState(Irrelevant);
locYT_->setDefaultEditedState(Irrelevant);
centerX_->setDefaultEditedState(Irrelevant);
centerY_->setDefaultEditedState(Irrelevant);
circrad_->setDefaultEditedState(Irrelevant);
transit_->setDefaultEditedState(Irrelevant);
thresh_->setDefaultEditedState(Irrelevant);
iter_->setDefaultEditedState(Irrelevant);
} else {
const LocallabParamsEdited::LocallabSpotEdited* defSpotState = new LocallabParamsEdited::LocallabSpotEdited(true);
if (index != 1 && index < (int)pedited->locallab.spots.size()) {
defSpotState = &pedited->locallab.spots.at(index);
}
sensiexclu_->setDefaultEditedState(defSpotState->sensiexclu ? Edited : UnEdited);
struc_->setDefaultEditedState(defSpotState->struc ? Edited : UnEdited);
locX_->setDefaultEditedState(defSpotState->locX ? Edited : UnEdited);
locXL_->setDefaultEditedState(defSpotState->locXL ? Edited : UnEdited);
locY_->setDefaultEditedState(defSpotState->locY ? Edited : UnEdited);
locYT_->setDefaultEditedState(defSpotState->locYT ? Edited : UnEdited);
centerX_->setDefaultEditedState(defSpotState->centerX ? Edited : UnEdited);
centerY_->setDefaultEditedState(defSpotState->centerY ? Edited : UnEdited);
circrad_->setDefaultEditedState(defSpotState->circrad ? Edited : UnEdited);
transit_->setDefaultEditedState(defSpotState->transit ? Edited : UnEdited);
thresh_->setDefaultEditedState(defSpotState->thresh ? Edited : UnEdited);
iter_->setDefaultEditedState(defSpotState->iter ? Edited : UnEdited);
}
}
/*
void ControlSpotPanel::updateDefaultsValues(const rtengine::procparams::ProcParams* defParams, int id)
{
const LocallabParams::LocallabSpot* defSpot = new LocallabParams::LocallabSpot();
for (int i = 0; i < (int)defParams->locallab.spots.size(); i++) {
if (defParams->locallab.spots.at(i).id == id) {
defSpot = &defParams->locallab.spots.at(i);
break;
}
}
// Set default values for adjusters
sensiexclu_->setDefault((double)defSpot->sensiexclu);
struc_->setDefault((double)defSpot->struc);
locX_->setDefault((double)defSpot->locX);
locXL_->setDefault((double)defSpot->locXL);
locY_->setDefault((double)defSpot->locY);
locYT_->setDefault((double)defSpot->locYT);
centerX_->setDefault((double)defSpot->centerX);
centerY_->setDefault((double)defSpot->centerY);
circrad_->setDefault((double)defSpot->circrad);
transit_->setDefault((double)defSpot->transit);
thresh_->setDefault((double)defSpot->thresh);
iter_->setDefault((double)defSpot->iter);
}
void ControlSpotPanel::updateDefaultsStates(const ParamsEdited* pedited, int id = 0)
{
}
*/
void ControlSpotPanel::setBatchMode(bool batchMode)
{
ToolPanel::setBatchMode(batchMode);
// Set batch mode for adjusters
sensiexclu_->showEditedCB();
struc_->showEditedCB();
locX_->showEditedCB();
locXL_->showEditedCB();
locY_->showEditedCB();
locYT_->showEditedCB();
centerX_->showEditedCB();
centerY_->showEditedCB();
circrad_->showEditedCB();
transit_->showEditedCB();
thresh_->showEditedCB();
iter_->showEditedCB();
}
//-----------------------------------------------------------------------------
// ControlSpots
//-----------------------------------------------------------------------------
ControlSpotPanel::ControlSpots::ControlSpots()
{
add(id);
add(name);
add(isvisible);
add(curveid);
add(shape);
add(spotMethod);
add(sensiexclu);
add(struc);
add(shapeMethod);
add(locX);
add(locXL);
add(locYT);
add(locY);
add(centerX);
add(centerY);
add(circrad);
add(qualityMethod);
add(transit);
add(thresh);
add(iter);
}
//-----------------------------------------------------------------------------
// RenameDialog
//-----------------------------------------------------------------------------
ControlSpotPanel::RenameDialog::RenameDialog(const Glib::ustring &actualname, Gtk::Window &parent):
Gtk::Dialog("Renaming Control Spot", parent)
{
Gtk::HBox *hb = Gtk::manage(new Gtk::HBox());
hb->pack_start(*Gtk::manage(new Gtk::Label("Enter the new Control Spot name")), false, false, 4);
newname_.set_text(actualname);
hb->pack_start(newname_);
get_content_area()->pack_start(*hb, Gtk::PACK_SHRINK, 4);
add_button(M("GENERAL_OK"), 1);
add_button(M("GENERAL_CANCEL"), 2);
show_all_children();
}
Glib::ustring ControlSpotPanel::RenameDialog::get_new_name()
{
return newname_.get_text();
}