Kagari
キーワードを入力してドキュメントを検索します。

モジュール

std::ui

安定性: 安定 — UI の値、リアクティビティ、UI フォームの脱糖先となる関数。

std::ui はゲームシステムの UI ツールキットです。要素型、リアクティブなシグナル、コンテンツとレイアウトの関数、そして UI フォーム(column![…]、button!{…}、text!(…) など)の脱糖先を提供します。コントロールの見た目は std::ui::style で宣言します。

UI は fn のコードです。コンポーネント は Element を返す fn で、その要素をモード型(RootPage、Overlay、GameOverlay、Dialog)で包むか、ゲームビューならそのまま Element を返します。スタイルは const fn のデータです。

プレリュードは signal と Element をインポートします。その他のアイテムは use std::ui::{Fit, each, show, thumbnail}; のようにパスでインポートしてください。

kis
pub mod style;

概要

アイテム種別概要
Element、Placedビルトイン構造体UI 要素、レイヤーに配置された要素
Align、Fit列挙型フレックスの整列、画像のボックスへの収め方
signal、effect、each、showfnリアクティビティ
label、spacer、scroll、thumbnail、messagefnコンテンツ
Element のメソッドfnサイズ、余白、整列、塗り、フォーカス順、配置
column、row、layerfnレイアウトフォームの脱糖先
text、image、game_screenfnコンテンツフォームの脱糖先
button、slider、toggle、select、optionfnコントロールフォームの脱糖先

要素

構造体: Element

kis
#[builtin] pub struct Element;

エンジンがレイアウトする UI 要素のツリーです。Element は不透明な値です。このモジュールの関数とフォームで作り、レイアウトのメソッド で調整します。

構造体: Placed

kis
#[builtin] pub struct Placed;

layer![…] に配置された要素です。Element::at または Element::cover で作ります。

列挙型: Align

kis
pub enum Align {
Start,
Center,
End,
Stretch,
SpaceBetween,
}

行または列の子のフレックス整列で、Element::align で使います。

バリアント行・列に沿った方向(main)交差する方向(cross)
Start先頭に詰める先頭に置く
Center中央に寄せる中央に置く
End末尾に詰める末尾に置く
StretchStart と同じ固定サイズでない子を交差方向いっぱいに引き伸ばす
SpaceBetween空き領域を子の間に等しく分ける(子が 1 つなら Start と同じ)Start と同じ

列挙型: Fit

kis
pub enum Fit {
Stretch,
Contain,
Cover,
Natural,
}

画像がボックスをどう埋めるかで、image! で使います。

バリアント意味
Stretch縦横比を無視してボックスを埋めます
Contain縦横比を保ち、ボックスに収まる最大のサイズにして、ボックスの中央に置きます
Cover縦横比を保ってボックスを埋めます。はみ出す方向の両側が均等に切り取られます
Natural画像本来のピクセルサイズで、ボックスの左上に置きます

コンポーネントとリアクティビティ

コンポーネントとリアクティビティは SolidJS に倣っています。

  • コンポーネントは、そのモードが表示されるときに 一度だけ 実行されます。
  • リアクティブなソース は、シグナルのゲッター、Setting::get、Meta::get、Narrative ハンドルの読み取り、saves::info、既見セット です。
  • リアクティブなクロージャ は、読み取ったソースが変わると再実行されます。リアクティブな属性と UI フォームの要素はこのようなクロージャです(UI フォーム を参照)。そのため text!(t!["Music: " {music().level}]) は music が変わるたびに更新されますが、コンポーネントの残りの部分は再実行されません。
  • on_click などのハンドラは普通のクロージャで、イベントが起きたときに実行されます。

シグナルは fn のコードにしか存在しません。物語と const fn はシグナルを使えません。

関数: signal(init)

kis
#[builtin] pub fn signal<T>(init: T) -> (Fn() -> T, Fn(T));
  • init T — 初期値。
  • 戻り値: (Fn() -> T, Fn(T)) — ゲッターとセッター。ゲッターはリアクティブなソースです。
  • 種別: fn · ビルトイン: はい
kix
let (hidden, set_hidden) = signal(false);

関数: effect(run)

kis
#[builtin] pub fn effect(run: Fn());
  • run Fn() — 実行するクロージャ。
  • 種別: fn · ビルトイン: はい

run を今すぐ実行し、読み取ったソースが変わるたびに再実行します。

関数: each(items, item)

