添加‘撤回/重做’功能模块,并完成了对‘添加图形’和‘删除图形’的指令实现

This commit is contained in:
duanshengchao 2024-08-15 10:15:56 +08:00
parent 2c4a2ad19b
commit be85c9d570
11 changed files with 212 additions and 69 deletions

View File

@ -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

View File

@ -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;

View File

@ -19,6 +19,9 @@ public:
DrawingPanel(QWidget *parent = nullptr);
~DrawingPanel();
QGraphicsScene* getQGraphicsScene();
DesignerScene* getDesignerScene();
public slots:
void onSignal_addGraphicsItem(GraphicsItemType&);

View File

@ -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

View File

@ -0,0 +1,46 @@
/**
*\file operationCommand.h
*
*\brief /,QUndoCommand
*
*\author dsc
*/
#ifndef OPERATIONCOMMAND_H
#define OPERATIONCOMMAND_H
#include <QUndoCommand>
#include <QGraphicsScene>
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<QGraphicsItem*> m_listItem;
QGraphicsScene* m_pGraphicsScene;
};
#endif

View File

@ -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;

View File

@ -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())

View File

@ -3,20 +3,11 @@
#include "ui_mainwindow.h"
#include <QWidgetAction>
#include <QLabel>
#include <QCalendarWidget>
#include <QTreeView>
#include <QFileSystemModel>
#include <QTableWidget>
#include <QHBoxLayout>
#include <QRadioButton>
#include <QPushButton>
#include <QInputDialog>
#include <QFileDialog>
#include <QSettings>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QToolBar>
#include <QUndoStack>
#include <QGraphicsScene>
#include <QGraphicsItem>
#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);
}

View File

@ -0,0 +1,64 @@
#include "operationCommand.h"
#include <QGraphicsItem>
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<QGraphicsItemGroup*>(item->parentItem());
if(!group)
{
m_pGraphicsScene->addItem(item);
}
}
m_pGraphicsScene->update();
}
void DeleteItemCommand::redo()
{
foreach(QGraphicsItem* item, m_listItem)
{
QGraphicsItemGroup* group = dynamic_cast<QGraphicsItemGroup*>(item->parentItem());
if(!group)
{
m_pGraphicsScene->removeItem(item); //remove即可不要delete因为会影响撤回undo操作
}
}
m_pGraphicsScene->update();
}

View File

@ -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;

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1284</width>
<height>757</height>
<height>756</height>
</rect>
</property>
<property name="windowTitle">
@ -60,8 +60,6 @@
<addaction name="actionZoomFit"/>
<addaction name="actionGrid"/>
<addaction name="separator"/>
<addaction name="actionUndo"/>
<addaction name="actionRedo"/>
</widget>
<action name="actionNew">
<property name="icon">
@ -224,9 +222,6 @@
<property name="toolTip">
<string>撤销</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionRedo">
<property name="icon">