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