1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 **
6 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 **
8 ** This file is part of a Qt Solutions component.
9 **
10 ** You may use this file under the terms of the BSD license as follows:
11 **
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
14 ** met:
15 **   * Redistributions of source code must retain the above copyright
16 **     notice, this list of conditions and the following disclaimer.
17 **   * Redistributions in binary form must reproduce the above copyright
18 **     notice, this list of conditions and the following disclaimer in
19 **     the documentation and/or other materials provided with the
20 **     distribution.
21 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 **     the names of its contributors may be used to endorse or promote
23 **     products derived from this software without specific prior written
24 **     permission.
25 **
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 **
38 ****************************************************************************/
39 
40 #include "mainwindow.h"
41 #include "qtpropertymanager.h"
42 #include "qteditorfactory.h"
43 #include "qttreepropertybrowser.h"
44 #include <QMatrix>
45 #include <QMouseEvent>
46 #include <QMenuBar>
47 #include <QMenu>
48 #include <QAction>
49 #include <QDockWidget>
50 
contentsMousePressEvent(QMouseEvent * event)51 void CanvasView::contentsMousePressEvent(QMouseEvent* event)
52 {
53     handleMouseClickEvent(event);
54 }
55 
contentsMouseDoubleClickEvent(QMouseEvent * event)56 void CanvasView::contentsMouseDoubleClickEvent(QMouseEvent* event)
57 {
58     handleMouseClickEvent(event);
59 }
60 
handleMouseClickEvent(QMouseEvent * event)61 void CanvasView::handleMouseClickEvent(QMouseEvent* event)
62 {
63     QPoint p = inverseWorldMatrix().map(event->pos());
64     QtCanvasItemList l = canvas()->collisions(p);
65     moving = 0;
66     if (!l.isEmpty())
67         moving = l.first();
68     moving_start = p;
69     emit itemClicked(moving);
70 }
71 
contentsMouseMoveEvent(QMouseEvent * event)72 void CanvasView::contentsMouseMoveEvent(QMouseEvent* event)
73 {
74     if (moving) {
75 	QPoint p = inverseWorldMatrix().map(event->pos());
76 	moving->moveBy(p.x() - moving_start.x(), p.y() - moving_start.y());
77 	moving_start = p;
78 	canvas()->update();
79         emit itemMoved(moving);
80     }
81 }
82 
83 
MainWindow(QWidget * parent)84 MainWindow::MainWindow(QWidget *parent)
85     : QMainWindow(parent)
86 {
87     QMenu *editMenu = menuBar()->addMenu(tr("Edit"));
88     QMenu *newObjectMenu = editMenu->addMenu(tr("New Object"));
89 
90     QAction *newRectangleAction = new QAction(tr("Rectangle"), this);
91     connect(newRectangleAction, SIGNAL(triggered(bool)), this, SLOT(newRectangle()));
92     newObjectMenu->addAction(newRectangleAction);
93 
94     QAction *newLineAction = new QAction(tr("Line"), this);
95     connect(newLineAction, SIGNAL(triggered(bool)), this, SLOT(newLine()));
96     newObjectMenu->addAction(newLineAction);
97 
98     QAction *newEllipseAction = new QAction(tr("Ellipse"), this);
99     connect(newEllipseAction, SIGNAL(triggered(bool)), this, SLOT(newEllipse()));
100     newObjectMenu->addAction(newEllipseAction);
101 
102     QAction *newTextAction = new QAction(tr("Text"), this);
103     connect(newTextAction, SIGNAL(triggered(bool)), this, SLOT(newText()));
104     newObjectMenu->addAction(newTextAction);
105 
106     deleteAction = new QAction(tr("Delete Object"), this);
107     connect(deleteAction, SIGNAL(triggered(bool)), this, SLOT(deleteObject()));
108     editMenu->addAction(deleteAction);
109 
110     QAction *clearAction = new QAction(tr("Clear All"), this);
111     connect(clearAction, SIGNAL(triggered(bool)), this, SLOT(clearAll()));
112     editMenu->addAction(clearAction);
113 
114     QAction *fillAction = new QAction(tr("Fill View"), this);
115     connect(fillAction, SIGNAL(triggered(bool)), this, SLOT(fillView()));
116     editMenu->addAction(fillAction);
117 
118     doubleManager = new QtDoublePropertyManager(this);
119     stringManager = new QtStringPropertyManager(this);
120     colorManager = new QtColorPropertyManager(this);
121     fontManager = new QtFontPropertyManager(this);
122     pointManager = new QtPointPropertyManager(this);
123     sizeManager = new QtSizePropertyManager(this);
124 
125     connect(doubleManager, SIGNAL(valueChanged(QtProperty *, double)),
126                 this, SLOT(valueChanged(QtProperty *, double)));
127     connect(stringManager, SIGNAL(valueChanged(QtProperty *, const QString &)),
128                 this, SLOT(valueChanged(QtProperty *, const QString &)));
129     connect(colorManager, SIGNAL(valueChanged(QtProperty *, const QColor &)),
130                 this, SLOT(valueChanged(QtProperty *, const QColor &)));
131     connect(fontManager, SIGNAL(valueChanged(QtProperty *, const QFont &)),
132                 this, SLOT(valueChanged(QtProperty *, const QFont &)));
133     connect(pointManager, SIGNAL(valueChanged(QtProperty *, const QPoint &)),
134                 this, SLOT(valueChanged(QtProperty *, const QPoint &)));
135     connect(sizeManager, SIGNAL(valueChanged(QtProperty *, const QSize &)),
136                 this, SLOT(valueChanged(QtProperty *, const QSize &)));
137 
138     QtDoubleSpinBoxFactory *doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this);
139     QtCheckBoxFactory *checkBoxFactory = new QtCheckBoxFactory(this);
140     QtSpinBoxFactory *spinBoxFactory = new QtSpinBoxFactory(this);
141     QtLineEditFactory *lineEditFactory = new QtLineEditFactory(this);
142     QtEnumEditorFactory *comboBoxFactory = new QtEnumEditorFactory(this);
143 
144     canvas = new QtCanvas(800, 600);
145     canvasView = new CanvasView(canvas, this);
146     setCentralWidget(canvasView);
147 
148     QDockWidget *dock = new QDockWidget(this);
149     addDockWidget(Qt::RightDockWidgetArea, dock);
150 
151     propertyEditor = new QtTreePropertyBrowser(dock);
152     propertyEditor->setFactoryForManager(doubleManager, doubleSpinBoxFactory);
153     propertyEditor->setFactoryForManager(stringManager, lineEditFactory);
154     propertyEditor->setFactoryForManager(colorManager->subIntPropertyManager(), spinBoxFactory);
155     propertyEditor->setFactoryForManager(fontManager->subIntPropertyManager(), spinBoxFactory);
156     propertyEditor->setFactoryForManager(fontManager->subBoolPropertyManager(), checkBoxFactory);
157     propertyEditor->setFactoryForManager(fontManager->subEnumPropertyManager(), comboBoxFactory);
158     propertyEditor->setFactoryForManager(pointManager->subIntPropertyManager(), spinBoxFactory);
159     propertyEditor->setFactoryForManager(sizeManager->subIntPropertyManager(), spinBoxFactory);
160     dock->setWidget(propertyEditor);
161 
162     currentItem = 0;
163 
164     connect(canvasView, SIGNAL(itemClicked(QtCanvasItem *)),
165             this, SLOT(itemClicked(QtCanvasItem *)));
166     connect(canvasView, SIGNAL(itemMoved(QtCanvasItem *)),
167             this, SLOT(itemMoved(QtCanvasItem *)));
168 
169     fillView();
170     itemClicked(0);
171 }
172 
newRectangle()173 void MainWindow::newRectangle()
174 {
175     QtCanvasItem *item = addRectangle();
176     canvas->update();
177     itemClicked(item);
178 }
179 
newEllipse()180 void MainWindow::newEllipse()
181 {
182     QtCanvasItem *item = addEllipse();
183     canvas->update();
184     itemClicked(item);
185 }
186 
newLine()187 void MainWindow::newLine()
188 {
189     QtCanvasItem *item = addLine();
190     canvas->update();
191     itemClicked(item);
192 }
193 
newText()194 void MainWindow::newText()
195 {
196     QtCanvasItem *item = addText();
197     canvas->update();
198     itemClicked(item);
199 }
200 
deleteObject()201 void MainWindow::deleteObject()
202 {
203     if (!currentItem)
204         return;
205 
206     delete currentItem;
207     itemClicked(0);
208     canvas->update();
209 }
210 
clearAll()211 void MainWindow::clearAll()
212 {
213     QtCanvasItemList list = canvas->allItems();
214     qDeleteAll(list);
215     itemClicked(0);
216     canvas->update();
217 }
218 
fillView()219 void MainWindow::fillView()
220 {
221     for (int i = 0; i < 10; i++) {
222         addRectangle();
223         addEllipse();
224         addLine();
225         addText();
226     }
227     canvas->update();
228 }
229 
addRectangle()230 QtCanvasItem *MainWindow::addRectangle()
231 {
232     QtCanvasPolygonalItem *item = new QtCanvasRectangle(rand() % canvas->width(),
233                 rand() % canvas->height(), 50, 50, canvas);
234     int z = rand() % 256;
235     item->setBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8));
236     item->setPen(QPen(QColor(rand() % 32*8, rand() % 32*8, rand() % 32*8), 4));
237     item->setZ(z);
238     item->show();
239     return item;
240 }
241 
addEllipse()242 QtCanvasItem *MainWindow::addEllipse()
243 {
244     QtCanvasPolygonalItem *item = new QtCanvasEllipse(50, 50, canvas);
245     item->setBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8));
246     item->move(rand() % canvas->width(), rand() % canvas->height());
247     item->setZ(rand() % 256);
248     item->show();
249     return item;
250 }
251 
addLine()252 QtCanvasItem *MainWindow::addLine()
253 {
254     QtCanvasLine *item = new QtCanvasLine(canvas);
255     item->setPoints(0, 0, rand() % canvas->width() - canvas->width() / 2,
256                 rand() % canvas->height() - canvas->height() / 2);
257     item->move(rand() % canvas->width(), rand() % canvas->height());
258     item->setPen(QPen(QColor(rand() % 32*8, rand() % 32*8, rand() % 32*8), 6));
259     item->setZ(rand() % 256);
260     item->show();
261     return item;
262 }
263 
addText()264 QtCanvasItem *MainWindow::addText()
265 {
266     QtCanvasText *item = new QtCanvasText(canvas);
267     item->setText(tr("Text"));
268     item->setColor(QColor(rand() % 32*8, rand() % 32*8, rand() % 32*8));
269     item->move(rand() % canvas->width(), rand() % canvas->height());
270     item->setZ(rand() % 256);
271     item->show();
272     return item;
273 }
274 
itemMoved(QtCanvasItem * item)275 void MainWindow::itemMoved(QtCanvasItem *item)
276 {
277     if (item != currentItem)
278         return;
279 
280     doubleManager->setValue(idToProperty[QLatin1String("xpos")], item->x());
281     doubleManager->setValue(idToProperty[QLatin1String("ypos")], item->y());
282     doubleManager->setValue(idToProperty[QLatin1String("zpos")], item->z());
283 }
284 
updateExpandState()285 void MainWindow::updateExpandState()
286 {
287     QList<QtBrowserItem *> list = propertyEditor->topLevelItems();
288     QListIterator<QtBrowserItem *> it(list);
289     while (it.hasNext()) {
290         QtBrowserItem *item = it.next();
291         QtProperty *prop = item->property();
292         idToExpanded[propertyToId[prop]] = propertyEditor->isExpanded(item);
293     }
294 }
295 
itemClicked(QtCanvasItem * item)296 void MainWindow::itemClicked(QtCanvasItem *item)
297 {
298     updateExpandState();
299 
300     QMap<QtProperty *, QString>::ConstIterator itProp = propertyToId.constBegin();
301     while (itProp != propertyToId.constEnd()) {
302         delete itProp.key();
303         itProp++;
304     }
305     propertyToId.clear();
306     idToProperty.clear();
307 
308     currentItem = item;
309     if (!currentItem) {
310         deleteAction->setEnabled(false);
311         return;
312     }
313 
314     deleteAction->setEnabled(true);
315 
316     QtProperty *property;
317 
318     property = doubleManager->addProperty(tr("Position X"));
319     doubleManager->setRange(property, 0, canvas->width());
320     doubleManager->setValue(property, item->x());
321     addProperty(property, QLatin1String("xpos"));
322 
323     property = doubleManager->addProperty(tr("Position Y"));
324     doubleManager->setRange(property, 0, canvas->height());
325     doubleManager->setValue(property, item->y());
326     addProperty(property, QLatin1String("ypos"));
327 
328     property = doubleManager->addProperty(tr("Position Z"));
329     doubleManager->setRange(property, 0, 256);
330     doubleManager->setValue(property, item->z());
331     addProperty(property, QLatin1String("zpos"));
332 
333     if (item->rtti() == QtCanvasItem::Rtti_Rectangle) {
334         QtCanvasRectangle *i = (QtCanvasRectangle *)item;
335 
336         property = colorManager->addProperty(tr("Brush Color"));
337         colorManager->setValue(property, i->brush().color());
338         addProperty(property, QLatin1String("brush"));
339 
340         property = colorManager->addProperty(tr("Pen Color"));
341         colorManager->setValue(property, i->pen().color());
342         addProperty(property, QLatin1String("pen"));
343 
344         property = sizeManager->addProperty(tr("Size"));
345         sizeManager->setValue(property, i->size());
346         addProperty(property, QLatin1String("size"));
347     } else if (item->rtti() == QtCanvasItem::Rtti_Line) {
348         QtCanvasLine *i = (QtCanvasLine *)item;
349 
350         property = colorManager->addProperty(tr("Pen Color"));
351         colorManager->setValue(property, i->pen().color());
352         addProperty(property, QLatin1String("pen"));
353 
354         property = pointManager->addProperty(tr("Vector"));
355         pointManager->setValue(property, i->endPoint());
356         addProperty(property, QLatin1String("endpoint"));
357     } else if (item->rtti() == QtCanvasItem::Rtti_Ellipse) {
358         QtCanvasEllipse *i = (QtCanvasEllipse *)item;
359 
360         property = colorManager->addProperty(tr("Brush Color"));
361         colorManager->setValue(property, i->brush().color());
362         addProperty(property, QLatin1String("brush"));
363 
364         property = sizeManager->addProperty(tr("Size"));
365         sizeManager->setValue(property, QSize(i->width(), i->height()));
366         sizeManager->setRange(property, QSize(0, 0), QSize(1000, 1000));
367         addProperty(property, QLatin1String("size"));
368     } else if (item->rtti() == QtCanvasItem::Rtti_Text) {
369         QtCanvasText *i = (QtCanvasText *)item;
370 
371         property = colorManager->addProperty(tr("Color"));
372         colorManager->setValue(property, i->color());
373         addProperty(property, QLatin1String("color"));
374 
375         property = stringManager->addProperty(tr("Text"));
376         stringManager->setValue(property, i->text());
377         addProperty(property, QLatin1String("text"));
378 
379         property = fontManager->addProperty(tr("Font"));
380         fontManager->setValue(property, i->font());
381         addProperty(property, QLatin1String("font"));
382     }
383 }
384 
addProperty(QtProperty * property,const QString & id)385 void MainWindow::addProperty(QtProperty *property, const QString &id)
386 {
387     propertyToId[property] = id;
388     idToProperty[id] = property;
389     QtBrowserItem *item = propertyEditor->addProperty(property);
390     if (idToExpanded.contains(id))
391         propertyEditor->setExpanded(item, idToExpanded[id]);
392 }
393 
valueChanged(QtProperty * property,double value)394 void MainWindow::valueChanged(QtProperty *property, double value)
395 {
396     if (!propertyToId.contains(property))
397         return;
398 
399     if (!currentItem)
400         return;
401 
402     QString id = propertyToId[property];
403     if (id == QLatin1String("xpos")) {
404         currentItem->setX(value);
405     } else if (id == QLatin1String("ypos")) {
406         currentItem->setY(value);
407     } else if (id == QLatin1String("zpos")) {
408         currentItem->setZ(value);
409     }
410     canvas->update();
411 }
412 
valueChanged(QtProperty * property,const QString & value)413 void MainWindow::valueChanged(QtProperty *property, const QString &value)
414 {
415     if (!propertyToId.contains(property))
416         return;
417 
418     if (!currentItem)
419         return;
420 
421     QString id = propertyToId[property];
422     if (id == QLatin1String("text")) {
423         if (currentItem->rtti() == QtCanvasItem::Rtti_Text) {
424             QtCanvasText *i = (QtCanvasText *)currentItem;
425             i->setText(value);
426         }
427     }
428     canvas->update();
429 }
430 
valueChanged(QtProperty * property,const QColor & value)431 void MainWindow::valueChanged(QtProperty *property, const QColor &value)
432 {
433     if (!propertyToId.contains(property))
434         return;
435 
436     if (!currentItem)
437         return;
438 
439     QString id = propertyToId[property];
440     if (id == QLatin1String("color")) {
441         if (currentItem->rtti() == QtCanvasItem::Rtti_Text) {
442             QtCanvasText *i = (QtCanvasText *)currentItem;
443             i->setColor(value);
444         }
445     } else if (id == QLatin1String("brush")) {
446         if (currentItem->rtti() == QtCanvasItem::Rtti_Rectangle ||
447                 currentItem->rtti() == QtCanvasItem::Rtti_Ellipse) {
448             QtCanvasPolygonalItem *i = (QtCanvasPolygonalItem *)currentItem;
449             QBrush b = i->brush();
450             b.setColor(value);
451             i->setBrush(b);
452         }
453     } else if (id == QLatin1String("pen")) {
454         if (currentItem->rtti() == QtCanvasItem::Rtti_Rectangle ||
455                 currentItem->rtti() == QtCanvasItem::Rtti_Line) {
456             QtCanvasPolygonalItem *i = (QtCanvasPolygonalItem *)currentItem;
457             QPen p = i->pen();
458             p.setColor(value);
459             i->setPen(p);
460         }
461     }
462     canvas->update();
463 }
464 
valueChanged(QtProperty * property,const QFont & value)465 void MainWindow::valueChanged(QtProperty *property, const QFont &value)
466 {
467     if (!propertyToId.contains(property))
468         return;
469 
470     if (!currentItem)
471         return;
472 
473     QString id = propertyToId[property];
474     if (id == QLatin1String("font")) {
475         if (currentItem->rtti() == QtCanvasItem::Rtti_Text) {
476             QtCanvasText *i = (QtCanvasText *)currentItem;
477             i->setFont(value);
478         }
479     }
480     canvas->update();
481 }
482 
valueChanged(QtProperty * property,const QPoint & value)483 void MainWindow::valueChanged(QtProperty *property, const QPoint &value)
484 {
485     if (!propertyToId.contains(property))
486         return;
487 
488     if (!currentItem)
489         return;
490 
491     QString id = propertyToId[property];
492     if (currentItem->rtti() == QtCanvasItem::Rtti_Line) {
493         QtCanvasLine *i = (QtCanvasLine *)currentItem;
494         if (id == QLatin1String("endpoint")) {
495             i->setPoints(i->startPoint().x(), i->startPoint().y(), value.x(), value.y());
496         }
497     }
498     canvas->update();
499 }
500 
valueChanged(QtProperty * property,const QSize & value)501 void MainWindow::valueChanged(QtProperty *property, const QSize &value)
502 {
503     if (!propertyToId.contains(property))
504         return;
505 
506     if (!currentItem)
507         return;
508 
509     QString id = propertyToId[property];
510     if (id == QLatin1String("size")) {
511         if (currentItem->rtti() == QtCanvasItem::Rtti_Rectangle) {
512             QtCanvasRectangle *i = (QtCanvasRectangle *)currentItem;
513             i->setSize(value.width(), value.height());
514         } else if (currentItem->rtti() == QtCanvasItem::Rtti_Ellipse) {
515             QtCanvasEllipse *i = (QtCanvasEllipse *)currentItem;
516             i->setSize(value.width(), value.height());
517         }
518     }
519     canvas->update();
520 }
521 
522