/* * Copyright 2009 Ben Boeckel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ // Header include #include "ShapeItem.h" // KDE includes #include #include // Qt includes #include #include #include #include #include #include using namespace Sigmodr::Widgets; ShapeItem::ShapeItem(const Shape shape) : m_shape(shape), m_rect(0, 0, 32, 32), m_thickness(1), m_rotation(0), m_xShear(1), m_yShear(1) { if ((m_shape == PolyLine) || (m_shape == Polygon)) { m_points.append(QPointF(0, 0)); if (m_shape == Polygon) m_points.append(QPointF(0, 0)); } recreatePath(); setFlags(ItemIsMovable | ItemIsSelectable); setOpacity(.5); } ShapeItem::ShapeItem(const QPainterPath& path) : m_shape(Path), m_path(path), m_rect(0, 0, 32, 32), m_thickness(1), m_rotation(0), m_xShear(1), m_yShear(1) { restroke(); } ShapeItem::Shape ShapeItem::shapeType() const { return m_shape; } QWidget* ShapeItem::widget() { QString filename; switch (m_shape) { default: break; } QWidget *mainWidget = NULL; if (!filename.isEmpty()) { QFile mainFile(filename); mainFile.open(QFile::ReadOnly); mainWidget = QUiLoader().load(&mainFile, NULL); mainFile.close(); } QFile commonFile(":/gui/shapes/common.ui"); commonFile.open(QFile::ReadOnly); QWidget *commonWidget = QUiLoader().load(&commonFile, NULL); commonFile.close(); KDoubleNumInput* thickness = commonWidget->findChild("varThickness"); KDoubleNumInput* rotation = commonWidget->findChild("varRotation"); KDoubleNumInput* xShear = commonWidget->findChild("varXShear"); KDoubleNumInput* yShear = commonWidget->findChild("varYShear"); connect(thickness, SIGNAL(valueChanged(double)), this, SLOT(setThickness(double))); connect(rotation, SIGNAL(valueChanged(double)), this, SLOT(setRotation(double))); connect(xShear, SIGNAL(valueChanged(double)), this, SLOT(setXShear(double))); connect(yShear, SIGNAL(valueChanged(double)), this, SLOT(setYShear(double))); if (mainWidget) { QGridLayout* layout = commonWidget->findChild("mainLayout"); layout->addWidget(mainWidget, 0, 0); commonWidget->setTabOrder(yShear, mainWidget); } return commonWidget; } void ShapeItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(widget) if (option->state & QStyle::State_MouseOver) { painter->setPen(QPen(KStatefulBrush(KColorScheme::View, KColorScheme::HoverColor).brush(QPalette::Active), 3)); painter->drawRect(boundingRect()); } if (option->state & QStyle::State_Selected) { painter->setPen(QPen(KStatefulBrush(KColorScheme::Selection, KColorScheme::ActiveBackground).brush(QPalette::Active), 3)); painter->drawRect(boundingRect()); } painter->setPen(QPen()); painter->setBrush(QBrush(Qt::red)); painter->drawPath(m_strokePath); } QRectF ShapeItem::boundingRect() const { return m_boundingRect; } QPainterPath ShapeItem::shape() const { return m_strokePath; } void ShapeItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) { QGraphicsItem::contextMenuEvent(event); } void ShapeItem::focusInEvent(QFocusEvent* event) { QGraphicsItem::focusInEvent(event); } void ShapeItem::focusOutEvent(QFocusEvent* event) { QGraphicsItem::focusOutEvent(event); } void ShapeItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) { QGraphicsItem::hoverEnterEvent(event); } void ShapeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) { QGraphicsItem::hoverLeaveEvent(event); } void ShapeItem::mousePressEvent(QGraphicsSceneMouseEvent* event) { QGraphicsItem::mousePressEvent(event); } void ShapeItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { QGraphicsItem::mouseMoveEvent(event); } void ShapeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { QGraphicsItem::mouseReleaseEvent(event); } void ShapeItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) { QGraphicsItem::mouseDoubleClickEvent(event); } void ShapeItem::setPosition(const QPointF& position) { m_rect.moveTo(position); } void ShapeItem::setWidth(const int width) { m_rect.setWidth(width); recreatePath(); } void ShapeItem::setHeight(const int height) { m_rect.setHeight(height); recreatePath(); } void ShapeItem::addPoint() { if (m_shape == PolyLine) m_points.append(QPointF(0, 0)); else if (m_shape == Polygon) m_points.insert(m_points.size() - 1, QPointF(0, 0)); else return; } void ShapeItem::removePoint() { if (m_shape == PolyLine) m_points.remove(m_points.size() - 1); else if (m_shape == Polygon) m_points.remove(m_points.size() - 2); else return; recreatePath(); } void ShapeItem::setStartAngle(const double startAngle) { m_startAngle = startAngle; recreatePath(); } void ShapeItem::setSpanAngle(const double spanAngle) { m_spanAngle = spanAngle; recreatePath(); } void ShapeItem::setThickness(const double thickness) { m_thickness = thickness; restroke(); } void ShapeItem::setRotation(const double rotation) { m_rotation = rotation; restroke(); } void ShapeItem::setXShear(const double xShear) { m_xShear = xShear; restroke(); } void ShapeItem::setYShear(const double yShear) { m_yShear = yShear; restroke(); } void ShapeItem::recreatePath() { if (m_shape != Path) m_path = QPainterPath(); switch (m_shape) { case Path: break; case Rectangle: m_path.addRect(m_rect); break; case PolyLine: for (QVectorIterator i(m_points); i.hasNext(); i.next()) { if (i.hasPrevious()) m_path.lineTo(i.peekNext()); else m_path.moveTo(i.peekNext()); } break; case Polygon: m_path.addPolygon(QPolygonF(m_points)); break; case Ellipse: m_path.addEllipse(m_rect); break; case Arc: m_path.arcMoveTo(m_rect, m_startAngle); m_path.arcTo(m_rect, m_startAngle, m_spanAngle); break; case Chord: { m_path.arcMoveTo(m_rect, m_startAngle); QPointF pos = m_path.currentPosition(); m_path.arcTo(m_rect, m_startAngle, m_spanAngle); m_path.lineTo(pos); break; } case Pie: m_path.moveTo(m_rect.center()); m_path.arcTo(m_rect, m_startAngle, m_spanAngle); m_path.closeSubpath(); break; } restroke(); } void ShapeItem::restroke() { QPainterPathStroker stroke; stroke.setWidth(m_thickness); m_strokePath = stroke.createStroke(m_path * QMatrix(m_xShear, m_yShear, 1, 1, -m_rect.left(), -m_rect.top()).rotate(m_rotation)); m_boundingRect = m_strokePath.boundingRect().adjusted(-2, -2, 2, 2); update(); }