Code

snap indicator: try a diamond shaped indicator for snapping to nodes. see how we...
[inkscape.git] / src / object-hierarchy.h
1 /** \file
2  * Inkscape::ObjectHierarchy - tracks a hierarchy of active SPObjects
3  *
4  * Authors:
5  *   MenTaLguY <mental@rydia.net>
6  *
7  * Copyright (C) 2004 MenTaLguY
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #ifndef SEEN_INKSCAPE_OBJECT_HIERARCHY_H
13 #define SEEN_INKSCAPE_OBJECT_HIERARCHY_H
15 #include <exception>
16 #include <list>
17 #include <sigc++/connection.h>
18 #include <sigc++/signal.h>
19 #include <glib/gmessages.h>
21 class SPObject;
23 namespace Inkscape {
25 /**
26  * An Inkscape::ObjectHierarchy is useful for situations where one wishes
27  * to keep a reference to an SPObject, but fall back on one of its ancestors
28  * when that object is removed.
29  *
30  * That cannot be accomplished simply by hooking the "release" signal of the
31  * SPObject, as by the time that signal is emitted, the object's parent
32  * field has already been cleared.
33  *
34  * There are also some subtle refcounting issues to take into account.
35  *
36  * @see SPObject
37  */
39 class ObjectHierarchy {
40 public:
41     ObjectHierarchy(SPObject *top=NULL);
42     ~ObjectHierarchy();
44     bool contains(SPObject *object);
46     sigc::connection connectAdded(const sigc::slot<void, SPObject *> &slot) {
47         return _added_signal.connect(slot);
48     }
49     sigc::connection connectRemoved(const sigc::slot<void, SPObject *> &slot) {
50         return _removed_signal.connect(slot);
51     }
52     sigc::connection connectChanged(const sigc::slot<void, SPObject *, SPObject *> &slot)
53     {
54         return _changed_signal.connect(slot);
55     }
57     void clear();
59     SPObject *top() {
60         return !_hierarchy.empty() ? _hierarchy.back().object : NULL;
61     }
62     void setTop(SPObject *object);
64     SPObject *bottom() {
65         return !_hierarchy.empty() ? _hierarchy.front().object : NULL;
66     }
67     void setBottom(SPObject *object);
69 private:
70     struct Record {
71         Record(SPObject *o, sigc::connection c)
72         : object(o), connection(c) {}
74         SPObject *object;
75         sigc::connection connection;
76     };
78     ObjectHierarchy(ObjectHierarchy const &); // no copy
79     void operator=(ObjectHierarchy const &); // no assign
81     /// @brief adds objects in range [senior, junior) to the top
82     void _addTop(SPObject *senior, SPObject *junior);
83     /// @brief adds one object to the top
84     void _addTop(SPObject *object);
85     /// @brief removes all objects above the limit object
86     void _trimAbove(SPObject *limit);
88     /// @brief adds objects in range (senior, junior] to the bottom
89     void _addBottom(SPObject *senior, SPObject *junior);
90     /// @brief adds one object to the bottom
91     void _addBottom(SPObject *object);
92     /// @brief removes all objects below the limit object
93     void _trimBelow(SPObject *limit);
95     Record _attach(SPObject *object);
96     void _detach(Record &record);
98     void _clear() { _trimBelow(NULL); }
100     void _trim_for_release(SPObject *released);
102     std::list<Record> _hierarchy;
103     sigc::signal<void, SPObject *> _added_signal;
104     sigc::signal<void, SPObject *> _removed_signal;
105     sigc::signal<void, SPObject *, SPObject *> _changed_signal;
106 };
110 #endif
111 /*
112   Local Variables:
113   mode:c++
114   c-file-style:"stroustrup"
115   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
116   indent-tabs-mode:nil
117   fill-column:99
118   End:
119 */
120 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :