diff options
| author | Jon A. Cruz <jon@joncruz.org> | 2012-05-17 02:33:16 +0000 |
|---|---|---|
| committer | Jon A. Cruz <jon@joncruz.org> | 2012-05-17 02:33:16 +0000 |
| commit | e9412c187da3f62f01bc5acb6190af2d5a395ccb (patch) | |
| tree | 4d6d98646a87c82dc1cc631d88875ca0d63c3fcf /src/ui/tool/node.h | |
| parent | Fixed warning with printf format. Also corrected inproper type that resulted ... (diff) | |
| download | inkscape-e9412c187da3f62f01bc5acb6190af2d5a395ccb.tar.gz inkscape-e9412c187da3f62f01bc5acb6190af2d5a395ccb.zip | |
Corrected protected type access (comments were incorrect).
Unified color set types; fixed uninitialized member; Switched colorsets to references; Added const correctness.
(bzr r11373)
Diffstat (limited to 'src/ui/tool/node.h')
| -rw-r--r-- | src/ui/tool/node.h | 158 |
1 files changed, 131 insertions, 27 deletions
diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index f2e31e018..daab19cae 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -3,6 +3,7 @@ */ /* Authors: * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2009 Authors * Released under GNU GPL, read the file 'COPYING' for more information @@ -80,10 +81,11 @@ struct NodeSharedData { class Handle : public ControlPoint { public: + virtual ~Handle(); - inline Geom::Point relativePos(); - inline double length(); - bool isDegenerate() { return _degenerate; } // True if the handle is retracted, i.e. has zero length. + inline Geom::Point relativePos() const; + inline double length() const; + bool isDegenerate() const { return _degenerate; } // True if the handle is retracted, i.e. has zero length. virtual void setVisible(bool); virtual void move(Geom::Point const &p); @@ -96,80 +98,160 @@ public: void setDirection(Geom::Point const &dir); Node *parent() { return _parent; } Handle *other(); + Handle const *other() const; static char const *handle_type_to_localized_string(NodeType type); + protected: + Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event); - virtual void dragged(Geom::Point &, GdkEventMotion *); - virtual bool grabbed(GdkEventMotion *); - virtual void ungrabbed(GdkEventButton *); - virtual bool clicked(GdkEventButton *); - - virtual Glib::ustring _getTip(unsigned state); - virtual Glib::ustring _getDragTip(GdkEventMotion *event); - virtual bool _hasDragTips() { return true; } + virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); + virtual bool grabbed(GdkEventMotion *event); + virtual void ungrabbed(GdkEventButton *event); + virtual bool clicked(GdkEventButton *event); + + virtual Glib::ustring _getTip(unsigned state) const; + virtual Glib::ustring _getDragTip(GdkEventMotion *event) const; + virtual bool _hasDragTips() const { return true; } + private: + inline PathManipulator &_pm(); Node *_parent; // the handle's lifetime does not extend beyond that of the parent node, // so a naked pointer is OK and allows setting it during Node's construction SPCtrlLine *_handle_line; bool _degenerate; // True if the handle is retracted, i.e. has zero length. This is used often internally so it makes sense to cache this + /** + * Control point of a cubic Bezier curve in a path. + * + * Handle keeps the node type invariant only for the opposite handle of the same node. + * Keeping the invariant on node moves is left to the %Node class. + */ static Geom::Point _saved_other_pos; + static double _saved_length; static bool _drag_out; + static ColorSet _handle_colors; friend class Node; }; class Node : ListNode, public SelectableControlPoint { public: + + /** + * Curve endpoint in an editable path. + * + * The method move() keeps node type invariants during translations. + */ Node(NodeSharedData const &data, Geom::Point const &pos); + virtual void move(Geom::Point const &p); virtual void transform(Geom::Affine const &m); - virtual Geom::Rect bounds(); - - NodeType type() { return _type; } + virtual Geom::Rect bounds() const; + + NodeType type() const { return _type; } + + /** + * Sets the node type and optionally restores the invariants associated with the given type. + * @param type The type to set. + * @param update_handles Whether to restore invariants associated with the given type. + * Passing false is useful e.g. wen initially creating the path, + * and when making cusp nodes during some node algorithms. + * Pass true when used in response to an UI node type button. + */ void setType(NodeType type, bool update_handles = true); + void showHandles(bool v); + + + /** + * Pick the best type for this node, based on the position of its handles. + * This is what assigns types to nodes created using the pen tool. + */ void pickBestType(); // automatically determine the type from handle positions - bool isDegenerate() { return _front.isDegenerate() && _back.isDegenerate(); } - bool isEndNode(); + + bool isDegenerate() const { return _front.isDegenerate() && _back.isDegenerate(); } + bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } + + /** + * Gets the handle that faces the given adjacent node. + * Will abort with error if the given node is not adjacent. + */ Handle *handleToward(Node *to); + + /** + * Gets the node in the direction of the given handle. + * Will abort with error if the handle doesn't belong to this node. + */ Node *nodeToward(Handle *h); + + /** + * Gets the handle that goes in the direction opposite to the given adjacent node. + * Will abort with error if the given node is not adjacent. + */ Handle *handleAwayFrom(Node *to); + + /** + * Gets the node in the direction opposite to the given handle. + * Will abort with error if the handle doesn't belong to this node. + */ Node *nodeAwayFrom(Handle *h); + NodeList &nodeList() { return *(static_cast<ListNode*>(this)->ln_list); } + + /** + * Move the node to the bottom of its canvas group. + * Useful for node break, to ensure that the selected nodes are above the unselected ones. + */ void sink(); static NodeType parse_nodetype(char x); static char const *node_type_to_localized_string(NodeType type); + // temporarily public + /** Customized event handler to catch scroll events needed for selection grow/shrink. */ virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event); + Inkscape::SnapCandidatePoint snapCandidatePoint(); + protected: - virtual void dragged(Geom::Point &, GdkEventMotion *); - virtual bool grabbed(GdkEventMotion *); - virtual bool clicked(GdkEventButton *); + + virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); + virtual bool grabbed(GdkEventMotion *event); + virtual bool clicked(GdkEventButton *event); virtual void _setState(State state); - virtual Glib::ustring _getTip(unsigned state); - virtual Glib::ustring _getDragTip(GdkEventMotion *event); - virtual bool _hasDragTips() { return true; } + virtual Glib::ustring _getTip(unsigned state) const; + virtual Glib::ustring _getDragTip(GdkEventMotion *event) const; + virtual bool _hasDragTips() const { return true; } + private: + Node(Node const &); void _fixNeighbors(Geom::Point const &old_pos, Geom::Point const &new_pos); void _updateAutoHandles(); + + /** + * Select or deselect a node in this node's subpath based on its path distance from this node. + * @param dir If negative, shrink selection by one node; if positive, grow by one node. + */ void _linearGrow(int dir); + Node *_next(); + Node const *_next() const; Node *_prev(); - Inkscape::SnapSourceType _snapSourceType(); - Inkscape::SnapTargetType _snapTargetType(); + Node const *_prev() const; + Inkscape::SnapSourceType _snapSourceType() const; + Inkscape::SnapTargetType _snapTargetType() const; inline PathManipulator &_pm(); static SPCtrlShapeType _node_type_to_shape(NodeType type); + + /** Determine whether two nodes are joined by a linear segment. */ static bool _is_line_segment(Node *first, Node *second); // Handles are always present, but are not visible if they coincide with the node @@ -179,6 +261,8 @@ private: Handle _back; ///< Node handle in the forward direction of the path NodeType _type; ///< Type of node - cusp, smooth... bool _handles_shown; + static ColorSet node_colors; + friend class Handle; friend class NodeList; friend class NodeIterator<Node>; @@ -271,7 +355,15 @@ public: typedef NodeIterator<value_type const> const_iterator; // TODO Lame. Make this private and make SubpathList a factory + /** + * An editable list of nodes representing a subpath. + * + * It can optionally be cyclic to represent a closed path. + * The list has iterators that act like plain node iterators, but can also be used + * to obtain shared pointers to nodes. + */ NodeList(SubpathList &_list); + ~NodeList(); // iterators @@ -286,7 +378,13 @@ public: // extra node-specific methods bool closed(); + + /** + * A subpath is degenerate if it has no segments - either one node in an open path + * or no nodes in a closed path. + */ bool degenerate(); + void setClosed(bool c) { _closed = c; } iterator before(double t, double *fracpart = NULL); const_iterator before(double t, double *fracpart = NULL) const { @@ -294,7 +392,10 @@ public: } // list operations + + /** insert a node before pos. */ iterator insert(iterator pos, Node *x); + template <class InputIterator> void insert(iterator pos, InputIterator first, InputIterator last) { for (; first != last; ++first) insert(pos, *first); @@ -342,7 +443,10 @@ private: friend class NodeIterator<Node const>; }; -/** List of node lists. Represents an editable path. */ +/** + * List of node lists. Represents an editable path. + * Editable path composed of one or more subpaths. + */ class SubpathList : public std::list< boost::shared_ptr<NodeList> > { public: typedef std::list< boost::shared_ptr<NodeList> > list_type; @@ -361,13 +465,13 @@ private: // define inline Handle funcs after definition of Node -inline Geom::Point Handle::relativePos() { +inline Geom::Point Handle::relativePos() const { return position() - _parent->position(); } inline void Handle::setRelativePos(Geom::Point const &p) { setPosition(_parent->position() + p); } -inline double Handle::length() { +inline double Handle::length() const { return relativePos().length(); } inline PathManipulator &Handle::_pm() { |
