もろもろ細かいレベルで元のnanoguiから手を加えているので、それを淡々と記録していく。目標としては、Qtなどの既存のGUIフレームワークを使ったことがある人が違和感を感じるようなところを無くす。
Screen/Window/Widgetまわり
- Screen内にレイアウトを設定してWindowを複数並べたりできるようにした
- Widgetを置いて、その中にWindowを複数並べられるようにした
- デバッグでツリー構造を表示する機能をつけた(Screen.DebugPrint())
- 子要素の表示順序
- Z値を持たせて、それに応じてソートして表示する。ただし、現状はZ値を持っているのはウインドウの子クラス(Window, Popup)のみ。
- クリッピング
- 親要素の範囲外のものは描画しなようにした。大量にあるデータをVScrollPanelで表示しても、表示領域にあるものしかOpenGL命令は呼ばない。
- ついでに、NanoVGoのテキストをTRIANGLESからTRIANGLE_STRIPにして頂点数を減らした
基本ウィジェット
- TextBox
- 編集中文字列の長さでセンタリングされるようにした。オリジナルはコミット後文字列
- MacOS Xと同じEmacsキーバインドを追加
- IMEサポート
- テーマのフォントを使わずに固有のフォントを設定するメソッドを追加した(FontFace/SetFontFace)
- VScrollPanel
- スクロール量を取得設定するメソッド(Scroll/SetScroll)を追加
- スクロールが不要な時はスクロールバーを非表示に。小さすぎるときは最低20px表示するように。
- スクロール値(0.0-1.0)だけを保持していたが、絶対座標を持つようにして、そこからスクロール値を計算するようにした。今まではスクロール値への変換を何度も行うことで誤差が拡大してスクロールがなめらかに行えなかった。
- Popup
- 子要素が大きかった時にスクロールバーを出すようにした。VScrollはクセが強いのでなんとかしたい。
- まだ完全ではない。ポップアップが画面からはみ出すかどうかでサイズの調整を自動にしたりしたい。
- Label
- SetWrap(bool)でラップの設定を行う。デフォルトはON。falseにすると、nanoguiext.ExpandListLayout()でも、折り曲げられないで表示される。
基本レイアウト
- BoxLayout(horizontal)
- ウインドウに対してレイアウトを設定するとおかしくなる。本家にもPR出した。
追加ウィジェット
- nanoguiext.Spinner
- スピナー。表示中はイベントハンドラをブロックする。設置されたところから一番近い親のウインドウ、もしくはスクリーンを覆う。
- スピナー自身はサイズゼロの要素で、別に全体を覆うフィルターコンポーネントを内部で作る。
- サイズや回転速度やらはパラメータで変更できる
追加レイアウト
オリジナルはボトムアップで大きさを決めていくレイアウトしかなかったので、親要素のサイズからトップダウンで決めていくものを追加した。ウインドウ全体に対して覆うようなレイアウトを実現する。
- nanoguiext.ExpandBoxLayout
- Boxレイアウトのトップダウン型。500のスペースがあって、ウィジェットが2つあれば250pxずつボックスを作って配置する。
- Clamp()が設定されている場合や、FixedSize()が設定された場合は、スペースを延長せずに並べる。残った空間が、他のウィジェットで等分されて配置される。
- nanoguiext.ExpandListLayout
- リスト型のテーブルを実現する。各カラムのベースの大きさと、スペースが余った時の戦略を設定する。
- スペースが余った時の戦略は、すべてのカラムに等分で配分(ExpandAll=default)と、最後のカラムにすべて配分(ExpandLast)と、個別指定がある。
- 個別指定はSetStretches()を呼ぶ。この数値の大きさで配分する。{0.5, 1.0}なら、1:2に配分される。全部ゼロの場合はExpandAll/ExpandLastが使われる
- ヘッダが固定長で、各項目が残りすべて、みたいな用途で使う。ラベルのように幅が決まってから高さが決まる要素で正しくレイアウトするのがこのレイアウトの目的
- SetColumnWidth()を持っているウィジェットには、これを内部で呼び出して、コンテンツの幅を設定する。ラベルのように幅によって高さが変わるウィジェットで、PreferredSize()メソッドが正しいサイズを返すために、期待する幅を設定する。
困りごと/追加したい機能
- VScrollPanel
- スクロールされる子もコンポーネント内で面倒みるようにしたい
- トップレベルのウィジェット
- Material Design LiteのLayoutあたりを実現したい。
- ボタンのラベル
- 長過ぎる時に三点リーダを使って省略というのをやりたい
- 自動レイアウト
- 今は自分でScreen.PerformLayout()を呼び出さないとレイアウトが実行されない。dirtyフラグを付けて、描画のコールバック内で自動で再レイアウトするようにしたい