From 9b96ed58ebd012554ab746594385225df8adff1e Mon Sep 17 00:00:00 2001 From: thomas_lucky13 Date: Mon, 16 Oct 2023 14:40:18 +0400 Subject: [PATCH] UBCompassTool upgrade Added new functionality to the compass. 1. Position and size normalization parameters. These parameters allow to align the position and size of the compass to the gridSize. Parameters are only enabled when the pageBackground is crossed. 2. Right angle rotation. This functionality allowsu to turn the compass counterclockwise to the nearest degree multiple 90 (0, 90, 180, 270). 3. Rotation of the compass by a given angle. You can rotate the compass by a given number of degrees absolutely or relative to the current rotation of the compass. At the same time, you can draw (this is optional). --- resources/OpenBoard.qrc | 3 + resources/i18n/OpenBoard_ru.ts | 34 ++ resources/images/angleRotateCompass.svg | 65 ++++ resources/images/rightAngleCompass.svg | 56 ++++ resources/images/settingsCompass.svg | 137 ++++++++ src/core/UBSettings.cpp | 1 + src/core/UBSettings.h | 1 + src/domain/UBGraphicsItemUndoCommand.cpp | 7 + src/domain/UBGraphicsScene.cpp | 5 + src/domain/UBGraphicsScene.h | 2 + src/tools/UBGraphicsCompass.cpp | 401 ++++++++++++++++++++++- src/tools/UBGraphicsCompass.h | 52 +++ 12 files changed, 761 insertions(+), 3 deletions(-) create mode 100644 resources/images/angleRotateCompass.svg create mode 100644 resources/images/rightAngleCompass.svg create mode 100644 resources/images/settingsCompass.svg diff --git a/resources/OpenBoard.qrc b/resources/OpenBoard.qrc index 03032e226..0b2ce1449 100644 --- a/resources/OpenBoard.qrc +++ b/resources/OpenBoard.qrc @@ -50,6 +50,9 @@ images/reload.svg images/frozen.svg images/unfrozen.svg + images/settingsCompass.svg + images/rightAngleCompass.svg + images/angleRotateCompass.svg images/toolbar/group.png images/toolbar/ungroup.png images/toolbar/window.png diff --git a/resources/i18n/OpenBoard_ru.ts b/resources/i18n/OpenBoard_ru.ts index 23bb78dce..a5de21c2b 100644 --- a/resources/i18n/OpenBoard_ru.ts +++ b/resources/i18n/OpenBoard_ru.ts @@ -1229,6 +1229,29 @@ Do you wish to override the security check and continue ? Закрыть + + UBCompassAngleRotateDialog + + Compass angle rotation + Задать угол поворота циркуля + + + Angle: + Угол: + + + With drawing + Прочертить + + + Rotate absolutely + Повернуть абсолютно + + + Rotate relative + Повернуть относительно + + UBDesktopPalette @@ -1896,6 +1919,17 @@ Providing a new name will create a new document. Загрузка + + UBGraphicsCompass + + Normalize position + Прилипание к сетке + + + Normalize size + Размер по сетке + + UBGraphicsGroupContainerItemDelegate diff --git a/resources/images/angleRotateCompass.svg b/resources/images/angleRotateCompass.svg new file mode 100644 index 000000000..1ab777a90 --- /dev/null +++ b/resources/images/angleRotateCompass.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + diff --git a/resources/images/rightAngleCompass.svg b/resources/images/rightAngleCompass.svg new file mode 100644 index 000000000..1eeb6783f --- /dev/null +++ b/resources/images/rightAngleCompass.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + diff --git a/resources/images/settingsCompass.svg b/resources/images/settingsCompass.svg new file mode 100644 index 000000000..6502e0b7d --- /dev/null +++ b/resources/images/settingsCompass.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/core/UBSettings.cpp b/src/core/UBSettings.cpp index 74962bb41..abfdb8454 100644 --- a/src/core/UBSettings.cpp +++ b/src/core/UBSettings.cpp @@ -839,6 +839,7 @@ void UBSettings::setPageBackground(UBPageBackground background) val = "plain"; setValue("Board/PageBackground", val); + emit(pageBackgroundChanged()); } void UBSettings::setSeyesRuledBackground(bool isSeyesRuledBackground) diff --git a/src/core/UBSettings.h b/src/core/UBSettings.h index e46948e94..46075d5b5 100644 --- a/src/core/UBSettings.h +++ b/src/core/UBSettings.h @@ -463,6 +463,7 @@ class UBSettings : public QObject signals: void colorContextChanged(); + void pageBackgroundChanged(); private: diff --git a/src/domain/UBGraphicsItemUndoCommand.cpp b/src/domain/UBGraphicsItemUndoCommand.cpp index 9c2af6048..529dda68d 100644 --- a/src/domain/UBGraphicsItemUndoCommand.cpp +++ b/src/domain/UBGraphicsItemUndoCommand.cpp @@ -103,6 +103,11 @@ void UBGraphicsItemUndoCommand::undo() bool bApplyTransform = false; UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast(item); if (polygonItem){ + if (!polygonItem->strokesGroup()) + { + polygonItem->setStrokesGroup(new UBGraphicsStrokesGroup()); + polygonItem->strokesGroup()->addToGroup(polygonItem); + } if (polygonItem->strokesGroup() && polygonItem->strokesGroup()->parentItem() && UBGraphicsGroupContainerItem::Type == polygonItem->strokesGroup()->parentItem()->type()) @@ -276,6 +281,8 @@ void UBGraphicsItemUndoCommand::redo() { mScene->removeItem(polygonItem); mScene->removeItemFromDeletion(polygonItem); + if (!polygonItem->strokesGroup()) + polygonItem->setStrokesGroup(new UBGraphicsStrokesGroup()); polygonItem->strokesGroup()->addToGroup(polygonItem); } } diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index c9ddb3619..d5caf5ca5 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -2404,6 +2404,11 @@ void UBGraphicsScene::controlViewportChanged() } } +void UBGraphicsScene::setPreviousPoint(QPointF _point) +{ + mPreviousPoint = _point; +} + void UBGraphicsScene::addCompass(QPointF center) { UBGraphicsCompass* compass = new UBGraphicsCompass(); // mem : owned and destroyed by the scene diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 48281418d..e90c7f94f 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -394,6 +394,8 @@ public slots: void controlViewportChanged(); + void setPreviousPoint(QPointF _point); + protected: UBGraphicsPolygonItem* lineToPolygonItem(const QLineF& pLine, const qreal& pWidth); diff --git a/src/tools/UBGraphicsCompass.cpp b/src/tools/UBGraphicsCompass.cpp index 8725acfec..7d691865a 100644 --- a/src/tools/UBGraphicsCompass.cpp +++ b/src/tools/UBGraphicsCompass.cpp @@ -25,6 +25,7 @@ */ +#include #include "tools/UBGraphicsCompass.h" @@ -33,9 +34,11 @@ #include "core/UBSettings.h" #include "gui/UBResources.h" #include "domain/UBGraphicsScene.h" +#include "core/UBSettings.h" #include "board/UBBoardController.h" // TODO UB 4.x clean that dependency #include "board/UBDrawingController.h" // TODO UB 4.x clean that dependency +#include "board/UBBoardView.h" // TODO UB 4.x clean that dependency #include "core/memcheck.h" @@ -49,7 +52,7 @@ const QColor UBGraphicsCompass::sDarkBackgroundDrawColor = QColor(0xff, 0xff, 0x const int UBGraphicsCompass::sMinRadius = UBGraphicsCompass::sNeedleLength + UBGraphicsCompass::sNeedleBaseLength + 24 + UBGraphicsCompass::sDefaultRect.height() + 24 + UBGraphicsCompass::sPencilBaseLength - + UBGraphicsCompass::sPencilLength; + + UBGraphicsCompass::sPencilLength + 48 + 48; UBGraphicsCompass::UBGraphicsCompass() : QGraphicsRectItem() @@ -61,8 +64,12 @@ UBGraphicsCompass::UBGraphicsCompass() , mDrewCircle(false) , mCloseSvgItem(0) , mResizeSvgItem(0) + , mSettingsSvgItem(0) + , mRihtAngleSvgItem(0) + , mAngleRotateSvgItem(0) , mAntiScaleRatio(1.0) , mDrewCenterCross(false) + , mSettingsMenu(0) { setRect(sDefaultRect); @@ -80,6 +87,21 @@ UBGraphicsCompass::UBGraphicsCompass() mResizeSvgItem->setVisible(false); mResizeSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); + mSettingsSvgItem = new QGraphicsSvgItem(":/images/settingsCompass.svg", this); + mSettingsSvgItem->setVisible(false); + mSettingsSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); + + mRihtAngleSvgItem = new QGraphicsSvgItem(":/images/rightAngleCompass.svg", this); + mRihtAngleSvgItem->setVisible(false); + mRihtAngleSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); + + mAngleRotateSvgItem = new QGraphicsSvgItem(":/images/angleRotateCompass.svg", this); + mAngleRotateSvgItem->setVisible(false); + mAngleRotateSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); + + mAngleRotateDialog = new UBCompassAngleRotateDialog(this); + mAngleRotateDialog->setWindowFlags(Qt::Tool); + updateResizeCursor(); updateDrawCursor(); @@ -90,6 +112,10 @@ UBGraphicsCompass::UBGraphicsCompass() connect(UBApplication::boardController, SIGNAL(penColorChanged()), this, SLOT(penColorChanged())); connect(UBDrawingController::drawingController(), SIGNAL(lineWidthIndexChanged(int)), this, SLOT(lineWidthChanged())); + connect(UBSettings::settings(), SIGNAL(pageBackgroundChanged()), this, SLOT(setMenuActions())); + + mNormalizePos = false; + mNormalizeSize = false; } UBGraphicsCompass::~UBGraphicsCompass() @@ -141,6 +167,21 @@ void UBGraphicsCompass::paint(QPainter *painter, const QStyleOptionGraphicsItem resizeButtonRect().center().x() - mResizeSvgItem->boundingRect().width() * mAntiScaleRatio / 2, resizeButtonRect().center().y() - mResizeSvgItem->boundingRect().height() * mAntiScaleRatio / 2); + mSettingsSvgItem->setTransform(antiScaleTransform); + mSettingsSvgItem->setPos( + settingsButtonRect().center().x() - mSettingsSvgItem->boundingRect().width() * mAntiScaleRatio / 2, + settingsButtonRect().center().y() - mSettingsSvgItem->boundingRect().height() * mAntiScaleRatio / 2); + + mRihtAngleSvgItem->setTransform(antiScaleTransform); + mRihtAngleSvgItem->setPos( + rightAngleButtonRect().center().x() - mRihtAngleSvgItem->boundingRect().width() * mAntiScaleRatio / 2, + rightAngleButtonRect().center().y() - mRihtAngleSvgItem->boundingRect().height() * mAntiScaleRatio /2); + + mAngleRotateSvgItem->setTransform(antiScaleTransform); + mAngleRotateSvgItem->setPos( + angleRotateButtonRect().center().x() - mAngleRotateSvgItem->boundingRect().width() * mAntiScaleRatio /2, + angleRotateButtonRect().center().y() - mAngleRotateSvgItem->boundingRect().height() * mAntiScaleRatio /2); + painter->setPen(drawColor()); painter->drawRoundedRect(hingeRect(), sCornerRadius, sCornerRadius); painter->fillPath(hingeShape(), middleFillColor()); @@ -190,6 +231,9 @@ QVariant UBGraphicsCompass::itemChange(GraphicsItemChange change, const QVariant { mCloseSvgItem->setParentItem(this); mResizeSvgItem->setParentItem(this); + mSettingsSvgItem->setParent(this); + mRihtAngleSvgItem->setParent(this); + mAngleRotateSvgItem->setParent(this); } return QGraphicsRectItem::itemChange(change, value); @@ -201,6 +245,9 @@ void UBGraphicsCompass::mousePressEvent(QGraphicsSceneMouseEvent *event) UBDrawingController::drawingController ()->stylusTool() != UBStylusTool::Play) return; + bool setting = false; + bool rightAngle = false; + bool angleRotate = false; bool closing = false; if (resizeButtonRect().contains(event->pos())) @@ -217,6 +264,19 @@ void UBGraphicsCompass::mousePressEvent(QGraphicsSceneMouseEvent *event) event->accept(); qDebug() << "hinge"; } + else if (settingsButtonRect().contains(event->pos())) + { + setting = true; + } + else if (rightAngleButtonRect().contains(event->pos())) + { + rightAngle = true; + } + else if (angleRotateButtonRect().contains((event->pos()))) + { + mBeforeRotatePosition = QLineF(needlePosition(), pencilPosition()); + angleRotate = true; + } else if (!closeButtonRect().contains(event->pos())) { qDebug() << "the rest"; @@ -237,6 +297,9 @@ void UBGraphicsCompass::mousePressEvent(QGraphicsSceneMouseEvent *event) mResizeSvgItem->setVisible(mShowButtons && mResizing); mCloseSvgItem->setVisible(mShowButtons && closing); + mSettingsSvgItem->setVisible(mShowButtons && setting); + mRihtAngleSvgItem->setVisible(mShowButtons && rightAngle); + mAngleRotateSvgItem->setVisible(mShowButtons && angleRotate); } void UBGraphicsCompass::mouseMoveEvent(QGraphicsSceneMouseEvent *event) @@ -290,8 +353,16 @@ void UBGraphicsCompass::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) UBDrawingController::drawingController ()->stylusTool() != UBStylusTool::Play) return; + + if (!mResizing && !mRotating && !mDrawing && mNormalizePos && (UBSettings::settings()->pageBackground()==UBPageBackground::crossed)) + { + normalizePos(); + event->accept(); + } if (mResizing) { + if (mNormalizeSize && (UBSettings::settings()->pageBackground()==UBPageBackground::crossed)) + normalizeSize(); event->accept(); } else if (mRotating) @@ -312,6 +383,30 @@ void UBGraphicsCompass::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) hide(); event->accept(); } + else if (settingsButtonRect().contains(event->pos())) + { + showSettings(); + event->accept(); + } + else if (rightAngleButtonRect().contains(event->pos())) + { + qreal rotateAngle = angleInDegrees(); + if (angleInDegrees() < 270) + { + int neededAngle = 90; + while (angleInDegrees() >= neededAngle) + neededAngle += 90; + rotateAngle -= neededAngle; + } + rotateAroundNeedle(rotateAngle); + event->accept(); + } + else if (angleRotateButtonRect().contains(event->pos())) + { + mAngleRotateDialog->clearData(); + mAngleRotateDialog->show(); + event->accept(); + } else { QGraphicsRectItem::mouseReleaseEvent(event); @@ -336,6 +431,10 @@ void UBGraphicsCompass::hoverEnterEvent(QGraphicsSceneHoverEvent *event) mCloseSvgItem->setParentItem(this); mResizeSvgItem->setParentItem(this); + mSettingsSvgItem->setParent(this); + mRihtAngleSvgItem->setParent(this); + mAngleRotateSvgItem->setParent(this); + mCloseSvgItem->setVisible(mShowButtons); if (mShowButtons) @@ -346,7 +445,10 @@ void UBGraphicsCompass::hoverEnterEvent(QGraphicsSceneHoverEvent *event) setCursor(drawCursor()); else if (resizeButtonRect().contains(event->pos())) setCursor(resizeCursor()); - else if (closeButtonRect().contains(event->pos())) + else if (closeButtonRect().contains(event->pos()) + || settingsButtonRect().contains(event->pos()) + || rightAngleButtonRect().contains(event->pos()) + || angleRotateButtonRect().contains(event->pos())) setCursor(closeCursor()); else setCursor(moveCursor()); @@ -364,6 +466,9 @@ void UBGraphicsCompass::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) mShowButtons = false; mCloseSvgItem->setVisible(mShowButtons); mResizeSvgItem->setVisible(mShowButtons); + mSettingsSvgItem->setVisible(mShowButtons); + mRihtAngleSvgItem->setVisible(mShowButtons); + mAngleRotateSvgItem->setVisible(mShowButtons); unsetCursor(); event->accept(); update(); @@ -378,6 +483,9 @@ void UBGraphicsCompass::hoverMoveEvent(QGraphicsSceneHoverEvent *event) mShowButtons = shape().contains(event->pos()); mCloseSvgItem->setVisible(mShowButtons); mResizeSvgItem->setVisible(mShowButtons); + mSettingsSvgItem->setVisible(mShowButtons); + mRihtAngleSvgItem->setVisible(mShowButtons); + mAngleRotateSvgItem->setVisible(mShowButtons); if (mShowButtons) { if (hingeRect().contains(event->pos())) @@ -386,7 +494,10 @@ void UBGraphicsCompass::hoverMoveEvent(QGraphicsSceneHoverEvent *event) setCursor(drawCursor()); else if (resizeButtonRect().contains(event->pos())) setCursor(resizeCursor()); - else if (closeButtonRect().contains(event->pos())) + else if (closeButtonRect().contains(event->pos()) + || settingsButtonRect().contains(event->pos()) + || rightAngleButtonRect().contains(event->pos()) + || angleRotateButtonRect().contains(event->pos())) setCursor(closeCursor()); else setCursor(moveCursor()); @@ -529,6 +640,60 @@ QRectF UBGraphicsCompass::resizeButtonRect() const return resizeRect; } +QRectF UBGraphicsCompass::settingsButtonRect() const +{ + QPixmap settingsPixmap(":/images/settingsCompass.svg"); + + QSizeF settingsRectSize( + settingsPixmap.width() * mAntiScaleRatio, + settingsPixmap.height() * mAntiScaleRatio); + + QPointF settingsRectTopLeft( + rect().width()/2 - hingeRect().width()/2 - settingsRectSize.width() - 2, + (rect().height() - settingsRectSize.height()) / 2); + + QRectF settingsRect(settingsRectTopLeft, settingsRectSize); + settingsRect.translate(rect().topLeft()); + + return settingsRect; +} + +QRectF UBGraphicsCompass::rightAngleButtonRect() const +{ + QPixmap rightAnglePixmap(":/images/rightAngleCompass.svg"); + + QSizeF rightAngleRectSize( + rightAnglePixmap.width() * mAntiScaleRatio, + rightAnglePixmap.height() * mAntiScaleRatio); + + QPointF rightAngleRectTopLeft( + rect().width()/2 - hingeRect().width()/2 - rightAngleRectSize.width() - settingsButtonRect().width() - 6, + (rect().height() - rightAngleRectSize.height()) / 2); + + QRectF rightAngleRect(rightAngleRectTopLeft, rightAngleRectSize); + rightAngleRect.translate(rect().topLeft()); + + return rightAngleRect; +} + +QRectF UBGraphicsCompass::angleRotateButtonRect() const +{ + QPixmap angleRotatePixmap(":/images/angleRotateCompass.svg"); + + QSizeF angleRotateRectSize( + angleRotatePixmap.width() * mAntiScaleRatio, + angleRotatePixmap.height() * mAntiScaleRatio); + + QPointF angleRotateRectTopLeft( + rect().width()/2 + hingeRect().width()/2 + angleRotateRectSize.width()/2, + (rect().height() - angleRotateRectSize.height()) / 2); + + QRectF angleRotateRect(angleRotateRectTopLeft, angleRotateRectSize); + angleRotateRect.translate(rect().topLeft()); + + return angleRotateRect; +} + void UBGraphicsCompass::rotateAroundNeedle(qreal angle) { QTransform transform; @@ -590,6 +755,61 @@ void UBGraphicsCompass::paintCenterCross() UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line); } +void UBGraphicsCompass::showSettings() +{ + if (!mSettingsMenu) + { + mSettingsMenu = new QMenu(UBApplication::boardController->controlView()); + decorateSettingsMenu(mSettingsMenu); + } + + UBBoardView* cv = UBApplication::boardController->controlView(); + QRect pinPos = cv->mapFromScene(mSettingsSvgItem->sceneBoundingRect()).boundingRect(); + + mSettingsMenu->exec(cv->mapToGlobal(pinPos.bottomRight())); +} + +void UBGraphicsCompass::decorateSettingsMenu(QMenu* menu) +{ + mNormalizePosAction = menu->addAction(tr("Normalize position"), this, SLOT(setNormalizePos(bool))); + mNormalizePosAction->setCheckable(true); + mNormalizePosAction->setChecked(mNormalizePos); + + mNormalizeSizeAction = menu->addAction(tr("Normalize size"), this, SLOT(setNormalizeSize(bool))); + mNormalizeSizeAction->setCheckable(true); + mNormalizeSizeAction->setChecked(mNormalizeSize); + setMenuActions(); +} + +void UBGraphicsCompass::angleRotateDialogResult() +{ + if (mAngleRotateDialog->isAbsolutely()) + rotateAroundNeedle(angleInDegrees()); + scene()->setPreviousPoint(mapToScene(pencilPosition())); + + qreal rotateAngle = -mAngleRotateDialog->Angle(); + qreal drawingAngle = rotateAngle; + if (!mAngleRotateDialog->isAbsolutely()) + drawingAngle -= angleInDegrees(); + + mSceneArcStartPoint = mapToScene(pencilPosition()); + rotateAroundNeedle(rotateAngle); + + if (mAngleRotateDialog->isDrawing()) + { + mSpanAngleInDegrees = rotateAngle; + if (mSpanAngleInDegrees >= 1080) + mSpanAngleInDegrees -= 360; + else if (mSpanAngleInDegrees < -1080) + mSpanAngleInDegrees += 360; + drawArc(); + } + updateResizeCursor(); + updateDrawCursor(); + scene()->inputDeviceRelease(); + scene()->moveTo(mSceneArcStartPoint); +} + QPointF UBGraphicsCompass::needlePosition() const { return QPointF(rect().x(), rect().y() + rect().height() / 2); @@ -804,3 +1024,178 @@ void UBGraphicsCompass::lineWidthChanged() QRect pencilRect(rect().right() - sPencilLength, rect().top(), sPencilLength, rect().height()); update(pencilRect); } + +void UBGraphicsCompass::setNormalizePos(bool isNormalize) +{ + mNormalizePos = isNormalize; + if (isNormalize) + normalizePos(); +} +void UBGraphicsCompass::setNormalizeSize(bool isNormalize) +{ + mNormalizeSize = isNormalize; + if (isNormalize) + normalizeSize(); +} + +void UBGraphicsCompass::setMenuActions() +{ + mNormalizePosAction->setEnabled(UBSettings::settings()->pageBackground()==UBPageBackground::crossed); + mNormalizeSizeAction->setEnabled(UBSettings::settings()->pageBackground()==UBPageBackground::crossed); +} + +void UBGraphicsCompass::normalizePos() +{ + QPointF newPos = nearPointFromGrid(mapToScene(needlePosition())); + qreal curAngle = angleInDegrees(); + if (curAngle!=0) + rotateAroundNeedle(curAngle); + setRect(newPos.x(), newPos.y() - rect().height() / 2, rect().width(), rect().height()); + setPos(0,0); + if (curAngle !=0) + rotateAroundNeedle(-curAngle); +} + +void UBGraphicsCompass::normalizeSize() +{ + int gridSize = UBSettings::settings()->crossSize; + int divGrid = rect().width()/gridSize; + if ((rect().toRect().width()%gridSize)>(gridSize/2)) + ++divGrid; + setRect(QRectF(rect().topLeft(), QSizeF(gridSize*divGrid,rect().height()))); +} + +QPointF UBGraphicsCompass::nearPointFromGrid(QPointF point) +{ + QPointF result = point; + QList gridPoints; + int sceneHeight = UBApplication::boardController->activeScene()->sceneSize().height(), + sceneWidth = UBApplication::boardController->activeScene()->sceneSize().width(), + gridSize = UBSettings::settings()->crossSize; + for (int i = 0; i >= sceneWidth/-2; i -= gridSize) + { + for (int j = 0; j >= sceneHeight/-2; j -=gridSize) + gridPoints.push_back(QPointF(i,j)); + for (int j = 0; j <= sceneHeight/2; j +=gridSize) + gridPoints.push_back(QPointF(i,j)); + } + for (int i = 0; i <= sceneWidth/2; i += gridSize) + { + for (int j = 0; j >= sceneHeight/-2; j -=gridSize) + gridPoints.push_back(QPointF(i,j)); + for (int j = 0; j <= sceneHeight/2; j +=gridSize) + gridPoints.push_back(QPointF(i,j)); + } + if (gridPoints.count() > 0) + { + result = gridPoints[0]; + QLineF checkLine = QLineF(point, result); + float length = qSqrt(qPow(checkLine.dx(),2) + qPow(checkLine.dy(),2)); + for (int i = 1; i < gridPoints.count(); ++i) + { + checkLine = QLineF(point, gridPoints[i]); + float checkLength = qSqrt(qPow(checkLine.dx(),2) + qPow(checkLine.dy(),2)); + if (checkLengthsetWindowTitle(tr("Compass angle rotation")); + window()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); + + mAngleSpinBox = new QDoubleSpinBox(this); + mAngleSpinBox->setMaximum(360); + mAngleSpinBox->setMinimum(-360); + QHBoxLayout* hLayout = new QHBoxLayout(this); + QLabel* angleLabel = new QLabel(this); + angleLabel->setText(tr("Angle:")); + angleLabel->setAlignment(Qt::AlignVCenter); + angleLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + hLayout->addWidget(angleLabel); + hLayout->addWidget(mAngleSpinBox); + hLayout->addSpacerItem(new QSpacerItem(26,20, QSizePolicy::Expanding, QSizePolicy::Preferred)); + QWidget* angleFrame = new QWidget(this); + angleFrame->setLayout(hLayout); + angleFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + mainLayout->addWidget(angleFrame); + + mDrawingCheckBox = new QCheckBox(this); + mDrawingCheckBox->setText(tr("With drawing")); + mDrawingCheckBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + QWidget* drawingCheckBoxWidget = new QWidget(this); + drawingCheckBoxWidget->setLayout(new QHBoxLayout(this)); + drawingCheckBoxWidget->layout()->addWidget(mDrawingCheckBox); + mainLayout->addWidget(drawingCheckBoxWidget); + + mainLayout->addSpacerItem(new QSpacerItem(26,20, QSizePolicy::Preferred, QSizePolicy::Expanding)); + + QWidget* buttonsWidget = new QWidget(this); + QPushButton* absolutButton = new QPushButton(this); + absolutButton->setText(tr("Rotate absolutely")); + absolutButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + QHBoxLayout* hLayout2 = new QHBoxLayout(this); + hLayout2->addWidget(absolutButton); + hLayout2->addSpacerItem(new QSpacerItem(26,20, QSizePolicy::Expanding, QSizePolicy::Preferred)); + QPushButton* relativeButton = new QPushButton(this); + relativeButton->setText(tr("Rotate relative")); + relativeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + hLayout2->addWidget(relativeButton); + buttonsWidget->setLayout(hLayout2); + mainLayout->addWidget(buttonsWidget); + setLayout(mainLayout); + + connect(absolutButton, SIGNAL(clicked()), this, SLOT(RotateAbsolutely())); + connect(relativeButton, SIGNAL(clicked()), this, SLOT(RotateRelative())); +} + +UBCompassAngleRotateDialog::~UBCompassAngleRotateDialog() +{ + delete mDrawingCheckBox; + delete mAngleSpinBox; +} + +void UBCompassAngleRotateDialog::RotateAbsolutely() +{ + mIsAbsolutely = true; + mCompass->angleRotateDialogResult(); + emit accept(); +} + +void UBCompassAngleRotateDialog::RotateRelative() +{ + mIsAbsolutely = false; + mCompass->angleRotateDialogResult(); + emit accept(); +} + +bool UBCompassAngleRotateDialog::isDrawing() +{ + return mDrawingCheckBox->isChecked(); +} + +bool UBCompassAngleRotateDialog::isAbsolutely() +{ + return mIsAbsolutely; +} + +qreal UBCompassAngleRotateDialog::Angle() +{ + return mAngleSpinBox->value(); +} + +void UBCompassAngleRotateDialog::clearData() +{ + mDrawingCheckBox->setChecked(false); + mAngleSpinBox->setValue(0); +} diff --git a/src/tools/UBGraphicsCompass.h b/src/tools/UBGraphicsCompass.h index 2af5e23cb..a6a296393 100644 --- a/src/tools/UBGraphicsCompass.h +++ b/src/tools/UBGraphicsCompass.h @@ -32,11 +32,39 @@ #include #include +#include +#include +#include #include "core/UB.h" #include "domain/UBItem.h" class UBGraphicsScene; +class UBGraphicsCompass; + +class UBCompassAngleRotateDialog: public QDialog +{ + Q_OBJECT; + + public: + explicit UBCompassAngleRotateDialog(UBGraphicsCompass* compass, QWidget *parent = nullptr); + bool isDrawing(); + bool isAbsolutely(); + void clearData(); + qreal Angle(); + ~UBCompassAngleRotateDialog(); + private: + QCheckBox* mDrawingCheckBox; + QDoubleSpinBox* mAngleSpinBox; + bool mIsAbsolutely; + UBGraphicsCompass* mCompass; + protected slots: + void RotateAbsolutely(); + void RotateRelative(); + signals: + void rotate(); + +}; class UBGraphicsCompass: public QObject, public QGraphicsRectItem, public UBItem { @@ -57,6 +85,9 @@ class UBGraphicsCompass: public QObject, public QGraphicsRectItem, public UBItem virtual void copyItemParameters(UBItem *copy) const; + + void angleRotateDialogResult(); + protected: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); @@ -72,6 +103,9 @@ class UBGraphicsCompass: public QObject, public QGraphicsRectItem, public UBItem private slots: void penColorChanged(); void lineWidthChanged(); + void setNormalizePos(bool); + void setNormalizeSize(bool); + void setMenuActions(); private: // Helpers @@ -82,6 +116,11 @@ class UBGraphicsCompass: public QObject, public QGraphicsRectItem, public UBItem void updateResizeCursor(); void updateDrawCursor(); void paintCenterCross(); + void normalizePos(); + void normalizeSize(); + QPointF nearPointFromGrid(QPointF point); + void showSettings(); + void decorateSettingsMenu(QMenu* menu); QCursor moveCursor() const; QCursor resizeCursor() const; @@ -93,6 +132,9 @@ class UBGraphicsCompass: public QObject, public QGraphicsRectItem, public UBItem QPointF pencilPosition() const; QRectF closeButtonRect() const; QRectF resizeButtonRect() const; + QRectF settingsButtonRect() const; + QRectF rightAngleButtonRect() const; + QRectF angleRotateButtonRect() const; virtual QPainterPath shape() const; QPainterPath needleShape() const; QPainterPath pencilShape() const; @@ -121,8 +163,18 @@ class UBGraphicsCompass: public QObject, public QGraphicsRectItem, public UBItem bool mDrewCircle; QGraphicsSvgItem* mCloseSvgItem; QGraphicsSvgItem* mResizeSvgItem; + QGraphicsSvgItem* mSettingsSvgItem; + QGraphicsSvgItem* mRihtAngleSvgItem; + QGraphicsSvgItem* mAngleRotateSvgItem; qreal mAntiScaleRatio; bool mDrewCenterCross; + bool mNormalizePos; + bool mNormalizeSize; + QMenu* mSettingsMenu; + QAction *mNormalizePosAction; + QAction *mNormalizeSizeAction; + UBCompassAngleRotateDialog* mAngleRotateDialog; + QLineF mBeforeRotatePosition; // Constants static const int sNeedleLength = 12;