diff --git a/rtdata/images/svg/draw-horizontal.svg b/rtdata/images/svg/draw-horizontal.svg
deleted file mode 100644
index ae8fa8c44..000000000
--- a/rtdata/images/svg/draw-horizontal.svg
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
diff --git a/rtdata/images/svg/draw-vertical.svg b/rtdata/images/svg/draw-vertical.svg
deleted file mode 100644
index 4613d95c6..000000000
--- a/rtdata/images/svg/draw-vertical.svg
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc
index 13fc170dc..02aea16f6 100644
--- a/rtgui/perspective.cc
+++ b/rtgui/perspective.cc
@@ -52,10 +52,9 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
lens_geom_listener = nullptr;
metadata = nullptr;
- Gtk::Image* ipers_draw_horiz = Gtk::manage (new RTImage ("draw-horizontal.png"));
- Gtk::Image* ipers_draw_vert = Gtk::manage (new RTImage ("draw-vertical.png"));
- std::unique_ptr ipers_draw(new RTImage ("draw.png"));
+ Gtk::Image* ipers_draw(new RTImage ("draw.png"));
Gtk::Image* ipers_trash = Gtk::manage (new RTImage ("trash-empty.png"));
+ Gtk::Image* ipers_apply = Gtk::manage (new RTImage ("tick.png"));
Gtk::Image* ipersHL = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png"));
Gtk::Image* ipersHR = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png"));
@@ -126,15 +125,11 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
camera_yaw->setAdjusterListener (this);
// Begin control lines interface.
- lines_button_h = Gtk::manage (new Gtk::ToggleButton());
- lines_button_h->set_image(*ipers_draw_horiz);
- lines_button_h->signal_toggled().connect(sigc::bind(sigc::mem_fun(
- *this, &::PerspCorrection::linesButtonPressed), lines_button_h));
-
- lines_button_v = Gtk::manage (new Gtk::ToggleButton());
- lines_button_v->set_image(*ipers_draw_vert);
- lines_button_v->signal_toggled().connect(sigc::bind(sigc::mem_fun(
- *this, &::PerspCorrection::linesButtonPressed), lines_button_v));
+ lines_button_apply = Gtk::manage (new Gtk::Button());
+ lines_button_apply->set_image(*ipers_apply);
+ lines_button_apply->set_sensitive(false);
+ lines_button_apply->signal_pressed().connect(sigc::mem_fun(
+ *this, &::PerspCorrection::linesApplyButtonPressed));
lines_button_edit = Gtk::manage (new Gtk::ToggleButton());
lines_button_edit->set_image(*ipers_draw);
@@ -150,16 +145,12 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
lines = std::unique_ptr(new ControlLineManager());
lines->callbacks = std::make_shared(this);
- img_ctrl_lines_apply = std::unique_ptr(new RTImage ("tick.png"));
- img_ctrl_lines_edit = std::move(ipers_draw);
-
Gtk::HBox* control_lines_box = Gtk::manage (new Gtk::HBox());
control_lines_box->set_tooltip_text( M("TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP") );
Gtk::Label* control_lines_label = Gtk::manage (new Gtk::Label (M("TP_PERSPECTIVE_CONTROL_LINES") + ": "));
control_lines_box->pack_start(*control_lines_label, Gtk::PACK_SHRINK);
- control_lines_box->pack_start(*lines_button_v);
- control_lines_box->pack_start(*lines_button_h);
control_lines_box->pack_start(*lines_button_edit);
+ control_lines_box->pack_start(*lines_button_apply);
control_lines_box->pack_start(*lines_button_erase);
// End control lines interface.
@@ -595,8 +586,6 @@ void PerspCorrection::setBatchMode (bool batchMode)
projection_shift_vert->showEditedCB ();
projection_yaw->showEditedCB ();
- lines_button_h->set_sensitive(false);
- lines_button_v->set_sensitive(false);
lines_button_edit->set_sensitive(false);
auto_pitch->set_sensitive(false);
auto_yaw->set_sensitive(false);
@@ -653,8 +642,6 @@ void PerspCorrection::setFocalLengthValue (const ProcParams* pparams, const Fram
void PerspCorrection::switchOffEditMode(void)
{
- lines_button_h->set_active(false);
- lines_button_v->set_active(false);
lines_button_edit->set_active(false);
}
@@ -663,62 +650,37 @@ void PerspCorrection::setEditProvider(EditDataProvider* provider)
lines->setEditProvider(provider);
}
-void PerspCorrection::linesButtonPressed(Gtk::ToggleButton* button)
+void PerspCorrection::linesApplyButtonPressed(void)
{
- lines->setLinesState(lines_button_h->get_active(), lines_button_v->get_active());
-
- if (!button->get_active()) {
- return;
+ if (method->get_active_row_number() == 1) {
+ // Calculate perspective distortion if in camera-based mode.
+ applyControlLines();
}
-
- if (button == lines_button_h) {
- lines->draw_line_type = rtengine::ControlLine::HORIZONTAL;
- if (lines_button_v->get_active()) {
- lines_button_v->set_active(false);
- }
- } else if (button == lines_button_v) {
- lines->draw_line_type = rtengine::ControlLine::VERTICAL;
- if (lines_button_h->get_active()) {
- lines_button_h->set_active(false);
- }
- }
-
- if (!lines_button_edit->get_active()) {
- lines_button_edit->set_active(true);
- }
-
- lines->setDrawMode(true);
+ lines_button_edit->set_active(false);
}
void PerspCorrection::linesEditButtonPressed(void)
{
if (lines_button_edit->get_active()) { // Enter edit mode.
lines->setActive(true);
- if (img_ctrl_lines_apply) {
- lines_button_edit->set_image(*img_ctrl_lines_apply);
- }
+ lines->setDrawMode(true);
render = false;
- lines->setLinesState(lines_button_h->get_active(), lines_button_v->get_active());
if (lens_geom_listener) {
lens_geom_listener->updateTransformPreviewRequested(EvPerspRender, false);
}
+ lines_button_apply->set_sensitive(true);
lines_button_erase->set_sensitive(true);
setCamBasedEventsActive(false);
} else { // Leave edit mode.
setCamBasedEventsActive(true);
+ lines_button_apply->set_sensitive(false);
lines_button_erase->set_sensitive(false);
render = true;
+ if (lens_geom_listener) {
+ lens_geom_listener->updateTransformPreviewRequested(EvPerspRender, true);
+ }
lines->setDrawMode(false);
lines->setActive(false);
- if (img_ctrl_lines_edit) {
- lines_button_edit->set_image(*img_ctrl_lines_edit);
- }
- lines_button_h->set_active(false);
- lines_button_v->set_active(false);
- if (method->get_active_row_number() == 1) {
- // Calculate perspective distortion if in camera-based mode.
- applyControlLines();
- }
}
}
@@ -763,16 +725,6 @@ ControlLineManager::ControlLineManager():
line_icon_v_prelight = Cairo::RefPtr(new RTSurface("bidirectional-arrow-vertical-prelight.png"));
}
-Geometry::State ControlLineManager::calcLineState(const ::ControlLine& line) const
-{
- if (line.type == rtengine::ControlLine::HORIZONTAL && active_h) {
- return Geometry::NORMAL;
- } else if (line.type == rtengine::ControlLine::VERTICAL && active_v) {
- return Geometry::NORMAL;
- }
- return Geometry::INSENSITIVE;
-}
-
void ControlLineManager::setActive(bool active)
{
EditDataProvider* provider = getEditProvider();
@@ -797,19 +749,6 @@ void ControlLineManager::setDrawMode(bool draw)
draw_mode = draw;
}
-void ControlLineManager::setLinesState(bool horiz_active, bool vert_active)
-{
- active_h = horiz_active;
- active_v = vert_active;
-
- for (auto line = control_lines.begin(); line != control_lines.end(); line++) {
- auto state = calcLineState(**line);
- (*line)->begin->state = state;
- (*line)->end->state = state;
- (*line)->line->state = state;
- }
-}
-
size_t ControlLineManager::size(void) const
{
return control_lines.size();
@@ -835,6 +774,7 @@ bool ControlLineManager::button1Pressed(int modifierKey)
}
} else if (draw_mode && (modifierKey & GDK_CONTROL_MASK)) { // Add new line.
addLine(dataProvider->posImage, dataProvider->posImage);
+ drawing_line = true;
selected_object = mouseOverGeometry.size() - 1; // Select endpoint.
action = Action::DRAGGING;
}
@@ -848,6 +788,7 @@ bool ControlLineManager::button1Released(void)
if (selected_object > 0) {
mouseOverGeometry[selected_object]->state = Geometry::NORMAL;
}
+ drawing_line = false;
selected_object = -1;
return false;
}
@@ -894,11 +835,6 @@ bool ControlLineManager::pick1(bool picked)
visibleGeometry[object_id - 1] = line.icon.get();
- auto state = calcLineState(line);
- line.begin->state = state;
- line.end->state = state;
- line.line->state = state;
-
return true;
}
@@ -975,6 +911,9 @@ bool ControlLineManager::drag1(int modifierKey)
control_line.icon_v->position.x = control_line.icon_h->position.x;
control_line.icon_v->position.y = control_line.icon_h->position.y;
+ if (drawing_line) {
+ autoSetLineType(selected_object);
+ }
return false;
}
@@ -1011,10 +950,8 @@ bool ControlLineManager::mouseOver(int modifierKey)
}
if (prev_obj != cur_obj && prev_obj > 0) {
- auto state = calcLineState(*control_lines[(prev_obj - 1) / ::ControlLine::OBJ_COUNT]);
- visibleGeometry[prev_obj - 1]->state = state;
+ visibleGeometry[prev_obj - 1]->state = Geometry::NORMAL;
}
-
prev_obj = cur_obj;
return true;
@@ -1073,13 +1010,9 @@ void ControlLineManager::addLine(Coord begin, Coord end)
control_line->end = std::move(end_c);
control_line->icon_h = icon_h;
control_line->icon_v = icon_v;
- if (draw_line_type == rtengine::ControlLine::HORIZONTAL) {
- control_line->icon = icon_h;
- } else if (draw_line_type == rtengine::ControlLine::VERTICAL) {
- control_line->icon = icon_v;
- }
+ control_line->icon = icon_v;
control_line->line = std::move(line);
- control_line->type = draw_line_type;
+ control_line->type = rtengine::ControlLine::VERTICAL;
EditSubscriber::visibleGeometry.push_back(control_line->line.get());
EditSubscriber::visibleGeometry.push_back(control_line->icon.get());
@@ -1094,6 +1027,39 @@ void ControlLineManager::addLine(Coord begin, Coord end)
control_lines.push_back(std::move(control_line));
}
+void ControlLineManager::autoSetLineType(int object_id)
+{
+ int line_id = (object_id - 1) / ::ControlLine::OBJ_COUNT;
+ ::ControlLine& line = *control_lines[line_id];
+
+ int dx = line.begin->center.x - line.end->center.x;
+ int dy = line.begin->center.y - line.end->center.y;
+
+ if (dx < 0) {
+ dx = -dx;
+ }
+ if (dy < 0) {
+ dy = -dy;
+ }
+
+ rtengine::ControlLine::Type type;
+ std::shared_ptr icon;
+
+ if (dx > dy) { // More horizontal than vertical.
+ type = rtengine::ControlLine::HORIZONTAL;
+ icon = line.icon_h;
+ } else {
+ type = rtengine::ControlLine::VERTICAL;
+ icon = line.icon_v;
+ }
+
+ if (type != line.type) { // Need to update line type.
+ line.type = type;
+ line.icon = icon;
+ visibleGeometry[line_id * ::ControlLine::OBJ_COUNT + 1] = line.icon.get();
+ }
+}
+
void ControlLineManager::removeAll(void)
{
visibleGeometry.clear();
diff --git a/rtgui/perspective.h b/rtgui/perspective.h
index 0c636373c..40c8d7e46 100644
--- a/rtgui/perspective.h
+++ b/rtgui/perspective.h
@@ -41,21 +41,27 @@ class ControlLineManager: EditSubscriber
{
protected:
- /** Determine how horizontal and vertical lines are displayed. */
- bool active_h, active_v;
/** Hidden object for capturing mouse events. */
std::unique_ptr canvas_area;
rtengine::Coord drag_delta;
std::vector> control_lines;
CursorShape cursor;
bool draw_mode;
+ bool drawing_line = false;
Cairo::RefPtr line_icon_h, line_icon_v;
Cairo::RefPtr line_icon_h_prelight, line_icon_v_prelight;
int prev_obj;
int selected_object;
void addLine (rtengine::Coord begin, rtengine::Coord end);
- Geometry::State calcLineState(const ControlLine& line) const;
+ /**
+ * Set the line type of the line containing the object according to the
+ * line's angle.
+ *
+ * If the line is within 45 degrees of a perfectly vertical
+ * line, inclusive, the line type is set to vertical. Otherwise, horizontal.
+ */
+ void autoSetLineType(int object_id);
void removeLine (size_t line_id);
public:
@@ -69,8 +75,6 @@ public:
/** Callbacks to invoke. */
std::shared_ptr callbacks;
- /** Type of line for newly drawn lines. */
- rtengine::ControlLine::Type draw_line_type;
ControlLineManager();
@@ -80,8 +84,6 @@ public:
/** Set whether or not lines can be drawn and deleted. */
void setDrawMode (bool draw);
void setEditProvider (EditDataProvider* provider);
- /** Determines how each line type is displayed. */
- void setLinesState (bool horiz_active, bool vert_active);
/** Returns the number of lines. */
size_t size (void) const;
/**
@@ -124,13 +126,10 @@ protected:
Adjuster* camera_shift_horiz;
Adjuster* camera_shift_vert;
Adjuster* camera_yaw;
- std::unique_ptr img_ctrl_lines_edit;
- std::unique_ptr img_ctrl_lines_apply;
std::unique_ptr lines;
+ Gtk::Button* lines_button_apply;
Gtk::ToggleButton* lines_button_edit;
Gtk::Button* lines_button_erase;
- Gtk::ToggleButton* lines_button_h;
- Gtk::ToggleButton* lines_button_v;
Adjuster* projection_pitch;
Adjuster* projection_rotate;
Adjuster* projection_shift_horiz;
@@ -174,7 +173,7 @@ public:
void adjusterChanged (Adjuster* a, double newval) override;
void autoCorrectionPressed (Gtk::Button* b);
- void linesButtonPressed (Gtk::ToggleButton* button);
+ void linesApplyButtonPressed (void);
void linesEditButtonPressed (void);
void linesEraseButtonPressed (void);
void methodChanged (void);