コンテンツにスキップ

Elements UI 機構の全体像

吉里吉里Z の ElementsDialog ( Elements ベースの UI ) は、4 つの層が 積み重なってできています。どの層に何があるか、どの層を直せばよいか、どの文書を読めば よいかをここにまとめます。個々の使い方は ダイアログ ( ガイド )、 API は ElementsDialog クラスリファレンス を参照してください。

層構造

┌─────────────────────────────────────────────────────────────┐
│ ④ ゲーム / TJS 側の UI コード                                  │
│    画面の出し入れ、ゲーム状態との接続、画面遷移の方針           │
│    ※ 共有の枠組みは無く、プロジェクトごとに書かれている         │
├─────────────────────────────────────────────────────────────┤
│ ③ krkrz 本体 ( src/core/common/visual/elements/ )             │
│    TJS ElementsDialog クラス / DrawDevice への描画接続 / 入力ルーティング │
│    複数インスタンスと z-order / モーダルの nested ループ         │
│    ホスト資源との接続 ( Storages・フォント・ソフトキーボード )    │
├─────────────────────────────────────────────────────────────┤
│ ② elements_modal ( external/elements/external/elements_modal ) │
│    画面 JSON の仕様と構築、変数 store、named action、画面遷移     │
│    overlay_session ( 描画先バッファと入力を受け取るだけの口 )     │
│    ※ 吉里吉里に依存しない。単体アプリからも同じ JSON が動く      │
├─────────────────────────────────────────────────────────────┤
│ ① elements ( cycfi/elements の派生 )                          │
│    ウィジェットの土台、レイアウト計算、フォーカス、ThorVG 描画    │
└─────────────────────────────────────────────────────────────┘

①②は吉里吉里Zと無関係に動きます。画面 JSON は単体のホストアプリでも同じように 表示・操作でき、③はそれをゲーム画面の上へ載せてゲームの入力と資源に繋ぐ役です。

どの層を直すのか ( 早見表 )

やりたいこと 直す層 具体的な場所
画面の見た目・配置・文言を変える 画面 JSON プロジェクトの画面 JSON
ウィジェットを増やす / 既存ウィジェットに属性を足す json_layout.cpp + elements_modal README
変数連動・入力バインド・画面遷移の仕様を変える 同上
ウィジェットの描画そのもの・レイアウト計算・フォーカス移動 elements 本体 (lib/)
TJS の API を増やす ( ElementsDialog.* ) DialogIntf.cpp + doc/manual/ElementsDialog.manual.tjs
表示先 ( DrawDevice ) や入力経路、複数インスタンスの扱い ElementsDialogManager.cpp
画面をどう出し入れするか、ゲーム状態とどう繋ぐか ゲーム側スクリプト

判断に迷ったときの目安は「吉里吉里Zが無くても意味がある機能か」です。意味があるなら ②か①、ゲーム側の事情が絡むなら③か④になります。

データの流れ

描画: ゲームのフレーム末尾で DrawDevice::Show() から PaintOverlay が呼ばれ、 ② がピクセルバッファへ描き、③ がそれを DrawDevice ごとのテクスチャ ( SDL / OpenGL / D3D11 ) へ転送してゲーム画面の上に出します。再描画が不要なフレームは前回のテクスチャを そのまま提示し、変化した矩形だけを描き直します。

入力: ウィンドウのマウス / キー / パッド入力を③が横取りし、表示中のダイアログへ 渡します。②が処理しなかった入力だけがゲーム ( レイヤ ) へ流れます ( 非モーダル時 )。

: 画面 JSON の中の変数は 1 本のストアにぶら下がります。TJS からは setVar で書き、getVar で 読み、onVar で変化を受け取れます。ボタン押下や値変更は onAction で届きます。日常的にはこの 4 つが ③と④の間のインターフェースの全てです ( ほかに画像やアトラスの差し替え、 セッション共有変数の読み書きといった「ホストにしかできないこと」の口があります。 次節参照 )。

設計方針: UI の処理は画面データ側で完結させる

複数のプロジェクトがそれぞれ独自の UI フレームワークを④に書き始めたのを受けて、 UI の処理は②と画面 JSON で完結させ、④は「呼ぶ / 値を供給する / アクションを 実行する」だけにする方針を採っています。切り分けの原則は「ゲームの状態に 触るか」です。

画面データ側 ( ②+ 画面 JSON ) ホスト側 ( ③④ )
画面遷移・タブ・一覧のスクロールと選択 設定値やセーブデータの実体
値の整形と出し分け・フォーカス・演出 セーブ / ロードの実行、SE の実再生
画面をまたいで値を保つ ( shared_vars ) ホストのダイアログ機構との調停

そのため、次のものはホストのコールバックを書かなくても画面 JSON だけで動きます

  • "shared_vars": ["cfg_*"] — 一致する変数を画面をまたいで保つ ( 設定画面をタブで渡り歩いてもスライダーが戻らない )
  • "value_var"checkbox / toggle_button / slide_switch の ON/OFF を変数連動
  • "image_var"image の絵そのものを変数で差し替え ( セーブ一覧のページ送り等 )
  • 差し替え可能アトラス — 同じ画面のまま絵の束だけ入れ替え ( CG 鑑賞のグループタブ等 )

ホスト側に残る仕事は「セーブデータへの落とし込み」だけで、その口が getSharedVars / setSharedVar / clearSharedVars、 アトラス差し替えが setAtlasImage です。

ドキュメント地図

文書 内容
ダイアログ ( ガイド ) ③④ 表示モード、フロー、一覧、変数、入力バインドの使い方
ElementsDialog クラスリファレンス TJS API の全メンバー
ElementsDialog.md 本体側の実装 SSOT。DrawDevice 接続、入力ルーティング、複数インスタンス、部分再描画、計測
elements_modal README 画面 JSON 仕様の SSOT。ウィジェット一覧、変数連動、テーマ、アトラス、遷移、演出
elements リポジトリ ライブラリ本体 ( 派生元は cycfi/elements )
ゲームパッド入力 パッドのキー変換 ( ダイアログのパッド操作もこの上に乗る )
仮想カーソル位置 hover 判定とカーソル参照の基準。キー / パッドのナビは実 OS カーソルを動かさない

用語

  • overlay … ゲーム画面の上に重ねて表示する形。非モーダルもモーダルもこの形が既定
  • 独立ウィンドウ modal … OS のウィンドウを別に開いてブロッキング表示する形
  • フロー ( navigator ) … 複数の画面 JSON を遷移させる仕組み。遷移先は画面 JSON 側の 宣言で決まり、ホストは遷移を書かない
  • 画面 JSON … 1 画面ぶんのレイアウト定義。TJS の Dictionary でも書ける
  • 変数ストア … 画面の中で共有される名前付きの値。文字列で持つ
  • セッション共有変数 … 画面をまたいで保たれる変数。画面 JSON の "shared_vars" が「どれを持ち回るか」を宣言する ( ホスト実装は不要 )
  • named action … キー / パッド / マウスへ割り当てる名前付き操作。組込名は ダイアログ内で処理され、それ以外はホストへ通知される