UI 重构 P3(2):TabBar 迁移到控件树(逐像素 0 差异 + 4 条交互断言)
TabBar 的标签 / 「+」/ 覆盖层拆成控件,手势语义原样保留(自行判双击、3px 拖拽阈值、
关闭 ✕ 的「移开取消」、拖拽排序的 drop 位置),公开 API 未变:
- 新增(TabBar.cpp 内实现的内部控件)
* UiTabItemWidget:单格标签的绘制(底色/描边/激活指示条/文本或重命名输入框/关闭 ✕),
关闭按钮热区由基类的悬停点自行判定。
* UiAddWidget:「+」按钮绘制与悬停配色。
* UiOverlayWidget:命中透明的覆盖层,最后绘制「拖拽插入指示条 + 底部分隔线」
(必须晚于标签与「+」,否则会被它们压住)。
* UiTabRootWidget:只铺标签栏底色。
- TabBar 移除 m_hoverIndex / m_hoverClose / m_hoverAdd 三个手工下标,
改为 dispatch MOUSE_MOVE 后由 root->TakeDirty() 判断是否需要重绘。
- 绘制顺序保持:底色 → 各标签 → 「+」→ 拖拽指示条 → 底部分隔线(与旧实现逐像素一致)。
- UiWidget 新增 HoverPoint(x,y):派生控件据此自行判断「悬停在自身内部哪个热区」。
验证:
- 像素:8 场景哈希与迁移前逐一相同(A 2166933…、H 23F390D…)。
- 交互断言(全部 PASS):
* tabbar-hover-marks-dirty (1,0) —— 进入标签只标记一次脏区;
* tabbar-add-creates-tab (1 -> 2) —— 「+」新建标签;
* tabbar-click-selects-tab (active=0) —— 点击标签切换激活页;
* tabbar-close-removes-tab (2 -> 1) —— 点击 ✕ 关闭标签。
- Tools/uicheck 69 passed / 0 failed。
- make release / make debug 零警告;Target.exe 886,784 B(< 900KB)。
This commit is contained in:
1 parent
c4faa930e2
commit
c3b79a6d2c
6 files changed
+429
-127
No files matched your search
@@ -5,11 +5,13 @@
|
||||
#include <objidl.h>
|
||||
#include <gdiplus.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "PaintUtil.hpp"
|
||||
#include "Theme.hpp"
|
||||
#include "UiWidget.hpp"
|
||||
|
||||
namespace jdi
|
||||
{
|
||||
@@ -48,6 +50,7 @@ namespace jdi
|
||||
{
|
||||
public:
|
||||
TabBar();
|
||||
~TabBar();
|
||||
|
||||
/**
|
||||
* @brief 绑定字体与主题资源。
|
||||
@@ -240,14 +243,11 @@ namespace jdi
|
||||
const Theme* m_theme = nullptr; /**< 主题资源。 */
|
||||
float m_scale = 1.0f; /**< DPI 缩放比例。 */
|
||||
|
||||
std::vector<TabItem> m_tabs; /**< 标签页布局集合。 */
|
||||
std::vector<TabItem> m_tabs; /**< 标签页数据(名称 + 几何;几何由控件回写)。 */
|
||||
gd::RectF m_addRect; /**< 新建按钮矩形。 */
|
||||
gd::RectF m_area; /**< 标签栏整体区域。 */
|
||||
|
||||
int m_activeIndex = -1; /**< 当前激活标签页下标。 */
|
||||
int m_hoverIndex = -1; /**< 当前悬停标签页下标。 */
|
||||
bool m_hoverClose = false; /**< 是否悬停在关闭按钮上。 */
|
||||
bool m_hoverAdd = false; /**< 是否悬停在新建按钮上。 */
|
||||
int m_pressedIndex = -1; /**< 当前按下的标签页下标。 */
|
||||
bool m_pressedClose = false; /**< 是否按在关闭按钮上。 */
|
||||
bool m_pressedAdd = false; /**< 是否按在新建按钮上。 */
|
||||
@@ -263,6 +263,13 @@ namespace jdi
|
||||
|
||||
int m_lastClickIndex = -1; /**< 上一次单击的标签页下标(用于自行判定双击)。 */
|
||||
DWORD m_lastClickTick = 0; /**< 上一次单击的时刻。 */
|
||||
|
||||
/** 控件树根:负责底色与底部分隔线,子节点是各标签与「+」按钮。 */
|
||||
std::unique_ptr<UiWidget> m_root;
|
||||
/** 重建控件树(标签数量变化时调用)。 */
|
||||
void RebuildWidgets();
|
||||
/** 把标签数据/激活态/编辑态同步给控件并摆放。 */
|
||||
void ArrangeWidgets();
|
||||
};
|
||||
|
||||
} // namespace jdi
|
||||
|
||||
Reference in new issue
Block a user