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)
{
discardBackground();
invalidateBackgroundSnapshot();
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);
}
if (!visible)
this->updateBackground();
discardBackground();
}
void Canvas::setDirty(bool dirty)
+13 -5
View File
@@ -58,7 +58,7 @@ void Control::setIsVisible(bool show)
if (!show)
{
// 隐藏:擦除自己在屏幕上的内容,并释放快照
this->updateBackground();
discardBackground();
return;
}
@@ -74,7 +74,7 @@ void Control::onWindowResize()
<< SX_T(" -> 丢背景快照 + 标脏", " -> discardSnap + dirty");
// 自己:丢快照 + 标脏
discardBackground();
invalidateBackgroundSnapshot();
setDirty(true);
}
void Control::setLayoutMode(StellarX::LayoutMode layoutMode_)
@@ -200,8 +200,16 @@ void Control::discardBackground()
hasSnap = false; saveWidth = saveHeight = 0;
}
void Control::updateBackground()
void Control::invalidateBackgroundSnapshot()
{
restBackground();
discardBackground();
if (saveBkImage)
{
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);
// putimage 回屏
virtual void restBackground();
// 释放快照(窗口重绘/尺寸变化后必须作废)
// 回贴旧背景并释放快照
void discardBackground();
public:
//释放快照重新保存,在尺寸变化时更新背景快照避免尺寸变化导致显示错位
void updateBackground();
//窗口变化丢快照
// 仅作废快照,不回贴旧背景
void invalidateBackgroundSnapshot();
//“纯作废快照 + 标脏”,不再在 resize 路径里回贴旧背景
virtual void onWindowResize();
// 获取位置和尺寸
int getX() const { return x; }
+6 -1
View File
@@ -247,6 +247,8 @@ void Dialog::setInitialization(bool init)
{
if (init)
{
// 窗口缩放后的重建不能再回贴旧快照;父窗口接下来会做一次完整重绘。
invalidateBackgroundSnapshot();
invalidateLayout(true);
}
else
@@ -659,7 +661,7 @@ void Dialog::performDelayedCleanup()
{
restBackground();
FlushBatchDraw();
discardBackground();
invalidateBackgroundSnapshot();
}
if (!(saveBkImage && hasSnap))
{
@@ -701,6 +703,9 @@ std::string Dialog::GetText() const
void Dialog::clearControls()
{
for (auto& control : controls)
control->invalidateBackgroundSnapshot();
controls.clear();
// 重置按钮指针
closeButton = nullptr;
+1 -2
View File
@@ -56,8 +56,7 @@ void Label::draw()
//用于“隐藏提示框”时调用(还原并释放快照)
void Label::hide()
{
restBackground(); // 还原屏幕像素
discardBackground(); // 作废快照,防止错贴旧图
discardBackground(); // 还原并释放快照
dirty = false;
}
void Label::setTextdisap(bool key)
+1 -1
View File
@@ -423,7 +423,7 @@ void Table::draw()
// 当尺寸变化或缓存图像无效时,需要重新截图
if (!saveBkImage || saveWidth != this->width || saveHeight != this->height)
{
discardBackground();
invalidateBackgroundSnapshot();
saveBackground(this->x, this->y, this->width, this->height);
}
}
+1 -2
View File
@@ -273,7 +273,7 @@ void Window::draw()
{
hWnd = initgraph(width, height, windowMode);
}
// 子类化:让我们的 WndProcThunk 接管窗口消息(仅执行一次)
if (!procHooked)
{
@@ -779,7 +779,6 @@ void Window::pumpResizeIfNeeded()
for (auto& c : controls)
{
adaptiveLayout(c, finalH, finalW);
c->onWindowResize();
}
for (auto& d : dialogs)
if (auto* dd = dynamic_cast<Dialog*>(d.get()))
+5 -3
View File
@@ -1,6 +1,6 @@
// 本工具基于 StellarX 构建,轻量级的 Windows GUI 框架。
#include"StellarX.h"
#define KEY 1
#define KEY 2
#if 1 == KEY
int main()
@@ -560,6 +560,8 @@ int main()
configuration->addControl(std::move(signedToggle));
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(function));
mainWindow.addControl(std::move(NumericalDisplayArea));
@@ -580,7 +582,7 @@ int main()
{
StellarX::SxLogger::setGBK();
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
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[1]->getText())logIn_textBox_ptr[1]->setTextBoxBk(RGB(255, 0, 0));
std::cout << "\a";
StellarX::MessageBox::showAsync(win, "账号或密码不能为空!", "提示");
StellarX::MessageBox::showModal(win, "账号或密码不能为空!", "提示");
}
else
{