diff --git a/vpsdk/vpui.vp b/vpsdk/vpui.vp index 3d077cb..7d2f605 100644 --- a/vpsdk/vpui.vp +++ b/vpsdk/vpui.vp @@ -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