From 31bb8269c26a781036448ed8f8cd93cc84fb2118 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 29 Nov 2009 16:33:18 +0100 Subject: First GSoC node tool commit to Bazaar (bzr r8846.1.1) --- src/ui/tool/node.h | 366 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 src/ui/tool/node.h (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h new file mode 100644 index 000000000..9a36642eb --- /dev/null +++ b/src/ui/tool/node.h @@ -0,0 +1,366 @@ +/** @file + * Editable node and associated data structures. + */ +/* Authors: + * Krzysztof KosiƄski + * + * Copyright (C) 2009 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_UI_TOOL_NODE_H +#define SEEN_UI_TOOL_NODE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ui/tool/selectable-control-point.h" +#include "ui/tool/node-types.h" + + +namespace Inkscape { +namespace UI { +template class NodeIterator; +} +} + +namespace std { +namespace tr1 { +template struct hash< Inkscape::UI::NodeIterator >; +} +} + +namespace Inkscape { +namespace UI { + +class PathManipulator; + +class Node; +class Handle; +class NodeList; +class SubpathList; +template class NodeIterator; + +std::ostream &operator<<(std::ostream &, NodeType); + +/* +template +struct ListMember { + T *next; + T *prev; +}; +struct SubpathMember : public ListMember { + Subpath *list; +}; +struct SubpathListMember : public ListMember { + SubpathList *list; +}; +*/ + +struct ListNode { + ListNode *next; + ListNode *prev; + NodeList *list; +}; + +struct NodeSharedData { + SPDesktop *desktop; + ControlPointSelection *selection; + SPCanvasGroup *node_group; + SPCanvasGroup *handle_group; + SPCanvasGroup *handle_line_group; +}; + +class Handle : public ControlPoint { +public: + virtual ~Handle(); + inline Geom::Point relativePos(); + inline double length(); + bool isDegenerate() { return _degenerate; } + + virtual void setVisible(bool); + virtual void move(Geom::Point const &p); + + virtual void setPosition(Geom::Point const &p); + inline void setRelativePos(Geom::Point const &p); + void setLength(double len); + void retract(); + void setDirection(Geom::Point const &from, Geom::Point const &to); + void setDirection(Geom::Point const &dir); + Node *parent() { return _parent; } + + static char const *handle_type_to_localized_string(NodeType type); + sigc::signal signal_update; +protected: + Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); + virtual Glib::ustring _getTip(unsigned state); + virtual Glib::ustring _getDragTip(GdkEventMotion *event); + virtual bool _hasDragTips() { return true; } +private: + void _grabbedHandler(); + void _draggedHandler(Geom::Point &, GdkEventMotion *); + void _ungrabbedHandler(); + 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 + SPCanvasItem *_handle_line; + bool _degenerate; // this is used often internally so it makes sense to cache this + + static double _saved_length; + static bool _drag_out; + friend class Node; +}; + +class Node : ListNode, public SelectableControlPoint { +public: + Node(NodeSharedData const &data, Geom::Point const &pos); + virtual void move(Geom::Point const &p); + virtual void transform(Geom::Matrix const &m); + virtual Geom::Rect bounds(); + + NodeType type() { return _type; } + void setType(NodeType type, bool update_handles = true); + void showHandles(bool v); + void pickBestType(); // automatically determine the type from handle positions + bool isDegenerate() { return _front.isDegenerate() && _back.isDegenerate(); } + bool isEndNode(); + Handle *front() { return &_front; } + Handle *back() { return &_back; } + static NodeType parse_nodetype(char x); + NodeList *list() { return static_cast(this)->list; } + void sink(); + + static char const *node_type_to_localized_string(NodeType type); +protected: + virtual void _setState(State state); + virtual Glib::ustring _getTip(unsigned state); + virtual Glib::ustring _getDragTip(GdkEventMotion *event); + virtual bool _hasDragTips() { return true; } +private: + Node(Node const &); + bool _grabbedHandler(GdkEventMotion *); + void _draggedHandler(Geom::Point &, GdkEventMotion *); + void _fixNeighbors(Geom::Point const &old_pos, Geom::Point const &new_pos); + void _updateAutoHandles(); + Node *_next(); + Node *_prev(); + static SPCtrlShapeType _node_type_to_shape(NodeType type); + static bool _is_line_segment(Node *first, Node *second); + + // Handles are always present, but are not visible if they coincide with the node + // (are degenerate). A segment that has both handles degenerate is always treated + // as a line segment + Handle _front; ///< Node handle in the backward direction of the path + Handle _back; ///< Node handle in the forward direction of the path + NodeType _type; ///< Type of node - cusp, smooth... + bool _handles_shown; + friend class Handle; + friend class NodeList; + friend class NodeIterator; + friend class NodeIterator; +}; + +template +class NodeIterator + : public boost::bidirectional_iterator_helper, N, std::ptrdiff_t, + N *, N &> +{ +public: + typedef NodeIterator self; + NodeIterator() + : _node(0) + {} + // default copy, default assign + + self &operator++() { + _node = _node->next; + return *this; + } + self &operator--() { + _node = _node->prev; + return *this; + } + bool operator==(self const &other) const { return _node == other._node; } + N &operator*() const { return *static_cast(_node); } + inline operator bool() const; // define after NodeList + N *get_pointer() const { return static_cast(_node); } + N *ptr() const { return static_cast(_node); } + + self next() const; + self prev() const; +private: + NodeIterator(ListNode const *n) + : _node(const_cast(n)) + {} + ListNode *_node; + friend class NodeList; + friend class std::tr1::hash; +}; + +class NodeList : ListNode, boost::noncopyable, public boost::enable_shared_from_this { +public: + typedef std::size_t size_type; + typedef Node &reference; + typedef Node const &const_reference; + typedef Node *pointer; + typedef Node const *const_pointer; + typedef Node value_type; + typedef NodeIterator iterator; + typedef NodeIterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // TODO Lame. Make this private and make SubpathList a factory + NodeList(SubpathList &_list); + ~NodeList(); + + // iterators + iterator begin() { return iterator(next); } + iterator end() { return iterator(this); } + const_iterator begin() const { return const_iterator(next); } + const_iterator end() const { return const_iterator(this); } + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + + // size + bool empty(); + size_type size(); + + // extra node-specific methods + bool closed(); + bool degenerate(); + void setClosed(bool c) { _closed = c; } + iterator before(double t, double *fracpart = NULL); + const_iterator before(double t, double *fracpart = NULL) const { + return const_iterator(before(t, fracpart)._node); + } + + // list operations + iterator insert(iterator pos, Node *x); + template + void insert(iterator pos, InputIterator first, InputIterator last) { + for (; first != last; ++first) insert(pos, *first); + } + void splice(iterator pos, NodeList &list); + void splice(iterator pos, NodeList &list, iterator i); + void splice(iterator pos, NodeList &list, iterator first, iterator last); + void reverse(); + void shift(int n); + void push_front(Node *x) { insert(begin(), x); } + void pop_front() { erase(begin()); } + void push_back(Node *x) { insert(end(), x); } + void pop_back() { erase(--end()); } + void clear(); + iterator erase(iterator pos); + iterator erase(iterator first, iterator last) { + NodeList::iterator ret = first; + while (first != last) ret = erase(first++); + return ret; + } + + // member access - undefined results when the list is empty + Node &front() { return *static_cast(next); } + Node &back() { return *static_cast(prev); } + + // HACK remove this subpath from its path. This will be removed later. + void kill(); + + static iterator get_iterator(Node *n) { return iterator(n); } + static const_iterator get_iterator(Node const *n) { return const_iterator(n); } + static NodeList &get(Node *n); + static NodeList &get(iterator const &i); +private: + // no copy or assign + NodeList(NodeList const &); + void operator=(NodeList const &); + + SubpathList &_list; + bool _closed; + + friend class Node; + friend class Handle; // required to access handle and handle line groups + friend class NodeIterator; + friend class NodeIterator; +}; + +/** List of node lists. Represents an editable path. */ +class SubpathList : public std::list< boost::shared_ptr > { +public: + typedef std::list< boost::shared_ptr > list_type; + + SubpathList() {} + + sigc::signal signal_insert_node; + sigc::signal signal_remove_node; +private: + list_type _nodelists; + friend class NodeList; + friend class Node; + friend class Handle; +}; + + + +// define inline Handle funcs after definition of Node +inline Geom::Point Handle::relativePos() { + return position() - _parent->position(); +} +inline void Handle::setRelativePos(Geom::Point const &p) { + setPosition(_parent->position() + p); +} +inline double Handle::length() { + return relativePos().length(); +} + +// definitions for node iterator +template +NodeIterator::operator bool() const { + return _node && static_cast(_node->list) != _node; +} +template +NodeIterator NodeIterator::next() const { + NodeIterator ret(*this); + ++ret; + if (!ret && _node->list->closed()) ++ret; + return ret; +} +template +NodeIterator NodeIterator::prev() const { + NodeIterator ret(*this); + --ret; + if (!ret && _node->list->closed()) --ret; + return ret; +} + +} // namespace UI +} // namespace Inkscape + +namespace std { +namespace tr1 { +template +struct hash< Inkscape::UI::NodeIterator > : public unary_function, size_t> { + size_t operator()(Inkscape::UI::NodeIterator const &ni) const { + return reinterpret_cast(ni._node); + } +}; +} +} + +#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:encoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 1075267dd1ba150a82b7e1aad543fbf0a69a1c00 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 26 Dec 2009 04:13:01 +0100 Subject: Implement selection spatial grow (bzr r8846.2.7) --- src/ui/tool/node.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 9a36642eb..68ad63ba9 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -39,6 +39,7 @@ namespace Inkscape { namespace UI { class PathManipulator; +class MultiPathManipulator; class Node; class Handle; @@ -136,6 +137,7 @@ public: static char const *node_type_to_localized_string(NodeType type); protected: + virtual bool _eventHandler(GdkEvent *event); virtual void _setState(State state); virtual Glib::ustring _getTip(unsigned state); virtual Glib::ustring _getDragTip(GdkEventMotion *event); @@ -294,12 +296,13 @@ class SubpathList : public std::list< boost::shared_ptr > { public: typedef std::list< boost::shared_ptr > list_type; - SubpathList() {} + SubpathList(PathManipulator &pm) : _path_manipulator(pm) {} sigc::signal signal_insert_node; sigc::signal signal_remove_node; private: list_type _nodelists; + PathManipulator &_path_manipulator; friend class NodeList; friend class Node; friend class Handle; -- cgit v1.2.3 From 6286e1b266d79742170df705ba6a1e6f94ca32d6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 27 Dec 2009 00:59:01 +0100 Subject: Implement selection linear grow (bzr r8846.2.8) --- src/ui/tool/node.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 68ad63ba9..167cf90b8 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -148,6 +148,7 @@ private: void _draggedHandler(Geom::Point &, GdkEventMotion *); void _fixNeighbors(Geom::Point const &old_pos, Geom::Point const &new_pos); void _updateAutoHandles(); + void _linearGrow(int dir); Node *_next(); Node *_prev(); static SPCtrlShapeType _node_type_to_shape(NodeType type); -- cgit v1.2.3 From b52865a71a9f83da9719a3ec5f50a4a2cd7cdace Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 10 Jan 2010 01:46:28 +0100 Subject: * Implement node snapping. * Fix minor bug in linear grow. * Add --fixes. * Move some node selection-related functions to ControlPointSelection. Fixed bugs: - https://launchpad.net/bugs/170561 - https://launchpad.net/bugs/171893 - https://launchpad.net/bugs/182585 - https://launchpad.net/bugs/446773 (bzr r8846.2.9) --- src/ui/tool/node.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 167cf90b8..a85877d5c 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -19,6 +19,7 @@ #include #include #include +#include "snapped-point.h" #include "ui/tool/selectable-control-point.h" #include "ui/tool/node-types.h" @@ -136,8 +137,9 @@ public: void sink(); static char const *node_type_to_localized_string(NodeType type); -protected: + // temporarily public virtual bool _eventHandler(GdkEvent *event); +protected: virtual void _setState(State state); virtual Glib::ustring _getTip(unsigned state); virtual Glib::ustring _getDragTip(GdkEventMotion *event); @@ -151,6 +153,8 @@ private: void _linearGrow(int dir); Node *_next(); Node *_prev(); + Inkscape::SnapSourceType _snapSourceType(); + Inkscape::SnapTargetType _snapTargetType(); static SPCtrlShapeType _node_type_to_shape(NodeType type); static bool _is_line_segment(Node *first, Node *second); -- cgit v1.2.3 From 1231b2ec93cbeedecf22af6d6872e25f0d98f297 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 13 Jan 2010 01:04:25 +0100 Subject: Some additional docs (bzr r8846.2.10) --- src/ui/tool/node.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index a85877d5c..d822d854f 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -171,6 +171,28 @@ private: friend class NodeIterator; }; +/// Iterator for editable nodes +/** Use this class for all operations that require some knowledge about the node's + * neighbors. It works like a bidirectional iterator. + * + * Because paths can be cyclic, node iterators have two different ways to + * increment and decrement them. Nodes can be iterated over either in the + * sequence order, which always has a beginning and an end, or in the path order, + * which can be cyclic (moving to the next node never yields the end iterator). + * + * When @a i is a node iterator, then: + * - ++i moves the iterator to the next node in sequence order; + * - --i moves the iterator to the previous node in sequence order; + * - i.next() returns the next node with wrap-around if the path is cyclic; + * - i.prev() returns the previous node with wrap-around if the path is cyclic. + * + * next() and prev() do not change their iterator. They can return the end iterator + * if the path is open. + * + * Unlike most other iterators, you can check whether a node iterator is invalid + * (is an end iterator) without having access to the iterator's container. + * Simply use if (i) { ... + * */ template class NodeIterator : public boost::bidirectional_iterator_helper, N, std::ptrdiff_t, @@ -194,7 +216,9 @@ public: bool operator==(self const &other) const { return _node == other._node; } N &operator*() const { return *static_cast(_node); } inline operator bool() const; // define after NodeList + /// Get a pointer to the underlying node. Equivalent to &*i. N *get_pointer() const { return static_cast(_node); } + /// @see get_pointer() N *ptr() const { return static_cast(_node); } self next() const; -- cgit v1.2.3 From 7ce8847f2410a24a6bce4ca8a43ad7ebdb4839eb Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 4 Feb 2010 03:14:09 +0100 Subject: Reduce libsigc++ usage to partially fix performance regressions in the new node tool. (bzr r9044) --- src/ui/tool/node.h | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index d822d854f..581cc9b6f 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -11,6 +11,7 @@ #ifndef SEEN_UI_TOOL_NODE_H #define SEEN_UI_TOOL_NODE_H +#include #include #include #include @@ -97,16 +98,19 @@ public: Node *parent() { return _parent; } static char const *handle_type_to_localized_string(NodeType type); - sigc::signal signal_update; protected: Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); + + 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; } private: - void _grabbedHandler(); - void _draggedHandler(Geom::Point &, GdkEventMotion *); - void _ungrabbedHandler(); + 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 SPCanvasItem *_handle_line; @@ -140,14 +144,16 @@ public: // temporarily public virtual bool _eventHandler(GdkEvent *event); protected: + virtual void dragged(Geom::Point &, GdkEventMotion *); + virtual bool grabbed(GdkEventMotion *); + virtual bool clicked(GdkEventButton *); + virtual void _setState(State state); virtual Glib::ustring _getTip(unsigned state); virtual Glib::ustring _getDragTip(GdkEventMotion *event); virtual bool _hasDragTips() { return true; } private: Node(Node const &); - bool _grabbedHandler(GdkEventMotion *); - void _draggedHandler(Geom::Point &, GdkEventMotion *); void _fixNeighbors(Geom::Point const &old_pos, Geom::Point const &new_pos); void _updateAutoHandles(); void _linearGrow(int dir); @@ -155,6 +161,7 @@ private: Node *_prev(); Inkscape::SnapSourceType _snapSourceType(); Inkscape::SnapTargetType _snapTargetType(); + inline PathManipulator &_pm(); static SPCtrlShapeType _node_type_to_shape(NodeType type); static bool _is_line_segment(Node *first, Node *second); @@ -327,8 +334,6 @@ public: SubpathList(PathManipulator &pm) : _path_manipulator(pm) {} - sigc::signal signal_insert_node; - sigc::signal signal_remove_node; private: list_type _nodelists; PathManipulator &_path_manipulator; @@ -349,6 +354,12 @@ inline void Handle::setRelativePos(Geom::Point const &p) { inline double Handle::length() { return relativePos().length(); } +inline PathManipulator &Handle::_pm() { + return _parent->_pm(); +} +inline PathManipulator &Node::_pm() { + return list()->_list._path_manipulator; +} // definitions for node iterator template @@ -359,14 +370,14 @@ template NodeIterator NodeIterator::next() const { NodeIterator ret(*this); ++ret; - if (!ret && _node->list->closed()) ++ret; + if (G_UNLIKELY(!ret) && _node->list->closed()) ++ret; return ret; } template NodeIterator NodeIterator::prev() const { NodeIterator ret(*this); --ret; - if (!ret && _node->list->closed()) --ret; + if (G_UNLIKELY(!ret) && _node->list->closed()) --ret; return ret; } -- cgit v1.2.3 From 81f88ca0856da56bdf426cd065ff0acd3414567f Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 9 Feb 2010 03:20:18 +0100 Subject: Fix multiple minor problems in the node tool (bzr r9070) --- src/ui/tool/node.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 581cc9b6f..c798a1fdb 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -96,6 +96,7 @@ public: void setDirection(Geom::Point const &from, Geom::Point const &to); void setDirection(Geom::Point const &dir); Node *parent() { return _parent; } + Handle &other(); static char const *handle_type_to_localized_string(NodeType type); protected: @@ -116,6 +117,7 @@ private: SPCanvasItem *_handle_line; bool _degenerate; // this is used often internally so it makes sense to cache this + static Geom::Point _saved_other_pos; static double _saved_length; static bool _drag_out; friend class Node; -- cgit v1.2.3 From 90e813701a7865bc36755fb0f35ab74c4b6963a2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 14 Mar 2010 18:38:50 +0100 Subject: Implement keyboard shortcuts for single handle adjustments. Minor disambiguating cleanup in node.h. (bzr r9190) --- src/ui/tool/node.h | 64 +++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index c798a1fdb..e502ddea1 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -66,9 +66,9 @@ struct SubpathListMember : public ListMember { */ struct ListNode { - ListNode *next; - ListNode *prev; - NodeList *list; + ListNode *ln_next; + ListNode *ln_prev; + NodeList *ln_list; }; struct NodeSharedData { @@ -139,7 +139,7 @@ public: Handle *front() { return &_front; } Handle *back() { return &_back; } static NodeType parse_nodetype(char x); - NodeList *list() { return static_cast(this)->list; } + NodeList &nodeList() { return *(static_cast(this)->ln_list); } void sink(); static char const *node_type_to_localized_string(NodeType type); @@ -182,24 +182,28 @@ private: /// Iterator for editable nodes /** Use this class for all operations that require some knowledge about the node's - * neighbors. It works like a bidirectional iterator. + * neighbors. It is a bidirectional iterator. * * Because paths can be cyclic, node iterators have two different ways to - * increment and decrement them. Nodes can be iterated over either in the - * sequence order, which always has a beginning and an end, or in the path order, - * which can be cyclic (moving to the next node never yields the end iterator). + * increment and decrement them. When using ++/--, the end iterator will eventually + * be returned. Whent using advance()/retreat(), the end iterator will only be returned + * when the path is open. If it's closed, calling advance() will cycle indefinitely. + * This is particularly useful for cases where the adjacency of nodes is more important + * than their sequence order. * * When @a i is a node iterator, then: * - ++i moves the iterator to the next node in sequence order; * - --i moves the iterator to the previous node in sequence order; - * - i.next() returns the next node with wrap-around if the path is cyclic; - * - i.prev() returns the previous node with wrap-around if the path is cyclic. + * - i.next() returns the next node with wrap-around; + * - i.prev() returns the previous node with wrap-around; + * - i.advance() moves the iterator to the next node with wrap-around; + * - i.retreat() moves the iterator to the previous node with wrap-around. * * next() and prev() do not change their iterator. They can return the end iterator * if the path is open. * - * Unlike most other iterators, you can check whether a node iterator is invalid - * (is an end iterator) without having access to the iterator's container. + * Unlike most other iterators, you can check whether you've reached the end of the list + * without having access to the iterator's container. * Simply use if (i) { ... * */ template @@ -215,11 +219,11 @@ public: // default copy, default assign self &operator++() { - _node = _node->next; + _node = _node->ln_next; return *this; } self &operator--() { - _node = _node->prev; + _node = _node->ln_prev; return *this; } bool operator==(self const &other) const { return _node == other._node; } @@ -232,13 +236,14 @@ public: self next() const; self prev() const; + self &advance(); + self &retreat(); private: NodeIterator(ListNode const *n) : _node(const_cast(n)) {} ListNode *_node; friend class NodeList; - friend class std::tr1::hash; }; class NodeList : ListNode, boost::noncopyable, public boost::enable_shared_from_this { @@ -259,9 +264,9 @@ public: ~NodeList(); // iterators - iterator begin() { return iterator(next); } + iterator begin() { return iterator(ln_next); } iterator end() { return iterator(this); } - const_iterator begin() const { return const_iterator(next); } + const_iterator begin() const { return const_iterator(ln_next); } const_iterator end() const { return const_iterator(this); } reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } @@ -305,11 +310,12 @@ public: } // member access - undefined results when the list is empty - Node &front() { return *static_cast(next); } - Node &back() { return *static_cast(prev); } + Node &front() { return *static_cast(ln_next); } + Node &back() { return *static_cast(ln_prev); } // HACK remove this subpath from its path. This will be removed later. void kill(); + SubpathList &subpathList() { return _list; } static iterator get_iterator(Node *n) { return iterator(n); } static const_iterator get_iterator(Node const *n) { return const_iterator(n); } @@ -335,6 +341,7 @@ public: typedef std::list< boost::shared_ptr > list_type; SubpathList(PathManipulator &pm) : _path_manipulator(pm) {} + PathManipulator &pm() { return _path_manipulator; } private: list_type _nodelists; @@ -360,43 +367,32 @@ inline PathManipulator &Handle::_pm() { return _parent->_pm(); } inline PathManipulator &Node::_pm() { - return list()->_list._path_manipulator; + return nodeList().subpathList().pm(); } // definitions for node iterator template NodeIterator::operator bool() const { - return _node && static_cast(_node->list) != _node; + return _node && static_cast(_node->ln_list) != _node; } template NodeIterator NodeIterator::next() const { NodeIterator ret(*this); ++ret; - if (G_UNLIKELY(!ret) && _node->list->closed()) ++ret; + if (G_UNLIKELY(!ret) && _node->ln_list->closed()) ++ret; return ret; } template NodeIterator NodeIterator::prev() const { NodeIterator ret(*this); --ret; - if (G_UNLIKELY(!ret) && _node->list->closed()) --ret; + if (G_UNLIKELY(!ret) && _node->ln_list->closed()) --ret; return ret; } } // namespace UI } // namespace Inkscape -namespace std { -namespace tr1 { -template -struct hash< Inkscape::UI::NodeIterator > : public unary_function, size_t> { - size_t operator()(Inkscape::UI::NodeIterator const &ni) const { - return reinterpret_cast(ni._node); - } -}; -} -} - #endif /* -- cgit v1.2.3 From bf83d5a03bf856e34bd0a6e2656a5b2dcfe8aafb Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Mon, 15 Mar 2010 00:58:16 +0100 Subject: Move around files to remove some vanity directories. Also remove the obsolete IDL file stub. (bzr r9194) --- src/ui/tool/node.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index e502ddea1..d04b87976 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -234,8 +234,16 @@ public: /// @see get_pointer() N *ptr() const { return static_cast(_node); } - self next() const; - self prev() const; + self next() const { + self r(*this); + r.advance(); + return r; + } + self prev() const { + self r(*this); + r.retreat(); + return r; + } self &advance(); self &retreat(); private: @@ -256,8 +264,6 @@ public: typedef Node value_type; typedef NodeIterator iterator; typedef NodeIterator const_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; // TODO Lame. Make this private and make SubpathList a factory NodeList(SubpathList &_list); @@ -268,10 +274,6 @@ public: iterator end() { return iterator(this); } const_iterator begin() const { return const_iterator(ln_next); } const_iterator end() const { return const_iterator(this); } - reverse_iterator rbegin() { return reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } // size bool empty(); @@ -376,18 +378,16 @@ NodeIterator::operator bool() const { return _node && static_cast(_node->ln_list) != _node; } template -NodeIterator NodeIterator::next() const { - NodeIterator ret(*this); - ++ret; - if (G_UNLIKELY(!ret) && _node->ln_list->closed()) ++ret; - return ret; +NodeIterator &NodeIterator::advance() { + ++(*this); + if (G_UNLIKELY(!*this) && _node->ln_list->closed()) ++(*this); + return *this; } template -NodeIterator NodeIterator::prev() const { - NodeIterator ret(*this); - --ret; - if (G_UNLIKELY(!ret) && _node->ln_list->closed()) --ret; - return ret; +NodeIterator &NodeIterator::retreat() { + --(*this); + if (G_UNLIKELY(!*this) && _node->ln_list->closed()) --(*this); + return *this; } } // namespace UI -- cgit v1.2.3 From 6f0f105886528bff81e43b32c9ab8dd9efa3fc22 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 18 Mar 2010 03:18:56 +0100 Subject: Fix scaling of degenerate handles using keybard shortcuts. (bzr r9203) --- src/ui/tool/node.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/ui/tool/node.h') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index d04b87976..af4cd7e3a 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -96,7 +96,7 @@ public: void setDirection(Geom::Point const &from, Geom::Point const &to); void setDirection(Geom::Point const &dir); Node *parent() { return _parent; } - Handle &other(); + Handle *other(); static char const *handle_type_to_localized_string(NodeType type); protected: @@ -138,10 +138,14 @@ public: bool isEndNode(); Handle *front() { return &_front; } Handle *back() { return &_back; } - static NodeType parse_nodetype(char x); + Handle *handleToward(Node *to); + Node *nodeToward(Handle *h); + Handle *handleAwayFrom(Node *to); + Node *nodeAwayFrom(Handle *h); NodeList &nodeList() { return *(static_cast(this)->ln_list); } void sink(); + static NodeType parse_nodetype(char x); static char const *node_type_to_localized_string(NodeType type); // temporarily public virtual bool _eventHandler(GdkEvent *event); -- cgit v1.2.3