kis
#[builtin] pub fn each<T>(items: Fn() -> Vec<T>, item: Fn(T) -> Element) -> Element;
  • items Fn() -> Vec<T> — 項目。リアクティブです。
  • item Fn(T) -> Element — 1 つの項目の要素を作ります。
  • 戻り値: Element — 項目ごとに 1 つの要素。items と同期し続けます。
  • 種別: fn · ビルトイン: はい
kix
scroll(|| each(|| game.history(), |entry| entry_view(entry)))

関数: show(when, then)

kis
#[builtin] pub fn show(when: Fn() -> bool, then: Fn() -> Element) -> Element;
  • when Fn() -> bool — 条件。リアクティブです。
  • then Fn() -> Element — 内容を作ります。
  • 戻り値: Element — when() が true の間は then()、そうでなければ何もなし。
  • 種別: fn · ビルトイン: はい

コンテンツ

関数: label(text)

kis
#[builtin] pub fn label(text: Text) -> Element;
  • text Text — テキスト。
  • 戻り値: Element — 静的なテキスト。
  • 種別: fn · ビルトイン: はい

テキストには System::text が使われます。ボタンやトグルの中では現在の見た目のテキストスタイルが使われます(インタラクションの見た目 を参照)。text!(…) は、スタイルを任意で指定できるリアクティブな形です。column!、row!、button!、toggle! の中では、裸の t![…] 要素は label(t![…]) になります。

関数: spacer()

kis
#[builtin] pub fn spacer() -> Element;
  • 戻り値: Element — 伸びて兄弟要素を押し広げる空の要素。
  • 種別: fn · ビルトイン: はい

関数: scroll(child)

kis
#[builtin] pub fn scroll(child: Fn() -> Element) -> Element;
  • child Fn() -> Element — 内容。
  • 戻り値: Element — 内容を囲むスクロール可能なボックス。
  • 種別: fn · ビルトイン: はい

関数: thumbnail(slot)

kis
#[builtin] pub fn thumbnail(slot: SaveSlot) -> Element;
  • slot SaveSlot — スロット。
  • 戻り値: Element — slot のセーブと一緒に保存されたスクリーンショット。
  • 種別: fn · ビルトイン: はい

関数: message(game, style)

kis
#[builtin] pub fn message(game: Narrative, style: TextStyle) -> Element;
  • game Narrative — 実行中のゲーム。
  • style TextStyle — ウィンドウのテキストスタイル(std::narrative::text を参照)。
  • 戻り値: Element — 現在の行。文字送り、テキスト効果、ポーズ、マーク、クリック待ちグリフを含みます。
  • 種別: fn · ビルトイン: はい

message はメッセージウィンドウの本体です。Narrative ハンドルが存在する場所、つまりゲームビューとゲームオーバーレイでだけ使えます。

安定性: 予定 — NVL モード(改ページまで複数の行が画面に残る全画面テキストモード)はまだ設計されていません。テキストウィンドウの表示内容と、バックログや Narrative::line がステップを表す方法が変わる予定です。

レイアウト

kis
impl Element {
#[builtin] pub fn width(self, px: u32) -> Element;
#[builtin] pub fn height(self, px: u32) -> Element;
#[builtin] pub fn padding(self, insets: Insets) -> Element;
#[builtin] pub fn gap(self, px: u32) -> Element;
#[builtin] pub fn align(self, main: Align, cross: Align) -> Element;
#[builtin] pub fn grow(self, factor: u32) -> Element;
#[builtin] pub fn background(self, paint: Paint) -> Element;
#[builtin] pub fn opacity(self, opacity: Decimal) -> Element;
#[builtin] pub fn focus_order(self, order: u32) -> Element;
#[builtin] pub fn at(self, position: Point, anchor: Anchor) -> Placed;
#[builtin] pub fn cover(self) -> Placed;
}

レイアウトはフレックスボックスに似ています。

  • column![…] と row![…] はフレックスコンテナです。gap と align が子の間隔と整列を決め、grow は子のフレックス伸長係数です。
  • layer![…] は Placed の子を重ねます。at は子のアンカーを点に置き、cover はレイヤー全体を埋めます。
  • サイズと位置はデザイン解像度(System::resolution)のピクセルです。
  • レイアウトは要素ツリーに対するエンジンの処理です。リサイズ時に再計算され、セーブされることはありません。

すべてのメソッドは要素を値で受け取り、調整した要素を返すので、column![…].gap(16).align(Align::Center, Align::Center) のように連鎖できます。いずれもビルトインの fn です。

