Initial baseline
This commit is contained in:
+207
@@ -0,0 +1,207 @@
|
||||
#include "Control.h"
|
||||
#include "SxLog.h"
|
||||
#include<assert.h>
|
||||
|
||||
StellarX::ControlText& StellarX::ControlText::operator=(const ControlText& text)
|
||||
{
|
||||
{
|
||||
nHeight = text.nHeight;
|
||||
nWidth = text.nWidth;
|
||||
lpszFace = text.lpszFace;
|
||||
color = text.color;
|
||||
nEscapement = text.nEscapement;
|
||||
nOrientation = text.nOrientation;
|
||||
nWeight = text.nWeight;
|
||||
bItalic = text.bItalic;
|
||||
bUnderline = text.bUnderline;
|
||||
bStrikeOut = text.bStrikeOut;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
bool StellarX::ControlText::operator!=(const ControlText& text)
|
||||
{
|
||||
if(nHeight != text.nHeight)
|
||||
return true;
|
||||
else if (nWidth != text.nWidth)
|
||||
return true;
|
||||
else if (lpszFace != text.lpszFace)
|
||||
return true;
|
||||
else if (color != text.color)
|
||||
return true;
|
||||
else if (nEscapement != text.nEscapement)
|
||||
return true;
|
||||
else if (nOrientation != text.nOrientation)
|
||||
return true;
|
||||
else if (nWeight != text.nWeight)
|
||||
return true;
|
||||
else if (bItalic != text.bItalic)
|
||||
return true;
|
||||
else if (bUnderline != text.bUnderline)
|
||||
return true;
|
||||
else if (bStrikeOut != text.bStrikeOut)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
void Control::setIsVisible(bool show)
|
||||
{
|
||||
SX_LOGD("Control") << SX_T("重置可见状态: id=", "setIsVisible: id=")
|
||||
<< id
|
||||
<< " show=" << (show ? 1 : 0);
|
||||
|
||||
if (this->show == show)
|
||||
return;
|
||||
|
||||
this->show = show;
|
||||
this->dirty = true;
|
||||
|
||||
if (!show)
|
||||
{
|
||||
// 隐藏:擦除自己在屏幕上的内容,并释放快照
|
||||
this->updateBackground();
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示:不在这里 requestRepaint(避免父容器快照未就绪时子控件抢跑 draw,污染快照)
|
||||
// 仅向上标脏,让事件收口阶段由容器统一重绘。
|
||||
if (parent)
|
||||
parent->setDirty(true);
|
||||
}
|
||||
|
||||
void Control::onWindowResize()
|
||||
{
|
||||
SX_LOGD("Layout") << SX_T("尺寸变化:id=", "onWindowResize: id=") << id
|
||||
<< SX_T(" -> 丢背景快照 + 标脏", " -> discardSnap + dirty");
|
||||
|
||||
// 自己:丢快照 + 标脏
|
||||
discardBackground();
|
||||
setDirty(true);
|
||||
}
|
||||
void Control::setLayoutMode(StellarX::LayoutMode layoutMode_)
|
||||
{
|
||||
this->layoutMode = layoutMode_;
|
||||
}
|
||||
void Control::setAnchor(StellarX::Anchor anchor_1, StellarX::Anchor anchor_2)
|
||||
{
|
||||
this->anchor_1 = anchor_1;
|
||||
this->anchor_2 = anchor_2;
|
||||
}
|
||||
StellarX::Anchor Control::getAnchor_1() const
|
||||
{
|
||||
return this->anchor_1;
|
||||
}
|
||||
StellarX::Anchor Control::getAnchor_2() const
|
||||
{
|
||||
return this->anchor_2;
|
||||
}
|
||||
StellarX::LayoutMode Control::getLayoutMode() const
|
||||
{
|
||||
return this->layoutMode;
|
||||
}
|
||||
// 保存当前的绘图状态(字体、颜色、线型等)
|
||||
// 在控件绘制前调用,确保不会影响全局绘图状态
|
||||
void Control::saveStyle()
|
||||
{
|
||||
|
||||
gettextstyle(¤tFont); // 获取当前字体样式
|
||||
currentColor = gettextcolor(); // 获取当前字体颜色
|
||||
currentBorderColor = getlinecolor(); //保存当前边框颜色
|
||||
getlinestyle(¤tLineStyle); //保存当前线型
|
||||
currentBkColor = getfillcolor(); //保存当前填充色
|
||||
}
|
||||
// 恢复之前保存的绘图状态
|
||||
// 在控件绘制完成后调用,恢复全局绘图状态
|
||||
void Control::restoreStyle()
|
||||
{
|
||||
settextstyle(¤tFont); // 恢复默认字体样式
|
||||
settextcolor(currentColor); // 恢复默认字体颜色
|
||||
setfillcolor(currentBkColor);
|
||||
setlinestyle(¤tLineStyle);
|
||||
setlinecolor(currentBorderColor);
|
||||
setfillstyle(BS_SOLID);//恢复填充
|
||||
}
|
||||
|
||||
void Control::requestRepaint(Control* parent)
|
||||
{
|
||||
// 说明:
|
||||
// - 常规路径:子控件调用 requestRepaint(this->parent),然后 parent 负责局部重绘(Canvas/TabControl override)
|
||||
// - 兜底路径:如果某个“容器控件”没 override requestRepaint,就会出现 parent==this 的递归风险
|
||||
// 此时我们改为向更上层冒泡,直到根重绘。
|
||||
if (parent == this)
|
||||
{
|
||||
SX_LOGW("Dirty")
|
||||
<< SX_T("requestRepaint(默认容器兜底):id=", "requestRepaint(default-container-fallback): id=")
|
||||
<< id
|
||||
<< SX_T(",parent==this,向上层 parent 继续冒泡", " parent==this, bubble to upper parent");
|
||||
|
||||
if (this->parent) this->parent->requestRepaint(this->parent);
|
||||
else onRequestRepaintAsRoot();
|
||||
return;
|
||||
}
|
||||
|
||||
SX_LOGD("Dirty") << SX_T("请求重绘:id=","requestRepaint: id=") << id << " parent=" << (parent ? parent->getId() : "null");
|
||||
|
||||
if (parent) parent->requestRepaint(parent); // 交给容器处理(容器可局部重绘)
|
||||
else onRequestRepaintAsRoot(); // 根兜底
|
||||
}
|
||||
|
||||
void Control::onRequestRepaintAsRoot()
|
||||
{
|
||||
SX_LOGI("Dirty")
|
||||
<< SX_T("触发根重绘:id=", "onRequestRepaintAsRoot: id=") << id
|
||||
<< SX_T("(从根节点开始重画)", " (root repaint)");
|
||||
|
||||
|
||||
discardBackground();
|
||||
setDirty(true);
|
||||
draw(); // 只有“无父”时才允许立即画,不会被谁覆盖
|
||||
}
|
||||
|
||||
void Control::saveBackground(int x, int y, int w, int h)
|
||||
{
|
||||
|
||||
if (w <= 0 || h <= 0) return;
|
||||
saveBkX = x; saveBkY = y; saveWidth = w; saveHeight = h;
|
||||
if (saveBkImage)
|
||||
{
|
||||
//尺寸变了才重建,避免反复 new/delete
|
||||
if (saveBkImage->getwidth() != w || saveBkImage->getheight() != h)
|
||||
{
|
||||
SX_LOGD("Snap") <<SX_T("重新保存背景快照:id=", "saveBackground rebuild: id=") << id << " size=(" << w << "x" << h << ")";
|
||||
|
||||
saveBkImage.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
SX_LOGD("Snap") << SX_T("保存背景快照:id=", "saveBackground rebuild: id=") << id << " size=(" << w << "x" << h << ")";
|
||||
if (!saveBkImage) saveBkImage = std::make_unique<IMAGE>(w, h);
|
||||
|
||||
SetWorkingImage(nullptr); // ★抓屏幕
|
||||
getimage(saveBkImage.get(), x, y, w, h);
|
||||
hasSnap = true;
|
||||
}
|
||||
|
||||
void Control::restBackground()
|
||||
{
|
||||
if (!hasSnap || !saveBkImage) return;
|
||||
// 直接回贴屏幕(与抓取一致)
|
||||
SetWorkingImage(nullptr);
|
||||
putimage(saveBkX, saveBkY, saveBkImage.get());
|
||||
}
|
||||
|
||||
void Control::discardBackground()
|
||||
{
|
||||
if (saveBkImage)
|
||||
{
|
||||
restBackground();
|
||||
SX_LOGD("Snap") << SX_T("丢弃背景快照:id=","discardBackground: id=") << id << " hasSnap=" << (hasSnap ? 1 : 0);
|
||||
saveBkImage.reset();
|
||||
}
|
||||
hasSnap = false; saveWidth = saveHeight = 0;
|
||||
}
|
||||
|
||||
void Control::updateBackground()
|
||||
{
|
||||
restBackground();
|
||||
discardBackground();
|
||||
}
|
||||
Reference in New Issue
Block a user