RawTherapee/rtgui/coordinateadjuster.h

166 lines
4.9 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/>.
*/
#ifndef _COORDINATEADJUSTER_
#define _COORDINATEADJUSTER_
#include <gtkmm.h>
class CurveEditorSubGroup;
class Axis
{
public:
Glib::ustring label;
unsigned int decimal;
double increment;
double pageIncrement;
double rangeLowerBound;
double rangeUpperBound;
Axis();
Axis(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin, double valMax);
void setValues(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin, double valMax);
};
class CoordinateAdjuster;
/**
* @brief Object that will emit NewCoordinates events
*/
class CoordinateProvider
{
protected:
CoordinateAdjuster *coordinateAdjuster;
public:
CoordinateProvider() : coordinateAdjuster(nullptr) {}
virtual ~CoordinateProvider() {}
void setListener(CoordinateAdjuster *adjuster)
{
coordinateAdjuster = adjuster;
}
/** @brief Update the position of the edited point ; will trigger events
*
* @param pos New position
* @param chanIdx Channel index as given in the std::vector upon instantiation
*/
virtual void setPos(double pos, int chanIdx) = 0;
virtual void stopNumericalAdjustment() = 0;
};
/**
* @brief Widget that displays spin buttons to adjust coordinates
*
* You can set up to 4 axis that will be displayed on a single line, so keep the labels short!
*
* The position of the Axis in the vector will be used in the communication between the Adjuster and the Provider to identify the Axis
*/
class CoordinateAdjuster : public Gtk::FlowBox
{
public:
//-------------------------------- AxisAdjuster -------------------
class AxisAdjuster
{
private:
char idx;
public:
CoordinateAdjuster *parent;
Gtk::Label *label;
Gtk::SpinButton *spinButton;
sigc::connection spinButtonConn;
float rangeLowerBound;
float rangeUpperBound;
AxisAdjuster(CoordinateAdjuster *parent, const Axis *axis, char index);
// used to update the AxisAdjuster's parameters
void updateGUI(const Axis &axis);
// used to update the displayed value
void setValue(double newValue);
//bool keyPressed(GdkEventKey* event);
void valueChanged();
};
//----------------------------------------------------------------
//-------------------------------- Boundaries -------------------
class Boundaries
{
public:
double minVal;
double maxVal;
};
//---------------------------------------------------------------
private:
typedef enum {
CA_STATUS_IDLE,
CA_STATUS_EDITING,
CA_STATUS_END_EDITING
} Status;
std::vector<AxisAdjuster*> axisAdjusters;
Status status;
CurveEditorSubGroup *parent;
void createWidgets(const std::vector<Axis> &axis);
protected:
friend class AxisAdjuster;
CoordinateProvider *coordinateProvider;
void updatePos(char index, double value);
public:
/// Basic X/Y adjuster, in the [0-1] range
CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent);
/// For more complex adjuster
CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent, const std::vector<Axis> &axis);
virtual ~CoordinateAdjuster();
// Update the Axis list, e.g. on Curve change, but MUST have the same axis count
void setAxis(const std::vector<Axis> &axis);
/** @brief Update the numbers in the spin buttons ; doesn't trigger any event
*
* @param pos Vector that gives the values of each channels
*/
void setPos(std::vector<double> &pos);
/// Start the adjustment session (enable the widget)
void startNumericalAdjustment(const std::vector<Boundaries> &newBoundaries);
/// Edit another point
void switchAdjustedPoint(std::vector<double> &pos, const std::vector<Boundaries> &newBoundaries);
/// Trigger the event to show the CoordinateAdjuster
void showMe(CoordinateProvider *provider);
/// Stop the adjustment session (disable the widget, i.e. you won't be able to edit the values)
void stopNumericalAdjustment();
};
#endif