diff --git a/rtdata/languages/default b/rtdata/languages/default index 2c012d9c2..69cc6adc3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -3321,6 +3321,7 @@ TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse, TP_PCVIGNETTE_STRENGTH;Strength TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). TP_PDSHARPENING_LABEL;Capture Sharpening +TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;At least two horizontal or two vertical control lines required. TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Crop factor TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Focal length TP_PERSPECTIVE_CAMERA_FRAME;Correction diff --git a/rtgui/controllines.cc b/rtgui/controllines.cc index 14454e2ef..65106f375 100644 --- a/rtgui/controllines.cc +++ b/rtgui/controllines.cc @@ -84,6 +84,7 @@ ControlLineManager::ControlLineManager(): draw_mode(false), drawing_line(false), edited(false), + horizontalCount(0), verticalCount(0), prev_obj(-1), selected_object(-1) { @@ -127,11 +128,21 @@ void ControlLineManager::setDrawMode(bool draw) draw_mode = draw; } -size_t ControlLineManager::size(void) const +std::size_t ControlLineManager::size() const { return control_lines.size(); } +std::size_t ControlLineManager::getHorizontalCount() const +{ + return horizontalCount; +} + +std::size_t ControlLineManager::getVerticalCount() const +{ + return verticalCount; +} + bool ControlLineManager::button1Pressed(int modifierKey) { EditDataProvider* dataProvider = getEditProvider(); @@ -214,9 +225,13 @@ bool ControlLineManager::pick1(bool picked) if (line.type == rtengine::ControlLine::HORIZONTAL) { line.icon = line.icon_v; line.type = rtengine::ControlLine::VERTICAL; + horizontalCount--; + verticalCount++; } else if (line.type == rtengine::ControlLine::VERTICAL) { line.icon = line.icon_h; line.type = rtengine::ControlLine::HORIZONTAL; + horizontalCount++; + verticalCount--; } visibleGeometry[mouseOverIdToVisibleId(object_id)] = line.icon.get(); @@ -491,6 +506,11 @@ void ControlLineManager::addLine(Coord begin, Coord end, EditSubscriber::mouseOverGeometry.push_back(control_line->end.get()); control_lines.push_back(std::move(control_line)); + if (type == rtengine::ControlLine::HORIZONTAL) { + horizontalCount++; + } else { + verticalCount++; + } } void ControlLineManager::autoSetLineType(int object_id) @@ -523,6 +543,13 @@ void ControlLineManager::autoSetLineType(int object_id) if (type != line.type) { // Need to update line type. line.type = type; line.icon = icon; + if (type == rtengine::ControlLine::HORIZONTAL) { + horizontalCount++; + verticalCount--; + } else { + horizontalCount--; + verticalCount++; + } visibleGeometry[line_id * ::ControlLine::OBJECT_COUNT + VISIBLE_OBJECT_COUNT + ::ControlLine::ICON] = line.icon.get(); @@ -535,13 +562,14 @@ void ControlLineManager::removeAll(void) mouseOverGeometry.erase(mouseOverGeometry.begin() + MO_OBJECT_COUNT, mouseOverGeometry.end()); control_lines.clear(); + horizontalCount = verticalCount = 0; prev_obj = -1; selected_object = -1; edited = true; callbacks->lineChanged(); } -void ControlLineManager::removeLine(size_t line_id) +void ControlLineManager::removeLine(std::size_t line_id) { if (line_id >= control_lines.size()) { return; @@ -556,6 +584,11 @@ void ControlLineManager::removeLine(size_t line_id) mouseOverGeometry.begin() + ::ControlLine::OBJECT_COUNT * line_id + MO_OBJECT_COUNT, mouseOverGeometry.begin() + ::ControlLine::OBJECT_COUNT * line_id + MO_OBJECT_COUNT + ::ControlLine::OBJECT_COUNT ); + if (control_lines[line_id]->type == rtengine::ControlLine::HORIZONTAL) { + horizontalCount--; + } else { + verticalCount--; + } control_lines.erase(control_lines.begin() + line_id); edited = true; diff --git a/rtgui/controllines.h b/rtgui/controllines.h index a05fb8b00..9e850da1c 100644 --- a/rtgui/controllines.h +++ b/rtgui/controllines.h @@ -59,6 +59,7 @@ protected: bool draw_mode; bool drawing_line; bool edited; + std::size_t horizontalCount, verticalCount; Cairo::RefPtr line_icon_h, line_icon_v; Cairo::RefPtr line_icon_h_prelight, line_icon_v_prelight; int prev_obj; @@ -74,7 +75,7 @@ protected: * line, inclusive, the line type is set to vertical. Otherwise, horizontal. */ void autoSetLineType(int object_id); - void removeLine(size_t line_id); + void removeLine(std::size_t line_id); public: class Callbacks @@ -94,6 +95,10 @@ public: ~ControlLineManager(); bool getEdited(void) const; + /** Returns the number of horizontal control lines. */ + std::size_t getHorizontalCount() const; + /** Returns the number of vertical control lines. */ + std::size_t getVerticalCount() const; /** Release anything that is currently being dragged. */ void releaseEdit(void); void removeAll(void); @@ -105,7 +110,7 @@ public: void setEditProvider(EditDataProvider* provider); void setLines(const std::vector& lines); /** Returns the number of lines. */ - size_t size(void) const; + std::size_t size() const; /** * Allocates a new array and populates it with copies of the control lines. */ diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index fb4797ae4..d06243524 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -351,6 +351,8 @@ void PerspCorrection::read (const ProcParams* pp, const ParamsEdited* pedited) method->set_active (1); } + updateApplyDeleteButtons(); + enableListener (); } @@ -517,22 +519,16 @@ void PerspCorrection::applyControlLines(void) } std::vector control_lines; - int h_count = 0, v_count = 0; double rot = camera_roll->getValue(); double pitch = camera_pitch->getValue(); double yaw = camera_yaw->getValue(); lines->toControlLines(control_lines); - for (unsigned int i = 0; i < lines->size(); i++) { - if (control_lines[i].type == rtengine::ControlLine::HORIZONTAL) { - h_count++; - } else if (control_lines[i].type == rtengine::ControlLine::VERTICAL) { - v_count++; - } - } - lens_geom_listener->autoPerspRequested(v_count > 1, h_count > 1, rot, pitch, - yaw, &control_lines); + lens_geom_listener->autoPerspRequested( + lines->getVerticalCount() >= MIN_VERT_LINES, + lines->getHorizontalCount() >= MIN_HORIZ_LINES, + rot, pitch, yaw, &control_lines); disableListener(); camera_pitch->setValue(pitch); @@ -739,11 +735,29 @@ void PerspCorrection::setEditProvider(EditDataProvider* provider) void PerspCorrection::lineChanged(void) { + updateApplyDeleteButtons(); + if (listener) { listener->panelChanged(EvPerspControlLines, M("HISTORY_CHANGED")); } } +void PerspCorrection::updateApplyDeleteButtons() +{ + if (batchMode) { + return; + } + + bool edit_mode = lines_button_edit->get_active(); + bool enough_lines = lines->getHorizontalCount() >= MIN_HORIZ_LINES || lines->getVerticalCount() >= MIN_VERT_LINES; + const auto tooltip = M("GENERAL_APPLY") + + ((edit_mode && !enough_lines) ? "\n\n" + M("TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP") : ""); + + lines_button_apply->set_sensitive(edit_mode && enough_lines); + lines_button_apply->set_tooltip_text(tooltip); + lines_button_erase->set_sensitive(edit_mode && lines->size() > 0); +} + void PerspCorrection::linesApplyButtonPressed(void) { if (method->get_active_row_number() == 1) { @@ -785,6 +799,7 @@ void PerspCorrection::linesEditButtonPressed(void) panel_listener->controlLineEditModeChanged(false); } } + updateApplyDeleteButtons(); } void PerspCorrection::linesEraseButtonPressed(void) @@ -796,6 +811,8 @@ void PerspCorrection::requestApplyControlLines(void) { if (lines_button_apply->is_sensitive()) { linesApplyButtonPressed(); + } else if (lines_button_edit->get_active()) { + lines_button_edit->set_active(false); } } diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 6f4a4ff52..404b02010 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -96,9 +96,15 @@ protected: void tweakParams(rtengine::procparams::ProcParams &pparams) override; void setCamBasedEventsActive (bool active = true); void setFocalLengthValue (const rtengine::procparams::ProcParams* pparams, const rtengine::FramesMetaData* metadata); + void updateApplyDeleteButtons(); public: + /** Minimum number of horizontal lines for horizontal/full correction. */ + static constexpr std::size_t MIN_HORIZ_LINES = 2; + /** Minimum number of vertical lines for vertical/full correction. */ + static constexpr std::size_t MIN_VERT_LINES = 2; + PerspCorrection (); void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override;