summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/QtUI/Whiteboard/GView.cpp')
-rw-r--r--Swift/QtUI/Whiteboard/GView.cpp499
1 files changed, 499 insertions, 0 deletions
diff --git a/Swift/QtUI/Whiteboard/GView.cpp b/Swift/QtUI/Whiteboard/GView.cpp
new file mode 100644
index 0000000..d725cbb
--- /dev/null
+++ b/Swift/QtUI/Whiteboard/GView.cpp
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2012 Mateusz Piękos
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "GView.h"
+#include <QtSwiftUtil.h>
+
+namespace Swift {
+ GView::GView(QGraphicsScene* scene, QWidget* parent) : QGraphicsView(scene, parent), brush(QColor(Qt::white)), defaultBrush(QColor(Qt::white)) {
+ selectionRect = 0;
+ lastItem = 0;
+ zValue = 0;
+ }
+
+ void GView::setLineWidth(int i) {
+ pen.setWidth(i);
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
+ lastItemChanged(item, items_.indexOf(item)+1, Update);
+ } else {
+ defaultPen.setWidth(i);
+ }
+ }
+
+ void GView::setLineColor(QColor color) {
+ pen.setColor(color);
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
+ lastItemChanged(item, items_.indexOf(item)+1, Update);
+ } else {
+ defaultPen.setColor(color);
+ }
+ lineColorChanged(color);
+ }
+
+ QColor GView::getLineColor() {
+ return pen.color();
+ }
+
+ void GView::setBrushColor(QColor color) {
+ brush.setColor(color);
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
+ lastItemChanged(item, items_.indexOf(item)+1, Update);
+ } else {
+ defaultBrush.setColor(color);
+ }
+ brushColorChanged(color);
+ }
+
+ QColor GView::getBrushColor() {
+ return brush.color();
+ }
+
+ void GView::setMode(Mode mode) {
+ this->mode = mode;
+ lastItem = 0;
+ deselect();
+ }
+
+ void GView::addItem(QGraphicsItem* item, QString id, int pos) {
+ itemsMap_.insert(id, item);
+ if (pos > items_.size()) {
+ item->setZValue(zValue++);
+ scene()->addItem(item);
+ items_.append(item);
+ } else {
+ QGraphicsItem* temp = items_.at(pos-1);
+ item->setZValue(temp->zValue());
+ scene()->addItem(item);
+ item->stackBefore(temp);
+ items_.insert(pos-1, item);
+ }
+ }
+
+ void GView::clear() {
+ scene()->clear();
+ items_.clear();
+ itemsMap_.clear();
+ lastItem = 0;
+ selectionRect = 0;
+ brush = QBrush(QColor(Qt::white));
+ defaultBrush = QBrush(QColor(Qt::white));
+ pen = QPen();
+ pen.setWidth(1);
+ defaultPen = pen;
+ lineWidthChanged(1);
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+
+ QGraphicsItem* GView::getItem(QString id) {
+ return itemsMap_.value(id);
+ }
+
+ void GView::deleteItem(QString id) {
+ deselect(id);
+ QGraphicsItem* item = itemsMap_.value(id);
+ items_.removeOne(item);
+ itemsMap_.remove(id);
+ scene()->removeItem(item);
+ delete item;
+ }
+
+ QString GView::getNewID() {
+ return P2QSTRING(idGenerator.generateID());
+ }
+
+ void GView::mouseMoveEvent(QMouseEvent* event)
+ {
+ if (!mousePressed) {
+ return;
+ }
+
+ if (mode == Line) {
+ QGraphicsLineItem* item = qgraphicsitem_cast<QGraphicsLineItem*>(lastItem);
+ if(item != 0) {
+ QLineF line = item->line();
+ line.setP1(this->mapToScene(event->pos()));
+ item->setLine(line);
+
+ }
+ }
+ else if (mode == Rect) {
+ QGraphicsRectItem* item = qgraphicsitem_cast<QGraphicsRectItem*>(lastItem);
+ if (item != 0) {
+ QPointF beginPoint = item->data(0).toPointF();
+ QPointF newPoint = this->mapToScene(event->pos());
+ QRectF rect = item->rect();
+ if (beginPoint.x() <= newPoint.x() && beginPoint.y() <= newPoint.y()) {
+ rect.setTopLeft(beginPoint);
+ rect.setBottomRight(newPoint);
+ }
+ else if (beginPoint.x() > newPoint.x() && beginPoint.y() <= newPoint.y()) {
+ rect.setTopRight(beginPoint);
+ rect.setBottomLeft(newPoint);
+ }
+ else if (beginPoint.x() <= newPoint.x() && beginPoint.y() > newPoint.y()) {
+ rect.setBottomLeft(beginPoint);
+ rect.setTopRight(newPoint);
+ }
+ else if (beginPoint.x() > newPoint.x() && beginPoint.y() > newPoint.y()) {
+ rect.setBottomRight(beginPoint);
+ rect.setTopLeft(newPoint);
+ }
+ item->setRect(rect);
+ }
+ }
+ else if (mode == Circle) {
+ QGraphicsEllipseItem* item = qgraphicsitem_cast<QGraphicsEllipseItem*>(lastItem);
+ QPainterPath path;
+ QPointF beginPoint = item->data(0).toPointF();
+ QPointF newPoint = this->mapToScene(event->pos());
+ QRectF rect = item->rect();
+ if (beginPoint.x() <= newPoint.x() && beginPoint.y() <= newPoint.y()) {
+ rect.setTopLeft(beginPoint);
+ rect.setBottomRight(newPoint);
+ }
+ else if (beginPoint.x() > newPoint.x() && beginPoint.y() <= newPoint.y()) {
+ rect.setTopRight(beginPoint);
+ rect.setBottomLeft(newPoint);
+ }
+ else if (beginPoint.x() <= newPoint.x() && beginPoint.y() > newPoint.y()) {
+ rect.setBottomLeft(beginPoint);
+ rect.setTopRight(newPoint);
+ }
+ else if (beginPoint.x() > newPoint.x() && beginPoint.y() > newPoint.y()) {
+ rect.setBottomRight(beginPoint);
+ rect.setTopLeft(newPoint);
+ }
+
+ item->setRect(rect);
+ }
+ else if (mode == HandLine) {
+ FreehandLineItem* item = qgraphicsitem_cast<FreehandLineItem*>(lastItem);
+ if (item != 0) {
+ QPointF newPoint = this->mapToScene(event->pos());
+ item->lineTo(newPoint);
+ }
+ }
+ else if (mode == Polygon) {
+ QGraphicsPolygonItem* item = qgraphicsitem_cast<QGraphicsPolygonItem*>(lastItem);
+ QPointF newPoint = this->mapToScene(event->pos());
+ QPolygonF polygon = item->polygon();
+ polygon.erase(polygon.end()-1);
+ polygon.append(newPoint);
+ item->setPolygon(polygon);
+ }
+ else if (mode == Select) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ if (item != 0) {
+ QPainterPath path;
+ QPointF beginPoint = selectionRect->data(0).toPointF();
+ QPointF newPoint = this->mapToScene(event->pos());
+ item->setPos(beginPoint + newPoint);
+ selectionRect->setPos(beginPoint + newPoint);
+ }
+ }
+ }
+
+ void GView::mousePressEvent(QMouseEvent *event)
+ {
+ mousePressed = true;
+ deselect();
+ if (mode == Line) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsItem* item = scene()->addLine(point.x(), point.y(), point.x(), point.y(), pen);
+ QString id = getNewID();
+ item->setZValue(10000000);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ lastItem = item;
+ }
+ else if (mode == Rect) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsRectItem* item = scene()->addRect(point.x(), point.y(), 0, 0, pen, brush);
+ QString id = getNewID();
+ item->setZValue(10000000);
+ item->setData(0, point);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ lastItem = item;
+ }
+ else if (mode == Rubber) {
+ QPointF point = this->mapToScene(event->pos());
+ int w = pen.width();
+ QRectF rect(point.x()-w, point.y()-w, w*2, w*2);
+ QList<QGraphicsItem*> list = scene()->items(rect);
+ if (!list.isEmpty())
+ {
+ QGraphicsItem* item = scene()->items(rect).first();
+ QString id = item->data(100).toString();
+ int pos = items_.indexOf(item)+1;
+ itemDeleted(id, pos);
+ deleteItem(id);
+ }
+ }
+ else if (mode == Circle) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsEllipseItem* item = scene()->addEllipse(point.x(), point.y(), 0, 0, pen, brush);
+ QString id = getNewID();
+ item->setZValue(10000000);
+ item->setData(0, point);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ lastItem = item;
+ }
+ else if (mode == HandLine) {
+ QPointF point = this->mapToScene(event->pos());
+ FreehandLineItem* item = new FreehandLineItem;
+ QString id = getNewID();
+ item->setPen(pen);
+ item->setStartPoint(point);
+ item->setZValue(10000000);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ scene()->addItem(item);
+ lastItem = item;
+ }
+ else if (mode == Text) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsTextItem* item = scene()->addText("");
+ QString id = getNewID();
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ item->setDefaultTextColor(pen.color());
+ textDialog = new TextDialog(item, this);
+ connect(textDialog, SIGNAL(accepted(QGraphicsTextItem*)), this, SLOT(handleTextItemModified(QGraphicsTextItem*)));
+ textDialog->setAttribute(Qt::WA_DeleteOnClose);
+ textDialog->show();
+ item->setPos(point);
+ lastItem = item;
+ }
+ else if (mode == Polygon) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsPolygonItem* item = dynamic_cast<QGraphicsPolygonItem*>(lastItem);
+ if (item == 0) {
+ QPolygonF polygon;
+ polygon.append(point);
+ polygon.append(point);
+ item = scene()->addPolygon(polygon, pen, brush);
+ QString id = getNewID();
+ item->setZValue(10000000);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ lastItem = item;
+ }
+ else {
+ QPolygonF polygon;
+ polygon = item->polygon();
+ polygon.append(point);
+ item->setPolygon(polygon);
+ }
+ }
+ else if (mode == Select) {
+ QPointF point = this->mapToScene(event->pos());
+ int w = pen.width();
+ if (w == 0) {
+ w = 1;
+ }
+ QRectF rect(point.x()-w, point.y()-w, w*2, w*2);
+ QList<QGraphicsItem*> list = scene()->items(rect);
+ if (!list.isEmpty()) {
+ QPen pen;
+ pen.setColor(QColor(Qt::gray));
+ pen.setStyle(Qt::DashLine);
+ QGraphicsItem *item = scene()->items(rect).first();
+ selectionRect = scene()->addRect(item->boundingRect(), pen);
+ selectionRect->setZValue(1000000);
+ selectionRect->setData(0, item->pos()-point);
+ selectionRect->setPos(item->pos());
+ QVariant var(QVariant::UserType);
+ var.setValue(item);
+ selectionRect->setData(1, var);
+ setActualPenAndBrushFromItem(item);
+ }
+ }
+ }
+
+ void GView::mouseReleaseEvent(QMouseEvent* /*event*/)
+ {
+ mousePressed = false;
+ QGraphicsPolygonItem* polygon = dynamic_cast<QGraphicsPolygonItem*>(lastItem);
+ if (polygon && polygon->polygon().size() >= 3) {
+ lastItemChanged(polygon, items_.indexOf(polygon)+1, Update);
+ } else if (lastItem) {
+ zValue++;
+ lastItem->setZValue(zValue++);
+ items_.append(lastItem);
+ itemsMap_.insert(lastItem->data(100).toString(), lastItem);
+
+ lastItemChanged(lastItem, items_.size(), New);
+ } else if (selectionRect){
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ lastItemChanged(item, items_.indexOf(item)+1, Update);
+ }
+ }
+
+
+ void GView::handleTextItemModified(QGraphicsTextItem* item) {
+ lastItemChanged(item, item->data(101).toInt(), Update);
+ }
+
+ void GView::moveUpSelectedItem()
+ {
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ int pos = items_.indexOf(item);
+ if (pos < items_.size()-1) {
+ lastItemChanged(item, pos+1, MoveUp);
+ move(item, pos+2);
+ }
+ }
+ }
+
+ void GView::moveDownSelectedItem()
+ {
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ int pos = items_.indexOf(item);
+ if (pos > 0) {
+ lastItemChanged(item, pos+1, MoveDown);
+ move(item, pos);
+ }
+ }
+ }
+
+ void GView::move(QGraphicsItem* item, int npos) {
+ int pos = items_.indexOf(item);
+ QGraphicsItem* itemAfter = NULL;
+ if (npos-1 > pos) {
+ if (npos == items_.size()) {
+ item->setZValue(zValue++);
+ } else {
+ itemAfter = items_.at(npos);
+ }
+
+ items_.insert(npos, item);
+ items_.removeAt(pos);
+ } else if (npos-1 < pos) {
+ itemAfter = items_.at(npos-1);
+ items_.insert(npos-1, item);
+ items_.removeAt(pos+1);
+ }
+ if (itemAfter) {
+ item->setZValue(itemAfter->zValue());
+ item->stackBefore(itemAfter);
+ }
+ }
+
+ void GView::changePenAndBrush(QGraphicsItem* item, QPen pen, QBrush brush) {
+ QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
+ if (lineItem) {
+ lineItem->setPen(pen);
+ }
+
+ FreehandLineItem* handLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
+ if (handLineItem) {
+ handLineItem->setPen(pen);
+ }
+
+ QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
+ if (rectItem) {
+ rectItem->setPen(pen);
+ rectItem->setBrush(brush);
+ }
+
+ QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
+ if (textItem) {
+ textItem->setDefaultTextColor(pen.color());
+ }
+
+ QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
+ if (polygonItem) {
+ polygonItem->setPen(pen);
+ polygonItem->setBrush(brush);
+ }
+
+ QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
+ if (ellipseItem) {
+ ellipseItem->setPen(pen);
+ ellipseItem->setBrush(brush);
+ }
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+
+ void GView::setActualPenAndBrushFromItem(QGraphicsItem* item) {
+ QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
+ if (lineItem) {
+ pen = lineItem->pen();
+ }
+
+ FreehandLineItem* handLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
+ if (handLineItem) {
+ pen = handLineItem->pen();
+ }
+
+ QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
+ if (rectItem) {
+ pen = rectItem->pen();
+ brush = rectItem->brush();
+ }
+
+ QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
+ if (textItem) {
+ pen.setColor(textItem->defaultTextColor());
+ }
+
+ QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
+ if (polygonItem) {
+ pen = polygonItem->pen();
+ brush = polygonItem->brush();
+ }
+
+ QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
+ if (ellipseItem) {
+ pen = ellipseItem->pen();
+ brush = ellipseItem->brush();
+ }
+ lineWidthChanged(pen.width());
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+
+ void GView::deselect() {
+ if (selectionRect != 0) {
+ pen = defaultPen;
+ brush = defaultBrush;
+ scene()->removeItem(selectionRect);
+ delete selectionRect;
+ selectionRect = 0;
+ lineWidthChanged(pen.width());
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+ }
+
+ void GView::deselect(QString id) {
+ if (selectionRect != 0) {
+ QGraphicsItem* item = getItem(id);
+ if (item && selectionRect->data(1).value<QGraphicsItem*>() == item) {
+ pen = defaultPen;
+ brush = defaultBrush;
+ scene()->removeItem(selectionRect);
+ delete selectionRect;
+ selectionRect = 0;
+ lineWidthChanged(pen.width());
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+ }
+ }
+}