1 /* -*- C++ -*-
2  *
3  *  This file is part of RawTherapee.
4  *
5  *  Copyright (c) 2019 Jean-Christophe FRISCH <natureh.510@gmail.com>
6  *
7  *  RawTherapee is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  RawTherapee is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with RawTherapee.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #pragma once
22 
23 #include <gtkmm.h>
24 #include "edit.h"
25 #include "toolpanel.h"
26 #include "adjuster.h"
27 #include "../rtengine/procparams.h"
28 #include "../rtengine/tweakoperator.h"
29 
30 /**
31  * @brief Let the user create/edit/delete points for Spot Removal tool
32  *
33  * User Interface:
34  *
35  * For the rest of this documentation, T represent a "target" point (where the image is edited) and
36  * S represent the "source" location (where the edition takes its source data).
37  *
38  * When the edit button is active, all T points are shown by a small "dot". When the user
39  * move the cursor over one of them, a circle is displayed to show the radius of the brush, as well
40  * as a second circle representing the source data (S point). The user can then use the left mouse button
41  * over the icon to drag the T point. The left mouse button can be used over the S circle or the right
42  * mouse button can be used over the T point to move the S point.
43  *
44  * Using the left mouse button over the circle of the T point will let the user adjust its radius.
45  *
46  * Using the left mouse button over the feather circle will let the user adjust its radius by setting
47  * a coefficient (0.0 = same radius than the inner circle ; 1.0 = 2 times the inner radius).
48  *
49  * To create a new point, just move over a free area, and press the left mouse button while holding
50  * the CTRL key. This will create a new S and T pair of points. The CTRL key can be released, but keep
51  * the left mouse button pressed and move away to position the S point.
52  *
53  * To delete a point, move your mouse over any of its geometry press the middle or right mouse button
54  * (the point will be deleted on button release).
55  */
56 
57 class Spot: public ToolParamBlock, public FoldableToolPanel, public rtengine::TweakOperator, public EditSubscriber, public AdjusterListener
58 {
59 
60 private:
61     enum class DraggedSide {
62         NONE,
63         SOURCE,
64         TARGET
65     };
66 
67     DraggedSide draggedSide;       // tells which of source or target is being dragged
68     int lastObject;                // current object that is hovered
69     int activeSpot;                // currently active spot, being edited
70     std::vector<rtengine::procparams::SpotEntry> spots; // list of edited spots
71     OPIcon sourceIcon;             // to show the source location
72     Circle sourceCircle;           // to show and change the Source radius
73     Circle sourceMODisc;           // to change the Source position
74     OPIcon targetIcon;             // to show the target location
75     Circle targetCircle;           // to show and change the Target radius
76     Circle targetMODisc;           // to change the Target position
77     Circle sourceFeatherCircle;    // to show the Feather radius at the Source position
78     Circle targetFeatherCircle;    // to show the Feather radius at the Target position
79     Line link;                     // to show the link between the Source and Target position
80     std::unique_ptr<Geometry> whole_area_rectangle; // dummy rectangle to always set a custom cursor
81 
82     OPIcon *getActiveSpotIcon ();
83     void updateGeometry ();
84     void createGeometry ();
85     void addNewEntry ();
86     void deleteSelectedEntry ();
87     void resetPressed ();
88 
89 protected:
90     Gtk::HBox* labelBox;
91     Gtk::CheckButton* editedCheckBox;
92     Gtk::Label* countLabel;
93     Gtk::ToggleButton* edit;
94     Gtk::Button* reset;
95     sigc::connection editConn, editedConn;
96 
97     void editToggled ();
98     void editedToggled ();
99     Geometry* getVisibleGeometryFromMO (int MOID);
100 
101     Gtk::Frame *spot_frame;
102     Adjuster *source_x;
103     Adjuster *source_y;
104     Adjuster *target_x;
105     Adjuster *target_y;
106     Adjuster *radius;
107     Adjuster *feather;
108     Adjuster *opacity;
109     Adjuster *detail;
110     std::vector<Adjuster *> spot_adjusters;
111 
112     rtengine::procparams::SpotParams initial_params;
113 
114     void reset_adjusters();
115     void on_fold(GdkEventButton *event);
116     void on_hide() override;
117 
118 public:
119 
120     Spot();
121     ~Spot();
122 
123     void read(const rtengine::procparams::ProcParams *pp) override;
124     void write (rtengine::procparams::ProcParams *pp) override;
125 
126     void enabledChanged() override;
127     void toolReset(bool to_initial) override;
128     void setDefaults(const rtengine::procparams::ProcParams *pp) override;
129 
130     void setEditProvider(EditDataProvider* provider) override;
131 
132     // EditSubscriber interface
133     CursorShape getCursor (int objectID, int xPos, int yPos) override;
134     bool mouseOver (int modifierKey) override;
135     bool button1Pressed (int modifierKey) override;
136     bool button1Released () override;
137     bool button2Pressed (int modifierKey) override;
138     bool button3Pressed (int modifierKey) override;
139     bool button3Released () override;
140     bool drag1 (int modifierKey) override;
141     bool drag3 (int modifierKey) override;
142     bool pick2 (bool picked) override;
143     bool pick3 (bool picked) override;
144     void switchOffEditMode () override;
145 
146     //TweakOperator interface
147     void tweakParams(rtengine::procparams::ProcParams& pparams) override;
148 
149     void adjusterChanged(Adjuster *a, double newval) override;
150 
151     rtengine::ProcEvent EvSpotEnabled;
152     rtengine::ProcEvent EvSpotEnabledOPA; // used to toggle-on the Spot 'On Preview Adjustment' mode
153     rtengine::ProcEvent EvSpotEntry;
154     rtengine::ProcEvent EvSpotEntryOPA;
155 };
156 
157