# UiKit —— 复用 `ETC/ymir work/ui/pattern/` 九宫格贴图构造控件。 # 从 hud.gd 抽出,charselect.gd / login.gd 共用(用 preload 引入)。PARITY §6.1。 extends RefCounted const PAT := "ETC/ymir work/ui/pattern/" static var _cache := {} static func ui_tex(assets: String, name: String) -> Texture2D: var key := assets + "|" + name if _cache.has(key): return _cache[key] var tex: Texture2D = null var cand := assets.path_join(PAT + name + ".tga") if not FileAccess.file_exists(cand): var da := DirAccess.open(assets) if da: for sub in da.get_directories(): var p := assets.path_join(sub).path_join("ymir work/ui/pattern/" + name + ".tga") if FileAccess.file_exists(p): cand = p break if FileAccess.file_exists(cand): var img := Image.new() if img.load(cand) == OK: tex = ImageTexture.create_from_image(img) _cache[key] = tex return tex # 4 角 + 4 边 + *_base 合成 atlas -> NinePatchRect。prefix = board | thinboard static func board(assets: String, prefix := "board", m := 32, base := 128) -> NinePatchRect: var total := m + base + m var atlas := Image.create_empty(total, total, false, Image.FORMAT_RGBA8) atlas.fill(Color(0, 0, 0, 0)) var put := func(nm: String, x: int, y: int) -> void: var t := ui_tex(assets, nm) if t == null: return var im := t.get_image() im.convert(Image.FORMAT_RGBA8) atlas.blit_rect(im, Rect2i(Vector2i.ZERO, im.get_size()), Vector2i(x, y)) put.call(prefix + "_corner_lefttop", 0, 0) put.call(prefix + "_corner_righttop", m + base, 0) put.call(prefix + "_corner_leftbottom", 0, m + base) put.call(prefix + "_corner_rightbottom", m + base, m + base) var edge := func(nm: String, r: Rect2i) -> void: var t := ui_tex(assets, nm) if t == null: return var im := t.get_image() im.convert(Image.FORMAT_RGBA8) im.resize(r.size.x, r.size.y, Image.INTERPOLATE_BILINEAR) atlas.blit_rect(im, Rect2i(Vector2i.ZERO, r.size), r.position) edge.call(prefix + "_line_top", Rect2i(m, 0, base, m)) edge.call(prefix + "_line_bottom", Rect2i(m, m + base, base, m)) edge.call(prefix + "_line_left", Rect2i(0, m, m, base)) edge.call(prefix + "_line_right", Rect2i(m + base, m, m, base)) var b := ui_tex(assets, prefix + "_base") if b: var bi := b.get_image() bi.convert(Image.FORMAT_RGBA8) bi.resize(base, base, Image.INTERPOLATE_BILINEAR) atlas.blit_rect(bi, Rect2i(Vector2i.ZERO, Vector2i(base, base)), Vector2i(m, m)) var np := NinePatchRect.new() np.texture = ImageTexture.create_from_image(atlas) np.patch_margin_left = m np.patch_margin_right = m np.patch_margin_top = m np.patch_margin_bottom = m return np