From be85c9d5700398e268d8d58e87560f47b758283d Mon Sep 17 00:00:00 2001 From: duanshengchao <519970194@qq.com> Date: Thu, 15 Aug 2024 10:15:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E2=80=98=E6=92=A4=E5=9B=9E/?= =?UTF-8?q?=E9=87=8D=E5=81=9A=E2=80=99=E5=8A=9F=E8=83=BD=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=AE=8C=E6=88=90=E4=BA=86=E5=AF=B9=E2=80=98?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9B=BE=E5=BD=A2=E2=80=99=E5=92=8C=E2=80=98?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=9B=BE=E5=BD=A2=E2=80=99=E7=9A=84=E6=8C=87?= =?UTF-8?q?=E4=BB=A4=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 + include/designerScene.h | 5 ++ include/drawingPanel.h | 3 + include/mainwindow.h | 18 +++-- include/operationCommand.h | 46 +++++++++++++ source/designerScene.cpp | 10 +++ source/drawingPanel.cpp | 12 +++- source/mainwindow.cpp | 113 ++++++++++++++++--------------- source/operationCommand.cpp | 64 +++++++++++++++++ source/util/creatingSelector.cpp | 1 + ui/mainwindow.ui | 7 +- 11 files changed, 212 insertions(+), 69 deletions(-) create mode 100644 include/operationCommand.h create mode 100644 source/operationCommand.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f864a11..2e94cc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ set(H_HEADER_FILES include/drawingPanel.h include/designerScene.h include/designerView.h + include/operationCommand.h include/util/baseSelector.h include/util/creatingSelector.h @@ -57,6 +58,7 @@ set(CPP_SOURCE_FILES source/drawingPanel.cpp source/designerScene.cpp source/designerView.cpp + source/operationCommand.cpp source/util/baseSelector.cpp source/util/creatingSelector.cpp diff --git a/include/designerScene.h b/include/designerScene.h index 8be2167..7cef347 100644 --- a/include/designerScene.h +++ b/include/designerScene.h @@ -16,12 +16,17 @@ public: QGraphicsView *getView() { return m_pView; } void callParentEvent(QGraphicsSceneMouseEvent*); +signals: + void signalAddItem(QGraphicsItem*); + protected: void drawBackground(QPainter*, const QRectF&) override; void mousePressEvent(QGraphicsSceneMouseEvent*) override; void mouseMoveEvent(QGraphicsSceneMouseEvent*) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*) override; + void keyPressEvent(QKeyEvent*) override; + void keyReleaseEvent(QKeyEvent*) override; private: bool m_bGridVisible; diff --git a/include/drawingPanel.h b/include/drawingPanel.h index e8c330e..6bb309e 100644 --- a/include/drawingPanel.h +++ b/include/drawingPanel.h @@ -19,6 +19,9 @@ public: DrawingPanel(QWidget *parent = nullptr); ~DrawingPanel(); + QGraphicsScene* getQGraphicsScene(); + DesignerScene* getDesignerScene(); + public slots: void onSignal_addGraphicsItem(GraphicsItemType&); diff --git a/include/mainwindow.h b/include/mainwindow.h index a3770ee..9d83590 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -13,8 +13,11 @@ QT_BEGIN_NAMESPACE namespace Ui { class CMainWindow; } QT_END_NAMESPACE +class QGraphicsItem; +class QUndoStack; class DrawingPanel; class GraphicElementsPanel; +class DesignerScene; class CMainWindow : public QMainWindow { @@ -27,11 +30,21 @@ public: protected: virtual void closeEvent(QCloseEvent* event) override; +private: + void initializeDockUi(); + void initializeAction(); + +private slots: + void onSignal_addItem(QGraphicsItem*); + void onSignal_deleteItem(); + private: QAction* SavePerspectiveAction = nullptr; QWidgetAction* PerspectiveListAction = nullptr; QComboBox* PerspectiveComboBox = nullptr; + QUndoStack* m_pUndoStack; + Ui::CMainWindow *ui; ads::CDockManager* DockManager; @@ -40,10 +53,5 @@ private: DrawingPanel* m_pDrawingPanel; GraphicElementsPanel* m_pGraphicElementsPanel; - - void createPerspectiveUi(); - -private slots: - void savePerspective(); }; #endif // MAINWINDOW_H diff --git a/include/operationCommand.h b/include/operationCommand.h new file mode 100644 index 0000000..627be23 --- /dev/null +++ b/include/operationCommand.h @@ -0,0 +1,46 @@ +/** + *\file operationCommand.h + * + *\brief 用来实现“撤销/重做”的操作指令,继承自QUndoCommand + * + *\author dsc + */ + +#ifndef OPERATIONCOMMAND_H +#define OPERATIONCOMMAND_H + +#include +#include + +class AddItemCommand : public QUndoCommand +{ +public: + explicit AddItemCommand(QGraphicsItem* item, QGraphicsScene* graphicsScene, QUndoCommand* parent = 0); + ~AddItemCommand(); + +public: + void undo() override; + void redo() override; + +private: + QGraphicsItem* m_pItem; + QPointF m_itemPos; + QGraphicsScene* m_pGraphicsScene; +}; + +class DeleteItemCommand : public QUndoCommand +{ +public: + explicit DeleteItemCommand(QGraphicsScene* graphicsScene, QUndoCommand* parent = 0); + ~DeleteItemCommand(); + +public: + void undo() override; + void redo() override; + +private: + QList m_listItem; + QGraphicsScene* m_pGraphicsScene; +}; + +#endif diff --git a/source/designerScene.cpp b/source/designerScene.cpp index c5f427f..53899ba 100644 --- a/source/designerScene.cpp +++ b/source/designerScene.cpp @@ -83,6 +83,16 @@ void DesignerScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent) QGraphicsScene::mouseReleaseEvent(mouseEvent); } +void DesignerScene::keyPressEvent(QKeyEvent* event) +{ + QGraphicsScene::keyPressEvent(event); +} + +void DesignerScene::keyReleaseEvent(QKeyEvent* event) +{ + QGraphicsScene::keyReleaseEvent(event); +} + void DesignerScene::setGridVisible(bool bVisible) { m_bGridVisible = bVisible; diff --git a/source/drawingPanel.cpp b/source/drawingPanel.cpp index 8ecf4e4..9a37224 100644 --- a/source/drawingPanel.cpp +++ b/source/drawingPanel.cpp @@ -19,8 +19,6 @@ DrawingPanel::DrawingPanel(QWidget *parent) m_pGraphicsView->setScene(m_pGraphicsScene); m_pGraphicsScene->setView(m_pGraphicsView); ui->mainLayout->addWidget(m_pGraphicsView); - - } DrawingPanel::~DrawingPanel() @@ -28,6 +26,16 @@ DrawingPanel::~DrawingPanel() delete ui; } +QGraphicsScene* DrawingPanel::getQGraphicsScene() +{ + return m_pGraphicsView->scene(); +} + +DesignerScene* DrawingPanel::getDesignerScene() +{ + return m_pGraphicsScene; +} + void DrawingPanel::onSignal_addGraphicsItem(GraphicsItemType& itemType) { if(SelectorManager::getInstance()) diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index badac92..bbc2998 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -3,20 +3,11 @@ #include "ui_mainwindow.h" #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include #include -#include -#include -#include +#include +#include +#include #include "DockAreaWidget.h" #include "DockAreaTitleBar.h" @@ -25,7 +16,9 @@ #include "DockComponentsFactory.h" #include "drawingPanel.h" +#include "designerScene.h" #include "graphicElementsPanel.h" +#include "operationCommand.h" using namespace ads; @@ -35,6 +28,30 @@ CMainWindow::CMainWindow(QWidget *parent) , ui(new Ui::CMainWindow) { ui->setupUi(this); + m_pUndoStack = nullptr; + + initializeDockUi(); + initializeAction(); + + connect(m_pGraphicElementsPanel,SIGNAL(addGraphicsItem(GraphicsItemType&)),m_pDrawingPanel,SLOT(onSignal_addGraphicsItem(GraphicsItemType&))); +} + +CMainWindow::~CMainWindow() +{ + delete ui; +} + + +void CMainWindow::closeEvent(QCloseEvent* event) +{ + // Delete dock manager here to delete all floating widgets. This ensures + // that all top level windows of the dock manager are properly closed + DockManager->deleteLater(); + QMainWindow::closeEvent(event); +} + +void CMainWindow::initializeDockUi() +{ CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true); CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false); CDockManager::setConfigFlag(CDockManager::FocusHighlighting, true); @@ -42,6 +59,7 @@ CMainWindow::CMainWindow(QWidget *parent) // Set central widget m_pDrawingPanel = new DrawingPanel(); + connect(m_pDrawingPanel->getDesignerScene(), SIGNAL(signalAddItem(QGraphicsItem*)), this, SLOT(onSignal_addItem(QGraphicsItem*))); CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget"); CentralDockWidget->setWidget(m_pDrawingPanel); auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget); @@ -54,10 +72,9 @@ CMainWindow::CMainWindow(QWidget *parent) GrapicElementsDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); GrapicElementsDockWidget->resize(400, 150); GrapicElementsDockWidget->setMinimumSize(200,150); - auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, GrapicElementsDockWidget); + DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, GrapicElementsDockWidget); ui->menuView->addAction(GrapicElementsDockWidget->toggleViewAction()); - QTableWidget* propertiesTable = new QTableWidget(); propertiesTable->setColumnCount(3); propertiesTable->setRowCount(10); @@ -68,57 +85,41 @@ CMainWindow::CMainWindow(QWidget *parent) PropertiesDockWidget->setMinimumSize(200,150); DockManager->addDockWidget(DockWidgetArea::RightDockWidgetArea, PropertiesDockWidget, CentralDockArea); ui->menuView->addAction(PropertiesDockWidget->toggleViewAction()); - - //createPerspectiveUi(); - connect(m_pGraphicElementsPanel,SIGNAL(addGraphicsItem(GraphicsItemType&)),m_pDrawingPanel,SLOT(onSignal_addGraphicsItem(GraphicsItemType&))); } -CMainWindow::~CMainWindow() +void CMainWindow::initializeAction() { - delete ui; + //撤销、重做 + m_pUndoStack = new QUndoStack(this); + ui->actionUndo = m_pUndoStack->createUndoAction(this, tr("撤销")); + ui->actionUndo->setIcon(QIcon::fromTheme(QString::fromUtf8("edit-undo"))); + ui->actionUndo->setShortcuts(QKeySequence::Undo); + ui->actionRedo = m_pUndoStack->createRedoAction(this, tr("重做")); + ui->actionRedo->setIcon(QIcon::fromTheme(QString::fromUtf8("edit-redo"))); + ui->actionRedo->setShortcuts(QKeySequence::Redo); + ui->toolBar->addAction(ui->actionUndo); + ui->toolBar->addAction(ui->actionRedo); + ui->actionUndo->setEnabled(m_pUndoStack->canUndo()); + ui->actionRedo->setEnabled(m_pUndoStack->canRedo()); + + ui->actionDelete->setShortcut(QKeySequence::Delete); + + connect(ui->actionDelete, SIGNAL(triggered()), this, SLOT(onSignal_deleteItem())); } - -void CMainWindow::createPerspectiveUi() +void CMainWindow::onSignal_addItem(QGraphicsItem* item) { - SavePerspectiveAction = new QAction("Create Perspective", this); - connect(SavePerspectiveAction, SIGNAL(triggered()), SLOT(savePerspective())); - PerspectiveListAction = new QWidgetAction(this); - PerspectiveComboBox = new QComboBox(this); - PerspectiveComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); - PerspectiveComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - connect(PerspectiveComboBox, SIGNAL(currentTextChanged(const QString&)), - DockManager, SLOT(openPerspective(const QString&))); - PerspectiveListAction->setDefaultWidget(PerspectiveComboBox); - ui->toolBar->addSeparator(); - ui->toolBar->addAction(PerspectiveListAction); - ui->toolBar->addAction(SavePerspectiveAction); + QUndoCommand* addItemCommand = new AddItemCommand(item, item->scene()); + m_pUndoStack->push(addItemCommand); } - -void CMainWindow::savePerspective() +void CMainWindow::onSignal_deleteItem() { - QString PerspectiveName = QInputDialog::getText(this, "Save Perspective", "Enter unique name:"); - if (PerspectiveName.isEmpty()) - { - return; - } + QGraphicsScene* scene = m_pDrawingPanel->getQGraphicsScene(); + if (scene && scene->selectedItems().isEmpty()) + return; - DockManager->addPerspective(PerspectiveName); - QSignalBlocker Blocker(PerspectiveComboBox); - PerspectiveComboBox->clear(); - PerspectiveComboBox->addItems(DockManager->perspectiveNames()); - PerspectiveComboBox->setCurrentText(PerspectiveName); + QUndoCommand* deleteItemCommand = new DeleteItemCommand(scene); + m_pUndoStack->push(deleteItemCommand); //push时会自动调用一次command的redo函数 } - -//============================================================================ -void CMainWindow::closeEvent(QCloseEvent* event) -{ - // Delete dock manager here to delete all floating widgets. This ensures - // that all top level windows of the dock manager are properly closed - DockManager->deleteLater(); - QMainWindow::closeEvent(event); -} - - diff --git a/source/operationCommand.cpp b/source/operationCommand.cpp new file mode 100644 index 0000000..a42e8e8 --- /dev/null +++ b/source/operationCommand.cpp @@ -0,0 +1,64 @@ +#include "operationCommand.h" +#include + +AddItemCommand::AddItemCommand(QGraphicsItem* item, QGraphicsScene* scene, QUndoCommand* parent) + : QUndoCommand(parent) +{ + m_pItem = item; + m_itemPos = item->pos(); + m_pGraphicsScene = scene; +} +AddItemCommand::~AddItemCommand() +{ +} +void AddItemCommand::undo() +{ + m_pGraphicsScene->removeItem(m_pItem); + m_pGraphicsScene->update(); +} +void AddItemCommand::redo() +{ + if(m_pItem->scene()) //因为添加图元后同步创建一条该指令,平且在push进入stack的时候redo会被触发一次,因此这里加判断,防止重复操作 + return; + + m_pGraphicsScene->addItem(m_pItem); + m_pItem->setPos(m_itemPos); + m_pGraphicsScene->update(); +} + +DeleteItemCommand::DeleteItemCommand(QGraphicsScene* scene, QUndoCommand* parent) + : QUndoCommand(parent) +{ + m_pGraphicsScene = scene; + m_listItem = scene->selectedItems(); +} +DeleteItemCommand::~DeleteItemCommand() +{ +} +void DeleteItemCommand::undo() +{ + foreach(QGraphicsItem* item, m_listItem) + { + QGraphicsItemGroup* group = dynamic_cast(item->parentItem()); + if(!group) + { + m_pGraphicsScene->addItem(item); + } + } + + m_pGraphicsScene->update(); +} +void DeleteItemCommand::redo() +{ + foreach(QGraphicsItem* item, m_listItem) + { + QGraphicsItemGroup* group = dynamic_cast(item->parentItem()); + if(!group) + { + m_pGraphicsScene->removeItem(item); //remove即可,不要delete,因为会影响撤回(undo)操作 + } + } + + m_pGraphicsScene->update(); +} + diff --git a/source/util/creatingSelector.cpp b/source/util/creatingSelector.cpp index 5ffcaa8..8a0d682 100644 --- a/source/util/creatingSelector.cpp +++ b/source/util/creatingSelector.cpp @@ -80,6 +80,7 @@ void CreatingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Design else if (m_pCreatingItem && ms_ptMouseLast != ms_ptMouseDown) { m_pCreatingItem->updateCoordinate(); + emit scene->signalAddItem(m_pCreatingItem); } ms_nDragHandle = H_none; diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 6b6157e..e4a0de3 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -7,7 +7,7 @@ 0 0 1284 - 757 + 756 @@ -60,8 +60,6 @@ - - @@ -224,9 +222,6 @@ 撤销 - - QAction::MenuRole::NoRole -