2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "treemodel.h"
24 #include "debugging/debugging.h"
27 #include <gtk/gtktreemodel.h>
28 #include <gtk/gtktreednd.h>
29 #include <gtk/gtkmain.h>
31 #include "iscenegraph.h"
34 #include "generic/callback.h"
36 #include "string/string.h"
37 #include "generic/reference.h"
39 inline Nameable* Node_getNameable(scene::Node& node)
41 return NodeTypeCast<Nameable>::cast(node);
46 #include "gtkutil/gtktreestore.h"
48 template<typename value_type>
49 inline void gtk_tree_model_get_pointer(GtkTreeModel* model, GtkTreeIter* iter, gint column, value_type** pointer)
51 GValue value = GValue_default();
52 gtk_tree_model_get_value(model, iter, column, &value);
53 *pointer = (value_type*)g_value_get_pointer(&value);
57 typedef GtkTreeStore GraphTreeModel;
59 GtkTreeStore* graph_tree_model_new(graph_type* graph)
61 return gtk_tree_store_new(2, G_TYPE_POINTER, G_TYPE_POINTER);
64 void graph_tree_model_delete(GraphTreeModel* model)
66 g_object_unref(G_OBJECT(model));
70 bool graph_tree_model_subtree_find_node(GraphTreeModel* model, GtkTreeIter* parent, const scene::Node& node, GtkTreeIter* iter)
72 for(gboolean success = gtk_tree_model_iter_children(GTK_TREE_MODEL(model), iter, parent);
74 success = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), iter))
77 gtk_tree_model_get_pointer(GTK_TREE_MODEL(model), iter, 0, ¤t);
86 typedef GtkTreeIter DoubleGtkTreeIter[2];
88 bool graph_tree_model_find_top(GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter)
91 GtkTreeIter* parent_pointer = NULL;
93 for(scene::Path::const_iterator i = path.begin(); i != path.end(); ++i)
95 if(!graph_tree_model_subtree_find_node(model, parent_pointer, *i, &iter))
100 parent_pointer = &parent;
105 bool graph_tree_model_find_parent(GraphTreeModel* model, const scene::Path& path, GtkTreeIter& iter)
108 GtkTreeIter* parent_pointer = NULL;
109 ASSERT_MESSAGE(path.size() > 1, "path too short");
110 for(scene::Path::const_iterator i = path.begin(); i != path.end()-1; ++i)
113 if(!graph_tree_model_subtree_find_node(model, parent_pointer, *i, &child))
118 parent_pointer = &iter;
123 void node_attach_name_changed_callback(scene::Node& node, const Callback& callback)
127 Nameable* nameable = Node_getNameable(node);
130 nameable->attach(callback);
134 void node_detach_name_changed_callback(scene::Node& node, const Callback& callback)
138 Nameable* nameable = Node_getNameable(node);
141 nameable->detach(callback);
146 GraphTreeModel* scene_graph_get_tree_model(); // temp hack
148 void graph_tree_model_row_changed(const scene::Instance& instance)
150 GraphTreeModel* model = scene_graph_get_tree_model();
153 ASSERT_MESSAGE(graph_tree_model_find_top(model, instance.path(), child), "RUNTIME ERROR");
155 gtk_tree_store_set(GTK_TREE_STORE(model), &child, 0, instance.path().top(), -1);
158 void graph_tree_model_row_inserted(GraphTreeModel* model, const scene::Instance& instance)
161 GtkTreeIter* parent_pointer = NULL;
162 if(instance.path().size() != 1)
164 ASSERT_MESSAGE(graph_tree_model_find_parent(model, instance.path(), parent), "RUNTIME ERROR");
165 parent_pointer = &parent;
168 gpointer node = instance.path().top();
169 gconstpointer selectable = Instance_getSelectable(instance);
172 gtk_tree_store_append(GTK_TREE_STORE(model), &child, parent_pointer);
173 gtk_tree_store_set(GTK_TREE_STORE(model), &child, 0, node, 1, selectable, -1);
175 node_attach_name_changed_callback(instance.path().top(), ConstReferenceCaller<scene::Instance, graph_tree_model_row_changed>(instance));
178 void graph_tree_model_row_deleted(GraphTreeModel* model, const scene::Instance& instance)
181 ASSERT_MESSAGE(graph_tree_model_find_top(model, instance.path(), child), "RUNTIME ERROR");
183 node_detach_name_changed_callback(instance.path().top(), ConstReferenceCaller<scene::Instance, graph_tree_model_row_changed>(instance));
185 gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
190 const char* node_get_name(scene::Node& node);
192 typedef scene::Node* NodePointer;
197 bool operator()(const NodePointer& self, const NodePointer& other) const
207 int result = string_compare(node_get_name(self), node_get_name(other));
219 bool operator()(const PathConstReference& self, const PathConstReference& other) const
221 return std::lexicographical_compare(self.get().begin(), self.get().end(), other.get().begin(), other.get().end(), NodeNameLess());
225 typedef std::map<PathConstReference, scene::Instance*, PathNameLess> graph_type;
227 struct GraphTreeModel
234 struct GraphTreeModelClass
236 GObjectClass parent_class;
239 #define GRAPH_TREE_MODEL(p) (reinterpret_cast<GraphTreeModel*>(p))
241 static GtkTreeModelFlags graph_tree_model_get_flags (GtkTreeModel* tree_model)
243 return GTK_TREE_MODEL_ITERS_PERSIST;
246 static gint graph_tree_model_get_n_columns (GtkTreeModel* tree_model)
248 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
249 GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model;
254 static const gint c_stamp = 0xabcdef;
256 inline graph_type::iterator graph_iterator_read_tree_iter(GtkTreeIter* iter)
258 ASSERT_MESSAGE(iter != 0, "tree model error");
259 ASSERT_MESSAGE(iter->user_data != 0, "tree model error");
260 ASSERT_MESSAGE(iter->stamp == c_stamp, "tree model error");
261 return *reinterpret_cast<graph_type::iterator*>(&iter->user_data);
264 inline void graph_iterator_write_tree_iter(graph_type::iterator i, GtkTreeIter* iter)
266 ASSERT_MESSAGE(iter != 0, "tree model error");
267 iter->stamp = c_stamp;
268 *reinterpret_cast<graph_type::iterator*>(&iter->user_data) = i;
269 ASSERT_MESSAGE(iter->user_data != 0, "tree model error");
272 static GType graph_tree_model_get_column_type (GtkTreeModel *tree_model, gint index)
274 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
275 GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model;
277 return G_TYPE_POINTER;
280 static gboolean graph_tree_model_get_iter(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreePath* path)
282 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
283 gint* indices = gtk_tree_path_get_indices (path);
284 gint depth = gtk_tree_path_get_depth (path);
286 g_return_val_if_fail (depth > 0, FALSE);
288 graph_type& graph = *GRAPH_TREE_MODEL(tree_model)->graph;
294 GtkTreeIter* parent = 0;
296 for(gint i = 0; i < depth; i++)
298 if (! gtk_tree_model_iter_nth_child (tree_model, iter, parent, indices[i]))
307 static GtkTreePath* graph_tree_model_get_path(GtkTreeModel* tree_model, GtkTreeIter* iter)
309 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
310 graph_type& graph = *GRAPH_TREE_MODEL(tree_model)->graph;
311 graph_type::iterator i = graph_iterator_read_tree_iter(iter);
313 GtkTreePath* path = gtk_tree_path_new();
315 for(std::size_t depth = (*i).first.get().size(); depth != 0; --depth)
317 std::size_t index = 0;
319 while(i != graph.begin() && (*i).first.get().size() >= depth)
322 if((*i).first.get().size() == depth)
326 gtk_tree_path_prepend_index(path, index);
333 static void graph_tree_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
335 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
336 ASSERT_MESSAGE(column == 0 || column == 1, "tree model error");
338 graph_type::iterator i = graph_iterator_read_tree_iter(iter);
340 g_value_init (value, G_TYPE_POINTER);
343 g_value_set_pointer(value, reinterpret_cast<gpointer>((*i).first.get().top()));
345 g_value_set_pointer(value, reinterpret_cast<gpointer>(Instance_getSelectable(*(*i).second)));
348 static gboolean graph_tree_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
350 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
351 graph_type& graph = *GRAPH_TREE_MODEL(tree_model)->graph;
352 graph_type::iterator i = graph_iterator_read_tree_iter(iter);
353 std::size_t depth = (*i).first.get().size();
357 while(i != graph.end() && (*i).first.get().size() > depth)
362 if(i == graph.end() || (*i).first.get().size() != depth)
367 graph_iterator_write_tree_iter(i, iter);
372 static gboolean graph_tree_model_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
374 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
375 graph_type& graph = *GRAPH_TREE_MODEL(tree_model)->graph;
376 graph_type::iterator i = (parent == 0) ? graph.begin() : graph_iterator_read_tree_iter(parent);
377 std::size_t depth = (parent == 0) ? 1 : (*i).first.get().size() + 1;
382 if(i != graph.end() && (*i).first.get().size() == depth)
384 graph_iterator_write_tree_iter(i, iter);
391 static gboolean graph_tree_model_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
393 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
394 graph_type& graph = *GRAPH_TREE_MODEL(tree_model)->graph;
395 graph_type::iterator i = graph_iterator_read_tree_iter(iter);
396 std::size_t depth = (*i).first.get().size() + 1;
398 return ++i != graph.end() && (*i).first.get().size() == depth;
401 static gint graph_tree_model_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *parent)
403 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
404 graph_type& graph = *GRAPH_TREE_MODEL(tree_model)->graph;
405 graph_type::iterator i = (parent == 0) ? graph.begin() : graph_iterator_read_tree_iter(parent);
406 std::size_t depth = (parent == 0) ? 1 : (*i).first.get().size() + 1;
412 while(i != graph.end() && (*i).first.get().size() >= depth)
421 static gboolean graph_tree_model_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
423 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
424 graph_type& graph = *GRAPH_TREE_MODEL(tree_model)->graph;
425 graph_type::iterator i = (parent == 0) ? graph.begin() : graph_iterator_read_tree_iter(parent);
426 std::size_t depth = (parent == 0) ? 1 : (*i).first.get().size() + 1;
431 while(i != graph.end() && (*i).first.get().size() >= depth)
433 if((*i).first.get().size() == depth && n-- == 0)
435 graph_iterator_write_tree_iter(i, iter);
444 static gboolean graph_tree_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
446 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
447 graph_type& graph = *GRAPH_TREE_MODEL(tree_model)->graph;
448 graph_type::iterator i = graph_iterator_read_tree_iter(child);
449 std::size_t depth = (*i).first.get().size();
460 while((*i).first.get().size() >= depth);
461 graph_iterator_write_tree_iter(i, iter);
466 static GObjectClass *g_parent_class = 0;
468 static void graph_tree_model_init (GraphTreeModel *graph_tree_model)
470 graph_tree_model->graph = 0;
473 static void graph_tree_model_finalize(GObject* object)
475 GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL(object);
478 (* g_parent_class->finalize) (object);
481 static void graph_tree_model_class_init (GraphTreeModelClass *class_)
483 GObjectClass *object_class;
485 g_parent_class = (GObjectClass*)g_type_class_peek_parent (class_);
486 object_class = (GObjectClass *) class_;
488 object_class->finalize = graph_tree_model_finalize;
491 static void graph_tree_model_tree_model_init (GtkTreeModelIface *iface)
493 iface->get_flags = graph_tree_model_get_flags;
494 iface->get_n_columns = graph_tree_model_get_n_columns;
495 iface->get_column_type = graph_tree_model_get_column_type;
496 iface->get_iter = graph_tree_model_get_iter;
497 iface->get_path = graph_tree_model_get_path;
498 iface->get_value = graph_tree_model_get_value;
499 iface->iter_next = graph_tree_model_iter_next;
500 iface->iter_children = graph_tree_model_iter_children;
501 iface->iter_has_child = graph_tree_model_iter_has_child;
502 iface->iter_n_children = graph_tree_model_iter_n_children;
503 iface->iter_nth_child = graph_tree_model_iter_nth_child;
504 iface->iter_parent = graph_tree_model_iter_parent;
507 static gboolean graph_tree_model_row_draggable(GtkTreeDragSource *drag_source, GtkTreePath *path)
510 gint depth = gtk_tree_path_get_depth(path);
512 return gtk_tree_path_get_depth(path) > 1;
515 static gboolean graph_tree_model_drag_data_delete(GtkTreeDragSource *drag_source, GtkTreePath *path)
519 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(drag_source), &iter, path))
521 graph_type::iterator i = graph_iterator_read_tree_iter(&iter);
522 Path_deleteTop((*i).first);
531 static gboolean graph_tree_model_drag_data_get (GtkTreeDragSource *drag_source, GtkTreePath *path, GtkSelectionData *selection_data)
533 if(gtk_tree_set_row_drag_data(selection_data, GTK_TREE_MODEL(drag_source), path))
539 /* FIXME handle text targets at least. */
545 static void graph_tree_model_drag_source_init (GtkTreeDragSourceIface *iface)
547 iface->row_draggable = graph_tree_model_row_draggable;
548 iface->drag_data_delete = graph_tree_model_drag_data_delete;
549 iface->drag_data_get = graph_tree_model_drag_data_get;
552 static gboolean graph_tree_model_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data)
554 GtkTreeModel *tree_model = GTK_TREE_MODEL (drag_dest);
556 GtkTreeModel *src_model = 0;
557 GtkTreePath *src_path = 0;
558 if(gtk_tree_get_row_drag_data(selection_data, &src_model, &src_path)
559 && src_model == tree_model)
561 /* Copy the given row to a new position */
564 if(gtk_tree_model_get_iter(src_model, &iter, src_path))
571 /* FIXME maybe add some data targets eventually, or handle text
572 * targets in the simple case.
579 static gboolean graph_tree_model_row_drop_possible(GtkTreeDragDest *drag_dest, GtkTreePath *dest_path, GtkSelectionData *selection_data)
581 gboolean retval = FALSE;
583 GtkTreeModel *src_model = 0;
584 GtkTreePath *src_path = 0;
585 if(gtk_tree_get_row_drag_data(selection_data, &src_model, &src_path) != FALSE)
587 /* can only drag to ourselves */
588 if(src_model == GTK_TREE_MODEL(drag_dest))
590 /* Can't drop into ourself. */
591 if(!gtk_tree_path_is_ancestor(src_path, dest_path))
593 /* Can't drop if dest_path's parent doesn't exist */
594 if (gtk_tree_path_get_depth (dest_path) > 1)
596 GtkTreePath* tmp = gtk_tree_path_copy (dest_path);
597 gtk_tree_path_up (tmp);
600 retval = gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest), &iter, tmp);
602 gtk_tree_path_free (tmp);
607 gtk_tree_path_free (src_path);
613 static void graph_tree_model_drag_dest_init (GtkTreeDragDestIface *iface)
615 iface->drag_data_received = graph_tree_model_drag_data_received;
616 iface->row_drop_possible = graph_tree_model_row_drop_possible;
619 GType graph_tree_model_get_type (void)
621 static GType graph_tree_model_type = 0;
623 if (!graph_tree_model_type)
625 static const GTypeInfo graph_tree_model_info =
627 sizeof (GraphTreeModelClass),
629 0, /* base_finalize */
630 (GClassInitFunc) graph_tree_model_class_init,
631 0, /* class_finalize */
633 sizeof (GraphTreeModel),
635 (GInstanceInitFunc) graph_tree_model_init
638 static const GInterfaceInfo tree_model_info =
640 (GInterfaceInitFunc) graph_tree_model_tree_model_init,
645 static const GInterfaceInfo drag_source_info =
647 (GInterfaceInitFunc) graph_tree_model_drag_source_init,
652 static const GInterfaceInfo drag_dest_info =
654 (GInterfaceInitFunc) graph_tree_model_drag_dest_init,
659 graph_tree_model_type = g_type_register_static (G_TYPE_OBJECT, "GraphTreeModel",
660 &graph_tree_model_info, (GTypeFlags)0);
662 g_type_add_interface_static (graph_tree_model_type,
665 g_type_add_interface_static (graph_tree_model_type,
666 GTK_TYPE_TREE_DRAG_SOURCE,
668 g_type_add_interface_static (graph_tree_model_type,
669 GTK_TYPE_TREE_DRAG_DEST,
673 return graph_tree_model_type;
676 GraphTreeModel* graph_tree_model_new()
678 GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL(g_object_new (graph_tree_model_get_type(), 0));
680 graph_tree_model->graph = new graph_type;
682 return graph_tree_model;
685 void graph_tree_model_delete(GraphTreeModel* model)
688 g_object_unref(G_OBJECT(model));
692 class TempNameable : public Nameable
696 TempNameable(const char* name) : m_name(name)
699 const char* name() const
703 void attach(const NameCallback& callback)
706 void detach(const NameCallback& callback)
711 void node_attach_name_changed_callback(scene::Node& node, const NameCallback& callback)
715 Nameable* nameable = Node_getNameable(node);
718 nameable->attach(callback);
722 void node_detach_name_changed_callback(scene::Node& node, const NameCallback& callback)
726 Nameable* nameable = Node_getNameable(node);
729 nameable->detach(callback);
734 GraphTreeModel* scene_graph_get_tree_model(); // temp hack
736 void graph_tree_model_row_inserted(GraphTreeModel* model, graph_type::iterator i)
739 graph_iterator_write_tree_iter(i, &iter);
741 GtkTreePath* tree_path = graph_tree_model_get_path(GTK_TREE_MODEL(model), &iter);
743 gint depth = gtk_tree_path_get_depth(tree_path);
744 gint* indices = gtk_tree_path_get_indices(tree_path);
746 gtk_tree_model_row_inserted(GTK_TREE_MODEL(model), tree_path, &iter);
748 gtk_tree_path_free(tree_path);
751 void graph_tree_model_row_deleted(GraphTreeModel* model, graph_type::iterator i)
754 graph_iterator_write_tree_iter(i, &iter);
756 GtkTreePath* tree_path = graph_tree_model_get_path(GTK_TREE_MODEL(model), &iter);
758 gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), tree_path);
760 gtk_tree_path_free(tree_path);
763 #include "generic/referencecounted.h"
765 void graph_tree_model_set_name(const scene::Instance& instance, const char* name)
767 GraphTreeModel* model = scene_graph_get_tree_model();
769 if(string_empty(name)) // hack!
771 graph_type::iterator i = model->graph->find(PathConstReference(instance.path()));
772 ASSERT_MESSAGE(i != model->graph->end(), "ERROR");
774 graph_tree_model_row_deleted(model, i);
776 model->graph->erase(i);
780 graph_type::iterator i = model->graph->insert(graph_type::value_type(PathConstReference(instance.path()), &const_cast<scene::Instance&>(instance))).first;
782 graph_tree_model_row_inserted(model, i);
786 void graph_tree_model_insert(GraphTreeModel* model, const scene::Instance& instance)
788 graph_type::iterator i = model->graph->insert(graph_type::value_type(PathConstReference(instance.path()), &const_cast<scene::Instance&>(instance))).first;
790 graph_tree_model_row_inserted(model, i);
792 node_attach_name_changed_callback(instance.path().top(), ConstReferenceCaller1<scene::Instance, const char*, graph_tree_model_set_name>(instance));
795 void graph_tree_model_erase(GraphTreeModel* model, const scene::Instance& instance)
797 node_detach_name_changed_callback(instance.path().top(), ConstReferenceCaller1<scene::Instance, const char*, graph_tree_model_set_name>(instance));
799 graph_type::iterator i = model->graph->find(PathConstReference(instance.path()));
800 ASSERT_MESSAGE(i != model->graph->end(), "ERROR");
802 graph_tree_model_row_deleted(model, i);
804 model->graph->erase(i);
810 void graph_tree_model_row_changed(GraphTreeNode& node);
814 typedef std::map<std::pair<CopiedString, scene::Node*>, GraphTreeNode*> ChildNodes;
815 ChildNodes m_childnodes;
817 Reference<scene::Instance> m_instance;
818 GraphTreeNode* m_parent;
820 typedef ChildNodes::iterator iterator;
821 typedef ChildNodes::key_type key_type;
822 typedef ChildNodes::value_type value_type;
823 typedef ChildNodes::size_type size_type;
825 GraphTreeNode(scene::Instance& instance) : m_instance(instance), m_parent(0)
827 m_instance.get().setChildSelectedChangedCallback(RowChangedCaller(*this));
831 m_instance.get().setChildSelectedChangedCallback(Callback());
832 ASSERT_MESSAGE(empty(), "GraphTreeNode::~GraphTreeNode: memory leak");
837 return m_childnodes.begin();
841 return m_childnodes.end();
844 size_type size() const
846 return m_childnodes.size();
850 return m_childnodes.empty();
853 iterator insert(const value_type& value)
855 iterator i = m_childnodes.insert(value).first;
856 (*i).second->m_parent = this;
859 void erase(iterator i)
861 m_childnodes.erase(i);
863 iterator find(const key_type& key)
865 return m_childnodes.find(key);
868 void swap(GraphTreeNode& other)
870 std::swap(m_parent, other.m_parent);
871 std::swap(m_childnodes, other.m_childnodes);
872 std::swap(m_instance, other.m_instance);
877 graph_tree_model_row_changed(*this);
879 typedef MemberCaller<GraphTreeNode, &GraphTreeNode::rowChanged> RowChangedCaller;
882 struct GraphTreeModel
886 GraphTreeNode* m_graph;
889 struct GraphTreeModelClass
891 GObjectClass parent_class;
894 #define GRAPH_TREE_MODEL(p) (reinterpret_cast<GraphTreeModel*>(p))
896 static GtkTreeModelFlags graph_tree_model_get_flags (GtkTreeModel* tree_model)
898 return GTK_TREE_MODEL_ITERS_PERSIST;
901 static gint graph_tree_model_get_n_columns (GtkTreeModel* tree_model)
903 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
904 //GraphTreeModel* graph_tree_model = (GraphTreeModel*) tree_model;
909 static const gint c_stamp = 0xabcdef;
911 inline GraphTreeNode::iterator graph_iterator_read_tree_iter(GtkTreeIter* iter)
913 ASSERT_MESSAGE(iter != 0, "tree model error");
914 ASSERT_MESSAGE(iter->user_data != 0, "tree model error");
915 ASSERT_MESSAGE(iter->stamp == c_stamp, "tree model error");
916 return *reinterpret_cast<GraphTreeNode::iterator*>(&iter->user_data);
919 inline void graph_iterator_write_tree_iter(GraphTreeNode::iterator i, GtkTreeIter* iter)
921 ASSERT_MESSAGE(iter != 0, "tree model error");
922 iter->stamp = c_stamp;
923 *reinterpret_cast<GraphTreeNode::iterator*>(&iter->user_data) = i;
924 ASSERT_MESSAGE(iter->user_data != 0, "tree model error");
927 static GType graph_tree_model_get_column_type (GtkTreeModel *tree_model, gint index)
929 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
930 //GraphTreeModel *graph_tree_model = (GraphTreeModel *) tree_model;
932 return G_TYPE_POINTER;
935 static gboolean graph_tree_model_get_iter(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreePath* path)
937 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
938 gint* indices = gtk_tree_path_get_indices (path);
939 gint depth = gtk_tree_path_get_depth (path);
941 g_return_val_if_fail (depth > 0, FALSE);
943 GraphTreeNode* graph = GRAPH_TREE_MODEL(tree_model)->m_graph;
949 GtkTreeIter* parent = 0;
951 for(gint i = 0; i < depth; i++)
953 if (! gtk_tree_model_iter_nth_child (tree_model, iter, parent, indices[i]))
962 static GtkTreePath* graph_tree_model_get_path(GtkTreeModel* tree_model, GtkTreeIter* iter)
964 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
965 GraphTreeNode* graph = GRAPH_TREE_MODEL(tree_model)->m_graph;
967 GtkTreePath* path = gtk_tree_path_new();
969 for(GraphTreeNode* node = (*graph_iterator_read_tree_iter(iter)).second; node != graph; node = node->m_parent)
971 std::size_t index = 0;
972 for(GraphTreeNode::iterator i = node->m_parent->begin(); i != node->m_parent->end(); ++i, ++index)
974 if((*i).second == node)
976 gtk_tree_path_prepend_index(path, gint(index));
980 ASSERT_MESSAGE(index != node->m_parent->size(), "error resolving tree path");
987 static void graph_tree_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
989 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
990 ASSERT_MESSAGE(column == 0 || column == 1, "tree model error");
992 GraphTreeNode::iterator i = graph_iterator_read_tree_iter(iter);
994 g_value_init (value, G_TYPE_POINTER);
998 g_value_set_pointer(value, reinterpret_cast<gpointer>((*i).first.second));
1002 g_value_set_pointer(value, reinterpret_cast<gpointer>(&(*i).second->m_instance.get()));
1006 static gboolean graph_tree_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
1008 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
1009 GraphTreeNode::iterator i = graph_iterator_read_tree_iter(iter);
1010 GraphTreeNode& parent = *(*i).second->m_parent;
1012 ASSERT_MESSAGE(i != parent.end(), "RUNTIME ERROR");
1014 if(++i == parent.end())
1019 graph_iterator_write_tree_iter(i, iter);
1024 static gboolean graph_tree_model_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
1026 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
1027 GraphTreeNode& node = (parent == 0) ? *GRAPH_TREE_MODEL(tree_model)->m_graph : *(*graph_iterator_read_tree_iter(parent)).second;
1030 graph_iterator_write_tree_iter(node.begin(), iter);
1037 static gboolean graph_tree_model_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
1039 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
1040 GraphTreeNode& node = *(*graph_iterator_read_tree_iter(iter)).second;
1041 return !node.empty();
1044 static gint graph_tree_model_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *parent)
1046 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
1047 GraphTreeNode& node = (parent == 0) ? *GRAPH_TREE_MODEL(tree_model)->m_graph : *(*graph_iterator_read_tree_iter(parent)).second;
1048 return static_cast<gint>(node.size());
1051 static gboolean graph_tree_model_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
1053 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
1054 GraphTreeNode& node = (parent == 0) ? *GRAPH_TREE_MODEL(tree_model)->m_graph : *(*graph_iterator_read_tree_iter(parent)).second;
1055 if(static_cast<std::size_t>(n) < node.size())
1057 GraphTreeNode::iterator i = node.begin();
1059 graph_iterator_write_tree_iter(i, iter);
1066 static gboolean graph_tree_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
1068 ASSERT_MESSAGE(tree_model != 0, "RUNTIME ERROR");
1069 GraphTreeNode& node = *(*graph_iterator_read_tree_iter(child)).second;
1070 if(node.m_parent != GRAPH_TREE_MODEL(tree_model)->m_graph)
1072 GraphTreeNode& parentParent = *node.m_parent->m_parent;
1073 for(GraphTreeNode::iterator i = parentParent.begin(); i != parentParent.end(); ++i)
1075 if((*i).second == node.m_parent)
1077 graph_iterator_write_tree_iter(i, iter);
1085 static GObjectClass *g_parent_class = 0;
1089 scene::Node* g_null_node = 0;
1092 class NullInstance : public scene::Instance
1095 NullInstance() : scene::Instance(scene::Path(makeReference(*g_null_node)), 0, 0, Static<InstanceTypeCastTable>::instance())
1102 NullInstance g_null_instance;
1105 static void graph_tree_model_init (GraphTreeModel *graph_tree_model)
1107 graph_tree_model->m_graph = new GraphTreeNode(g_null_instance);
1110 static void graph_tree_model_finalize(GObject* object)
1112 GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL(object);
1114 delete graph_tree_model->m_graph;
1117 (* g_parent_class->finalize) (object);
1120 static void graph_tree_model_class_init (GraphTreeModelClass *class_)
1122 GObjectClass *object_class;
1124 g_parent_class = (GObjectClass*)g_type_class_peek_parent (class_);
1125 object_class = (GObjectClass *) class_;
1127 object_class->finalize = graph_tree_model_finalize;
1130 static void graph_tree_model_tree_model_init (GtkTreeModelIface *iface)
1132 iface->get_flags = graph_tree_model_get_flags;
1133 iface->get_n_columns = graph_tree_model_get_n_columns;
1134 iface->get_column_type = graph_tree_model_get_column_type;
1135 iface->get_iter = graph_tree_model_get_iter;
1136 iface->get_path = graph_tree_model_get_path;
1137 iface->get_value = graph_tree_model_get_value;
1138 iface->iter_next = graph_tree_model_iter_next;
1139 iface->iter_children = graph_tree_model_iter_children;
1140 iface->iter_has_child = graph_tree_model_iter_has_child;
1141 iface->iter_n_children = graph_tree_model_iter_n_children;
1142 iface->iter_nth_child = graph_tree_model_iter_nth_child;
1143 iface->iter_parent = graph_tree_model_iter_parent;
1146 GType graph_tree_model_get_type (void)
1148 static GType graph_tree_model_type = 0;
1150 if (!graph_tree_model_type)
1152 static const GTypeInfo graph_tree_model_info =
1154 sizeof (GraphTreeModelClass),
1156 0, /* base_finalize */
1157 (GClassInitFunc) graph_tree_model_class_init,
1158 0, /* class_finalize */
1160 sizeof (GraphTreeModel),
1161 0, /* n_preallocs */
1162 (GInstanceInitFunc) graph_tree_model_init,
1166 static const GInterfaceInfo tree_model_info =
1168 (GInterfaceInitFunc) graph_tree_model_tree_model_init,
1173 graph_tree_model_type = g_type_register_static (G_TYPE_OBJECT, "GraphTreeModel",
1174 &graph_tree_model_info, (GTypeFlags)0);
1176 g_type_add_interface_static (graph_tree_model_type,
1177 GTK_TYPE_TREE_MODEL,
1181 return graph_tree_model_type;
1184 GraphTreeModel* graph_tree_model_new()
1186 GraphTreeModel* graph_tree_model = GRAPH_TREE_MODEL(g_object_new (graph_tree_model_get_type(), 0));
1188 return graph_tree_model;
1191 void graph_tree_model_delete(GraphTreeModel* model)
1193 g_object_unref(G_OBJECT(model));
1196 void graph_tree_model_row_changed(GraphTreeModel* model, GraphTreeNode::iterator i)
1199 graph_iterator_write_tree_iter(i, &iter);
1201 GtkTreePath* tree_path = graph_tree_model_get_path(GTK_TREE_MODEL(model), &iter);
1203 gtk_tree_model_row_changed(GTK_TREE_MODEL(model), tree_path, &iter);
1205 gtk_tree_path_free(tree_path);
1208 void graph_tree_model_row_inserted(GraphTreeModel* model, GraphTreeNode::iterator i)
1211 graph_iterator_write_tree_iter(i, &iter);
1213 GtkTreePath* tree_path = graph_tree_model_get_path(GTK_TREE_MODEL(model), &iter);
1215 gtk_tree_model_row_inserted(GTK_TREE_MODEL(model), tree_path, &iter);
1217 gtk_tree_path_free(tree_path);
1220 void graph_tree_model_row_deleted(GraphTreeModel* model, GraphTreeNode::iterator i)
1223 graph_iterator_write_tree_iter(i, &iter);
1225 GtkTreePath* tree_path = graph_tree_model_get_path(GTK_TREE_MODEL(model), &iter);
1227 gtk_tree_model_row_deleted(GTK_TREE_MODEL(model), tree_path);
1229 gtk_tree_path_free(tree_path);
1232 void graph_tree_model_row_inserted(GraphTreeModel& model, GraphTreeNode::iterator i)
1234 graph_tree_model_row_inserted(&model, i);
1237 void graph_tree_model_row_deleted(GraphTreeModel& model, GraphTreeNode::iterator i)
1239 graph_tree_model_row_deleted(&model, i);
1242 const char* node_get_name(scene::Node& node);
1244 const char* node_get_name_safe(scene::Node& node)
1250 return node_get_name(node);
1253 GraphTreeNode* graph_tree_model_find_parent(GraphTreeModel* model, const scene::Path& path)
1255 GraphTreeNode* parent = model->m_graph;
1256 for(scene::Path::const_iterator i = path.begin(); i != path.end()-1; ++i)
1258 GraphTreeNode::iterator child = parent->find(GraphTreeNode::key_type(node_get_name_safe((*i).get()), (*i).get_pointer()));
1259 ASSERT_MESSAGE(child != parent->end(), "ERROR");
1260 parent = (*child).second;
1265 void node_attach_name_changed_callback(scene::Node& node, const NameCallback& callback)
1269 Nameable* nameable = Node_getNameable(node);
1272 nameable->attach(callback);
1276 void node_detach_name_changed_callback(scene::Node& node, const NameCallback& callback)
1280 Nameable* nameable = Node_getNameable(node);
1283 nameable->detach(callback);
1288 GraphTreeModel* scene_graph_get_tree_model(); // temp hack
1290 void graph_tree_node_foreach_pre(GraphTreeNode::iterator root, const Callback1<GraphTreeNode::iterator>& callback)
1293 for(GraphTreeNode::iterator i = (*root).second->begin(); i != (*root).second->end(); ++i)
1295 graph_tree_node_foreach_pre(i, callback);
1299 void graph_tree_node_foreach_post(GraphTreeNode::iterator root, const Callback1<GraphTreeNode::iterator>& callback)
1301 for(GraphTreeNode::iterator i = (*root).second->begin(); i != (*root).second->end(); ++i)
1303 graph_tree_node_foreach_post(i, callback);
1308 void graph_tree_model_row_changed(GraphTreeNode& node)
1310 GraphTreeModel* model = scene_graph_get_tree_model();
1311 const scene::Instance& instance = node.m_instance.get();
1313 GraphTreeNode::iterator i = node.m_parent->find(GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), instance.path().top().get_pointer()));
1315 graph_tree_model_row_changed(model, i);
1318 void graph_tree_model_set_name(const scene::Instance& instance, const char* name)
1320 GraphTreeModel* model = scene_graph_get_tree_model();
1321 GraphTreeNode* parent = graph_tree_model_find_parent(model, instance.path());
1323 GraphTreeNode::iterator oldNode = parent->find(GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), instance.path().top().get_pointer()));
1324 graph_tree_node_foreach_post(oldNode, ReferenceCaller1<GraphTreeModel, GraphTreeNode::iterator, graph_tree_model_row_deleted>(*model));
1325 GraphTreeNode* node((*oldNode).second);
1326 parent->erase(oldNode);
1328 GraphTreeNode::iterator newNode = parent->insert(GraphTreeNode::value_type(GraphTreeNode::key_type(name, &instance.path().top().get()), node));
1329 graph_tree_node_foreach_pre(newNode, ReferenceCaller1<GraphTreeModel, GraphTreeNode::iterator, graph_tree_model_row_inserted>(*model));
1332 void graph_tree_model_insert(GraphTreeModel* model, const scene::Instance& instance)
1334 GraphTreeNode* parent = graph_tree_model_find_parent(model, instance.path());
1336 GraphTreeNode::iterator i = parent->insert(GraphTreeNode::value_type(GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), instance.path().top().get_pointer()), new GraphTreeNode(const_cast<scene::Instance&>(instance))));
1338 graph_tree_model_row_inserted(model, i);
1340 node_attach_name_changed_callback(instance.path().top(), ConstReferenceCaller1<scene::Instance, const char*, graph_tree_model_set_name>(instance));
1343 void graph_tree_model_erase(GraphTreeModel* model, const scene::Instance& instance)
1345 node_detach_name_changed_callback(instance.path().top(), ConstReferenceCaller1<scene::Instance, const char*, graph_tree_model_set_name>(instance));
1347 GraphTreeNode* parent = graph_tree_model_find_parent(model, instance.path());
1349 GraphTreeNode::iterator i = parent->find(GraphTreeNode::key_type(node_get_name_safe(instance.path().top().get()), instance.path().top().get_pointer()));
1351 graph_tree_model_row_deleted(model, i);
1353 GraphTreeNode* node((*i).second);
1366 class TestGraphTreeModel
1369 TestGraphTreeModel()
1375 scene::Node* root = *(scene::Node*)0xa0000000;
1376 scene::Node* node1 = (scene::Node*)0xa0000001;
1377 scene::Node* node2 = (scene::Node*)0xa0000002;
1378 scene::Node* node3 = (scene::Node*)0xa0000003;
1379 scene::Node* node4 = (scene::Node*)0xa0000004;
1380 scene::Instance* instance = (scene::Instance*)0xaaaaaaaa;
1382 scene::Path rootpath(root);
1384 graph.insert(graph_type::value_type(rootpath, instance));
1386 rootpath.push(node1);
1387 graph.insert(graph_type::value_type(rootpath, instance));
1390 rootpath.push(node2);
1391 graph.insert(graph_type::value_type(rootpath, instance));
1392 rootpath.push(node3);
1393 graph.insert(graph_type::value_type(rootpath, instance));
1395 rootpath.push(node4);
1396 graph.insert(graph_type::value_type(rootpath, instance));
1400 GtkTreeModel* model = GTK_TREE_MODEL(graph_tree_model_new(&graph));
1403 gint n_columns = gtk_tree_model_get_n_columns(model);
1404 ASSERT_MESSAGE(n_columns == 2, "test failed!");
1408 GType type = gtk_tree_model_get_column_type(model, 0);
1409 ASSERT_MESSAGE(type == G_TYPE_POINTER, "test failed!");
1413 GType type = gtk_tree_model_get_column_type(model, 1);
1414 ASSERT_MESSAGE(type == G_TYPE_POINTER, "test failed!");
1420 gtk_tree_model_get_iter_first(model, &iter);
1422 graph_type::iterator i = graph_iterator_read_tree_iter(&iter);
1423 ASSERT_MESSAGE((*i).first.get().size() == 2 && (*i).first.get().top() == node1, "test failed!");
1428 gtk_tree_model_get_iter_first(model, &iter);
1430 ASSERT_MESSAGE(gtk_tree_model_iter_has_child(model, &iter) == FALSE, "test failed!");
1432 ASSERT_MESSAGE(gtk_tree_model_iter_n_children(model, &iter) == 0, "test failed!");
1434 gtk_tree_model_iter_next(model, &iter);
1436 ASSERT_MESSAGE(gtk_tree_model_iter_has_child(model, &iter) != FALSE, "test failed!");
1438 ASSERT_MESSAGE(gtk_tree_model_iter_n_children(model, &iter) == 2, "test failed!");
1442 gtk_tree_model_iter_nth_child(model, &child, &iter, 0);
1445 gtk_tree_model_get_value(model, &child, 0, (GValue*)&test);
1446 ASSERT_MESSAGE(test == node3, "test failed!");
1450 gtk_tree_model_iter_parent(model, &parent, &child);
1453 gtk_tree_model_get_value(model, &parent, 0, (GValue*)&test);
1454 ASSERT_MESSAGE(test == node2, "test failed!");
1460 gtk_tree_model_iter_nth_child(model, &child, &iter, 1);
1463 gtk_tree_model_get_value(model, &child, 0, (GValue*)&test);
1464 ASSERT_MESSAGE(test == node4, "test failed!");
1470 std::size_t count = 0;
1471 for(gboolean good = gtk_tree_model_get_iter_first(model, &iter); good; good = gtk_tree_model_iter_next(model, &iter))
1474 gtk_tree_model_get_value(model, &iter, 0, (GValue*)&test);
1476 ASSERT_MESSAGE((count == 0 && test == node1) || (count == 1 && test == node2), "test failed!");
1480 ASSERT_MESSAGE(count == 2, "test failed!");
1486 gtk_tree_model_get_iter_first(model, &iter);
1489 gtk_tree_model_get_value(model, &iter, 0, (GValue*)&test);
1490 ASSERT_MESSAGE(test == node1, "test failed!");
1495 GtkTreePath* path = gtk_tree_path_new_from_string("0");
1496 gtk_tree_model_get_iter(model, &iter, path);
1497 gtk_tree_path_free(path);
1499 graph_type::iterator i = graph_iterator_read_tree_iter(&iter);
1500 ASSERT_MESSAGE((*i).first.get().size() == 2 && (*i).first.get().top() == node1, "test failed!");
1505 GtkTreePath* path = gtk_tree_path_new_from_string("1");
1506 gtk_tree_model_get_iter(model, &iter, path);
1507 gtk_tree_path_free(path);
1509 graph_type::iterator i = graph_iterator_read_tree_iter(&iter);
1510 ASSERT_MESSAGE((*i).first.get().size() == 2 && (*i).first.get().top() == node2, "test failed!");
1515 graph_type::iterator i = graph.begin();
1517 graph_iterator_write_tree_iter(i, &iter);
1519 GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
1521 gint depth = gtk_tree_path_get_depth(path);
1522 gint* indices = gtk_tree_path_get_indices(path);
1524 ASSERT_MESSAGE(depth == 1 && indices[0] == 0, "test failed!");
1526 gtk_tree_path_free(path);
1531 graph_type::iterator i = graph.begin();
1534 graph_iterator_write_tree_iter(i, &iter);
1536 GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
1538 gint depth = gtk_tree_path_get_depth(path);
1539 gint* indices = gtk_tree_path_get_indices(path);
1541 ASSERT_MESSAGE(depth == 1 && indices[0] == 1, "test failed!");
1543 gtk_tree_path_free(path);
1549 TestGraphTreeModel g_TestGraphTreeModel;