OUTFOCUS Wiki - wifky!

Inside KAG3 - systembutton.ks改造のヒント

ポイント

ボタンの追加・削除

ボタンを追加・削除するにはSystemButtonPlugin.createButtons()メソッドを修正する。 初期状態では、ボタン0(セーブ)とボタン1(ロード)の2つを作るようになっている。 最初に作ったボタンほど左側に表示される。

// ボタン 0 (セーブ)
array.add(obj = new SystemButtonLayer(kag, parent, onSaveButtonClick));
obj.loadImages('YesButton'); // save ボタン用画像を読み込む

// ボタン 1 (ロード)
array.add(obj = new SystemButtonLayer(kag, parent, onLoadButtonClick));
obj.loadImages('NoButton'); // load ボタン用画像を読み込む

ボタン0のコードを例に説明すると、 SystemButtonLayerコンストラクタの第3引数(イベントハンドラ;下線部)と、

array.add(obj = new SystemButtonLayer(kag, parent, onSaveButtonClick));

次の行のボタン用画像を用意すれば良いことが判る。

obj.loadImages('YesButton');

なお、ボタン用画像はbuttonタグでのそれと同じ要領で作れば良い。

イベントハンドラの定義

ボタンをクリックした際に呼び出されるメソッド(イベントハンドラ)は、初期状態ではSystemButtonLayerクラスに2つ定義されている。

function onSaveButtonClick()
{
  // セーブ ボタンが押された
  kag.saveBookMarkToFileWithAsk();
}

function onLoadButtonClick()
{
  // ロード ボタンが押された
  kag.loadBookMarkFromFileWithAsk();
}

ボタン0のイベントハンドラonSaveButtonClick()を例に説明すると、戻り値なし・引数なしのメソッドを定義すれば良いことが判る。

function onSaveButtonClick()

このメソッドがSystemButtonLayerコンストラクタの第3引数に指定される。

改造例

メッセージ履歴を表示する

SystemButtonPlugin.createButtons()メソッドの修正

SystemButtonPlugin.createButtons()メソッドに以下のコードを挿入する。 この例ではボタンクリック時にonLogMode()メソッドを呼び出し、ボタン用画像としてLogMode.pngを必要とする。

array.add(obj = new SystemButtonLayer(kag, parent, onLogMode));
obj.loadImages('LogMode.png'); // メッセージ履歴用画像を読み込む
SystemButtonPlugin.onLogMode()メソッドの追加

SystemButtonPluginクラスに以下のメソッドを追加する。

function onLogMode()
{
  if (kag.historyEnabled)
    kag.onShowHistoryMenuItemClick(kag);  // メッセージ履歴を表示する
}

自動的に読み進む

SystemButtonPlugin.createButtons()メソッドの修正

SystemButtonPlugin.createButtons()メソッドに以下のコードを挿入する。 この例ではボタンクリック時にonAutoMode()メソッドを呼び出し、ボタン用画像としてAutoMode.pngを必要とする。

array.add(obj = new SystemButtonLayer(kag, parent, onAutoMode));
obj.loadImages('AutoMode.png'); // オートモード用画像を読み込む
SystemButtonPlugin.onAutoMode()メソッドの追加

SystemButtonPluginクラスに以下のメソッドを追加する。

function onAutoMode()
{
  kag.enterAutoMode();  // [自動的に読み進む]モードに移行する
}

以下のような記述でも良い。

function onAutoMode()
{
  kag.onAutoModeMenuItemClick(kag);  // [自動的に読み進む]メニューのイベントハンドラを呼び出す
}

kag.onAutoModeMenuItemClick()メソッドは、本来[自動的に読み進む]のオン/オフを切り替えるメソッドだが、安定(s、l、pタグで停止)しない限りボタンがクリックできないので、結果的に[自動的に読み進む]をオンにする機能だけが使える。

次の選択肢/未読まで進む

SystemButtonPlugin.createButtons()メソッドの修正

SystemButtonPlugin.createButtons()メソッドに以下のコードを挿入する。 この例ではボタンクリック時にonSkipToNextStop()メソッドを呼び出し、ボタン用画像としてSkipToNextStop.pngを必要とする。

array.add(obj = new SystemButtonLayer(kag, parent, onSkipToNextStop));
obj.loadImages('SkipToNextStop.png'); // スキップ用画像を読み込む
SystemButtonPlugin.onSkipToNextStop()メソッドの追加

SystemButtonPluginクラスに以下のメソッドを追加する。

function onSkipToNextStop()
{
  kag.skipToStop();  // 次の選択肢/未読まで進む
}

クイックセーブ

SystemButtonPlugin.createButtons()メソッドの修正

SystemButtonPlugin.createButtons()メソッドに以下のコードを挿入する。 この例ではボタンクリック時にonQuickSaveButtonClick()メソッドを呼び出し、ボタン用画像としてQuickSaveButton.pngを必要とする。

array.add(obj = new SystemButtonLayer(kag, parent, onQuickSaveButtonClick));
obj.loadImages('QuickSaveButton.png'); // クイックセーブ用画像を読み込む
SystemButtonPlugin.onQuickSaveButtonClick()メソッドの追加

SystemButtonPluginクラスに以下のメソッドを追加する。 この例では、最後の栞に確認ありでセーブしている(どういう実装をするにせよ、クイックセーブ対象とクイックロード対象の栞の番号は合わせておいた方が良い)。

function onQuickSaveButtonClick()
{
  if (kag.canStore())
    kag.storeBookMark(kag.numBookMarks-1);  // クイックセーブ
}

