root/deus/GraphDisplay.cpp

Revision 8, 11.4 kB (checked in by pantley2, 4 years ago)

added old DEUS project to SVN

Line 
1 /*     
2  *      GraphDisplay.cpp
3  *
4  *      Zone display pane
5  *
6  *      $Header: /afs/acm/sig/art/cvs/deus/DEUS/GraphDisplay.cpp,v 1.1.1.2 2003-06-27 02:25:48 hanneke Exp $
7  */
8
9 #include "GraphDisplay.h"
10 #include "GraphIcon.h"
11 #include "AuthorInterface_impl.h"
12
13 #include <qsizepolicy.h>
14 #include <qpainter.h>
15 #include <qpixmap.h>
16 #include <qimage.h>
17 #include <qrect.h>
18
19
20 GraphDisplay::GraphDisplay(QWidget *parent, const char *name)
21         : QWidget(parent, name, WRepaintNoErase)
22 {
23         setWFlags(WRepaintNoErase);
24        
25         zoom = DEFAULT_ZOOM;
26         factor = 1.0;
27         moving = NULL;
28         maxx = maxy = minx = miny = 0;
29         moving_icon = moving_pane = false;
30         setPalette(QPalette(QColor(255,255,255)));
31         buffer = new QPixmap();
32         center();
33
34         modified = suppress_repaint = false;
35         fit_pending = false;
36 }
37
38
39 PlanGraphDisplay::PlanGraphDisplay(PlanNode *root, QWidget *parent, const char *name)
40         : GraphDisplay(parent, name)
41 {
42         this->root = root;
43         boundingBox();
44 }
45
46
47 AuthorGraphDisplay::AuthorGraphDisplay(AuthorForm_impl *author, QWidget *parent, const char *name)
48         : GraphDisplay(parent, name)
49 {
50         this->author = author;
51         boundingBox();
52 }      
53
54
55 void 
56 GraphDisplay::paintEvent(QPaintEvent *)
57 {
58         if (fit_pending) {
59                 fit_pending = false;
60                 int z = zoom;
61                 fit(width(), height());
62                 if (zoom != z) emit zoomChanged(zoom);
63         }
64
65         draw(this, width(), height());
66
67         QString s = "Zoom: " + QString::number(100 - int(zoom*100/99.0)) + "%";
68         QPainter p(this);
69         p.setPen(QPen(QColor(0,0,0),1));
70         p.drawText(5, height()-5, s);
71
72 }
73
74
75 void
76 PlanGraphDisplay::draw(QPaintDevice *surface, int width, int height)
77 {
78         QPainter p(buffer);
79         p.translate((width/2) + z(cx), (height/2) + z(cy));
80         buffer->fill(this, rect().topLeft());
81
82         node_set.clear();
83         draw_recursive(p, root);
84        
85         // copy buffer to screen
86         p.end();
87         p.begin(surface);
88         p.drawPixmap(rect().topLeft(), *buffer);
89 }
90
91
92 void
93 AuthorGraphDisplay::draw(QPaintDevice *surface, int width, int height)
94 {
95         QPainter p(buffer);
96         p.translate((width/2) + z(cx), (height/2) + z(cy));
97         buffer->fill(this, rect().topLeft());
98
99         if (author->viewing == STORY_VIEW)                      draw_recursive(p, story_root);
100         else if (author->viewing == KEYFRAME_VIEW)      draw_recursive(p, author->current_story->frame);
101         else printf("Error: View type %d is unknown...\n", author->viewing);
102        
103         // copy buffer to screen
104         p.end();
105         p.begin(surface);
106         p.drawPixmap(rect().topLeft(), *buffer);
107 }
108
109
110 void
111 PlanGraphDisplay::draw_recursive(QPainter &p, PlanNode *n)
112 {
113         if (!n) return;
114         node_set.insert(n);
115        
116         // First draw lines to unvisited parents and children, then drawn them
117         std::vector<PlanNode *>::iterator It;
118         for (It = n->branches.begin(); It != n->branches.end(); It++)
119                 if (*It && (node_set.find(*It) == node_set.end()))
120                 {
121                         p.setPen(QPen(QColor(0,0,0),2));
122                         p.drawLine(z(n->icon->ul_x + (n->icon->width()/2)), z(n->icon->ul_y + (n->icon->height()/2)),
123                                            z((*It)->icon->ul_x + ((*It)->icon->width()/2)), z((*It)->icon->ul_y + ((*It)->icon->height()/2)));
124                         draw_recursive(p, *It);
125                 }
126
127         for (It = n->prevs.begin(); It != n->prevs.end(); It++)
128                 if (*It && (node_set.find(*It) == node_set.end()))
129                 {
130                         p.setPen(QPen(QColor(0,0,0),2));
131                         p.drawLine(z(n->icon->ul_x + (n->icon->width()/2)), z(n->icon->ul_y + (n->icon->height()/2)),
132                                            z((*It)->icon->ul_x + ((*It)->icon->width()/2)), z((*It)->icon->ul_y + ((*It)->icon->height()/2)));
133                         draw_recursive(p, *It);
134                 }
135
136         // Node Image
137         QImage img;
138         img = n->icon->getIcon()->convertToImage();
139         img = img.smoothScale(z(img.width()), z(img.height()));
140         p.drawImage(z(n->icon->ul_x), z(n->icon->ul_y), img);
141 }
142
143
144 void
145 AuthorGraphDisplay::draw_recursive(QPainter &p, AuthorNode *n)
146 {
147         if (!n) return;
148
149         // First draw connecting lines, then children, then node
150         if (n->type == NODE_STORY)
151         {
152                 StoryNode *nt = (StoryNode *)n;
153                 std::vector<StoryNode*>::iterator It;
154                 for (It = nt->next.begin(); It != nt->next.end(); It++)
155                         if (*It)
156                         {
157                                 p.setPen(QPen(QColor(0,0,0),2));
158                                 p.drawLine(z(n->icon->ul_x + (n->icon->width()/2)), z(n->icon->ul_y + (n->icon->height()/2)),
159                                                    z((*It)->icon->ul_x + ((*It)->icon->width()/2)), z((*It)->icon->ul_y + ((*It)->icon->height()/2)));
160                                 draw_recursive(p, *It);
161                         }
162         }
163         else    // NODE_KEYFRAME
164         {
165                 KeyFrameNode *nt = (KeyFrameNode *)n;
166                 std::vector<KeyFrameNode*>::iterator It;
167                 for (It = nt->preconds.begin(); It != nt->preconds.end(); It++)
168                         if (*It)
169                         {
170                                 p.setPen(QPen(QColor(0,0,0),2));
171                                 p.drawLine(z(n->icon->ul_x + (n->icon->width()/2)), z(n->icon->ul_y + (n->icon->height()/2)),
172                                                    z((*It)->icon->ul_x + ((*It)->icon->width()/2)), z((*It)->icon->ul_y + ((*It)->icon->height()/2)));
173                                 draw_recursive(p, *It);
174                         }
175         }
176
177         // Node Image
178         QImage img;
179         img = n->icon->getIcon()->convertToImage();
180         img = img.smoothScale(z(img.width()), z(img.height()));
181         p.drawImage(z(n->icon->ul_x), z(n->icon->ul_y), img);
182 }
183
184
185 void
186 GraphDisplay::setZoom(int zoom)
187 {
188         if (this->zoom == zoom) return;
189
190         if (zoom < 0) {this->zoom = 0;}
191         else if (zoom > 99) {this->zoom = 99;}
192         else this->zoom = zoom;
193         factor = 1.0-(((1.0-FACTOR_MIN)*zoom)/99.0);
194         repaint();
195         emit zoomChanged(zoom);
196 }
197
198
199 void
200 GraphDisplay::resizeEvent(QResizeEvent *re)
201 {
202         QWidget::resizeEvent(re);
203         delete buffer;
204         buffer = new QPixmap(re->size());
205         repaint();
206 }
207
208
209 QSizePolicy 
210 GraphDisplay::sizePolicy() const
211 {
212         return QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
213 }
214
215
216 void 
217 GraphDisplay::repaint(int x, int y, int w, int h, bool clear)
218 {
219         if (!suppress_repaint) QWidget::repaint(x,y,w,h,false);
220 }
221
222
223 void
224 GraphDisplay::repaint() {if (!suppress_repaint) QWidget::repaint(false);}
225
226
227 void
228 GraphDisplay::center() {cx = cy = 0; repaint();}
229
230
231 void
232 GraphDisplay::fit() 
233 {
234         int z = zoom;
235         fit(width(), height());
236         if (zoom != z) emit zoomChanged(zoom);
237         repaint();
238 }
239
240
241 void
242 GraphDisplay::fit(int width, int height)
243 {
244         boundingBox();
245         int xspan = maxx - minx;
246         int yspan = maxy - miny;
247
248         cx = -1*(maxx + minx)/2;
249         cy = -1*(maxy + miny)/2;
250
251         factor = __min(width/float(xspan), height/float(yspan));
252         if (factor > 1.0) factor = 1.0;
253         if (factor < FACTOR_MIN) factor = FACTOR_MIN;
254
255         int zoom_t = int(-99.0*(factor-1.0)/(1.0-FACTOR_MIN));
256         zoom = zoom_t;
257 }
258
259
260 void
261 AuthorGraphDisplay::mouseMoveEvent(QMouseEvent *me)
262 {
263         if (moving_icon) {
264                 int px = oldx + dez(me->x() - clickx);
265                 int py = oldy + dez(me->y() - clicky);
266                 int p2x = moving->ul_x;
267                 int p2y = moving->ul_y;
268
269                 moving->ul_x = px;
270                 moving->ul_y = py;     
271                 moving->modified = true;
272                 boundingBox();
273                 repaint();
274         }
275         else if (moving_pane) {
276                 cx = oldcx + dez(me->x() - clickx);
277                 cy = oldcy + dez(me->y() - clicky);
278                 repaint();
279         }
280 }
281
282
283 void
284 AuthorGraphDisplay::mousePressEvent(QMouseEvent *me)
285 {
286         clickx = me->x();
287         clicky = me->y();       
288         moving_icon = false;
289         moving_pane = false;
290
291         if (me->button() == RightButton) {
292                 // see if an icon is being dragged
293                 moving = intersect(tx(clickx), ty(clicky));
294                 if (moving != NULL) {
295                         moving_icon = true;
296                         oldx = moving->ul_x;
297                         oldy = moving->ul_y;
298                         setCursor(pointingHandCursor);
299                 }
300         }
301         else if (me->button() == LeftButton) {
302                 GraphIcon* i = intersect(tx(clickx), ty(clicky));
303                 if (i != NULL)
304                         author->changeSelected(i->parent);
305                 else {
306                         moving_pane = true;
307                         oldcx = cx;
308                         oldcy = cy;
309                         setCursor(sizeAllCursor);
310                 }
311         }
312         else setCursor(forbiddenCursor);
313 }
314
315
316 void 
317 AuthorGraphDisplay::mouseDoubleClickEvent(QMouseEvent *me)
318 {
319         clickx = me->x();
320         clicky = me->y();
321
322         // Go to keyframe view!
323         if (me->button() == LeftButton) {
324                 GraphIcon* i = intersect(tx(clickx), ty(clicky));
325                 if (i != NULL && author->viewing == STORY_VIEW)
326                         author->keyframeView((StoryNode*)i->parent);
327         }
328 }
329
330
331 void
332 AuthorGraphDisplay::mouseReleaseEvent(QMouseEvent *me)
333 {
334         setCursor(arrowCursor);
335         moving = NULL;
336         moving_icon = false;
337         moving_pane = false;
338 }
339
340
341 GraphIcon*
342 AuthorGraphDisplay::intersect(int x, int y)
343 {
344         if (author->viewing == STORY_VIEW)
345         {
346                 StoryNode *n;
347                 list<StoryNode*> queue;
348                 queue.push_back(story_root);
349                
350                 std::vector<StoryNode*>::iterator It;
351                 while (!queue.empty()) {
352                         n = queue.front(); queue.pop_front();
353                
354                         if (n) {
355                                 if (x >= n->icon->ul_x && x <= (n->icon->ul_x + n->icon->width()))
356                                         if (y >= n->icon->ul_y && y <= (n->icon->ul_y + n->icon->height()))
357                                                 return n->icon;
358
359                                 for (It = n->next.begin(); It != n->next.end(); It++)
360                                         queue.push_back(*It);
361                         }
362                 }
363         }
364         else
365         {
366                 KeyFrameNode *n;
367                 list<KeyFrameNode*> queue;
368                 queue.push_back(author->current_story->frame);
369
370                 std::vector<KeyFrameNode*>::iterator It;
371                 while (!queue.empty()) {
372                         n = queue.front(); queue.pop_front();
373                
374                         if (n) {
375                                 if (x >= n->icon->ul_x && x <= (n->icon->ul_x + n->icon->width()))
376                                         if (y >= n->icon->ul_y && y <= (n->icon->ul_y + n->icon->height()))
377                                                 return n->icon;
378
379                                 for (It = n->preconds.begin(); It != n->preconds.end(); It++)
380                                         queue.push_back(*It);
381                         }
382                 }
383         }
384
385         return NULL;
386 }
387
388
389 void
390 PlanGraphDisplay::boundingBox()
391 {
392         maxx = maxy = -1e16 + 1;
393         minx = miny = 1e16 - 1;
394
395         PlanNode *n;
396         std::vector<PlanNode *>::iterator It;
397         set<PlanNode *> visited;
398         list<PlanNode *> queue;
399         queue.push_back(root);
400
401         while (!queue.empty())
402         {
403                 n = queue.front(); queue.pop_front();
404                
405                 if (n && visited.find(n) == visited.end())
406                 {
407                         visited.insert(n);
408                        
409                         if ((n->icon->ul_x + n->icon->width()) > maxx)
410                                 maxx = n->icon->ul_x + n->icon->width();
411                         if (n->icon->ul_x < minx) minx = n->icon->ul_x;
412                         if ((n->icon->ul_y + n->icon->height()) > maxy)
413                                 maxy = n->icon->ul_y + n->icon->height();
414                         if (n->icon->ul_y < miny) miny = n->icon->ul_y;
415
416                         // Parents and children
417                         for (It = n->branches.begin(); It != n->branches.end(); It++)
418                                 queue.push_back(*It);
419                         for (It = n->prevs.begin(); It != n->prevs.end(); It++)
420                                 queue.push_back(*It);
421                 }
422         }
423
424         maxx += dez(10);
425         maxy += dez(10);
426         minx -= dez(10);
427         miny -= dez(10);
428 }
429
430
431 void
432 AuthorGraphDisplay::boundingBox()
433 {
434         maxx = maxy = -1e16 + 1;
435         minx = miny = 1e16 - 1;
436
437         if (author->viewing == STORY_VIEW)
438         {
439                 StoryNode *n;
440                 list<StoryNode*> queue;
441                 queue.push_back(story_root);
442                
443                 std::vector<StoryNode*>::iterator It;
444                 while (!queue.empty()) {
445                         n = queue.front(); queue.pop_front();
446                
447                         if (n) {
448                                 if ((n->icon->ul_x + n->icon->width()) > maxx)
449                                         maxx = n->icon->ul_x + n->icon->width();
450                                 if (n->icon->ul_x < minx) minx = n->icon->ul_x;
451                                 if ((n->icon->ul_y + n->icon->height()) > maxy)
452                                         maxy = n->icon->ul_y + n->icon->height();
453                                 if (n->icon->ul_y < miny) miny = n->icon->ul_y;
454        
455                                 for (It = n->next.begin(); It != n->next.end(); It++)
456                                         queue.push_back(*It);
457                         }
458                 }
459         }
460         else
461         {
462                 KeyFrameNode *n;
463                 list<KeyFrameNode*> queue;
464                 queue.push_back(author->current_story->frame);
465
466                 std::vector<KeyFrameNode*>::iterator It;
467                 while (!queue.empty()) {
468                         n = queue.front(); queue.pop_front();
469                
470                         if (n) {
471                                 if ((n->icon->ul_x + n->icon->width()) > maxx)
472                                         maxx = n->icon->ul_x + n->icon->width();
473                                 if (n->icon->ul_x < minx) minx = n->icon->ul_x;
474                                 if ((n->icon->ul_y + n->icon->height()) > maxy)
475                                         maxy = n->icon->ul_y + n->icon->height();
476                                 if (n->icon->ul_y < miny) miny = n->icon->ul_y;
477
478                                 for (It = n->preconds.begin(); It != n->preconds.end(); It++)
479                                         queue.push_back(*It);
480                         }
481                 }
482
483         }
484
485         maxx += dez(10);
486         maxy += dez(10);
487         minx -= dez(10);
488         miny -= dez(10);
489 }
490
491
Note: See TracBrowser for help on using the browser.