Finalize layout stage 2 fixes and refresh regression scenes
This commit is contained in:
+83
-1
@@ -432,6 +432,8 @@ bool Button::handleEvent(const ExMessage& msg)
|
||||
// 事件吞噬规则:
|
||||
// - 鼠标移动:只有“当前命中按钮”时才吞掉,避免前一个按钮在清 hover 时截断消息,
|
||||
// 导致后一个真正命中的按钮收不到 WM_MOUSEMOVE。
|
||||
// 这里的前提是:父容器会保证“没有拿到真实消息的后续兄弟”还能走一遍
|
||||
// clearTransientMouseState(),从而清掉旧 hover / tooltip。
|
||||
// - 鼠标按下/抬起:命中按钮区域时吞掉,避免点击穿透到底层控件。
|
||||
if (msg.message == WM_MOUSEMOVE)
|
||||
{
|
||||
@@ -451,6 +453,79 @@ bool Button::handleEvent(const ExMessage& msg)
|
||||
return consume;
|
||||
}
|
||||
|
||||
bool Button::clearTransientMouseState()
|
||||
{
|
||||
if (!show)
|
||||
return false;
|
||||
|
||||
bool hoverChanged = false;
|
||||
bool normalClickChanged = false;
|
||||
bool bodyVisualChanged = false;
|
||||
bool tooltipChanged = false;
|
||||
|
||||
if (hover)
|
||||
{
|
||||
hover = false;
|
||||
hoverChanged = true;
|
||||
bodyVisualChanged = true;
|
||||
}
|
||||
|
||||
// NORMAL 模式下的按下态只属于一次鼠标交互过程;
|
||||
// 如果本次 WM_MOUSEMOVE 已经被同层更上层的兄弟控件消费,
|
||||
// 当前按钮就不应继续保留这笔临时按下视觉。
|
||||
if (mode == StellarX::ButtonMode::NORMAL && click)
|
||||
{
|
||||
click = false;
|
||||
normalClickChanged = true;
|
||||
bodyVisualChanged = true;
|
||||
}
|
||||
|
||||
if (tipVisible)
|
||||
{
|
||||
hideTooltip();
|
||||
tooltipChanged = true;
|
||||
}
|
||||
|
||||
const bool stateChanged = bodyVisualChanged || tooltipChanged;
|
||||
if (!stateChanged)
|
||||
return false;
|
||||
|
||||
SX_LOG_TRACE("Event")
|
||||
<< SX_T("清理按钮鼠标临时状态:id=", "clear button transient mouse state: id=")
|
||||
<< id
|
||||
<< SX_T(" hover=", " hover=") << (hoverChanged ? 1 : 0)
|
||||
<< SX_T(" tooltip=", " tooltip=") << (tooltipChanged ? 1 : 0)
|
||||
<< SX_T(" normalClick=", " normalClick=") << (normalClickChanged ? 1 : 0);
|
||||
|
||||
markEventVisualChanged(true);
|
||||
|
||||
// 只有按钮本体视觉真正变化时,才请求按钮自身区域重绘;
|
||||
// 若只是 Tooltip 消失,hideTooltip() 已经通过回贴快照清掉了悬浮层区域,
|
||||
// 不再额外重绘按钮本体,避免高频鼠标移动时的无意义重画。
|
||||
if (bodyVisualChanged)
|
||||
{
|
||||
dirty = true;
|
||||
requestRepaint(parent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RECT Button::getManagedRepaintCoverageRect() const
|
||||
{
|
||||
RECT coverage = getBoundsRect();
|
||||
|
||||
if (!tipEnabled || !tipVisible)
|
||||
return coverage;
|
||||
|
||||
const RECT tipRect = tipLabel.getManagedRepaintCoverageRect();
|
||||
coverage.left = (std::min)(coverage.left, tipRect.left);
|
||||
coverage.top = (std::min)(coverage.top, tipRect.top);
|
||||
coverage.right = (std::max)(coverage.right, tipRect.right);
|
||||
coverage.bottom = (std::max)(coverage.bottom, tipRect.bottom);
|
||||
return coverage;
|
||||
}
|
||||
|
||||
void Button::setOnClickListener(std::function<void()> callback)
|
||||
{
|
||||
this->onClickCallback = std::move(callback);
|
||||
@@ -558,7 +633,14 @@ void Button::setButtonShape(StellarX::ControlShape shape)
|
||||
//允许通过外部函数修改按钮的点击状态,并执行相应的回调函数
|
||||
void Button::setButtonClick(BOOL click)
|
||||
{
|
||||
this->click = click;
|
||||
const bool targetClick = (click != FALSE);
|
||||
// TOGGLE 状态若没有发生变化,就不应重复触发 onToggleOn/OffCallback。
|
||||
// 否则像 TabControl 这种“外部再次激活已激活页签”的场景,
|
||||
// 会把页面显示/隐藏、快照失效、重绘链整条重复执行一遍,最终破坏可见页的背景恢复语义。
|
||||
if (mode == StellarX::ButtonMode::TOGGLE && this->click == targetClick)
|
||||
return;
|
||||
|
||||
this->click = targetClick;
|
||||
|
||||
if (mode == StellarX::ButtonMode::NORMAL && click)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user