Element::width(px)

kis
#[builtin] pub fn width(self, px: u32) -> Element;
  • px u32 — ピクセル単位の固定幅。

Element::height(px)

kis
#[builtin] pub fn height(self, px: u32) -> Element;
  • px u32 — ピクセル単位の固定高さ。

Element::padding(insets)

kis
#[builtin] pub fn padding(self, insets: Insets) -> Element;
  • insets Insets — 内側の余白。std::screen::insets(top, right, bottom, left) で作ります(std::screen を参照)。

Element::gap(px)

kis
#[builtin] pub fn gap(self, px: u32) -> Element;
  • px u32 — 行または列の子の間隔。

Element::align(main, cross)

kis
#[builtin] pub fn align(self, main: Align, cross: Align) -> Element;
  • main Align — 行または列に沿った子の整列。
  • cross Align — それと交差する方向の整列。

Element::grow(factor)

kis
#[builtin] pub fn grow(self, factor: u32) -> Element;
  • factor u32 — フレックス伸長係数。行または列の空き領域のうち、この要素が取る割合です。

Element::background(paint)

kis
#[builtin] pub fn background(self, paint: Paint) -> Element;
  • paint Paint — 要素の背後に描くもの。

Element::opacity(opacity)

kis
#[builtin] pub fn opacity(self, opacity: Decimal) -> Element;
  • opacity Decimal — 要素の不透明度。0.0..=1.0。

Element::focus_order(order)

kis
#[builtin] pub fn focus_order(self, order: u32) -> Element;
  • order u32 — フォーカス順における要素の位置(フォーカス を参照)。

Element::at(position, anchor)

kis
#[builtin] pub fn at(self, position: Point, anchor: Anchor) -> Placed;
  • position Point — レイヤー上の点。
  • anchor Anchor — そこに置く要素側の点。TOP_LEFT や CENTER など(std::screen を参照)。
  • 戻り値: Placed — layer![…] 用。

Element::cover()

kis
#[builtin] pub fn cover(self) -> Placed;
  • 戻り値: Placed — レイヤー全体を埋める要素。
kix
use std::screen::CENTER;
use std::ui::Fit;
fn Title() -> RootPage {
RootPage(layer![
image!(fit = Fit::Cover, TITLE_BG).cover(),
column![
button!{on_click = || nav::start(story::Main, (), |_end| nav::goto(Title)), t!["Start"]},
button!{on_click = || nav::call(Config), t!["Config"]},
button!{on_click = || nav::quit(), t!["Quit"]},
].gap(16).at(point(640, 520), CENTER),
])
}

フォーカス

  • フォーカス可能な要素は、ボタン、スライダー、トグル、セレクトです。
  • focus_order(focus_order)が設定されていなければ、フォーカスは文書順に従います。
  • モードが開くと、最初のフォーカス可能な要素にフォーカスが当たります。フォーカスは最初のフォーカスキーから表示され、Enter と PadButton::South がフォーカス中のコントロールを実行するのは、フォーカスが表示されている間だけです。
  • 上下左右キー、十字キー、Tab と Shift+Tab はフォーカスを移動します。フォーカス中のスライダーとセレクトでは、左右キーは代わりに値を変えます。スライダーは step ずつ、セレクトは前後の選択肢に切り替わります。
  • これらのキーは組み込みで、バインドできません(バインディング を参照)。

UI フォーム

UI フォームは .kix ファイルに書き、props 構造体を伴う以下の関数の呼び出しに脱糖されます。fn と const fn のコードでは値を作るもので、ステップになることはありません。言語の区切り文字の規則に従います(リファレンスの フォーム の章を参照)。

  • name![…] は要素だけを取ります。
  • name!(…) は属性と、決まった数の要素を取ります。
  • name!{…} は属性と、任意の数の要素を取ります。

脱糖

  • リアクティブな属性 は key: Some(|| expr) になります。必須の属性なら key: || expr です。
  • ハンドラ属性(on_*)は key: Some(expr) になります。
  • 省略された任意の属性 は None になります。必須の属性の欠落、未知の属性、要素の数の誤り(text! と image! はちょうど 1 つ、game_screen! と slider! は 0 個)は構文エラーです。
  • 要素。 各要素 e は || e になります。column!、row!、button!、toggle! の中では、構文上 t![…] である要素は || ui::label(t![…]) になります。
