feat: add a new awesome feature

This commit is contained in:
2026-01-09 20:17:47 +08:00
parent 0c1cf2938f
commit 5cb59b3652
18 changed files with 1301 additions and 102 deletions
+70 -8
View File
@@ -1,4 +1,10 @@
#include "Canvas.h"
#include "SxLog.h"
static bool SxIsNoisyMsg(UINT m)
{
return m == WM_MOUSEMOVE;
}
Canvas::Canvas()
:Control(0, 0, 100, 100)
@@ -106,25 +112,57 @@ void Canvas::draw()
bool Canvas::handleEvent(const ExMessage& msg)
{
if (!show)return false;
if (!show) return false;
bool consumed = false;
bool anyDirty = false;
Control* firstConsumer = nullptr;
for (auto it = controls.rbegin(); it != controls.rend(); ++it)
{
consumed |= it->get()->handleEvent(msg);
if (it->get()->isDirty()) anyDirty = true;
Control* c = it->get();
bool cConsumed = c->handleEvent(msg);
if (cConsumed && !firstConsumer) firstConsumer = c;
consumed |= cConsumed;
if (c->isDirty()) anyDirty = true;
}
if (anyDirty) requestRepaint(parent);
if (firstConsumer && !SxIsNoisyMsg(msg.message))
{
SX_LOGD("Event") << SX_T("Canvas 消耗消息: ","Canvas consumed: msg=") << msg.message
<< SX_T("子控件"," by child")<<" id=" << firstConsumer->getId();
}
if (anyDirty)
{
if (!SxIsNoisyMsg(msg.message))
SX_LOGD("Dirty") << SX_T("Canvas检测有控件为脏状态 -> 请求重绘, ","Canvas anyDirty -> requestRepaint, ")<<"id = " << id;
requestRepaint(parent);
}
return consumed;
}
void Canvas::addControl(std::unique_ptr<Control> control)
{
//坐标转化
control->setX(control->getLocalX() + this->x);
control->setY(control->getLocalY() + this->y);
control->setParent(this);
SX_LOGI("Canvas")
<< SX_T("添加子控件:父=Canvas 子id=", "addControl: parent=Canvas childId=")
<< control->getId()
<< SX_T(" 相对坐标=(", " local=(")
<< control->getLocalX() << "," << control->getLocalY()
<< SX_T(") 绝对坐标=(", ") abs=(")
<< control->getX() << "," << control->getY()
<< ")";
controls.push_back(std::move(control));
dirty = true;
}
@@ -187,7 +225,6 @@ void Canvas::setIsVisible(bool visible)
for (auto& control : controls)
{
control->setIsVisible(visible);
control->setDirty(true);
}
if (!visible)
this->updateBackground();
@@ -375,10 +412,35 @@ void Canvas::requestRepaint(Control* parent)
{
if (this == parent)
{
if (!show)
return;
// 关键护栏:
// - Canvas 自己是脏的 / 没有快照 / 缓存图为空
// => 禁止局部重绘,直接升级为一次完整 draw(先把 dirty 置真,避免 draw() 早退)
if (dirty || !hasSnap || !saveBkImage)
{
SX_LOGD("Dirty")
<< SX_T("Canvas 局部重绘降级为全量重绘: id=", "Canvas partial->full draw: id=")
<< id
<< " dirty=" << (dirty ? 1 : 0)
<< " hasSnap=" << (hasSnap ? 1 : 0);
this->dirty = true;
this->draw();
return;
}
SX_LOGD("Dirty") << SX_T("Canvas 请求局部重绘:id=", "Canvas::requestRepaint(partial): id=") << id;
for (auto& control : controls)
if (control->isDirty() && control->IsVisible())
control->draw();
return;
}
else
onRequestRepaintAsRoot();
}
SX_LOGD("Dirty") << SX_T("Canvas 请求根级重绘:id=", "Canvas::requestRepaint(root): id=") << id;
onRequestRepaintAsRoot();
}