123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 |
- #include "WindowAppUiFrame.h"
- #include "selectwidget.h"
- #include "UiManager.h"
- #include "WindowMain.h"
- #include "DialogUiOption.h"
- #include "WindowAppUiScene.h"
- #include "VPCommand.h"
- #include "Preferences.h"
- #include "VControlObject.h"
- WindowAppUiFrame::WindowAppUiFrame(const QString& strTitle, QWidget *parent)
- : QMainWindow(parent)
- , m_nUiViewHeight(DEFAULT_UIVIEW_HEIGHT)
- , m_nUiViewWidth(DEFAULT_UIVIEW_WIDTH)
- , actionUndo(nullptr)
- , actionRedo(nullptr)
- {
- ui.setupUi(this);
- m_nScrollValueH = 0;
- m_nScrollValueV = 0;
- // UI元素初始化
- this->initUI();
- // 初始化布局工具栏
- this->initLayoutToolbar();
- //// 初始化控件工具栏
- //this->initControlToolbar();
- this->addToolBar(m_layoutToolbar);
- m_layoutToolbar->setMovable(false);
-
- //this->addToolBarBreak();
- //this->addToolBar(m_controlToolbar);
- //m_controlToolbar->setMovable(false);
- // 初始化UiView
- ui.widgetUiView->init(strTitle, ui.uiNavView, this, ui.objectController);
- // 绑定鸟瞰图缩放时的同步刷新动作
- connect(ui.widgetUiView, &WindowAppUiView::navigatorViewRequired, this, [=](bool required, const QTransform& tf)
- {
- Q_UNUSED(required);
- Q_UNUSED(tf);
- //ui.uiNavView->setTransform(WindowAppPouView::resetScale(tf));
- ui.uiNavView->fitInView(ui.uiNavView->sceneRect(), Qt::KeepAspectRatio);
- ui.uiNavView->setVisible(required);
- ui.uiNavView->updateMainViewportRegion();
- }
- );
-
- //// 矩形区域变动时的响应动作
- //connect(ui.widgetUiView, &WindowAppUiView::viewportRectChanged, ui.uiNavView, &WindowAppUiNavView::updateMainViewportRegion);
- // 统一转换为初始化函数
- //ui.widgetUiView->uiScene()->m_pPropertyController = ui.objectController;
- //ui.widgetUiView->m_strPageName = strTitle;
- // g_pUiManager->registerNewUi(ui.widgetUiView);
- //// 将当前Scene绑定到鸟瞰图中进行同步
- //ui.uiNavView->setScene((QGraphicsScene*)ui.widgetUiView->scene());
- //// 绑定同步的鸟瞰图
- //ui.uiNavView->setMainView(ui.widgetUiView);
- //// 调整View
- //ui.uiNavView->fitInView(ui.uiNavView->sceneRect(), Qt::KeepAspectRatio);
- WindowAppUiScene* pScene = ui.widgetUiView->uiScene();
- WindowAppUiView* pView = ui.widgetUiView;
- WindowAppUiFrame* pFrame = this;
- vDebug() << pScene << " " << pView << " " << pFrame;
- }
- WindowAppUiFrame::~WindowAppUiFrame()
- {
-
- }
- /// <summary>
- /// 获取本Frame下的View指针
- /// </summary>
- /// <returns></returns>
- WindowAppUiView* WindowAppUiFrame::getUiView()
- {
- return ui.widgetUiView;
- }
- /// <summary>
- /// UI元素初始化
- /// </summary>
- void WindowAppUiFrame::initUI()
- {
- //QWidget* mainWidget = new QWidget();
- //QVBoxLayout* mainLayout = new QVBoxLayout();
- //mainLayout->addWidget(ui.toolbarLayoutFrame, 0, Qt::AlignTop);
- //mainLayout->addWidget(ui.toolbarControlFrame, 1, Qt::AlignTop);
- //mainLayout->addWidget(ui.widgetUiView);
- //mainLayout->setContentsMargins(0, 0, 0, 0);
- //mainLayout->setSpacing(0);
- //mainWidget->setLayout(mainLayout);
- //this->setCentralWidget(mainWidget);
- // 2021-8-30 在QMainWindow作为QMdiSubView时,需要将QMainWindow设置为 Widget风格,否则窗体不显示
- this->setWindowFlags(Qt::Widget);
-
- ui.widgetUiView->uiScene()->m_pUiFrame = this;
- QScrollArea* ScrollArea = new QScrollArea(ui.widget_1);
- ScrollArea->setWidget(ui.widgetUiView);//设置滚动条
- ui.gridLayout->addWidget(ScrollArea);
- connect(ScrollArea->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(horizontalValueChanged(int)));
- connect(ScrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(verticalValueChanged(int)));
- //connect(ScrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)));
- ui.widgetUiView->resize(this->m_nUiViewWidth, this->m_nUiViewHeight);
- // 初始化界面分隔区域
- //for (int i = 0; i < thePrefs.listUiStretchFactors.size(); i++)
- //{
- // ui.splitter->setStretchFactor(i, 4);
- //}
- //// 更新界面分隔区域
- //this->updateSplitterFromPref();
- // 先按照默认尺寸进行拆分
- ui.splitter->setStretchFactor(0, 4);
- ui.splitter->setStretchFactor(1, 2);
- //QList<int> list = ui.splitter->sizes();
- }
- /// <summary>
- /// 初始化布局工具栏
- /// </summary>
- void WindowAppUiFrame::initLayoutToolbar()
- {
- m_layoutToolbar = new QToolBar();
- m_layoutToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
- QAction* actionZorderTop = new QAction(QIcon(":/image/ZorderTop.png"), ("ZorderTop"));
- QAction* actionZorderBottom = new QAction(QIcon(":/image/ZorderBottom.png"), ("ZorderBottom"));
- QAction* actionZorderUp = new QAction(QIcon(":/image/ZorderUp.png"), ("ZorderUp"));
- QAction* actionZorderDown = new QAction(QIcon(":/image/ZorderDown.png"), ("ZorderDown"));
- // QAction* actionAlignLeft = new QAction(QIcon(":/image/AlignLeft.png"), ("Align Left"));
- // QAction* actionAlignTop = new QAction(QIcon(":/image/AlignTop.png"), ("Align Top"));
- // QAction* actionAlignRight = new QAction(QIcon(":/image/AlignRight.png"), ("Align Right"));
- // QAction* actionAlignBottom = new QAction(QIcon(":/image/AlignBottom.png"), ("Align Bottom"));
- // QAction* actionSamesize = new QAction(QIcon("./image/Samesize.png"), ("Make same size"));
- // QAction* actionZoomIn = new QAction(QIcon(":/image/ZoomOut.png"), ("Zoom In"));
- // QAction* actionZoomOut = new QAction(QIcon(":/image/ZoomIn.png"), ("Zoom Out"));
- // QAction* actionZoomZero = new QAction(QIcon(":/image/Zoom.png"), ("Zoom Zero"));
- QAction* actionOption = new QAction(QIcon(":/image/Option.png"), ("Options"));
- // QAction* actionSnap = new QAction(QIcon(":/image/Snap.png"), ("Snap to Grid"));
- // 2022-9-29,增加了Undo和Redo操作
- actionUndo = new QAction(QIcon(":/image/Undo.png"), ("Undo"));
- actionRedo = new QAction(QIcon(":/image/Redo.png"), ("Redo"));
- // QAction* actionUpdate = new QAction(QIcon(":/image/Update.png"), ("Update ro Runtime"));
- QAction* actionDelete = new QAction(QIcon(":/image/Delete.png"), ("Delete"));
- QAction* actionPublish = new QAction(QIcon(":/image/ui_run.png"), ("Publish UI in Runtime"));
- m_layoutToolbar->addAction(actionZorderTop);
- m_layoutToolbar->addAction(actionZorderBottom);
- m_layoutToolbar->addAction(actionZorderUp);
- m_layoutToolbar->addAction(actionZorderDown);
- m_layoutToolbar->addSeparator();
- // m_layoutToolbar->addAction(actionAlignLeft);
- // m_layoutToolbar->addAction(actionAlignTop);
- // m_layoutToolbar->addAction(actionAlignRight);
- // m_layoutToolbar->addAction(actionAlignBottom);
- // m_layoutToolbar->addAction(actionSamesize);
- // m_layoutToolbar->addSeparator();
- // m_layoutToolbar->addAction(actionZoomIn);
- // m_layoutToolbar->addAction(actionZoomOut);
- // m_layoutToolbar->addAction(actionZoomZero);
- m_layoutToolbar->addAction(actionOption);
- // m_layoutToolbar->addAction(actionSnap);
- m_layoutToolbar->addSeparator();
- m_layoutToolbar->addAction(actionUndo);
- m_layoutToolbar->addAction(actionRedo);
- m_layoutToolbar->addSeparator();
- // m_layoutToolbar->addAction(actionUpdate);
- m_layoutToolbar->addAction(actionDelete);
- m_layoutToolbar->addSeparator();
- m_layoutToolbar->addAction(actionPublish);
- m_layoutToolbar->setIconSize(QSize(14, 14));
- // 工具栏Signal
- connect(actionZorderTop, &QAction::triggered, this, &WindowAppUiFrame::onToolZorderTop);
- connect(actionZorderBottom, &QAction::triggered, this, &WindowAppUiFrame::onToolZorderBottom);
- connect(actionZorderUp, &QAction::triggered, this, &WindowAppUiFrame::onToolZorderUp);
- connect(actionZorderDown, &QAction::triggered, this, &WindowAppUiFrame::onToolZorderDown);
- connect(actionUndo, &QAction::triggered, this, &WindowAppUiFrame::onToolUndo);
- connect(actionRedo, &QAction::triggered, this, &WindowAppUiFrame::onToolRedo);
- connect(actionPublish, &QAction::triggered, this, &WindowAppUiFrame::onToolPublish);
- connect(actionDelete, &QAction::triggered, this, &WindowAppUiFrame::onToolDelete);
- connect(actionOption, &QAction::triggered, this, &WindowAppUiFrame::onToolOption);
- // 拆分栏Signal
- connect(ui.splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(slotSplitterMoved(int, int)));
- }
- /// <summary>
- /// 拆分条移动时(暂未使用)
- /// </summary>
- /// <param name="pos"></param>
- /// <param name="index"></param>
- void WindowAppUiFrame::slotSplitterMoved(int pos, int index)
- {
- Q_UNUSED(pos);
- Q_UNUSED(index);
- QList<int> list = ui.splitter->sizes();
- // qDebug() << list;
- }
- //========================================================================
- //
- // 刻度尺绘制相关
- //
- //========================================================================
- /// <summary>
- /// 绘制水平刻度尺
- /// </summary>
- /// <param name="painter"></param>
- /// <param name="pen"></param>
- void WindowAppUiFrame::DrawHorizontalScale(QPainter* painter, QPen* pen)
- {
- int Y = 51;
- int X = 4;
- //绘制一条水平坐标线
- QPoint ptBegin(X, Y);
- QPoint ptEnd(this->rect().width(), Y);
- painter->drawLine(ptBegin, ptEnd);
- float m_fInterval = 4;
- float fDrawLeft = 10;
- int nIndex = 0;
- int nScaleHeight = 8; //刻度线高度
- while (fDrawLeft < this->rect().width())
- {
- if ((nIndex % 2 == 0) && (nIndex % 5 == 0))
- {
- nScaleHeight = 8;
- QString sText = QString::number(nIndex / 10);
- painter->drawText(QPoint(fDrawLeft + X + 2, Y - nScaleHeight + 2), sText);
- }
- else
- {
- pen->setWidth(1);
- painter->setPen(*pen);
- //当是中间节点时,长度要比一般的长
- nScaleHeight = (nIndex % 4) == 0 ? 4 : 2;
- }
- //绘制刻度值
- painter->drawRect(QRectF((double)fDrawLeft + (double)X, (double)Y - (double)nScaleHeight, 0.1, (double)nScaleHeight));
- fDrawLeft += m_fInterval;
- nIndex = nIndex + 1;
- }
- }
- /// <summary>
- /// 绘制垂直刻度尺
- /// </summary>
- /// <param name="painter"></param>
- /// <param name="pen"></param>
- void WindowAppUiFrame::DrawVerticalScale(QPainter* painter, QPen* pen)
- {
- //绘制一条垂直坐标线
- int X = 15 - 1;
- int Y = 51;
- QPoint ptBegin(X, Y);
- QPoint ptEnd(X, ui.widgetUiView->rect().height() - Y);
- painter->drawLine(ptBegin, ptEnd);
- float m_fInterval = 4;
- float fDrawTop = 0;
- int nIndex = 0;
- int nScaleWidth = 20; //刻度线宽度
- while (fDrawTop < this->rect().height())
- {
- if ((nIndex % 2 == 0) && (nIndex % 5 == 0))
- {
- nScaleWidth = 8;
- QString sText = QString::number(nIndex / 10);
- int fontWidth = fontMetrics().width(sText);
- int nleft = (((X - nScaleWidth) - fontWidth) / 2) + 4;
- painter->drawText(QPoint(nleft, fDrawTop + Y + 10), sText);
- }
- else
- {
- pen->setWidth(1);
- painter->setPen(*pen);
- //当是中间节点时,长度要比一般的长
- nScaleWidth = (nIndex % 4) == 0 ? 4 : 2;
- }
- //绘制刻度值
- painter->drawRect(QRectF((double)X - (double)nScaleWidth, (double)fDrawTop + (double)Y, nScaleWidth, 0.1));
- fDrawTop += m_fInterval;
- nIndex++;
- }
- }
- /// <summary>
- /// 绘制界面
- /// </summary>
- /// <param name=""></param>
- void WindowAppUiFrame::paintEvent(QPaintEvent*)
- {
- QPainter painter(this);
- //设置画刷
- QPen pen(Qt::black, 1);
- pen.setWidth(1);
- painter.setPen(pen);
- painter.translate(0, 0);
- //抗锯齿绘制
- painter.setRenderHint(QPainter::Antialiasing);
- //绘制水平刻度尺
- this->DrawHorizontalScale(&painter, &pen);
- //绘制垂直刻度尺
- this->DrawVerticalScale(&painter, &pen);
- // 刷新Undo菜单启用禁用
- this->refreshUndoMenu();
- }
- /// <summary>
- /// 水平滚动条数值改变时,保存数值
- /// </summary>
- /// <param name="value"></param>
- void WindowAppUiFrame::horizontalValueChanged(int value)
- {
- m_nScrollValueH = value;
- }
- /// <summary>
- /// 垂直滚动条数值改变时,保存数值
- /// </summary>
- /// <param name="value"></param>
- void WindowAppUiFrame::verticalValueChanged(int value)
- {
- m_nScrollValueV = value;
- }
- void WindowAppUiFrame::onToolZorderTop()
- {
- ui.widgetUiView->uiScene()->zorderTopCurrentControl();
- }
- void WindowAppUiFrame::onToolZorderBottom()
- {
- ui.widgetUiView->uiScene()->zorderBottomCurrentControl();
- }
- void WindowAppUiFrame::onToolZorderUp()
- {
- ui.widgetUiView->uiScene()->zorderUpCurrentControl();
- }
- void WindowAppUiFrame::onToolZorderDown()
- {
- ui.widgetUiView->uiScene()->zorderDownCurrentControl();
- }
- /// <summary>
- /// Undo
- /// </summary>
- void WindowAppUiFrame::onToolUndo()
- {
- // vDebug() << "WindowAppUiFrame::onToolUndo()";
- ui.widgetUiView->uiScene()->m_CommandManager.undo();
- }
- /// <summary>
- /// Redo
- /// </summary>
- void WindowAppUiFrame::onToolRedo()
- {
- // vDebug() << "WindowAppUiFrame::onToolRedo()";
- ui.widgetUiView->uiScene()->m_CommandManager.redo();
- }
- //========================================================================
- //
- // Toolbar 消息处理
- //
- //========================================================================
- /// <summary>
- /// UI界面设置
- /// </summary>
- void WindowAppUiFrame::onToolOption()
- {
- DialogUiOption dialogUiOption(
- this->m_nUiViewWidth,
- this->m_nUiViewHeight,
- this
- );
- // 进行UI界面设置
- if (dialogUiOption.exec() == QDialog::Accepted)
- {
- // 保存用户设置的UI宽度和高度
- this->m_nUiViewWidth = dialogUiOption.m_nWidth;
- this->m_nUiViewHeight = dialogUiOption.m_nHeight;
- // 同步修改UiView和UiScene的界面尺寸
- ui.widgetUiView->resize(this->m_nUiViewWidth, this->m_nUiViewHeight);
- // 调整鸟瞰图View
- ui.uiNavView->fitInView(ui.uiNavView->sceneRect(), Qt::KeepAspectRatio);
- }
- }
- /// <summary>
- /// Ui控件删除
- /// </summary>
- void WindowAppUiFrame::onToolDelete()
- {
- // ui.widgetUiView->uiScene()->deleteCurrentControl();
- // 2022-10-19,统一替换成了Undo框架进行删除,但是步骤要复杂一些
- WindowAppUiScene* uiScene = ui.widgetUiView->uiScene();
- // 获取当前删除的控件
- VControlObject* pDelControl = uiScene->getCurrentControl();
- if (pDelControl == nullptr)
- {
- vDebug() << "Ignore, current control is nullptr.";
- return;
- }
- // 求出控件的中心点坐标
- // 由于控件并非是QGraphicObject,所以位置需要换算一下
- QPoint ptControlPos = pDelControl->m_pWidget->pos();
- ptControlPos.setX(ptControlPos.x() + pDelControl->m_pWidget->geometry().width() / 2);
- ptControlPos.setY(ptControlPos.y() + pDelControl->m_pWidget->geometry().height() / 2);
- //QPoint ptPos = pDelControl->m_pProxyWidget->scenePos().toPoint();
- // QPoint ptPos2 = pDelControl->m_pWidget->pos();
- // 生成删除指令,调用Undo体系进行删除
- UiControlDelCommand* controlDelCommand = new UiControlDelCommand(
- uiScene,
- pDelControl->m_Type,
- pDelControl->m_strID,
- ptControlPos,
- pDelControl->m_pWidget->size()
- );
- uiScene->m_CommandManager.executeCommand(controlDelCommand);
- }
- /// <summary>
- /// UI界面发布至Runtime
- /// </summary>
- void WindowAppUiFrame::onToolPublish()
- {
- qDebug() << "WindowAppUiFrame::onActionRun.";
- // 通过Manager发布所有UI
- bool bRet = g_pUiManager->publishAll();
- if (bRet)
- {
- INFORMATION_MESSAGE("Publish to runtime success!");
- // 成功发布后,通知主框架把页面切换到Runtime页面
- g_pMainWindow->onViewRunTime();
- }
- else
- {
- // CRITICAL_MESSAGE("Publish to runtime failed!");
- }
- }
- /// <summary>
- /// 序列化支持
- /// </summary>
- /// <param name="dataStream"></param>
- /// <param name="in"></param>
- /// <returns></returns>
- bool WindowAppUiFrame::serialized(QDataStream& ar, bool in /*= true*/)
- {
- int paranum;//参数数量
- // 保存
- if (!in)
- {
- paranum = 3;
- ar << paranum;//先保存参数数量
- // 宽和高
- ar << (int)1 << m_nUiViewWidth;
- ar << (int)2 << m_nUiViewHeight;
- ar << (int)3 << ui.splitter->sizes();
- }
- // 读取
- else
- {
- QList<int> splitters;
- int para;
- ar >> paranum;//读取参数数量
- for (int i = 0; i < paranum; i++)
- {
-
- ar >> para;
- switch (para)
- {
- case 1: ar >> m_nUiViewWidth; break;
- case 2: ar >> m_nUiViewHeight; break;
- case 3: ar >> splitters; break;
- default:
- {
- vWarning() << "Serialized(In) Error";
- return false;
- }
- break;
- }
- }
- // 设置Splitter 在 UI 上无数据的时候的(应该是属性表无数据)Splitter 的 sizes 是无效的
- if (splitters.size()==2
- && splitters[0] > 0
- && splitters[1] > 0)
- {
- ui.splitter->setSizes(splitters);
- }
- }
- return true;
- }
- /// <summary>
- /// 刷新Undo/Redo按钮
- /// </summary>
- void WindowAppUiFrame::refreshUndoMenu()
- {
- if (actionUndo != nullptr)
- {
- actionUndo->setEnabled( ui.widgetUiView->uiScene()->m_CommandManager.canUndo());
- actionRedo->setEnabled( ui.widgetUiView->uiScene()->m_CommandManager.canRedo());
- }
- }
|