13#include <boost/none.hpp>
14#include <gdk/gdkkeysyms.h>
57 , _handles_visible(true)
58 , _one_node_handles(false)
83 return std::pair<iterator, bool>(found,
false);
86 found =
_points.insert(x).first;
98 return std::pair<iterator, bool>(found,
true);
115 if (pos ==
_points.end())
return 0;
125 std::vector<SelectableControlPoint *> out(first, last);
126 while (first != last) {
127 erase(first++,
false);
140 std::vector<SelectableControlPoint *> out(
begin(),
end());
143 for (
auto erased : out) {
144 erased->updateState();
155 insert(_all_point,
false,
false);
166 std::vector<SelectableControlPoint *> out;
168 if (path.
winding(_all_point->position()) % 2 != 0) {
170 erase(_all_point,
false);
172 insert(_all_point,
false,
false);
174 out.push_back(_all_point);
185 std::vector<SelectableControlPoint *> in, out;
187 if (_all_point->selected()) {
188 in.push_back(_all_point);
189 erase(_all_point,
false);
192 out.push_back(_all_point);
193 insert(_all_point,
false,
false);
204 bool grow = (dir > 0);
206 double best_dist = grow ? HUGE_VAL : 0;
209 bool selected = _all_point->
selected();
210 if (grow && !selected) {
212 if (dist < best_dist) {
217 if (!grow && selected) {
220 if (dist >= best_dist) {
261 if (!bound) {
return; }
272 new_coord=bound->middle();
275 new_coord=bound->min();
278 new_coord=bound->max();
297 typedef std::multimap<double, SelectableControlPoint*> SortMap;
305 sm.insert(std::make_pair(pos[d], _point));
309 if (!bound) {
return; }
312 double step =
size() == 1 ? 0 : bound->extent() / (
size() - 1);
313 double start = bound->min();
315 for (SortMap::iterator i = sm.begin(); i != sm.end(); ++i, ++
num) {
318 i->second->move(pos);
385 if (dist > maxdist) {
402 double deltafrac = 0.5 + 0.5 * cos(M_PI * dist/fdist);
420 double deltafracdx = 0.5 + 0.5 * cos(M_PI * distdx/fdist);
421 double deltafracdy = 0.5 + 0.5 * cos(M_PI * distdy/fdist);
423 Geom::Point newpx = origpx + abs_delta * deltafracdx;
424 Geom::Point newpy = origpy + abs_delta * deltafracdy;
440 cur->transform(trans);
495 }
else if (
size() == 1) {
546 double nudge = prefs->getDoubleLimited(
"/options/nudgedistance/value", 2, 0, 1000,
"px");
550 bool const rotated = prefs->getBool(
"/options/moverotated/value",
true);
566 if (
empty())
return 1.0;
569 for (
unsigned i = 0; i < 4; ++i) {
571 if (
len > maxlen) maxlen =
len;
584 if (
empty())
return false;
615 int snaps = prefs->
getIntLimited(
"/options/rotationsnapsperpi/value", 12, 1, 1000);
616 angle = M_PI * dir / snaps;
629 if (
empty())
return false;
631 double maxext =
bounds()->maxExtent();
643 double length_change;
650 length_change = prefs->
getDoubleLimited(
"/options/defaultscale/value", 2, 1, 1000,
"px");
651 length_change *= dir;
653 double scale = (maxext + length_change) / maxext;
663 if (
empty())
return false;
702 switch (keyevent.keyval) {
709 case GDK_KEY_KP_Down:
713 case GDK_KEY_KP_Right:
717 case GDK_KEY_KP_Left:
722 case GDK_KEY_bracketleft:
724 case GDK_KEY_bracketright:
731 case GDK_KEY_greater:
771 for (
auto node : nodes) {
772 if (!
node->selected()) {
774 pts.push_back(n->snapCandidatePoint());
3x3 matrix representing an affine transformation.
Coord descrim() const
Calculate the descriminant.
bool isSingular(Coord eps=EPSILON) const
Check whether this matrix is singular.
void setIdentity()
Sets this matrix to be the Identity Affine.
Affine inverse() const
Compute the inverse matrix.
constexpr void unionWith(GenericOptInterval< C > const &a)
Union with another interval, gracefully handling empty ones.
void expandTo(CPoint const &p)
Create or enlarge the rectangle to contain the given point.
CPoint corner(unsigned i) const
Return the n-th corner of the rectangle.
Range of real numbers that can be empty.
Axis-aligned rectangle that can be empty.
Sequence of contiguous curves, aka spline.
int winding(Point const &p) const
Determine the winding number at the specified point.
Two-dimensional point that doubles as a vector.
constexpr Coord x() const noexcept
Axis aligned, non-empty rectangle.
Rotation around the origin.
void remove_snaptarget(bool only_if_presnap=false)
Preference storage class.
static Preferences * get()
Access the singleton Preferences object.
int getIntLimited(Glib::ustring const &pref_path, int def=0, int min=INT_MIN, int max=INT_MAX)
Retrieve a limited integer.
double getDoubleLimited(Glib::ustring const &pref_path, double def=0.0, double min=DBL_MIN, double max=DBL_MAX, Glib::ustring const &unit="")
Retrieve a limited floating point value.
std::pair< iterator, bool > insert(const value_type &x, bool notify=true, bool to_update=true)
Add a control point to the selection.
ControlPointSelection(SPDesktop *d, Inkscape::CanvasItemGroup *th_group)
SelectableControlPoint * _farthest_point
std::optional< Geom::Point > firstSelectedPoint() const
The first selected point is the first selection a user makes, but only if they selected exactly one p...
std::list< SelectableControlPoint * > _points_list
void _updateTransformHandles(bool preserve_center)
sigc::signal< void()> signal_update
Fires when the display needs to be updated to reflect changes.
TransformHandleSet * _handles
void getUnselectedPoints(std::vector< Inkscape::SnapCandidatePoint > &pts)
void selectArea(Geom::Path const &, bool invert=false)
Select all points inside the given rectangle (in desktop coordinates).
sigc::signal< void(std::vector< SelectableControlPoint * >, bool)> signal_selection_changed
std::optional< double > _mouseover_rot_radius
void _pointDragged(Geom::Point &, MotionEvent const &)
void toggleTransformHandlesMode()
set_type::size_type size_type
set_type const & allPoints() const
bool _keyboardRotate(KeyPressEvent const &, int)
Rotates the selected points in the given direction according to the modifier state from the supplied ...
void align(Geom::Dim2 d, AlignTargetNode target=AlignTargetNode::MID_NODE)
Align control points on the specified axis.
void _commitHandlesTransform(CommitEvent ce)
std::unordered_map< SelectableControlPoint *, Geom::Point > _original_positions
~ControlPointSelection() override
void erase(iterator pos, bool to_update=true)
Remove a point from the selection.
bool _keyboardMove(KeyPressEvent const &, Geom::Point const &)
Moves the selected points along the supplied unit vector according to the modifier state of the suppl...
Geom::OptRect pointwiseBounds()
Get the bounds of the selection.
SelectableControlPoint * _grabbed_point
std::optional< double > _rot_radius
std::optional< Geom::Point > _first_point
bool _keyboardFlip(Geom::Dim2)
unsigned _one_node_handles
bool _keyboardScale(KeyPressEvent const &, int)
std::unordered_map< SelectableControlPoint *, Geom::Affine > _last_trans
void invertSelection()
Unselect all selected points and select all unselected points.
void restoreTransformHandles()
void getOriginalPoints(std::vector< Inkscape::SnapCandidatePoint > &pts)
bool event(Inkscape::UI::Tools::ToolBase *tool, CanvasEvent const &event) override
Handle input event. Returns true if handled.
double _rotationRadius(Geom::Point const &)
Computes the distance to the farthest corner of the bounding box.
unsigned _handles_visible
bool _pointClicked(SelectableControlPoint *, ButtonReleaseEvent const &)
void _pointGrabbed(SelectableControlPoint *)
set_type::iterator iterator
void showTransformHandles(bool v, bool one_node)
void transform(Geom::Affine const &m)
Transform all selected control points by the given affine transformation.
sigc::signal< void(CommitEvent)> signal_commit
Fires when a change that needs to be committed to XML happens.
void clear()
Remove all points from the selection, making it empty.
void spatialGrow(SelectableControlPoint *origin, int dir)
void selectAll()
Select all points that this selection can contain.
void distribute(Geom::Dim2 d)
Equdistantly distribute control points by moving them in the specified dimension.
void hideTransformHandles()
Geom::Point const & position() const
Current position of the control point.
static sigc::signal< void(ControlPoint *)> signal_mouseover_change
Emitted when the mouseovered point changes.
virtual void move(Geom::Point const &pos)
Move the control point to new position with side effects.
static ControlPoint * mouseovered_point
Holds the currently mouseovered control point.
virtual void setVisible(bool v)
Set the visibility of the control point.
Tool component that processes events and does something in response to them.
SPDesktop *const _desktop
Desktop-bound selectable control object.
virtual Geom::Rect bounds() const
To do: update description of desktop.
double current_zoom() const
Inkscape::Display::SnapIndicator * getSnapIndicator() const
Geom::Rotate const & current_rotation() const
Control point selection - stores a set of control points and applies transformations to them.
Editable view implementation.
Dim2
2D axis enumeration (X or Y).
constexpr Coord EPSILON
Default "acceptably small" value.
Inkscape::XML::Node * node
Angle distance(Angle const &a, Angle const &b)
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
CommitEvent
This is used to provide sensible messages on the undo stack.
@ COMMIT_KEYBOARD_SCALE_UNIFORM
Helper class to stream background task notifications as a series of messages.
bool held_ctrl(CanvasEvent const &event)
bool held_shift(CanvasEvent const &event)
bool held_any_modifiers(CanvasEvent const &event)
bool held_alt(CanvasEvent const &event)
bool held_no_modifiers(CanvasEvent const &event)
bool held_only_alt(CanvasEvent const &event)
Provides a class that shows a temporary indicator on the canvas of where the snap was,...
void invert(const double v[16], double alpha[16])
Abstract base class for events.
Movement of the mouse pointer.