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 "qtvariantproperty.h"
42 #include "qttreepropertybrowser.h"
43 #include <QMatrix>
44 #include <QMouseEvent>
45 #include <QMenuBar>
46 #include <QMenu>
47 #include <QAction>
48 #include <QDockWidget>
49 
contentsMousePressEvent(QMouseEvent * event)50 void CanvasView::contentsMousePressEvent(QMouseEvent* event)
51 {
52     handleMouseClickEvent(event);
53 }
54 
contentsMouseDoubleClickEvent(QMouseEvent * event)55 void CanvasView::contentsMouseDoubleClickEvent(QMouseEvent* event)
56 {
57     handleMouseClickEvent(event);
58 }
59 
handleMouseClickEvent(QMouseEvent * event)60 void CanvasView::handleMouseClickEvent(QMouseEvent* event)
61 {
62     QPoint p = inverseWorldMatrix().map(event->pos());
63     QtCanvasItemList l = canvas()->collisions(p);
64     moving = 0;
65     if (!l.isEmpty())
66         moving = l.first();
67     moving_start = p;
68     emit itemClicked(moving);
69 }
70 
contentsMouseMoveEvent(QMouseEvent * event)71 void CanvasView::contentsMouseMoveEvent(QMouseEvent* event)
72 {
73     if (moving) {
74 	QPoint p = inverseWorldMatrix().map(event->pos());
75 	moving->moveBy(p.x() - moving_start.x(), p.y() - moving_start.y());
76 	moving_start = p;
77 	canvas()->update();
78         emit itemMoved(moving);
79     }
80 }
81 
82 
MainWindow(QWidget * parent)83 MainWindow::MainWindow(QWidget *parent)
84     : QMainWindow(parent)
85 {
86     QMenu *editMenu = menuBar()->addMenu(tr("Edit"));
87     QMenu *newObjectMenu = editMenu->addMenu(tr("New Object"));
88 
89     QAction *newRectangleAction = new QAction(tr("Rectangle"), this);
90     connect(newRectangleAction, SIGNAL(triggered(bool)), this, SLOT(newRectangle()));
91     newObjectMenu->addAction(newRectangleAction);
92 
93     QAction *newLineAction = new QAction(tr("Line"), this);
94     connect(newLineAction, SIGNAL(triggered(bool)), this, SLOT(newLine()));
95     newObjectMenu->addAction(newLineAction);
96 
97     QAction *newEllipseAction = new QAction(tr("Ellipse"), this);
98     connect(newEllipseAction, SIGNAL(triggered(bool)), this, SLOT(newEllipse()));
99     newObjectMenu->addAction(newEllipseAction);
100 
101     QAction *newTextAction = new QAction(tr("Text"), this);
102     connect(newTextAction, SIGNAL(triggered(bool)), this, SLOT(newText()));
103     newObjectMenu->addAction(newTextAction);
104 
105     deleteAction = new QAction(tr("Delete Object"), this);
106     connect(deleteAction, SIGNAL(triggered(bool)), this, SLOT(deleteObject()));
107     editMenu->addAction(deleteAction);
108 
109     QAction *clearAction = new QAction(tr("Clear All"), this);
110     connect(clearAction, SIGNAL(triggered(bool)), this, SLOT(clearAll()));
111     editMenu->addAction(clearAction);
112 
113     QAction *fillAction = new QAction(tr("Fill View"), this);
114     connect(fillAction, SIGNAL(triggered(bool)), this, SLOT(fillView()));
115     editMenu->addAction(fillAction);
116 
117     variantManager = new QtVariantPropertyManager(this);
118 
119     connect(variantManager, SIGNAL(valueChanged(QtProperty *, const QVariant &)),
120                 this, SLOT(valueChanged(QtProperty *, const QVariant &)));
121 
122     QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory(this);
123 
124     canvas = new QtCanvas(800, 600);
125     canvasView = new CanvasView(canvas, this);
126     setCentralWidget(canvasView);
127 
128     QDockWidget *dock = new QDockWidget(this);
129     addDockWidget(Qt::RightDockWidgetArea, dock);
130 
131     propertyEditor = new QtTreePropertyBrowser(dock);
132     propertyEditor->setFactoryForManager(variantManager, variantFactory);
133     dock->setWidget(propertyEditor);
134 
135     currentItem = 0;
136 
137     connect(canvasView, SIGNAL(itemClicked(QtCanvasItem *)),
138             this, SLOT(itemClicked(QtCanvasItem *)));
139     connect(canvasView, SIGNAL(itemMoved(QtCanvasItem *)),
140             this, SLOT(itemMoved(QtCanvasItem *)));
141 
142     fillView();
143     itemClicked(0);
144 }
145 
newRectangle()146 void MainWindow::newRectangle()
147 {
148     QtCanvasItem *item = addRectangle();
149     canvas->update();
150     itemClicked(item);
151 }
152 
newEllipse()153 void MainWindow::newEllipse()
154 {
155     QtCanvasItem *item = addEllipse();
156     canvas->update();
157     itemClicked(item);
158 }
159 
newLine()160 void MainWindow::newLine()
161 {
162     QtCanvasItem *item = addLine();
163     canvas->update();
164     itemClicked(item);
165 }
166 
newText()167 void MainWindow::newText()
168 {
169     QtCanvasItem *item = addText();
170     canvas->update();
171     itemClicked(item);
172 }
173 
deleteObject()174 void MainWindow::deleteObject()
175 {
176     if (!currentItem)
177         return;
178 
179     delete currentItem;
180     itemClicked(0);
181     canvas->update();
182 }
183 
clearAll()184 void MainWindow::clearAll()
185 {
186     QtCanvasItemList list = canvas->allItems();
187     qDeleteAll(list);
188     itemClicked(0);
189     canvas->update();
190 }
191 
fillView()192 void MainWindow::fillView()
193 {
194     for (int i = 0; i < 10; i++) {
195         addRectangle();
196         addEllipse();
197         addLine();
198         addText();
199     }
200     canvas->update();
201 }
202 
addRectangle()203 QtCanvasItem *MainWindow::addRectangle()
204 {
205     QtCanvasPolygonalItem *item = new QtCanvasRectangle(rand() % canvas->width(),
206                 rand() % canvas->height(), 50, 50, canvas);
207     int z = rand() % 256;
208     item->setBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8));
209     item->setPen(QPen(QColor(rand() % 32*8, rand() % 32*8, rand() % 32*8), 4));
210     item->setZ(z);
211     item->show();
212     return item;
213 }
214 
addEllipse()215 QtCanvasItem *MainWindow::addEllipse()
216 {
217     QtCanvasPolygonalItem *item = new QtCanvasEllipse(50, 50, canvas);
218     item->setBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8));
219     item->move(rand() % canvas->width(), rand() % canvas->height());
220     item->setZ(rand() % 256);
221     item->show();
222     return item;
223 }
224 
addLine()225 QtCanvasItem *MainWindow::addLine()
226 {
227     QtCanvasLine *item = new QtCanvasLine(canvas);
228     item->setPoints(0, 0, rand() % canvas->width() - canvas->width() / 2,
229                 rand() % canvas->height() - canvas->height() / 2);
230     item->move(rand() % canvas->width(), rand() % canvas->height());
231     item->setPen(QPen(QColor(rand() % 32*8, rand() % 32*8, rand() % 32*8), 6));
232     item->setZ(rand() % 256);
233     item->show();
234     return item;
235 }
236 
addText()237 QtCanvasItem *MainWindow::addText()
238 {
239     QtCanvasText *item = new QtCanvasText(canvas);
240     item->setText(tr("Text"));
241     item->setColor(QColor(rand() % 32*8, rand() % 32*8, rand() % 32*8));
242     item->move(rand() % canvas->width(), rand() % canvas->height());
243     item->setZ(rand() % 256);
244     item->show();
245     return item;
246 }
247 
itemMoved(QtCanvasItem * item)248 void MainWindow::itemMoved(QtCanvasItem *item)
249 {
250     if (item != currentItem)
251         return;
252 
253     variantManager->setValue(idToProperty[QLatin1String("xpos")], item->x());
254     variantManager->setValue(idToProperty[QLatin1String("ypos")], item->y());
255     variantManager->setValue(idToProperty[QLatin1String("zpos")], item->z());
256 }
257 
updateExpandState()258 void MainWindow::updateExpandState()
259 {
260     QList<QtBrowserItem *> list = propertyEditor->topLevelItems();
261     QListIterator<QtBrowserItem *> it(list);
262     while (it.hasNext()) {
263         QtBrowserItem *item = it.next();
264         QtProperty *prop = item->property();
265         idToExpanded[propertyToId[prop]] = propertyEditor->isExpanded(item);
266     }
267 }
268 
itemClicked(QtCanvasItem * item)269 void MainWindow::itemClicked(QtCanvasItem *item)
270 {
271     updateExpandState();
272 
273     QMap<QtProperty *, QString>::ConstIterator itProp = propertyToId.constBegin();
274     while (itProp != propertyToId.constEnd()) {
275         delete itProp.key();
276         itProp++;
277     }
278     propertyToId.clear();
279     idToProperty.clear();
280 
281     currentItem = item;
282     if (!currentItem) {
283         deleteAction->setEnabled(false);
284         return;
285     }
286 
287     deleteAction->setEnabled(true);
288 
289     QtVariantProperty *property;
290 
291     property = variantManager->addProperty(QVariant::Double, tr("Position X"));
292     property->setAttribute(QLatin1String("minimum"), 0);
293     property->setAttribute(QLatin1String("maximum"), canvas->width());
294     property->setValue(item->x());
295     addProperty(property, QLatin1String("xpos"));
296 
297     property = variantManager->addProperty(QVariant::Double, tr("Position Y"));
298     property->setAttribute(QLatin1String("minimum"), 0);
299     property->setAttribute(QLatin1String("maximum"), canvas->height());
300     property->setValue(item->y());
301     addProperty(property, QLatin1String("ypos"));
302 
303     property = variantManager->addProperty(QVariant::Double, tr("Position Z"));
304     property->setAttribute(QLatin1String("minimum"), 0);
305     property->setAttribute(QLatin1String("maximum"), 256);
306     property->setValue(item->z());
307     addProperty(property, QLatin1String("zpos"));
308 
309     if (item->rtti() == QtCanvasItem::Rtti_Rectangle) {
310         QtCanvasRectangle *i = (QtCanvasRectangle *)item;
311 
312         property = variantManager->addProperty(QVariant::Color, tr("Brush Color"));
313         property->setValue(i->brush().color());
314         addProperty(property, QLatin1String("brush"));
315 
316         property = variantManager->addProperty(QVariant::Color, tr("Pen Color"));
317         property->setValue(i->pen().color());
318         addProperty(property, QLatin1String("pen"));
319 
320         property = variantManager->addProperty(QVariant::Size, tr("Size"));
321         property->setValue(i->size());
322         addProperty(property, QLatin1String("size"));
323     } else if (item->rtti() == QtCanvasItem::Rtti_Line) {
324         QtCanvasLine *i = (QtCanvasLine *)item;
325 
326         property = variantManager->addProperty(QVariant::Color, tr("Pen Color"));
327         property->setValue(i->pen().color());
328         addProperty(property, QLatin1String("pen"));
329 
330         property = variantManager->addProperty(QVariant::Point, tr("Vector"));
331         property->setValue(i->endPoint());
332         addProperty(property, QLatin1String("endpoint"));
333     } else if (item->rtti() == QtCanvasItem::Rtti_Ellipse) {
334         QtCanvasEllipse *i = (QtCanvasEllipse *)item;
335 
336         property = variantManager->addProperty(QVariant::Color, tr("Brush Color"));
337         property->setValue(i->brush().color());
338         addProperty(property, QLatin1String("brush"));
339 
340         property = variantManager->addProperty(QVariant::Size, tr("Size"));
341         property->setValue(QSize(i->width(), i->height()));
342         addProperty(property, QLatin1String("size"));
343     } else if (item->rtti() == QtCanvasItem::Rtti_Text) {
344         QtCanvasText *i = (QtCanvasText *)item;
345 
346         property = variantManager->addProperty(QVariant::Color, tr("Color"));
347         property->setValue(i->color());
348         addProperty(property, QLatin1String("color"));
349 
350         property = variantManager->addProperty(QVariant::String, tr("Text"));
351         property->setValue(i->text());
352         addProperty(property, QLatin1String("text"));
353 
354         property = variantManager->addProperty(QVariant::Font, tr("Font"));
355         property->setValue(i->font());
356         addProperty(property, QLatin1String("font"));
357     }
358 }
359 
addProperty(QtVariantProperty * property,const QString & id)360 void MainWindow::addProperty(QtVariantProperty *property, const QString &id)
361 {
362     propertyToId[property] = id;
363     idToProperty[id] = property;
364     QtBrowserItem *item = propertyEditor->addProperty(property);
365     if (idToExpanded.contains(id))
366         propertyEditor->setExpanded(item, idToExpanded[id]);
367 }
368 
valueChanged(QtProperty * property,const QVariant & value)369 void MainWindow::valueChanged(QtProperty *property, const QVariant &value)
370 {
371     if (!propertyToId.contains(property))
372         return;
373 
374     if (!currentItem)
375         return;
376 
377     QString id = propertyToId[property];
378     if (id == QLatin1String("xpos")) {
379         currentItem->setX(value.toDouble());
380     } else if (id == QLatin1String("ypos")) {
381         currentItem->setY(value.toDouble());
382     } else if (id == QLatin1String("zpos")) {
383         currentItem->setZ(value.toDouble());
384     } else if (id == QLatin1String("text")) {
385         if (currentItem->rtti() == QtCanvasItem::Rtti_Text) {
386             QtCanvasText *i = (QtCanvasText *)currentItem;
387             i->setText(value.value<QString>());
388         }
389     } else if (id == QLatin1String("color")) {
390         if (currentItem->rtti() == QtCanvasItem::Rtti_Text) {
391             QtCanvasText *i = (QtCanvasText *)currentItem;
392             i->setColor(value.value<QColor>());
393         }
394     } else if (id == QLatin1String("brush")) {
395         if (currentItem->rtti() == QtCanvasItem::Rtti_Rectangle ||
396                 currentItem->rtti() == QtCanvasItem::Rtti_Ellipse) {
397             QtCanvasPolygonalItem *i = (QtCanvasPolygonalItem *)currentItem;
398             QBrush b = i->brush();
399             b.setColor(value.value<QColor>());
400             i->setBrush(b);
401         }
402     } else if (id == QLatin1String("pen")) {
403         if (currentItem->rtti() == QtCanvasItem::Rtti_Rectangle ||
404                 currentItem->rtti() == QtCanvasItem::Rtti_Line) {
405             QtCanvasPolygonalItem *i = (QtCanvasPolygonalItem *)currentItem;
406             QPen p = i->pen();
407             p.setColor(value.value<QColor>());
408             i->setPen(p);
409         }
410     } else if (id == QLatin1String("font")) {
411         if (currentItem->rtti() == QtCanvasItem::Rtti_Text) {
412             QtCanvasText *i = (QtCanvasText *)currentItem;
413             i->setFont(value.value<QFont>());
414         }
415     } else if (id == QLatin1String("endpoint")) {
416         if (currentItem->rtti() == QtCanvasItem::Rtti_Line) {
417             QtCanvasLine *i = (QtCanvasLine *)currentItem;
418             QPoint p = value.value<QPoint>();
419             i->setPoints(i->startPoint().x(), i->startPoint().y(), p.x(), p.y());
420         }
421     } else if (id == QLatin1String("size")) {
422         if (currentItem->rtti() == QtCanvasItem::Rtti_Rectangle) {
423             QtCanvasRectangle *i = (QtCanvasRectangle *)currentItem;
424             QSize s = value.value<QSize>();
425             i->setSize(s.width(), s.height());
426         } else if (currentItem->rtti() == QtCanvasItem::Rtti_Ellipse) {
427             QtCanvasEllipse *i = (QtCanvasEllipse *)currentItem;
428             QSize s = value.value<QSize>();
429             i->setSize(s.width(), s.height());
430         }
431     }
432     canvas->update();
433 }
434 
435