#include "WindowAppUiView.h" #include "WindowAppUiTool.h" #include "UiManager.h" #include "WindowAppUiNavView.h" #include "CommonDraw.h" #include "WindowAppUiFrame.h" #include "VPCommand.h" #include "vpControls/VControlObject.h" WindowAppUiView::WindowAppUiView(QWidget *parent) : QGraphicsView(parent) , m_pBkImage(nullptr) , m_parentFrame(nullptr) , m_pUiScene(nullptr) , m_nGridSize(UI_DEFAULT_GRID_SIZE) { // 设置为接收拖拽 this->setAcceptDrops(true); // 初始化方格背景(只需要初始化一次即可) this->initBkImage(); this->setBackgroundRole(QPalette::Light); this->setAutoFillBackground(true); m_pRubberBand = nullptr; // 设置View大小 this->resize(DEFAULT_UIVIEW_WIDTH + 1, DEFAULT_UIVIEW_HEIGHT+ 1); // 初始化并绑定Scene m_pUiScene = new WindowAppUiScene(this); //QRectF rc = this->rect(); m_pUiScene->setSceneRect(QRectF(0, 0, DEFAULT_UIVIEW_WIDTH, DEFAULT_UIVIEW_HEIGHT)); this->setScene(m_pUiScene); this->centerOn(0, 0); // 全界面刷新,防止出现拖尾 this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); //设置橡皮筋选择选项 this->setDragMode(QGraphicsView::RubberBandDrag); // 设置抗锯齿(解决link 拖拽的时候,预览线有锯齿) this->setRenderHint(QPainter::Antialiasing, true); } WindowAppUiView::~WindowAppUiView() { RELEASE(m_pBkImage); } /// /// 初始化 /// /// /// /// void WindowAppUiView::init(const QString& strTitle, WindowAppUiNavView* navView, WindowAppUiFrame* parentFrame, ObjectController* objectController) { // 设置页面名称 this->m_strPageName = strTitle; // 2022-8-30 加入,绑定所属的Frame this->m_parentFrame = parentFrame; // 绑定属性表 m_pUiScene->m_pPropertyController = objectController; // 将当前Scene绑定到鸟瞰图中进行同步 navView->setScene(m_pUiScene); // 绑定同步的鸟瞰图 navView->setMainView(this); // 调整View navView->fitInView(navView->sceneRect(), Qt::KeepAspectRatio); // 向UI Manager注册本View g_pUiManager->registerNewUi(this); // 与Scene一起设置为左对齐 this->setAlignment(Qt::AlignLeft | Qt::AlignTop); } /// /// 初始化方格背景 /// void WindowAppUiView::initBkImage() { // 棋盘格背景 栅格背景 #if 0 m_pBkImage = new QPixmap(32, 32); QColor color1(60, 60, 60); QColor color2(45, 45, 45); m_pBkImage->fill(color1); QPainter painter1(m_pBkImage); painter1.fillRect(0, 0, 16, 16, color2); painter1.fillRect(16, 16, 16, 16, color2); painter1.end(); #else m_pBkImage = new QPixmap(QSize(static_cast(width()), static_cast(height()))); m_pBkImage->fill(qRgb(61, 61, 61)); // QPainter painter(m_pBkImage); // int gridSize = 10; // const int maxX = static_cast(std::ceil(width()) / gridSize) * gridSize; // const int maxY = static_cast(std::ceil(height()) / gridSize) * gridSize; // painter.setPen(qRgb(100, 100, 120)); // painter.setBrush(Qt::NoBrush); // for (int i = 0; i < maxX; i += gridSize) // { // for (int j = 0; j < maxY; j += gridSize) // { // painter.drawPoint(i, j); // } // } #endif } /// /// 绘制界面背景 /// /// /// void WindowAppUiView::drawBackground(QPainter* painter, const QRectF& rect) { if (m_pBkImage) { painter->drawTiledPixmap(rect, *m_pBkImage); } // 计算坐标 int nLeft = 0; int nTop = 0; int nWwidth = width() ; int nHeight = height() ; int nStepW = (nWwidth + nLeft) / 3; int nStepH = (nHeight + nTop) / 3; painter->setPen(UI_LINE_BK_PEN); // 画两条横线 painter->drawLine(QLine(nLeft, nStepH, nWwidth, nStepH)); painter->drawLine(QLine(nLeft, nStepH * 2, nWwidth, nStepH * 2)); // 画两条竖线 painter->drawLine(QLine(nStepW, nTop, nStepW, nHeight)); painter->drawLine(QLine(nStepW * 2, nTop, nStepW * 2, nHeight)); // 绘制背景栅格点 const int maxX = static_cast(std::ceil(width()) / UI_DEFAULT_GRID_SIZE) * UI_DEFAULT_GRID_SIZE; const int maxY = static_cast(std::ceil(height()) / UI_DEFAULT_GRID_SIZE) * UI_DEFAULT_GRID_SIZE; painter->setPen(UI_POINT_BK_PEN); painter->setBrush(Qt::NoBrush); for (int i = 0; i < maxX; i += UI_DEFAULT_GRID_SIZE) { for (int j = 0; j < maxY; j += UI_DEFAULT_GRID_SIZE) { painter->drawPoint(i, j); } } } /// /// 控件拖动完毕,在指定位置生成新的控件 /// /// void WindowAppUiView::dropEvent(QDropEvent* event) { //根据最后按下的控件位置生成控件 QPoint point = event->pos(); WindowAppUiTool* source = qobject_cast(event->source()); if (source) { int row = source->currentRow(); if (row < 0) { return; } //// 生成控件 //VControlObject* pNewControl = m_pUiScene->newControl(row, point); //// 向UI注册本控件(2022-10-7移到了Scene中进行操作) //g_pUiManager->regiterNewControl(pNewControl, this); // 将界面中用户选择的行数转换成对应的valueType VALUE_TYPE controlType = (VALUE_TYPE)(row + (int)VALUE_TYPE::Control_Base + 1); // 2022-10-7,将UI控件的添加整合进Undo体系 UiControlAddCommand* controlAddCommand = new UiControlAddCommand(m_pUiScene, controlType, mapToScene(point).toPoint()); m_pUiScene->m_CommandManager.executeCommand(controlAddCommand); // 表示本事件可以在本窗体中拖动对象 event->acceptProposedAction(); return; } else { event->ignore(); QWidget::dropEvent(event); } } ///// ///// 当控件正在拖动过程中 ///// ///// //void WindowAppUiView::dragEnterEvent(QDragEnterEvent* event) //{ // //if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist")) { // event->setDropAction(Qt::MoveAction); // event->accept(); // //} // //else { // // event->ignore(); // //} //} /// /// 拖动中的移动消息 /// /// void WindowAppUiView::dragMoveEvent(QDragMoveEvent* event) { event->acceptProposedAction(); event->accept(); } //鼠标在窗体中按下时,创建一个QRubberBand 类,QRubberBand::Rectangle 是设置橡皮筋线的类型, //这种线的效果是描绘了一个方形的区域,还有一种是QRubberBand::Line,则为一个被直线填满的方形区域, //相当于一个阴影的方形区域。QRubberBand 应用最多的函数是 setGeometry(),其作用是设置了橡皮筋线的位置及大小。 void WindowAppUiView::mousePressEvent(QMouseEvent* e) { m_tmpPoint = e->pos(); if (!m_pRubberBand) { m_pRubberBand = new QRubberBand(QRubberBand::Line, this); } m_pRubberBand->setGeometry(QRect(m_tmpPoint, QSize())); m_pRubberBand->show(); } //在鼠标按下,并且鼠标发生移动的时候,这时就可以会出橡皮线的区域, //鼠标拖动事件函数重载如下 改区域的大小由QRect(origin,e->pos()).normalized()) 来体现, //其中normalized() 函数返回的也是一个QRect的对象,不过该对象的长和宽的值都是大于零时值 void WindowAppUiView::mouseMoveEvent(QMouseEvent* e) { if (m_pRubberBand) { m_pRubberBand->setGeometry(QRect(m_tmpPoint, e->pos()).normalized()); } } /// /// 当鼠标松开时,橡皮筋线就可以隐藏了 /// /// void WindowAppUiView::mouseReleaseEvent(QMouseEvent* e) { Q_UNUSED(e); if (m_pRubberBand) { m_pRubberBand->hide(); } } /// /// 尺寸改变后,同步调整Scene的尺寸 /// /// void WindowAppUiView::resizeEvent(QResizeEvent* resizeEvent) { // qDebug() << "WindowAppUiView::resizeEvent - " << resizeEvent->size(); int newWidth = resizeEvent->size().width(); int newHeight = resizeEvent->size().height(); m_pUiScene->setSceneRect(QRectF(0, 0, newWidth, newHeight)); emit navigatorViewRequired(true, transform()); } /// /// 序列化 /// /// /// /// QDataStream& operator<<(QDataStream& out, WindowAppUiView* pView) { if (pView != nullptr) { // 序列化UI中的控件 pView->uiScene()->serialized(out, false); // 序列化Frame中的参数 pView->m_parentFrame->serialized(out, false); } // Error else { vDebug() << "[Error] WindowAppUiView - operator<< failed, pView == nullptr"; } return out; } /// /// 反序列化 /// /// /// /// QDataStream& operator>>(QDataStream& in, WindowAppUiView* pView) { if (pView != nullptr) { // 反序列化UI中的控件 pView->uiScene()->serialized(in, true); // 序列化Frame中的参数 pView->m_parentFrame->serialized(in, true); } // Error else { vDebug() << "[Error] WindowAppUiView - operator>> failed, pView == nullptr"; } return in; } ///// ///// 更新用户设定的尺寸 ///// ///// ///// //void WindowAppUiView::updateUiSize(int nWidth, int nHeight) //{ // //} ///// ///// dll中的控件同步消息 ///// ///// ///// //void WindowAppUiView::controlSync(QWidget* pWidget, UI_SYNC_MSG msg) //{ // // 查找本窗体中是否有此控件 // for (int i = 0; i < selectWidgets.count(); i++) // { // VControlObject* pControlObject = qobject_cast(selectWidgets.at(i)->getWidget()); // // if (pControlObject->m_pDllControl == pWidget) // { // // // break; // } // } //} ///// ///// 过滤子控件消息 ///// ///// ///// ///// //bool WindowAppUiView::eventFilter(QObject* object, QEvent* event) //{ // if (object->objectName() == CLASS_NAME_LINEDIT) // { // if (event->type() == QEvent::Paint) // { // qDebug() << "WindowAppUiView::eventFilter - " << ((VLineEdit*)object)->getText(); // // // 向dll同步 // g_pUiManager->syncToDll(object, UI_SYNC_MSG::EDIT_TEXT_CHANGED); // } // } // // // qDebug() << object->objectName(); // // return QWidget::eventFilter(object, event); //}