フォーム脱糖先属性要素
column![…]、row![…]ui::column([…])、ui::row([…])なしElement
layer![…]ui::layer([…])なしPlaced
text!(…)ui::text(TextProps { … })style: リアクティブな TextStyleちょうど 1 つの Text → content
image!(…)ui::image(ImageProps { … })fit: リアクティブな Fitちょうど 1 つの ImageAsset → source
game_screen!(…)ui::game_screen(GameScreenProps { … })game: リアクティブな Narrative、必須なし
button!{…}ui::button(ButtonProps { … })on_click: ハンドラ Fn()、disabled: リアクティブな bool、style: リアクティブな ButtonStyleElement → children
slider!{…}ui::slider(SliderProps { … })value: リアクティブな Int<LO, HI>、必須、on_change: ハンドラ Fn(Int<LO, HI>)、step: リアクティブな u32、disabled: リアクティブな bool、style: リアクティブな SliderStyleなし
toggle!{…}ui::toggle(ToggleProps { … })value: リアクティブな bool、必須、on_change: ハンドラ Fn(bool)、disabled: リアクティブな bool、style: リアクティブな ButtonStyleElement → children
select!{…}ui::select(SelectProps { … })value: リアクティブな T、必須、on_change: ハンドラ Fn(T)、disabled: リアクティブな bool、style: リアクティブな ButtonStyleui::option(v, label) → options

例えば

kix
button!{on_click = || nav::back(), t!["Back"]}

は次のように脱糖されます。

kis
ui::button(ButtonProps {
on_click: Some(|| nav::back()),
disabled: None,
style: None,
children: [|| ui::label(t!["Back"])],
})

また

kix
slider!{value = music().level, on_change = |v| set_level(v)}

は次のようになります。

kis
ui::slider(SliderProps {
value: || music().level,
on_change: Some(|v| set_level(v)),
step: None,
disabled: None,
style: None,
})

関数: column(children)

kis
#[builtin] pub fn column<const N: usize>(children: [Fn() -> Element; N]) -> Element;

column![…] の脱糖先です。子を上から下へ積みます。

関数: row(children)

kis
#[builtin] pub fn row<const N: usize>(children: [Fn() -> Element; N]) -> Element;

row![…] の脱糖先です。子を左から右へ並べます。

関数: layer(children)

kis
#[builtin] pub fn layer<const N: usize>(children: [Fn() -> Placed; N]) -> Element;

layer![…] の脱糖先です。Placed の子を重ね、後の子ほど上に描かれます。

構造体: TextProps

kis
pub struct TextProps {
pub style: Option<Fn() -> TextStyle>,
pub content: Fn() -> Text,
}

text!(…) の属性と内容です。

関数: text(props)

kis
#[builtin] pub fn text(props: TextProps) -> Element;

text!(…) の脱糖先で、リアクティブなテキストです。style がなければ System::text が使われ、ボタンやトグルの中では現在の見た目のテキストスタイルが使われます。

kix
text!(style = NAME_STYLE, who_text(game))

構造体: ImageProps

kis
pub struct ImageProps {
pub fit: Option<Fn() -> Fit>,
pub source: Fn() -> ImageAsset,
}

image!(…) の属性とソースです。

関数: image(props)

kis
#[builtin] pub fn image(props: ImageProps) -> Element;

image!(…) の脱糖先で、画像です。ソースはリアクティブなので、image!(if seen_image(cg) { cg } else { LOCKED }) は条件が変わるとすぐに切り替わります。

構造体: GameScreenProps

kis
pub struct GameScreenProps {
pub game: Fn() -> Narrative,
}

game_screen!(…) の属性です。

関数: game_screen(props)

kis
#[builtin] pub fn game_screen(props: GameScreenProps) -> Element;

game_screen!(…) の脱糖先で、物語のレンダーが描く実行中のゲームの画面です。ゲームビューでは通常、layer![…] の最初に .cover() 付きで置きます。

kix
use std::narrative::text::text_style;
use std::screen::BOTTOM_CENTER;
use std::ui::message;
fn GameView(game: Narrative) -> Element {
layer![
game_screen!(game = game).cover(),
message(game, text_style(26, WHITE)).width(1000).at(point(640, 690), BOTTOM_CENTER),
]
}

構造体: ButtonProps

kis
pub struct ButtonProps<const N: usize> {
pub on_click: Option<Fn()>,
pub disabled: Option<Fn() -> bool>,
pub style: Option<Fn() -> ButtonStyle>,
pub children: [Fn() -> Element; N],
}

