/* * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath * * 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 . */ #include "coordinateadjuster.h" #include "multilangmgr.h" #include #include "curveeditorgroup.h" Axis::Axis() : decimal(5), increment(0.001), pageIncrement(0.01), rangeLowerBound(0.), rangeUpperBound(1.) {} Axis::Axis(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin = 0.0, double valMax = 1.0) : label(label), decimal(decimal), increment(increment), pageIncrement(pageIncrement), rangeLowerBound(valMin), rangeUpperBound(valMax) {} void Axis::setValues(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin, double valMax) { this->label = label; this->decimal = decimal; this->increment = increment; this->pageIncrement = pageIncrement; this->rangeLowerBound = valMin; this->rangeUpperBound = valMax; } CoordinateAdjuster::AxisAdjuster::AxisAdjuster(CoordinateAdjuster *parent, const Axis *axis, char index) : idx(index), parent(parent), rangeLowerBound(0.f), rangeUpperBound(0.f) { label = Gtk::manage(new Gtk::Label(axis->label)); spinButton = Gtk::manage(new Gtk::SpinButton()); spinButton->set_name("AxisAdjuster"); spinButton->set_digits(axis->decimal); spinButton->set_increments(axis->increment, axis->pageIncrement); spinButton->set_range(axis->rangeLowerBound, axis->rangeUpperBound); spinButton->set_sensitive(false); spinButtonConn = spinButton->signal_value_changed().connect( sigc::mem_fun(*this, &CoordinateAdjuster::AxisAdjuster::valueChanged) ); //spinButton->signal_key_press_event().connect( sigc::mem_fun(*this, &CoordinateAdjuster::AxisAdjuster::keyPressed) ); } void CoordinateAdjuster::AxisAdjuster::updateGUI(const Axis &axis) { label->set_text(axis.label); spinButton->set_digits(axis.decimal); spinButton->set_increments(axis.increment, axis.pageIncrement); spinButton->set_range(axis.rangeLowerBound, axis.rangeUpperBound); spinButton->set_sensitive(false); rangeLowerBound = axis.rangeLowerBound; rangeUpperBound = axis.rangeUpperBound; } void CoordinateAdjuster::AxisAdjuster::setValue(double newValue) { float range = rangeUpperBound - rangeLowerBound; spinButtonConn.block(true); spinButton->set_value(static_cast(newValue) * range + rangeLowerBound); spinButtonConn.block(false); } void CoordinateAdjuster::AxisAdjuster::valueChanged() { float range = rangeUpperBound - rangeLowerBound; parent->updatePos(idx, (static_cast(spinButton->get_value()) - rangeLowerBound) / range); } CoordinateAdjuster::CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent, const std::vector &axis) : status(CA_STATUS_IDLE), parent(parent), coordinateProvider(provider) { provider->setListener(this); createWidgets(axis); } CoordinateAdjuster::CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent) : status(CA_STATUS_IDLE), parent(parent), coordinateProvider(provider) { std::vector defaultAxis; Axis X(M("CURVEEDITOR_AXIS_IN"), 3, 0.1, 1., 0., 100.); Axis Y(M("CURVEEDITOR_AXIS_OUT"), 3, 0.1, 1., 0., 100.); defaultAxis.push_back(X); defaultAxis.push_back(Y); provider->setListener(this); createWidgets(defaultAxis); } CoordinateAdjuster::~CoordinateAdjuster() { for (std::vector::iterator iterator = axisAdjusters.begin(); iterator != axisAdjusters.end(); ++iterator) delete *iterator; } void CoordinateAdjuster::createWidgets(const std::vector &axis) { unsigned int count = axis.size(); if (!count) { printf("CoordinateAdjuster - Error: the Axis list is empty!\n"); return; } assert (count <= 4); axisAdjusters.resize(axis.size()); for (unsigned int i = 0; i < count; ++i) { const Axis *currAxis = &(axis.at(i)); axisAdjusters.at(i) = new AxisAdjuster(this, currAxis, i); AxisAdjuster *currAdjuster = axisAdjusters.at(i); currAdjuster->rangeLowerBound = currAxis->rangeLowerBound; currAdjuster->rangeUpperBound = currAxis->rangeUpperBound; Gtk::Grid *box = Gtk::manage (new Gtk::Grid()); box->set_orientation(Gtk::ORIENTATION_HORIZONTAL); setExpandAlignProperties(currAdjuster->label, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); setExpandAlignProperties(currAdjuster->spinButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); box->attach_next_to(*(currAdjuster->spinButton), Gtk::POS_LEFT, 1, 1); box->attach_next_to(*(currAdjuster->label), Gtk::POS_LEFT, 1, 1); Gtk::FlowBoxChild *fbChild = Gtk::manage(new Gtk::FlowBoxChild()); fbChild->set_can_focus(false); fbChild->add(*box); add(*fbChild); } } void CoordinateAdjuster::updatePos(char index, double value) { coordinateProvider->setPos(value, index); } void CoordinateAdjuster::setAxis(const std::vector &axis) { assert (axis.size() == axisAdjusters.size()); for (size_t i = 0; i < axisAdjusters.size(); ++i) { axisAdjusters.at(i)->updateGUI(axis.at(i)); } } void CoordinateAdjuster::setPos(std::vector &pos) { if (is_visible()) { for (size_t i = 0; i < pos.size(); ++i) { axisAdjusters.at(i)->setValue(pos.at(i)); } } } void CoordinateAdjuster::startNumericalAdjustment(const std::vector &newBoundaries) { for (size_t i = 0; i < axisAdjusters.size(); ++i) { Gtk::SpinButton *currSpinButton = axisAdjusters.at(i)->spinButton; currSpinButton->set_sensitive(true); float range = axisAdjusters.at(i)->rangeUpperBound - axisAdjusters.at(i)->rangeLowerBound; currSpinButton->set_range(newBoundaries.at(i).minVal * static_cast(range) + static_cast(axisAdjusters.at(i)->rangeLowerBound), newBoundaries.at(i).maxVal * static_cast(range) + static_cast(axisAdjusters.at(i)->rangeLowerBound)); } axisAdjusters.at(0)->spinButton->grab_focus(); status = CA_STATUS_EDITING; } void CoordinateAdjuster::switchAdjustedPoint(std::vector &pos, const std::vector &newBoundaries) { if (status != CA_STATUS_EDITING) { return; } for (size_t i = 0; i < axisAdjusters.size(); ++i) { AxisAdjuster *currAxis = axisAdjusters.at(i); // disable events currAxis->spinButtonConn.block(true); // To avoid trimmed values, we have to... // ...enlarge range to the maximum currAxis->spinButton->set_range(axisAdjusters.at(i)->rangeLowerBound, axisAdjusters.at(i)->rangeUpperBound); // ...set the new value currAxis->setValue(pos.at(i)); // ...narrow the range to the new interval float range = axisAdjusters.at(i)->rangeUpperBound - axisAdjusters.at(i)->rangeLowerBound; currAxis->spinButton->set_range(newBoundaries.at(i).minVal * static_cast(range) + static_cast(axisAdjusters.at(i)->rangeLowerBound), newBoundaries.at(i).maxVal * static_cast(range) + static_cast(axisAdjusters.at(i)->rangeLowerBound)); // enable events currAxis->spinButtonConn.block(false); } axisAdjusters.at(0)->spinButton->grab_focus(); status = CA_STATUS_EDITING; } void CoordinateAdjuster::showMe(CoordinateProvider *provider) { parent->showCoordinateAdjuster(provider); } void CoordinateAdjuster::stopNumericalAdjustment() { for (size_t i = 0; i < axisAdjusters.size(); ++i) { axisAdjusters.at(i)->spinButtonConn.block(true); axisAdjusters.at(i)->spinButton->set_sensitive(false); axisAdjusters.at(i)->spinButton->set_range(axisAdjusters.at(i)->rangeLowerBound, axisAdjusters.at(i)->rangeUpperBound); axisAdjusters.at(i)->spinButtonConn.block(false); } status = CA_STATUS_IDLE; }