123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #include "WindowAppIsometricLineManager.h"
- #include "WindowAppUiScene.h"
- WindowAppIsometricLineManager::WindowAppIsometricLineManager() :
- m_pScene(nullptr)
- {
- }
- /// <summary>
- /// 根据主控件和其他控件的关系进行等宽线的判断(核心逻辑)
- /// </summary>
- /// <param name="srcWidget"></param>
- /// <param name="dstWidgets"></param>
- void WindowAppIsometricLineManager::check(QWidget* srcWidget, QList<QWidget*> dstWidgets, STRETCH_DIRECTION dir)
- {
- // 由于等宽线只会在移动到某一个固定位置的时候出现,所以每次检查前都直接清空之前的重新绘制即可
- this->clear();
- // 是否有高度相同的控件
- // MEMO:先判断是否有高度相同,最后再根据拖拽的位置在决定在源控件的哪个方向上绘制等宽线
- // 因为各个目标控件的等宽线位置是固定的,固定在右侧和下侧,但是源控件根据拖拽位置不同而不同
- bool bSameHeight = false; // 是否有高度相同的控件
- bool bSameWidth = false; // 是否有宽度相同的控件
- // 遍历所有目标控件(只需要比较右侧和下侧即可)
- for (QWidget* dstWidget : dstWidgets)
- {
- // 首先检查高度
- bool bRet = this->checkHeight(srcWidget, dstWidget, dir);
- // 如果高度相同,那么设置一个源控件需要绘制高度方向等宽线的标记
- // 因为无论有多少个高度相同,源控件只需要绘制一次等高线
- bSameHeight ? bSameHeight : bSameHeight = bRet;
- // 继续检查宽度
- bRet = this->checkWidth(srcWidget, dstWidget, dir);
- // 如果宽度相同,那么设置一个源控件需要绘制宽度方向等宽线的标记
- bSameWidth ? bSameWidth : bSameWidth = bRet;
- }
- // 遍历完毕之后,判断是否需要绘制源控件的等宽线
- this->checkSourceWidget(srcWidget, bSameHeight, bSameWidth, dir);
- }
- /// <summary>
- /// 比较高度
- /// </summary>
- /// <param name="srcWidget"></param>
- /// <param name="dstWidget"></param>
- /// <param name="dir"></param>
- /// <returns>返回高度是否相同</returns>
- bool WindowAppIsometricLineManager::checkHeight(QWidget* srcWidget, QWidget* dstWidget, STRETCH_DIRECTION dir)
- {
- // 源边(仅比较右侧即可)
- QLine srcRighLine = Utility::getSideLineByID(srcWidget, (short)SIDE_DIRECTION::SIDE_RIGHT);
- // 目标边(仅比较右侧即可)
- QLine dstRightLine = Utility::getSideLineByID(dstWidget, (short)SIDE_DIRECTION::SIDE_RIGHT);
- // 比较右侧长度是否相同
-
- // 如果右侧相同
- if (srcRighLine.dy() == dstRightLine.dy())
- {
- // 如果拉伸的不是左右两侧,那么就需要绘制等高线
- if (dir != STRETCH_DIRECTION::DIR_LEFT && dir != STRETCH_DIRECTION::DIR_RIGHT)
- {
- // 生成一个新的等高线(高度方向)
- UI_ISOLINE_INFO newLine;
- newLine.pWidget = dstWidget;
- newLine.sideDir = SIDE_DIRECTION::SIDE_RIGHT;
- this->newIsoLine(newLine);
- // vDebug() << "Add height isometric line in [" << dstWidget << "] Side:" << (short)newLine.sideDir;
- // 返回高度相同
- return true;
- }
- }
- // 高度不相同
- return false;
- }
- /// <summary>
- /// 比较宽度
- /// </summary>
- /// <param name="srcWidget"></param>
- /// <param name="dstWidget"></param>
- /// <param name="dir"></param>
- /// <returns>返回宽度是否相同</returns>
- bool WindowAppIsometricLineManager::checkWidth(QWidget* srcWidget, QWidget* dstWidget, STRETCH_DIRECTION dir)
- {
- // 源边(仅比较下侧即可)
- QLine srcBottomLine = Utility::getSideLineByID(srcWidget, (short)SIDE_DIRECTION::SIDE_BOTTOM);
- // 目标边(仅比较下侧即可)
- QLine dstBottomLine = Utility::getSideLineByID(dstWidget, (short)SIDE_DIRECTION::SIDE_BOTTOM);
- // 比较下侧长度是否相同
- // 如果下侧相同
- if (srcBottomLine.dx() == dstBottomLine.dx())
- {
- // 如果拉伸的不是上下两侧,那么就需要绘制等宽线
- if (dir != STRETCH_DIRECTION::DIR_TOP && dir != STRETCH_DIRECTION::DIR_BOTTOM)
- {
- // 生成一个新的等宽线(宽度方向)
- UI_ISOLINE_INFO newLine;
- newLine.pWidget = dstWidget;
- newLine.sideDir = SIDE_DIRECTION::SIDE_BOTTOM;
- this->newIsoLine(newLine);
- // vDebug() << "Add width isometric line in [" << dstWidget << "] Side:" << (short)newLine.sideDir;
- // 返回高度相同
- return true;
- }
- }
- // 宽度不同
- return false;
- }
- /// <summary>
- /// 检查是否需要绘制源控件的等宽线
- /// </summary>
- /// <param name="srcWidget"></param>
- /// <param name="bSameHeight"></param>
- /// <param name="bSameWidth"></param>
- /// <param name="dir"></param>
- /// <returns></returns>
- bool WindowAppIsometricLineManager::checkSourceWidget(
- QWidget* srcWidget,
- bool bSameHeight,
- bool bSameWidth,
- STRETCH_DIRECTION dir
- )
- {
- // 如果高度相同,生成一个新的源控件等高线
- if (bSameHeight)
- {
- UI_ISOLINE_INFO newLine;
- newLine.pWidget = srcWidget;
- newLine.sideDir = SIDE_DIRECTION::SIDE_RIGHT; // 此处虽然是右侧,但是源控件的等宽线不一定生成在右侧
- newLine.stretchDir = dir;
- this->newIsoLine(newLine);
- }
- // 如果宽度相同,生成一个新的源控件等宽线
- if (bSameWidth)
- {
- UI_ISOLINE_INFO newLine;
- newLine.pWidget = srcWidget;
- newLine.sideDir = SIDE_DIRECTION::SIDE_BOTTOM; // 此处虽然是下侧,但是源控件的等宽线不一定生成在下侧
- newLine.stretchDir = dir;
- this->newIsoLine(newLine);
- }
- return false;
- }
- /// <summary>
- /// 清空所有的等宽线
- /// </summary>
- void WindowAppIsometricLineManager::clear()
- {
- QVector<WindowAppItemIsometricLine*>::iterator itr = m_IsoLines.begin();
- for (; itr != m_IsoLines.end();)
- {
- // 清空当前等宽线
- m_pScene->removeItem(*itr);
- itr = m_IsoLines.erase(itr);
- }
- this->m_IsoLines.clear();
- }
- /// <summary>
- /// 生成新的等宽线
- /// </summary>
- /// <param name="info"></param>
- void WindowAppIsometricLineManager::newIsoLine(const UI_ISOLINE_INFO& info)
- {
- // 根据对齐参数新建等宽线
- WindowAppItemIsometricLine* newLine = new WindowAppItemIsometricLine(info);
- // 添加到Scene
- m_pScene->addItem(newLine);
- // 加入到参考线组
- m_IsoLines.push_back(newLine);
- }
|