feat: add a new awesome feature
This commit is contained in:
+70
-8
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user