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