#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);
//}