goat3d

view goatview/src/scenemodel.cc @ 88:7941e89798e5

selections
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 15 May 2014 06:52:01 +0300
parents 6d04caf510ab
children
line source
1 #include <assert.h>
2 #include "scenemodel.h"
3 #include "goatview.h"
5 SceneModel::SceneModel()
6 {
7 scn = 0;
8 }
10 SceneModel::~SceneModel()
11 {
12 clear_scene();
13 }
15 void SceneModel::set_scene(goat3d *scn)
16 {
17 clear_scene();
18 this->scn = scn;
20 if(!scn) return;
22 // create the SceneNodeData for each node
23 int num_nodes = goat3d_get_node_count(scn);
24 for(int i=0; i<num_nodes; i++) {
25 goat3d_node *node = goat3d_get_node(scn, i);
27 SceneNodeData data;
28 data.visible = true;
29 data.selected = false;
31 node_data[node] = data;
32 }
33 }
35 void SceneModel::clear_scene()
36 {
37 node_data.clear();
38 scn = 0;
39 }
41 SceneNodeData *SceneModel::get_node_data(goat3d_node *node) const
42 {
43 auto it = node_data.find(node);
44 if(it == node_data.end()) {
45 return 0;
46 }
47 return (SceneNodeData*)&it->second;
48 }
50 Qt::ItemFlags SceneModel::flags(const QModelIndex &index) const
51 {
52 if(!index.isValid()) {
53 return 0;
54 }
56 Qt::ItemFlags res = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
57 if(index.column() == 1) {
58 res |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
59 }
60 return res;
61 }
63 QVariant SceneModel::data(const QModelIndex &index, int role) const
64 {
65 if(!index.isValid()) {
66 return QVariant();
67 }
69 goat3d_node *node = (goat3d_node*)index.internalPointer();
70 SceneNodeData *data = get_node_data(node);
72 switch(index.column()) {
73 case 0:
74 if(role == Qt::DisplayRole) {
75 return QString(goat3d_get_node_name(node));
76 }
77 break;
79 case 1:
80 if(role == Qt::CheckStateRole && data) {
81 return data->visible ? Qt::Checked : Qt::Unchecked;
82 }
83 break;
85 default:
86 break;
87 }
89 return QVariant();
90 }
92 bool SceneModel::setData(const QModelIndex &index, const QVariant &value, int role)
93 {
94 if(!index.isValid()) {
95 return false;
96 }
98 goat3d_node *node = (goat3d_node*)index.internalPointer();
99 SceneNodeData *data = get_node_data(node);
100 assert(data);
102 switch(index.column()) {
103 case 1:
104 if(role == Qt::CheckStateRole) {
105 data->visible = value.toBool();
106 emit dataChanged(index, index);
107 return true;
108 }
109 break;
111 default:
112 break;
113 }
114 return false;
115 }
117 QVariant SceneModel::headerData(int section, Qt::Orientation orient, int role) const
118 {
119 if(orient == Qt::Horizontal && role == Qt::DisplayRole) {
120 switch(section) {
121 case 0:
122 return QString("name");
123 case 1:
124 return QString("vis");
125 default:
126 return QString("???");
127 }
128 }
129 return QVariant();
130 }
132 int SceneModel::rowCount(const QModelIndex &parent) const
133 {
134 if(!scn) return 0;
136 if(!parent.isValid()) {
137 // return the number of root nodes
138 int num_nodes = goat3d_get_node_count(scn);
139 int num_root_nodes = 0;
140 for(int i=0; i<num_nodes; i++) {
141 goat3d_node *node = goat3d_get_node(scn, i);
142 if(!goat3d_get_node_parent(node)) {
143 ++num_root_nodes;
144 }
145 }
146 return num_root_nodes;
147 }
149 goat3d_node *pnode = (goat3d_node*)parent.internalPointer();
150 return goat3d_get_node_child_count(pnode);
151 }
153 int SceneModel::columnCount(const QModelIndex &parent) const
154 {
155 return 2;
156 }
158 bool SceneModel::hasChildren(const QModelIndex &parent) const
159 {
160 if(!parent.isValid()) {
161 return true;
162 }
164 goat3d_node *pnode = (goat3d_node*)parent.internalPointer();
165 return goat3d_get_node_child_count(pnode) > 0;
166 }
168 QModelIndex SceneModel::index(int row, int column, const QModelIndex &parent) const
169 {
170 if(!scn) {
171 return QModelIndex();
172 }
174 goat3d_node *node = 0;
176 if(!parent.isValid()) {
177 int num_nodes = goat3d_get_node_count(scn);
178 int idx = 0;
179 for(int i=0; i<num_nodes; i++) {
180 goat3d_node *n = goat3d_get_node(scn, i);
181 if(!goat3d_get_node_parent(n)) {
182 if(idx == row) {
183 node = n;
184 break;
185 }
186 idx++;
187 }
188 }
190 if(idx != row) {
191 return QModelIndex(); // failed
192 }
193 } else {
194 goat3d_node *pnode = (goat3d_node*)parent.internalPointer();
195 node = goat3d_get_node_child(pnode, row);
196 }
198 if(!node) {
199 return QModelIndex();
200 }
201 return createIndex(row, column, (void*)node);
202 }
204 QModelIndex SceneModel::parent(const QModelIndex &index) const
205 {
206 if(!index.isValid()) {
207 return QModelIndex(); // root node
208 }
210 goat3d_node *node = (goat3d_node*)index.internalPointer();
211 goat3d_node *parent = node ? goat3d_get_node_parent(node) : 0;
213 if(!parent) {
214 return QModelIndex();
215 }
217 // find out which child of its parent is our parent
218 int pidx = -1;
220 goat3d_node *grandparent = goat3d_get_node_parent(parent);
221 if(grandparent) {
222 int num_children = goat3d_get_node_child_count(grandparent);
223 for(int i=0; i<num_children; i++) {
224 if(goat3d_get_node_child(grandparent, i) == parent) {
225 pidx = i;
226 break;
227 }
228 }
229 } else {
230 int idx = 0;
231 int num_nodes = goat3d_get_node_count(scn);
232 for(int i=0; i<num_nodes; i++) {
233 goat3d_node *n = goat3d_get_node(scn, i);
234 if(!goat3d_get_node_parent(n)) {
235 if(n == parent) {
236 pidx = idx;
237 break;
238 }
239 idx++;
240 }
241 }
242 }
244 if(pidx == -1) {
245 fprintf(stderr, "%s: wtf?\n", __FUNCTION__);
246 return QModelIndex(); // failed
247 }
249 return createIndex(pidx, 0, (void*)parent);
250 }
253 void SceneModel::selchange(const QModelIndexList &selidx)
254 {
255 // go over the previously selected and unselect them
256 std::set<goat3d_node*>::iterator it = selected.begin();
257 while(it != selected.end()) {
258 goat3d_node *node = *it++;
259 SceneNodeData *data = get_node_data(node);
260 data->selected = false;
261 }
262 selected.clear();
264 for(int i=0; i<selidx.size(); i++) {
265 goat3d_node *node = (goat3d_node*)selidx.at(i).internalPointer();
266 SceneNodeData *data = get_node_data(node);
267 data->selected = true;
268 selected.insert(node);
269 }
271 post_redisplay();
272 }