VGUIのコントロールについて



・画面づくりしたい
VGUIコントロール親子がHL2の画面を構成しているのは分かりましたが、 どっから手を付けたらよいのやら。

大抵の人は「とりあえずWindowsのダイアログみたいなのをこしらえてボタンを置いてみてえよ」 って思うでしょう。


実際に上のイメージのようなウインドウを作る場合には。 先ずFrameのサブクラスを定義し、そのクラスのコンストラクタ内で以下の処理を記述します
  • ウインドウ自身の基本的なスタイル設定(×ボタンを表示するだとか、サイズ変更可能にするだとか・・・)。
  • つくりたきゃ子コントロール作成。
  • Look&Feelを他のウインドウと揃えるためにSchemeを設定(スキーム設定のリソースファイル読み込み)。
  • コントロール設定のリソースファイル読み込み。


  • こんだけ

    ・子コントロールの作成方法
    さて、上の行程で「ボタンを作る」としたらどこでしょうか?

    実は2つの方法があります。


  • コントロール設定のリソースファイル読み込み前にnewで作成

  • 行程の「つくりたきゃ子コントロール作成。」の時点で行います。
    あらかじめコントロールクラスの実体をnewで作成してしまい、 細かい設定はリソースの設定に任せてしまう方法です。 コントロールの配置やキャプション等は簡単に変更できる作りが望ましいですからこの方法がベストでしょう。


  • コントロール設定のリソースファイル読み込み時に自動で作成

  • 行程の「コントロール設定のリソースファイル読み込み。」の時点で行なわれます。
    コントロールを作成しないままコントロール設定のリソースファイル読み込みを行うと 自動的に不足分のコントロールを作成してくれます。
    例えば"pochi"という名前のコントロールが未作成の状態で、読み込んだコントロール設定のリソースファイル内に以下の 記述があった場合、"pochi"という名前のButtonクラスのコントロールが作成されます。
    	"pochi"
    	{
    		"ControlName"	"Button"
    		"fieldName"	"pochi"
    		"xpos"		"50"
    		"ypos"		"50"
    		"wide"		"200"
    		"tall"		"20"
    		"labelText"	"ポチっとな"
    		"Default"		"1"
    	}
    
    「うっひょ〜!自動でコントロールを作ってくれるなんてマジ楽ちんじゃん、最高」
    ・・・と言いたいところですが、あまりよくありません。

    一見お手軽で便利そうな機能ですね。作成後にこのコントロールへアクセスする場合、
    vgui::Button* button = (vgui::Button*)this->FindChildByName("pochi");
    
    こんな形でコントロールクラスのポインタを引っ張ってこられるのですが、 リソースファイルがいくらでもテキストエディタで編集できる以上、上のbuttonに渡されたポインタが本当にvgui::Buttonのポインタだという保証が ないのです。vgui::TextEntryやvgui::HTMLのポインタの可能性もあります。
    下手にそのまま操作をすると最悪の場合クラッシュしてしまうため、更に
    const char *name = button->GetClassName();
    
    で取れるクラス名が"Button"だということを確認してやらなければなりません。
    結局、現時点ではメンドくせぇよバロー!になるだけで、ラベル程度の物以外は自動作成してもらうメリットがないんじゃないかと思います。 でも、これを活かせる拡張機能を自作してしまうのもアリDA・YO・NE☆。


    こうして作った子コントロール、終了時の後始末はどうするのというと、親コントロールを deleteしたら自動的に子コントロールも deleteしてくれる仕組みなので安心してくらはい。

    ・コントロール設定のリソースファイルフォーマット
    コントロール設定のリソースファイルは先頭にリソースファイル名のパス、続く中括弧で囲まれた 中へ各コントロール設定の定義を書き込みます。(resource/uiの下に何個かファイルが転がってるから見てみそ)
    "[リソースファイルのパス]"
    {
    	・
    	・
    	・
    	"[コントロール名]"
    	{
    		"ControlName"	"[コントロールクラス名]"
    		・
    		・
    		・
    		[その他各種設定]
    		・
    		・
    		・
    	}
    	・
    	・
    	・
    }
    

    先頭の[リソースファイルのパス]の部分に関しては実際のところ何を 書いてもOKのようです。まあまあ、こんなところでわざわざナイフみたいにトンがる必要ないじゃないか、 素直にファイル自身のパスを書いときゃいいんだよ。

    各コントロールの定義先頭に書く[コントロール名]、この名前に該当 するコントロールがリソースを読み込んだPanelやFrame自身、もしくはその直下の子コントロールに 見つかった場合は、[その他各種設定]に書かれた設定内容をそのコントロール に適用する。
    該当する名称のコントロールが見つからない場合は[コントロールクラス名] に指定されたコントロールクラスをリソースを読み込んだPanelやFrameの子コントロールとして新規に作成し、 [その他各種設定]に書かれた設定内容を適用する。


    ( ゚Д゚)「子コントロールの更に子コントロールの名前を[コントロール名]に指定したらどうなんの?
    対象はリソースを読み込んだPanelやFrame自身、もしくはその直下の子コントロールなので、 子コントロールの更に子コントロールの名前を指定しても「未作成のコントロール」として扱われて リソースを読み込んだPanelやFrameの直下へ新規に子コントロールが勝手に作られやがります。

    ( ゚Д゚)「同じ[コントロール名]の定義が複数あったらどうなんの?
    最初のコントロールの定義から順に設定が上書きされて、各定義が互いに同じ設定項目を持っている場合には最後にその項目を設定してある定義の内容が 適用されます。


    ・コントロールの基本設定
    リソーススクリプトにて指定するコントロール設定のうち、基本設定(基底クラスのPanel)について 以下に載せときますね。サブクラスではこれに加えて独自の設定項目を設けています(各クラスのApplySettingsメンバ関数を参照)。
    ControlName コントロールのクラス名。
    自分で既存コントロールの派生クラスを作成する場合にはクラスの宣言時に DECLARE_CLASS_SIMPLEマクロを埋め込んでおかないとこの指定が役に立たなくなる。
    xpos コントロールを配置するX座標を指定。コントロールの左端がこの座標に来るようにコントロールは配置されます。
    SetProportional(true)の指定されたコントロールに対してはスクリーンサイズに合わせたスケールに変換されて使用されます。。
    先頭に特定の文字を付加すると基準位置が変わります。
    無指定 - 座標は親コントロールの左端を基準とした場合の相対X座標です。
    r または R - 座標は親コントロールの右端を基準とした場合の相対X座標です。
    c または C - 座標は親コントロールの中心を基準とした場合の相対X座標です。
    ypos コントロールを配置するY座標を指定。コントロールの上端がこの座標に来るようにコントロールは配置されます。
    SetProportional(true)の指定されたコントロールに対してはスクリーンサイズに合わせたスケールに変換されて使用されます。。
    先頭に特定の文字を付加すると基準位置が変わります。
    無指定 - 座標は親コントロールの上端を基準とした場合の相対Y座標です。
    r または R - 座標は親コントロールの下端を基準とした場合の相対Y座標です。(b or Bにするのを忘れたのだろうと思われる)
    c または C - 座標は親コントロールの中心を基準とした場合の相対Y座標です。
    zpos Zオーダーを指定、低い値を指定されたコントロールは、それよりも高い値を指定されたコントロールの背面に配置されます。
    wide コントロールの横幅を指定。コントロールの左端を基準に幅が右方向に伸縮します。
    SetProportional(true)の指定されたコントロールに対してはスクリーンサイズに合わせたスケールに変換されて使用されます。。
    tall コントロールの高さを指定。コントロールの上端を基準に幅が下方向に伸縮します。
    SetProportional(true)の指定されたコントロールに対してはスクリーンサイズに合わせたスケールに変換されて使用されます。。
    autoResize コントロールの状態によってサイズが自動的に調節されます。
    0 - 自動調節機能OFF(※デフォルト)
    1 - 右方向のみ自動調節機能ON
    2 - 下方向のみ自動調節機能ON
    3 - 右方向、下方向共に自動調節機能ON
    pinCorner 親コントロールがリサイズされた際に、どの場所を基準に移動させるかを指定。
    0 - 左上(※デフォルト)
    1 - 右上
    2 - 左下
    3 - 右下
    IgnoreScheme スキーム設定の無視指定。
    0 - すべてのスキーム設定を反映(※デフォルト)
    1 - 色以外のスキーム設定は反映されなくなる。
    visible コントロールの可視/不可視を指定。
    0 - 不可視
    1 - 可視(※デフォルト)
    enabled ユーザによるコントロールの使用可/不可を指定。
    0 - 使用不可
    1 - 使用可(※デフォルト)
    tabPosition タブキーによってフォーカスが移動する順番を指定(0〜)。(※デフォルト:0)
    tooltiptext マウスがホバリングしている際に表示するヒントのテキストを指定。(※デフォルト:NULL)
    paintbackground 背景描画の有無を指定。
    0以上 - 背景の描画あり
    -1以下 - 背景の描画なし(※デフォルト:-1)
    paintborder コントロールのボーダー描画の有無を指定。
    0以上 - ボーダーの描画あり
    -1以下 - ボーダーの描画なし(※デフォルト:-1)
    fieldName コントロール名。
    コンストラクタ呼び出し時や、SetName()メンバ関数で指定したコントロールのインスタンス毎に指定 された名前を上書きする。

    (´・ω・`)つもどる