確認なしでセーブしたい場合は、kag.storeBookMark()の第2引数にfalseを指定すれば良い。

クイックロード

SystemButtonPlugin.createButtons()メソッドの修正

SystemButtonPlugin.createButtons()メソッドに以下のコードを挿入する。 この例ではボタンクリック時にonQuickLoadButtonClick()メソッドを呼び出し、ボタン用画像としてQuickLoadButton.pngを必要とする。

array.add(obj = new SystemButtonLayer(kag, parent, onQuickLoadButtonClick));
obj.loadImages('QuickLoadButton.png'); // クイックロード用画像を読み込む
SystemButtonPlugin.onQuickLoadButtonClick()メソッドの追加

SystemButtonPluginクラスに以下のメソッドを追加する。 この例では、最後の栞を確認ありでロードしている(どういう実装をするにせよ、クイックセーブ対象とクイックロード対象の栞の番号は合わせておいた方が良い)。

function onQuickLoadButtonClick()
{
  if (kag.canRestore())
    kag.restoreBookMark(kag.numBookMarks-1);  // クイックロード
}

確認なしでロードしたい場合は、kag.restoreBookMark()の第2引数にfalseを指定すれば良い。

右クリックサブルーチンを呼び出す

SystemButtonPlugin.createButtons()メソッドの修正

SystemButtonPlugin.createButtons()メソッドに以下のコードを挿入する。 この例ではボタンクリック時にonRightClick()メソッドを呼び出し、ボタン用画像としてRightClick.pngを必要とする。

array.add(obj = new SystemButtonLayer(kag, parent, onRightClick));
obj.loadImages('RightClick.png'); // 右クリックボタン用画像を読み込む
SystemButtonPlugin.onRightClick()メソッドの追加

SystemButtonPluginクラスに以下のメソッドを追加する。 なお、rclickタグで右クリックサブルーチンを設定していない場合は、(デフォルトの)メッセージレイヤの消去となる。

function onRightClick()
{
  kag.onPrimaryRightClick();  // 右クリックサブルーチンを呼び出す
}

任意のサブルーチンを呼び出す

SystemButtonPlugin.createButtons()メソッドの修正

SystemButtonPlugin.createButtons()メソッドに以下のコードを挿入する。 この例ではボタンクリック時にonConfigClick()メソッドを呼び出し、ボタン用画像としてConfigClick.pngを必要とする。

array.add(obj = new SystemButtonLayer(kag, parent, onConfigClick));
obj.loadImages('ConfigClick.png'); // コンフィグボタン用画像を読み込む
SystemButtonPlugin.onConfigClick()メソッドの追加

SystemButtonPluginクラスに以下のメソッドを追加する。この例では、config.ks内のサブルーチン*config_menuを呼び出している。

function onConfigClick()
{
  kag.callExtraConductor("config.ks", "*config_menu");  // コンフィグ画面用サブルーチンを呼び出す
}

その他

ヒントを表示する

アイコンボタンを使う場合は、ヒントを表示するようにしておくと良い。 以下の例ではボタンの上にマウスを置いたら、「クイックセーブ」というヒントを出す。

array.add(obj = new SystemButtonLayer(kag, parent, onQuickSaveButtonClick));
obj.loadImages('QuickSaveButton.png'); // クイックセーブ用画像を読み込む
obj.hint = "クイックセーブ";           // ヒントに「クイックセーブ」と表示
表示位置の調整など

システムボタンの初期表示位置を変更するには、SystemButtonPluginクラスのメンバ変数xおよびyの値を変更すれば良い。

  var x = 510; // 初期 x 位置
  var y = 300; // 初期 y 位置

システムボタンの並び方を変更したい――例えば間隔を離す、縦に並べる、グループ分けする――場合は、メソッドrealign()を改造すれば良い。 初期状態のメソッドは、横一列に隙間なく並べる実装になっている。

  function realign()
  {
    // ボタンの再配置
    // このメソッドは、ボタンを x y 位置から横一列に配置する
    var fore, back, count, btn_x;

    count = foreButtons.count;
    btn_x = 0;
    for(var i = 0; i < count; i++)
    {
      var xpos = btn_x + x;
      var obj;

      obj = backButtons[i];
      obj.setPos(xpos, y);
      obj.absolute = 2000000-3; // 重ね合わせ順序はメッセージ履歴よりも奥

      obj = foreButtons[i];
      obj.setPos(xpos, y);
      obj.absolute = 2000000-3;

      btn_x += obj.width;
    }
  }

補足

実際には以下の考慮が必要になる。onStableStateChanged()イベントハンドラ内に追加すると良い。

  • historyタグでメッセージ履歴の表示が抑止されている場合、メッセージ履歴ボタンをディセーブル化する
    • kag.historyEnabledの値を調べる
  • disablestore/storeタグでセーブが抑止されている場合、セーブボタンをディセーブル化する
    • kag.canStore()の戻り値を調べる
  • disablestore/storeタグでロードが抑止されている場合、ロードボタンをディセーブル化する
    • kag.canRestore()の戻り値を調べる

また、確認した限りでは、最初の1行目のメッセージを描画する際、安定(s、l、pタグで停止)していないにも関わらずシステムボタンがイネーブル状態になっているケースがあった。念のためSystemButtonPluginクラスのコンストラクタの最後で、

onStableStateChanged(kag.inStable);

を呼び出し、最新の状態を反映しておいた方が良さそうである。

ダウンロード

以下はsystembutton.ksの簡単な改造例。背景画像(_24.jpg、_24_3.jpg)は紹介シナリオから調達のこと。