Initial creation of Control Spot panel
This commit is contained in:
@@ -34,6 +34,7 @@ set(NONCLISOURCEFILES
|
||||
colorappearance.cc
|
||||
coloredbar.cc
|
||||
colortoning.cc
|
||||
controlspotpanel.cc
|
||||
coordinateadjuster.cc
|
||||
crop.cc
|
||||
crophandler.cc
|
||||
|
||||
1114
rtgui/controlspotpanel.cc
Normal file
1114
rtgui/controlspotpanel.cc
Normal file
File diff suppressed because it is too large
Load Diff
131
rtgui/controlspotpanel.h
Normal file
131
rtgui/controlspotpanel.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* This file is part of RawTherapee.
|
||||
*/
|
||||
|
||||
#ifndef _CONTROLSPOTPANEL_H_
|
||||
#define _CONTROLSPOTPANEL_H_
|
||||
|
||||
#include "../rtengine/coord.h"
|
||||
#include "adjuster.h"
|
||||
#include "edit.h"
|
||||
#include "guiutils.h"
|
||||
#include "toolpanel.h"
|
||||
#include <gtkmm.h>
|
||||
#include <string>
|
||||
|
||||
class ControlSpotPanel:
|
||||
public ToolParamBlock,
|
||||
public AdjusterListener,
|
||||
public EditSubscriber
|
||||
{
|
||||
public:
|
||||
ControlSpotPanel();
|
||||
void setEditProvider(EditDataProvider* provider);
|
||||
|
||||
private:
|
||||
// cell renderer
|
||||
void render_id (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
|
||||
void render_name (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
|
||||
void render_isvisible (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
|
||||
|
||||
void on_button_add();
|
||||
void on_button_delete();
|
||||
void on_button_rename();
|
||||
// TODO Add visibility button
|
||||
// TODO Add duplication button
|
||||
|
||||
void save_ControlSpot_param();
|
||||
void load_ControlSpot_param();
|
||||
|
||||
void controlspotChanged();
|
||||
|
||||
void shapeChanged();
|
||||
void shapeMethodeChanged();
|
||||
void updateParamVisibility();
|
||||
void adjusterChanged(Adjuster* a, double newval);
|
||||
void disableParamlistener(bool cond);
|
||||
void setParamEditable(bool cond);
|
||||
|
||||
void addControlSpotCurve(Gtk::TreeModel::Row row);
|
||||
void updateControlSpotCurve(Gtk::TreeModel::Row row);
|
||||
void deleteControlSpotCurve(Gtk::TreeModel::Row row);
|
||||
CursorShape getCursor(int objectID);
|
||||
bool mouseOver(int modifierKey);
|
||||
bool button1Pressed(int modifierKey);
|
||||
bool button1Released();
|
||||
bool drag1(int modifierKey);
|
||||
|
||||
class ControlSpots:
|
||||
public Gtk::TreeModel::ColumnRecord
|
||||
{
|
||||
public:
|
||||
ControlSpots();
|
||||
|
||||
Gtk::TreeModelColumn<int> id; // Control spot id
|
||||
Gtk::TreeModelColumn<Glib::ustring> name;
|
||||
Gtk::TreeModelColumn<bool> isvisible;
|
||||
Gtk::TreeModelColumn<int> curveid; // Associated curve id
|
||||
Gtk::TreeModelColumn<int> shape; // 0 = Ellipse, 1 = Rectangle
|
||||
Gtk::TreeModelColumn<int> spotMethod; // 0 = Normal, 1 = Excluding
|
||||
Gtk::TreeModelColumn<int> shapeMethod; // 0 = Independent (mouse), 1 = Symmetrical (mouse), 2 = Independent (mouse + sliders), 3 = Symmetrical (mouse + sliders)
|
||||
Gtk::TreeModelColumn<int> locX;
|
||||
Gtk::TreeModelColumn<int> locXL;
|
||||
Gtk::TreeModelColumn<int> locY;
|
||||
Gtk::TreeModelColumn<int> locYT;
|
||||
Gtk::TreeModelColumn<int> centerX;
|
||||
Gtk::TreeModelColumn<int> centerY;
|
||||
Gtk::TreeModelColumn<int> circrad;
|
||||
Gtk::TreeModelColumn<int> qualityMethod; // 0 = Standard, 1 = Enhanced, 2 = Enhanced + chroma denoise
|
||||
Gtk::TreeModelColumn<int> transit;
|
||||
Gtk::TreeModelColumn<int> thresh;
|
||||
Gtk::TreeModelColumn<int> iter;
|
||||
};
|
||||
|
||||
class RenameDialog:
|
||||
public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
RenameDialog (const Glib::ustring &actualname, Gtk::Window &parent);
|
||||
Glib::ustring get_new_name();
|
||||
|
||||
private:
|
||||
Gtk::Entry newname_;
|
||||
};
|
||||
|
||||
ControlSpots spots_;
|
||||
|
||||
// Child widgets
|
||||
Gtk::ScrolledWindow scrolledwindow_;
|
||||
Gtk::TreeView treeview_;
|
||||
Glib::RefPtr<Gtk::ListStore> treemodel_;
|
||||
|
||||
Gtk::ButtonBox buttonbox_;
|
||||
Gtk::Button button_add_;
|
||||
Gtk::Button button_delete_;
|
||||
Gtk::Button button_rename_;
|
||||
|
||||
MyComboBoxText* const shape_;
|
||||
sigc::connection shapeconn_;
|
||||
MyComboBoxText* const spotMethod_;
|
||||
sigc::connection spotMethodconn_;
|
||||
MyComboBoxText* const shapeMethod_;
|
||||
sigc::connection shapeMethodconn_;
|
||||
MyComboBoxText* const qualityMethod_;
|
||||
sigc::connection qualityMethodconn_;
|
||||
|
||||
Adjuster* const locX_;
|
||||
Adjuster* const locXL_;
|
||||
Adjuster* const locY_;
|
||||
Adjuster* const locYT_;
|
||||
Adjuster* const centerX_;
|
||||
Adjuster* const centerY_;
|
||||
Adjuster* const circrad_;
|
||||
Adjuster* const transit_;
|
||||
Adjuster* const thresh_;
|
||||
Adjuster* const iter_;
|
||||
|
||||
int lastObject_;
|
||||
rtengine::Coord* lastCoord_;
|
||||
};
|
||||
|
||||
#endif // _CONTROLSPOTPANEL_H_
|
||||
@@ -312,14 +312,9 @@ void Arcellipse::drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOB
|
||||
|
||||
rtengine::Coord center_ = center;
|
||||
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius)) : double (radius);
|
||||
// double radius2_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius2)) : double (radius2);
|
||||
double scalx_ = scalx; //radius2_ / radius_;
|
||||
|
||||
double scaly_ = scaly;
|
||||
double radius2_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius2)) : double (radius2);
|
||||
double begang_ = begang;
|
||||
double endang_ = endang;
|
||||
double translax_ = translax;
|
||||
double translay_ = translay;
|
||||
|
||||
if (datum == IMAGE) {
|
||||
coordSystem.imageCoordToScreen (center.x, center.y, center_.x, center_.y);
|
||||
@@ -329,17 +324,24 @@ void Arcellipse::drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOB
|
||||
center_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
|
||||
}
|
||||
|
||||
if (radius_ > 0 && radius2_ > 0.) {
|
||||
cr->save();
|
||||
cr->translate (translax_, translay_);
|
||||
|
||||
cr->scale (scalx_, scaly_);
|
||||
cr->translate (- translax_ , - translay_);
|
||||
// To have an ellipse with radius of (rad1, rad2), a circle of radius rad1 shall be twisted with a scale
|
||||
// of rad2 / rad1 for y axis
|
||||
// Center of coordinates (x, y) in previous coordinates system becomes (X, Y) = (x, rad2 / rad1 * y) in new one
|
||||
// To go back to previous location, center shall be translated to t = -Y * (1 - rad1 / rad2) in y axis
|
||||
// (Y = rad2 / rad1 * y and y = t + Y)
|
||||
double scale_ = radius2_ / radius_;
|
||||
cr->scale (1., scale_);
|
||||
cr->translate (0., - center_.y * (1 - 1 / scale_));
|
||||
|
||||
cr->arc (center_.x + 0.5, center_.y + 0.5, radius_, begang_, endang_);
|
||||
|
||||
cr->restore();
|
||||
cr->stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -363,15 +365,9 @@ void Arcellipse::drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOB
|
||||
|
||||
rtengine::Coord center_ = center;
|
||||
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius)) : double (radius);
|
||||
// double radius2_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius2)) : double (radius2);
|
||||
|
||||
double scalx_ = scalx; //radius2_ / radius_;
|
||||
|
||||
double scaly_ = scaly;
|
||||
double radius2_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius2)) : double (radius2);
|
||||
double begang_ = begang;
|
||||
double endang_ = endang;
|
||||
double translax_ = translax;
|
||||
double translay_ = translay;
|
||||
|
||||
if (datum == IMAGE) {
|
||||
coordSystem.imageCoordToScreen (center.x, center.y, center_.x, center_.y);
|
||||
@@ -382,16 +378,23 @@ void Arcellipse::drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOB
|
||||
}
|
||||
|
||||
if (filled && state != INSENSITIVE) {
|
||||
if (radius_ > 0 && radius2_ > 0.) {
|
||||
cr->save();
|
||||
|
||||
cr->translate (translax_, translay_);
|
||||
|
||||
cr->scale (scalx_, scaly_);
|
||||
cr->translate (- translax_ , - translay_);
|
||||
// To have an ellipse with radius of (rad1, rad2), a circle of radius rad1 shall be twisted with a scale
|
||||
// of rad2 / rad1 for y axis
|
||||
// Center of coordinates (x, y) in previous coordinates system becomes (X, Y) = (x, rad2 / rad1 * y) in new one
|
||||
// To go back to previous location, center shall be translated to t = -Y * (1 - rad1 / rad2) in y axis
|
||||
// (Y = rad2 / rad1 * y and y = t + Y)
|
||||
double scale_ = radius2_ / radius_;
|
||||
cr->scale (1., scale_);
|
||||
cr->translate (0., - center_.y * (1 - 1 / scale_));
|
||||
|
||||
cr->arc (center_.x + 0.5, center_.y + 0.5, radius_, begang_, endang_);
|
||||
|
||||
cr->restore();
|
||||
cr->stroke();
|
||||
}
|
||||
|
||||
if (innerLineWidth > 0.) {
|
||||
cr->fill_preserve();
|
||||
@@ -400,16 +403,23 @@ void Arcellipse::drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOB
|
||||
cr->fill();
|
||||
}
|
||||
} else if (innerLineWidth > 0.) {
|
||||
if (radius_ > 0 && radius2_ > 0.) {
|
||||
cr->save();
|
||||
|
||||
cr->translate (translax_ , translay_);
|
||||
|
||||
cr->scale (scalx_, scaly_);
|
||||
cr->translate (- translax_ , - translay_);
|
||||
// To have an ellipse with radius of (rad1, rad2), a circle of radius rad1 shall be twisted with a scale
|
||||
// of rad2 / rad1 for y axis
|
||||
// Center of coordinates (x, y) in previous coordinates system becomes (X, Y) = (x, rad2 / rad1 * y) in new one
|
||||
// To go back to previous location, center shall be translated to t = -Y * (1 - rad1 / rad2) in y axis
|
||||
// (Y = rad2 / rad1 * y and y = t + Y)
|
||||
double scale_ = radius2_ / radius_;
|
||||
cr->scale (1., scale_);
|
||||
cr->translate (0., - center_.y * (1 - 1 / scale_));
|
||||
|
||||
cr->arc (center_.x + 0.5, center_.y + 0.5, radius_, begang_, endang_);
|
||||
|
||||
cr->restore();
|
||||
cr->stroke();
|
||||
}
|
||||
|
||||
if (state == INSENSITIVE) {
|
||||
std::valarray<double> ds (1);
|
||||
@@ -437,14 +447,9 @@ void Arcellipse::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned sh
|
||||
cr->set_line_width ( getMouseOverLineWidth() );
|
||||
rtengine::Coord center_ = center;
|
||||
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius)) : double (radius);
|
||||
// double radius2_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius2)) : double (radius2);
|
||||
|
||||
double scalx_ = scalx ; //radius2_ / radius_;
|
||||
double scaly_ = scaly;
|
||||
double radius2_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas (double (radius2)) : double (radius2);
|
||||
double begang_ = begang;
|
||||
double endang_ = endang;
|
||||
double translax_ = translax;
|
||||
double translay_ = translay;
|
||||
|
||||
if (datum == IMAGE) {
|
||||
coordSystem.imageCoordToCropCanvas (center.x, center.y, center_.x, center_.y);
|
||||
@@ -454,15 +459,23 @@ void Arcellipse::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned sh
|
||||
center_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
|
||||
}
|
||||
|
||||
if (radius_ > 0 && radius2_ > 0.) {
|
||||
cr->save();
|
||||
|
||||
cr->translate (translax_ , translay_);
|
||||
// To have an ellipse with radius of (rad1, rad2), a circle of radius rad1 shall be twisted with a scale
|
||||
// of rad2 / rad1 for y axis
|
||||
// Center of coordinates (x, y) in previous coordinates system becomes (X, Y) = (x, rad2 / rad1 * y) in new one
|
||||
// To go back to previous location, center shall be translated to t = -Y * (1 - rad1 / rad2) in y axis
|
||||
// (Y = rad2 / rad1 * y and y = t + Y)
|
||||
double scale_ = radius2_ / radius_;
|
||||
cr->scale (1., scale_);
|
||||
cr->translate (0., - center_.y * (1 - 1 / scale_));
|
||||
|
||||
cr->scale (scalx_, scaly_);
|
||||
cr->translate (- translax_ , - translay_);
|
||||
cr->arc (center_.x + 0.5, center_.y + 0.5, radius_, begang_, endang_);
|
||||
|
||||
cr->restore();
|
||||
cr->stroke();
|
||||
}
|
||||
|
||||
if (filled) {
|
||||
if (innerLineWidth > 0.) {
|
||||
|
||||
@@ -357,9 +357,9 @@ class Arcellipse : public Geometry
|
||||
{
|
||||
public:
|
||||
rtengine::Coord center;
|
||||
// rtengine::Coord scalx;
|
||||
// rtengine::Coord scaly;
|
||||
|
||||
// rtengine::Coord scalx;
|
||||
// rtengine::Coord scaly;
|
||||
// TODO translax, translay, scalx and scaly are not used
|
||||
double radius;
|
||||
double radius2;
|
||||
double translax;
|
||||
|
||||
@@ -280,6 +280,8 @@ Locallab::Locallab():
|
||||
Evlocallabshapemethod = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_LOCSHAPEMETH");// = 600,
|
||||
Evlocallabspotduplicated = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_LOCSPOTDUP");
|
||||
|
||||
spotPanel = Gtk::manage(new ControlSpotPanel());
|
||||
expsettings->add(*spotPanel);
|
||||
editHBox = Gtk::manage(new Gtk::HBox());
|
||||
edit = Gtk::manage(new Gtk::ToggleButton());
|
||||
edit->add(*Gtk::manage(new RTImage("editmodehand.png")));
|
||||
@@ -4879,7 +4881,7 @@ void Locallab::setEditProvider(EditDataProvider * provider)
|
||||
EditSubscriber::setEditProvider(provider);
|
||||
cTgainshape->setEditProvider(provider);
|
||||
cTgainshaperab->setEditProvider(provider);
|
||||
|
||||
spotPanel->setEditProvider(provider);
|
||||
}
|
||||
|
||||
void Locallab::editToggled()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <string>
|
||||
#include "../rtengine/improcfun.h"
|
||||
#include "thresholdadjuster.h"
|
||||
|
||||
#include "controlspotpanel.h"
|
||||
|
||||
class Locallab :
|
||||
public ToolParamBlock,
|
||||
@@ -165,7 +165,7 @@ private:
|
||||
CurveEditorGroup* const LocalcurveEditorgainTrab;
|
||||
CurveEditorGroup* const llCurveEditorG;
|
||||
|
||||
|
||||
ControlSpotPanel *spotPanel;
|
||||
Gtk::HBox *editHBox;
|
||||
Gtk::ToggleButton* edit;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user