ボタンやトグルを組み立てる
ボタンが効くオーバーレイの種類
Section titled “ボタンが効くオーバーレイの種類”今、コントローラーで押せるのは、ダッシュボードのオーバーレイだけです。WorldSpaceWindow と DeviceTrackedWindow は表示専用で、GestureDetector のコールバックが呼ばれません(追跡: #182)。ボタンやトグルを組み立てるときは、DashboardWindow に出します。
Button ウィジェットは、まだありません(追跡: #219)。この手順では、GestureDetector と見た目のウィジェットを組み合わせて、押せるボタンと、押すたびに切り替わるトグルを作ります。
自分のオーバーレイの種類は、CreateWindow に渡している型で確かめます。ダッシュボード以外に出したい場合は、オーバーレイの種類と選び方で、種類ごとの違いを確かめます。
- 最初のオーバーレイを作るを終え、ダッシュボードにオーバーレイが出ること
SetState()で値を変えると画面が変わることを知っていること- ソースの先頭に、
FloatSoda.Geometrics、FloatSoda.Widgets.Gesture、FloatSoda.Widgets.Layout、FloatSoda.Widgets.Paint、FloatSoda.Painting、SkiaSharpのusingがあること
SetState() の仕組みが分からない場合は、値が変わると、画面が変わる仕組みを先に読みます。
手順1: 押せるボタンを作る
Section titled “手順1: 押せるボタンを作る”見た目の四角を GestureDetector で包み、OnTap で SetState() を呼びます。OnTap は、押して離した時点で呼ばれます。押しただけでは呼ばれません。
public record CountButton : StatefulWidget<CountButton>{ public override State<CountButton> CreateState() => new CountButtonState();}
public class CountButtonState : State<CountButton>{ private int _count;
public override Widget Build(IBuildContext context) => new GestureDetector { OnTap = () => SetState(() => _count++), Child = new ClipRoundRect { BorderRadius = BorderRadius.All(Radius.Circular(15)), Child = new SizedBox { Width = 300, Height = 100, Child = new ColoredBox { Color = SKColors.CornflowerBlue, Child = new Center { Child = new Text($"押した回数: {_count}") { Style = new TextStyle { Color = SKColors.WhiteSmoke, FontSize = 40, FontWeight = 700 }, }, }, }, }, }, };}起動のコードで、DashboardWindow の Child を new CountButton() に置き換えます。
できた? ダッシュボードで、コントローラーのレーザーを四角に当てて押し、離したときに押した回数が増えれば、手順1は完了です。
できなかったら
押しても反応しないときは、ウィンドウが DashboardWindow であることを確かめます。WorldSpaceWindow と DeviceTrackedWindow では、コントローラーのレーザー操作を受け取れません(追跡: #182)。それでも直らないときは、反応しないときに切り分けるに進みます。
手順2: 押すたびに切り替わるトグルを作る
Section titled “手順2: 押すたびに切り替わるトグルを作る”トグルは、ボタンと同じ仕組みで作れます。bool の状態を State に持ち、OnTap で反転させ、状態に合わせて見た目を変えます。
public record ToggleButton : StatefulWidget<ToggleButton>{ public override State<ToggleButton> CreateState() => new ToggleButtonState();}
public class ToggleButtonState : State<ToggleButton>{ private bool _isOn;
public override Widget Build(IBuildContext context) => new GestureDetector { OnTap = () => SetState(() => _isOn = !_isOn), Child = new ClipRoundRect { BorderRadius = BorderRadius.All(Radius.Circular(15)), Child = new SizedBox { Width = 300, Height = 100, Child = new ColoredBox { Color = _isOn ? SKColors.SeaGreen : SKColors.Gray, Child = new Center { Child = new Text(_isOn ? "ON" : "OFF") { Style = new TextStyle { Color = SKColors.White, FontSize = 40, FontWeight = 700 }, }, }, }, }, }, };}手順1の確認のあとは、DashboardWindow の Child を new ToggleButton() に置き換えます。
できた? 押すたびに、緑の ON と灰色の OFF が切り替われば、手順2は完了です。
手順3: 押せる範囲を決める
Section titled “手順3: 押せる範囲を決める”GestureDetector の Behaviour の既定は HitTestBehaviour.DeferToChild で、子が押された位置を受け取れるときだけ反応します。ColoredBox と Text は、自分の範囲全体で押された位置を受け取ります。Padding や SizedBox は受け取らないので、これらの余白だけが残る位置は、押しても反応しません。余白を含む領域全体で反応させるには、Behaviour = HitTestBehaviour.Opaque を指定します。
new GestureDetector{ Behaviour = HitTestBehaviour.Opaque, OnTap = () => SetState(() => _count++), Child = new Padding { Spacing = EdgeInsets.All(40), Child = new Text($"押した回数: {_count}"), },}HitTestBehaviour は、FloatSoda.Gesture の名前空間にあります。
できた? 文字の周りの余白を押しても、押した回数が増えれば、手順3は完了です。
ボタンを押したまま動かすドラッグは、OnPanUpdate で受け取ります。コードはサンプルの DragBoxWidget.cs にあります。ホバーや生のポインターイベントが要るときは、Listener と PointerRegion を使います。
結果を確かめる
Section titled “結果を確かめる”ダッシュボードのタブを開き、コントローラーで次の3点を試します。
- ボタンを押すと、値が変わる
- トグルを押すたびに、見た目が切り替わる
- 余白を含む範囲を押しても、反応する
HMD を被らずに確かめたいときは、HMD を被らずに確かめるに進みます。ただし、デスクトップで動いても、ダッシュボードで動く確認の代わりにはなりません(追跡: #182)。最後は、ダッシュボードで押して確かめます。
組み立てた部品を使った、通しの例は表情切り替えパネルを作るです。
うまくいかないとき
Section titled “うまくいかないとき”押しても反応しないときは、反応しないときに切り分けるで原因を切り分けます。