Refine snapshot invalidation and modal resize behavior

This commit is contained in:
Codex
2026-03-29 20:47:04 +08:00
parent 4a6e153da5
commit 7f8431a18c
8 changed files with 33 additions and 20 deletions
+2 -2
View File
@@ -72,7 +72,7 @@ void Canvas::draw()
// 如果位置或尺寸变了,或没有有效缓存,则重新抓取 // 如果位置或尺寸变了,或没有有效缓存,则重新抓取
if (!saveBkImage || saveBkX != this->x - margin || saveBkY != this->y - margin || saveWidth != this->width + margin * 2 || saveHeight != this->height + margin * 2) if (!saveBkImage || saveBkX != this->x - margin || saveBkY != this->y - margin || saveWidth != this->width + margin * 2 || saveHeight != this->height + margin * 2)
{ {
discardBackground(); invalidateBackgroundSnapshot();
saveBackground(this->x - margin, this->y - margin, this->width + margin * 2, this->height + margin * 2); saveBackground(this->x - margin, this->y - margin, this->width + margin * 2, this->height + margin * 2);
} }
} }
@@ -231,7 +231,7 @@ void Canvas::setIsVisible(bool visible)
control->setIsVisible(visible); control->setIsVisible(visible);
} }
if (!visible) if (!visible)
this->updateBackground(); discardBackground();
} }
void Canvas::setDirty(bool dirty) void Canvas::setDirty(bool dirty)
+13 -5
View File
@@ -58,7 +58,7 @@ void Control::setIsVisible(bool show)
if (!show) if (!show)
{ {
// 隐藏:擦除自己在屏幕上的内容,并释放快照 // 隐藏:擦除自己在屏幕上的内容,并释放快照
this->updateBackground(); discardBackground();
return; return;
} }
@@ -74,7 +74,7 @@ void Control::onWindowResize()
<< SX_T(" -> 丢背景快照 + 标脏", " -> discardSnap + dirty"); << SX_T(" -> 丢背景快照 + 标脏", " -> discardSnap + dirty");
// 自己:丢快照 + 标脏 // 自己:丢快照 + 标脏
discardBackground(); invalidateBackgroundSnapshot();
setDirty(true); setDirty(true);
} }
void Control::setLayoutMode(StellarX::LayoutMode layoutMode_) void Control::setLayoutMode(StellarX::LayoutMode layoutMode_)
@@ -200,8 +200,16 @@ void Control::discardBackground()
hasSnap = false; saveWidth = saveHeight = 0; hasSnap = false; saveWidth = saveHeight = 0;
} }
void Control::updateBackground() void Control::invalidateBackgroundSnapshot()
{ {
restBackground(); if (saveBkImage)
discardBackground(); {
SX_LOGD("Snap") << SX_T("作废背景快照:id=", "invalidateBackgroundSnapshot: id=") << id
<< " hasSnap=" << (hasSnap ? 1 : 0);
saveBkImage.reset();
}
hasSnap = false;
saveBkX = saveBkY = 0;
saveWidth = saveHeight = 0;
} }
+4 -4
View File
@@ -86,12 +86,12 @@ protected:
virtual void saveBackground(int x, int y, int w, int h); virtual void saveBackground(int x, int y, int w, int h);
// putimage 回屏 // putimage 回屏
virtual void restBackground(); virtual void restBackground();
// 释放快照(窗口重绘/尺寸变化后必须作废) // 回贴旧背景并释放快照
void discardBackground(); void discardBackground();
public: public:
//释放快照重新保存,在尺寸变化时更新背景快照避免尺寸变化导致显示错位 // 仅作废快照,不回贴旧背景
void updateBackground(); void invalidateBackgroundSnapshot();
//窗口变化丢快照 //“纯作废快照 + 标脏”,不再在 resize 路径里回贴旧背景
virtual void onWindowResize(); virtual void onWindowResize();
// 获取位置和尺寸 // 获取位置和尺寸
int getX() const { return x; } int getX() const { return x; }
+6 -1
View File
@@ -247,6 +247,8 @@ void Dialog::setInitialization(bool init)
{ {
if (init) if (init)
{ {
// 窗口缩放后的重建不能再回贴旧快照;父窗口接下来会做一次完整重绘。
invalidateBackgroundSnapshot();
invalidateLayout(true); invalidateLayout(true);
} }
else else
@@ -659,7 +661,7 @@ void Dialog::performDelayedCleanup()
{ {
restBackground(); restBackground();
FlushBatchDraw(); FlushBatchDraw();
discardBackground(); invalidateBackgroundSnapshot();
} }
if (!(saveBkImage && hasSnap)) if (!(saveBkImage && hasSnap))
{ {
@@ -701,6 +703,9 @@ std::string Dialog::GetText() const
void Dialog::clearControls() void Dialog::clearControls()
{ {
for (auto& control : controls)
control->invalidateBackgroundSnapshot();
controls.clear(); controls.clear();
// 重置按钮指针 // 重置按钮指针
closeButton = nullptr; closeButton = nullptr;
+1 -2
View File
@@ -56,8 +56,7 @@ void Label::draw()
//用于“隐藏提示框”时调用(还原并释放快照) //用于“隐藏提示框”时调用(还原并释放快照)
void Label::hide() void Label::hide()
{ {
restBackground(); // 还原屏幕像素 discardBackground(); // 还原并释放快照
discardBackground(); // 作废快照,防止错贴旧图
dirty = false; dirty = false;
} }
void Label::setTextdisap(bool key) void Label::setTextdisap(bool key)
+1 -1
View File
@@ -423,7 +423,7 @@ void Table::draw()
// 当尺寸变化或缓存图像无效时,需要重新截图 // 当尺寸变化或缓存图像无效时,需要重新截图
if (!saveBkImage || saveWidth != this->width || saveHeight != this->height) if (!saveBkImage || saveWidth != this->width || saveHeight != this->height)
{ {
discardBackground(); invalidateBackgroundSnapshot();
saveBackground(this->x, this->y, this->width, this->height); saveBackground(this->x, this->y, this->width, this->height);
} }
} }
-1
View File
@@ -779,7 +779,6 @@ void Window::pumpResizeIfNeeded()
for (auto& c : controls) for (auto& c : controls)
{ {
adaptiveLayout(c, finalH, finalW); adaptiveLayout(c, finalH, finalW);
c->onWindowResize();
} }
for (auto& d : dialogs) for (auto& d : dialogs)
if (auto* dd = dynamic_cast<Dialog*>(d.get())) if (auto* dd = dynamic_cast<Dialog*>(d.get()))
+5 -3
View File
@@ -1,6 +1,6 @@
// 本工具基于 StellarX 构建,轻量级的 Windows GUI 框架。 // 本工具基于 StellarX 构建,轻量级的 Windows GUI 框架。
#include"StellarX.h" #include"StellarX.h"
#define KEY 1 #define KEY 2
#if 1 == KEY #if 1 == KEY
int main() int main()
@@ -560,6 +560,8 @@ int main()
configuration->addControl(std::move(signedToggle)); configuration->addControl(std::move(signedToggle));
configuration->addControl(std::move(configurationLabel)); configuration->addControl(std::move(configurationLabel));
selectionArea->setAnchor(StellarX::Anchor::Right, StellarX::Anchor::Left);
selectionArea->setLayoutMode(StellarX::LayoutMode::AnchorToEdges);
mainWindow.addControl(std::move(selectionArea)); mainWindow.addControl(std::move(selectionArea));
mainWindow.addControl(std::move(function)); mainWindow.addControl(std::move(function));
mainWindow.addControl(std::move(NumericalDisplayArea)); mainWindow.addControl(std::move(NumericalDisplayArea));
@@ -580,7 +582,7 @@ int main()
{ {
StellarX::SxLogger::setGBK(); StellarX::SxLogger::setGBK();
StellarX::SxLogger::Get().enableConsole(true); StellarX::SxLogger::Get().enableConsole(true);
StellarX::SxLogger::Get().setMinLevel(StellarX::SxLogLevel::Trace); // Info/Debug/Trace 自己切 StellarX::SxLogger::Get().setMinLevel(StellarX::SxLogLevel::Debug); // Info/Debug/Trace 自己切
StellarX::SxLogger::Get().setLanguage(StellarX::SxLogLanguage::ZhCN); // ZhCN / EnUS StellarX::SxLogger::Get().setLanguage(StellarX::SxLogLanguage::ZhCN); // ZhCN / EnUS
Window win(1300, 800, 1, RGB(255, 255, 0), "记账管理系统"); Window win(1300, 800, 1, RGB(255, 255, 0), "记账管理系统");
@@ -691,7 +693,7 @@ int main()
if ("\0" == logIn_textBox_ptr[0]->getText())logIn_textBox_ptr[0]->setTextBoxBk(RGB(255, 0, 0)); if ("\0" == logIn_textBox_ptr[0]->getText())logIn_textBox_ptr[0]->setTextBoxBk(RGB(255, 0, 0));
if ("\0" == logIn_textBox_ptr[1]->getText())logIn_textBox_ptr[1]->setTextBoxBk(RGB(255, 0, 0)); if ("\0" == logIn_textBox_ptr[1]->getText())logIn_textBox_ptr[1]->setTextBoxBk(RGB(255, 0, 0));
std::cout << "\a"; std::cout << "\a";
StellarX::MessageBox::showAsync(win, "账号或密码不能为空!", "提示"); StellarX::MessageBox::showModal(win, "账号或密码不能为空!", "提示");
} }
else else
{ {