fix(vpui): Label 自然尺寸与 pack 交叉轴居中
Input Demo 的两个显示问题: - Label 没有显式 w/h,构造后 w/h 恒为 0:pack 时按 0 尺寸计算, PACK_BOTTOM 的标签被贴到内容区底边之外(字模被裁),且不占纵向空间, 后面的按钮与 Name: 标签重叠。新增 _fit_natural() 按文本最长行/行数 计算自然尺寸,__init__ 与 config() 时更新。 - pack 在未 fill 时原先一律贴左上,导致 Submit 按钮紧贴左边缘。 改为与 tkinter 默认 anchor=center 一致:TOP/BOTTOM 横向居中、 LEFT/RIGHT 纵向居中,沿 pack 方向仍保留 padx/pady。 - redraw 先刷新窗口尺寸再 _do_layout(),避免 resize 后布局滞后一帧。
This commit is contained in:
1 parent
ad6f0f68a2
commit
338472e304
1 file changed
+40
-5
+40
-5
@@ -596,8 +596,31 @@ virtual class Label(Widget):
|
||||
self.text[i] = ch
|
||||
i += 1
|
||||
self.text[i] = 0
|
||||
# Label 没有显式 w/h 参数:自然尺寸必须由文本推出。否则 pack 拿到的请求尺寸是
|
||||
# 0×0 ⇒ 不占布局空间,且 PACK_BOTTOM/非 fill 时会被贴到可视区域之外(文字被裁掉)。
|
||||
self._fit_natural()
|
||||
_register_widget(master, Widget*(self))
|
||||
|
||||
# 按当前 text 计算自然尺寸:宽取最长行,高取行数(多行 Label 也成立)。
|
||||
def _fit_natural(self):
|
||||
line_chars: int = 0
|
||||
max_chars: int = 0
|
||||
lines: int = 1
|
||||
i: int = 0
|
||||
while i < 64:
|
||||
ch: char = self.text[i]
|
||||
if ch == 0: break
|
||||
if ch == 10:
|
||||
if line_chars > max_chars: max_chars = line_chars
|
||||
line_chars = 0
|
||||
lines += 1
|
||||
else:
|
||||
line_chars += 1
|
||||
i += 1
|
||||
if line_chars > max_chars: max_chars = line_chars
|
||||
self.w = max_chars * CHAR_W
|
||||
self.h = lines * CHAR_H
|
||||
|
||||
def draw(self, fb: uint32*, fw: int, fh: int):
|
||||
_draw_text(fb, fw, fh, self.x, self.y, &self.text[0], self.color)
|
||||
|
||||
@@ -613,6 +636,7 @@ virtual class Label(Widget):
|
||||
if ch == 0: break
|
||||
i += 1
|
||||
self.text[i] = 0
|
||||
self._fit_natural()
|
||||
if color is not None:
|
||||
self.color = color
|
||||
|
||||
@@ -1649,7 +1673,6 @@ virtual class Tk(Wm, Misc):
|
||||
# 窗口槽已回收(用户点了关闭):立即返回,不再触碰共享 arena / flush。
|
||||
if self.win_id < 0: return
|
||||
if window.is_active(self.win_id) == 0: return
|
||||
self._do_layout()
|
||||
self.buf = window.get_winbuf(self.win_id)
|
||||
sz: int = window.get_win_size(self.win_id)
|
||||
if sz != 0:
|
||||
@@ -1657,6 +1680,8 @@ virtual class Tk(Wm, Misc):
|
||||
self.bh = sz & 0xFFFF
|
||||
if not self.buf: return
|
||||
if self.bw <= 0 or self.bh <= 0: return
|
||||
# 先刷新尺寸再布局:窗口 resize 后若沿用上一帧的 bw/bh,布局会滞后一帧。
|
||||
self._do_layout()
|
||||
# 【诊断·临时】每个进程第一次真正走到 redraw 时打一行:证明"app 侧开始绘制了",
|
||||
# 并给出它拿到的缓冲地址/尺寸(与 explorer 侧 shm0/flush 对照)。
|
||||
# `_first` 只在本帧为 1:下面的 st1..st4 分段打点也只打这一次,用于定位
|
||||
@@ -1742,13 +1767,17 @@ virtual class Tk(Wm, Misc):
|
||||
py: int = _g_wl_pady[i]
|
||||
ww: int = w.w
|
||||
wh: int = w.h
|
||||
# 交叉轴上未 fill 时按 Tk 默认 anchor=center 居中;沿 pack 方向仍贴腔体边缘 +
|
||||
# padding(与 tkinter 一致)。此前一律贴左上,导致不 fill 的控件全部挤在左边缘。
|
||||
if side == PACK_TOP:
|
||||
if fill == FILL_X or fill == FILL_BOTH:
|
||||
ww = cav_w - 2 * px
|
||||
w.x = cav_x + px
|
||||
else:
|
||||
w.x = cav_x + px + (cav_w - 2 * px - ww) / 2
|
||||
if expand:
|
||||
if fill == FILL_Y or fill == FILL_BOTH:
|
||||
wh = cav_h - 2 * py
|
||||
w.x = cav_x + px
|
||||
w.y = cav_y + py
|
||||
w.w = ww
|
||||
w.h = wh
|
||||
@@ -1757,10 +1786,12 @@ virtual class Tk(Wm, Misc):
|
||||
elif side == PACK_BOTTOM:
|
||||
if fill == FILL_X or fill == FILL_BOTH:
|
||||
ww = cav_w - 2 * px
|
||||
w.x = cav_x + px
|
||||
else:
|
||||
w.x = cav_x + px + (cav_w - 2 * px - ww) / 2
|
||||
if expand:
|
||||
if fill == FILL_Y or fill == FILL_BOTH:
|
||||
wh = cav_h - 2 * py
|
||||
w.x = cav_x + px
|
||||
w.y = cav_y + cav_h - wh - py
|
||||
w.w = ww
|
||||
w.h = wh
|
||||
@@ -1768,11 +1799,13 @@ virtual class Tk(Wm, Misc):
|
||||
elif side == PACK_LEFT:
|
||||
if fill == FILL_Y or fill == FILL_BOTH:
|
||||
wh = cav_h - 2 * py
|
||||
w.y = cav_y + py
|
||||
else:
|
||||
w.y = cav_y + py + (cav_h - 2 * py - wh) / 2
|
||||
if expand:
|
||||
if fill == FILL_X or fill == FILL_BOTH:
|
||||
ww = cav_w - 2 * px
|
||||
w.x = cav_x + px
|
||||
w.y = cav_y + py
|
||||
w.w = ww
|
||||
w.h = wh
|
||||
cav_x += ww + 2 * px
|
||||
@@ -1780,11 +1813,13 @@ virtual class Tk(Wm, Misc):
|
||||
elif side == PACK_RIGHT:
|
||||
if fill == FILL_Y or fill == FILL_BOTH:
|
||||
wh = cav_h - 2 * py
|
||||
w.y = cav_y + py
|
||||
else:
|
||||
w.y = cav_y + py + (cav_h - 2 * py - wh) / 2
|
||||
if expand:
|
||||
if fill == FILL_X or fill == FILL_BOTH:
|
||||
ww = cav_w - 2 * px
|
||||
w.x = cav_x + cav_w - ww - px
|
||||
w.y = cav_y + py
|
||||
w.w = ww
|
||||
w.h = wh
|
||||
cav_w -= ww + 2 * px
|
||||
|
||||
Reference in new issue
Block a user