diff options
Diffstat (limited to 'Swift/QtUI/Whiteboard/GView.cpp')
-rw-r--r-- | Swift/QtUI/Whiteboard/GView.cpp | 499 |
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()); + } + } + } +} |