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