From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- src/ui/tool/control-point-selection.h | 179 ++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 src/ui/tool/control-point-selection.h (limited to 'src/ui/tool/control-point-selection.h') diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h new file mode 100644 index 0000000..dc58211 --- /dev/null +++ b/src/ui/tool/control-point-selection.h @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * Control point selection - stores a set of control points and applies transformations + * to them + */ +/* Authors: + * Krzysztof KosiƄski + * + * Copyright (C) 2009 Authors + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H +#define SEEN_UI_TOOL_CONTROL_POINT_SELECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include <2geom/forward.h> +#include <2geom/point.h> +#include <2geom/rect.h> +#include "ui/tool/commit-events.h" +#include "ui/tool/manipulator.h" +#include "ui/tool/node-types.h" +#include "snap-candidate.h" + +class SPDesktop; + +namespace Inkscape { +class CanvasItemGroup; +namespace UI { +class TransformHandleSet; +class SelectableControlPoint; +} +} + +namespace Inkscape { +namespace UI { + +class ControlPointSelection : public Manipulator, public sigc::trackable { +public: + ControlPointSelection(SPDesktop *d, Inkscape::CanvasItemGroup *th_group); + ~ControlPointSelection() override; + typedef std::unordered_set set_type; + typedef set_type Set; // convenience alias + + typedef set_type::iterator iterator; + typedef set_type::const_iterator const_iterator; + typedef set_type::size_type size_type; + typedef SelectableControlPoint *value_type; + typedef SelectableControlPoint *key_type; + + // size + bool empty() { return _points.empty(); } + size_type size() { return _points.size(); } + + // iterators + iterator begin() { return _points.begin(); } + const_iterator begin() const { return _points.begin(); } + iterator end() { return _points.end(); } + const_iterator end() const { return _points.end(); } + + // insert + std::pair insert(const value_type& x, bool notify = true, bool to_update = true); + template + void insert(InputIterator first, InputIterator last) { + for (; first != last; ++first) { + insert(*first, false, false); + } + _update(); + signal_selection_changed.emit(std::vector(first, last), true); + } + + // erase + void clear(); + void erase(iterator pos, bool to_update = true); + size_type erase(const key_type& k, bool notify = true); + void erase(iterator first, iterator last); + + // find + iterator find(const key_type &k) { + return _points.find(k); + } + + // Sometimes it is very useful to keep a list of all selectable points. + set_type const &allPoints() const { return _all_points; } + set_type &allPoints() { return _all_points; } + // ...for example in these methods. Another useful case is snapping. + void selectAll(); + void selectArea(Geom::Rect const &, bool invert = false); + void invertSelection(); + void spatialGrow(SelectableControlPoint *origin, int dir); + + bool event(Inkscape::UI::Tools::ToolBase *, GdkEvent *) override; + + void transform(Geom::Affine const &m); + void align(Geom::Dim2 d, AlignTargetNode target = AlignTargetNode::MID_NODE); + void distribute(Geom::Dim2 d); + + Geom::OptRect pointwiseBounds(); + Geom::OptRect bounds(); + + bool transformHandlesEnabled() { return _handles_visible; } + void showTransformHandles(bool v, bool one_node); + // the two methods below do not modify the state; they are for use in manipulators + // that need to temporarily hide the handles, for example when moving a node + void hideTransformHandles(); + void restoreTransformHandles(); + void toggleTransformHandlesMode(); + + sigc::signal signal_update; + // It turns out that emitting a signal after every point is selected or deselected is not too efficient, + // so this can be done in a massive group once the selection is finally changed. + sigc::signal, bool> signal_selection_changed; + sigc::signal signal_commit; + + void getOriginalPoints(std::vector &pts); + void getUnselectedPoints(std::vector &pts); + void setOriginalPoints(); + //the purpose of this list is to keep track of first and last selected + std::list _points_list; + +private: + // The functions below are invoked from SelectableControlPoint. + // Previously they were connected to handlers when selecting, but this + // creates problems when dragging a point that was not selected. + void _pointGrabbed(SelectableControlPoint *); + void _pointDragged(Geom::Point &, GdkEventMotion *); + void _pointUngrabbed(); + bool _pointClicked(SelectableControlPoint *, GdkEventButton *); + void _mouseoverChanged(); + + void _update(); + void _updateTransformHandles(bool preserve_center); + void _updateBounds(); + bool _keyboardMove(GdkEventKey const &, Geom::Point const &); + bool _keyboardRotate(GdkEventKey const &, int); + bool _keyboardScale(GdkEventKey const &, int); + bool _keyboardFlip(Geom::Dim2); + void _keyboardTransform(Geom::Affine const &); + void _commitHandlesTransform(CommitEvent ce); + double _rotationRadius(Geom::Point const &); + + set_type _points; + + set_type _all_points; + std::unordered_map _original_positions; + std::unordered_map _last_trans; + std::optional _rot_radius; + std::optional _mouseover_rot_radius; + Geom::OptRect _bounds; + TransformHandleSet *_handles; + SelectableControlPoint *_grabbed_point, *_farthest_point; + unsigned _dragging : 1; + unsigned _handles_visible : 1; + unsigned _one_node_handles : 1; + + friend class SelectableControlPoint; +}; + +} // namespace UI +} // namespace Inkscape + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : -- cgit v1.2.3