button!{…} の属性と子です。

関数: button(props)

kis
#[builtin] pub fn button<const N: usize>(props: ButtonProps<N>) -> Element;

button!{…} の脱糖先で、フォーカス可能なボタンです。on_click はクリックまたは実行時に走ります。無効なボタンは入力を無視し、無効時の見た目を表示します(インタラクションの見た目 を参照)。ボタンは現在の見た目の背景をボックス全体に塗り、その上に子を中央揃えで配置します。そのため子のないボタンは背景だけで描かれ、画像ボタンを作れます。

kix
button!{style = image_style(START, START_HOVER), on_click = || start_game()}.width(300).height(70)

構造体: SliderProps

kis
pub struct SliderProps<const LO: i64, const HI: i64> {
pub value: Fn() -> Int<LO, HI>,
pub on_change: Option<Fn(Int<LO, HI>)>,
pub step: Option<Fn() -> u32>,
pub disabled: Option<Fn() -> bool>,
pub style: Option<Fn() -> SliderStyle>,
}

slider!{…} の属性です。範囲は値の Int 型の範囲で、min や max の属性はありません。

関数: slider(props)

kis
#[builtin] pub fn slider<const LO: i64, const HI: i64>(props: SliderProps<LO, HI>) -> Element;

slider!{…} の脱糖先で、LO から HI まで step 刻みで動く、フォーカス可能なスライダーです。Volume::level は Int<0, 100> なので、音量スライダーに範囲の指定は要りません。

kix
slider!{
value = MUSIC.get().level,
on_change = |v| MUSIC.set(Volume { level: v, muted: MUSIC.get().muted }),
}

構造体: ToggleProps

kis
pub struct ToggleProps<const N: usize> {
pub value: Fn() -> bool,
pub on_change: Option<Fn(bool)>,
pub disabled: Option<Fn() -> bool>,
pub style: Option<Fn() -> ButtonStyle>,
pub children: [Fn() -> Element; N],
}

toggle!{…} の属性と子です。

関数: toggle(props)

kis
#[builtin] pub fn toggle<const N: usize>(props: ToggleProps<N>) -> Element;

toggle!{…} の脱糖先で、フォーカス可能なオン・オフのコントロールです。実行する(クリック、Enter、PadButton::South)と、!value() で on_change を呼びます。値が true の間、トグルはオンの見た目を表示します(インタラクションの見た目 を参照)。

kix
toggle!{value = SKIP_UNREAD.get(), on_change = |v| SKIP_UNREAD.set(v), t!["Skip unread text"]}

構造体: SelectOption<T>

kis
pub struct SelectOption<T> {
pub value: T,
pub label: Element,
}

select!{…} の選択肢です。

関数: option(value, label)

kis
pub fn option<T>(value: T, label: Element) -> SelectOption<T> {
SelectOption { value, label }
}
  • value T — 選択肢が表す値。
  • label Element — 選択肢の表示。
  • 戻り値: SelectOption<T> — label として表示される選択肢 value。
  • 種別: fn · ビルトイン: いいえ

構造体: SelectProps<T, N>

kis
pub struct SelectProps<T, const N: usize> {
pub value: Fn() -> T,
pub on_change: Option<Fn(T)>,
pub disabled: Option<Fn() -> bool>,
pub style: Option<Fn() -> ButtonStyle>,
pub options: [Fn() -> SelectOption<T>; N],
}

select!{…} の属性と選択肢です。

関数: select(props)

kis
#[builtin] pub fn select<T: Eq, const N: usize>(props: SelectProps<T, N>) -> Element;

select!{…} の脱糖先で、選択肢を順に切り替えるフォーカス可能なコントロールです。値が value() と等しい選択肢のラベルを表示するため、T は Eq でなければなりません。実行すると次の選択肢の値で on_change を呼び、最後の次は最初に戻ります。フォーカス中は、右キーと左キーで次と前の選択肢に切り替わります。value() と等しい選択肢がないときは、最初の選択肢の値が次の値になります。

kix
use std::ui::{label, option};
select!{
value = WINDOW_OPACITY.get(),
on_change = |v| WINDOW_OPACITY.set(v),
option(50, label("50%")),
option(80, label("80%")),
option(100, label("100%")),
}

安定性: 予定 — UI 要素のフェードとトランジションはまだサポートされていません。アニメーションするのはコントロールの見た目の変化だけです(ButtonStyle::change を参照)。

最終更新日 2026年10月29日