48 lines
2.5 KiB
Plaintext
48 lines
2.5 KiB
Plaintext
// 源 paint 产出真正进入窗口的 DisplayList;允许构造并修改本次计算的新命令,禁止改已有业务对象。
|
||
// 同一 rect 出现两次,两份命令随同一 tint 更新;业务身份共享,几何按 Mount 分开。
|
||
// 原生矩形测量不变,仅将绘制颜色切换为源字段 tint。
|
||
class TintRect: RectBlock {
|
||
tint: String
|
||
// 从原生基类取得当前出现位置的矩形命令,再修改本次返回列表中的颜色并交回。
|
||
function paint(self: TintRect, mount: Mount, geometry: Bounds): DisplayList {
|
||
drawing = RectBlock.paint(self, mount, geometry)
|
||
drawing.commands.at(0).color = self.tint
|
||
return drawing
|
||
}
|
||
}
|
||
// 在原生文字前增加圆角底色,背景大小使用实际分配 geometry 而不是固定猜测值。
|
||
class Badge: TextBlock {
|
||
background: String
|
||
// 先完整填写 roundedRect 命令,再取原生文字命令改成白色;列表顺序决定先画背景后画文字。
|
||
function paint(self: Badge, mount: Mount, geometry: Bounds): DisplayList {
|
||
fill = PaintCommand()
|
||
// 命令 kind 决定宿主解码所需字段,坐标/宽高来自本次 Mount,radius/color 由业务策略提供。
|
||
fill.kind = "roundedRect"
|
||
fill.x = geometry.x
|
||
fill.y = geometry.y
|
||
fill.width = geometry.width
|
||
fill.height = geometry.height
|
||
fill.radius = 6
|
||
fill.color = self.background
|
||
// 复用原生文字塑形和换行所需参数,避免手工文字命令漏掉边界。
|
||
text = TextBlock.paint(self, mount, geometry).commands.at(0)
|
||
text.color = "#FFFFFF"
|
||
return DisplayList(ObjectList(fill, text))
|
||
}
|
||
}
|
||
// 保存目标 TintRect,onEvent 是托管事件目标方法覆盖,不额外创建另一份状态。
|
||
class RecolorButton: Button {
|
||
target: TintRect
|
||
// 事件阶段可修改已有业务字段;依赖跟踪检测 tint 变化后重绘两个出现位置。
|
||
function onEvent(self: RecolorButton, event: Event): Unit {
|
||
self.target.tint = "#526AC7"
|
||
}
|
||
}
|
||
// 两次使用 rect 是同一对象,Badge 与按钮独立;根容器只组合它们,不复制业务数据。
|
||
rect = TintRect(200, 60, 12, "#DDEEFF", "#ED6A5A")
|
||
badge = Badge("Endor 源码正在绘制这个背景", 2, "#237A45")
|
||
button = RecolorButton("通过对象方法改变绘制颜色", rect)
|
||
root = Column(24, 16, TextBlock("源码 paint 进入真实窗口", 2), rect, rect, badge, button)
|
||
page = Page()
|
||
page.render(root)
|