tcellでTUIアプリを作成するで作成しましたTUIアプリで矢印キーでカーソルを移動できるようにします。
前回作成したコードに太字で示したコードを追加します。
~/workspace/tcell_sample/main.go
package main import ( "github.com/gdamore/tcell/v2" ) func main() { screen, err := tcell.NewScreen() if err != nil { panic(err) } if err := screen.Init(); err != nil { panic(err) } defer screen.Fini() pos_x, pos_y := 5, 10 for { ev := screen.PollEvent() // イベントを取得する switch ev := ev.(type) { case *tcell.EventKey: switch ev.Key() { case tcell.KeyEscape: // ESCキーが押されたら終了する return case tcell.KeyUp: pos_y-- if pos_y <= 0 { pos_y = 0 } case tcell.KeyDown: pos_y++ case tcell.KeyLeft: pos_x-- if pos_x <= 0 { pos_x = 0 } case tcell.KeyRight: pos_x++ } } screen.ShowCursor(pos_x, pos_y) screen.Show() } }
pos_x, pos_y := 5, 10
でカーソルを最初に配置する場所を決め、for のイベントループ内の
screen.ShowCursor(pos_x, pos_y)
で指定した場所にカーソルを配置します。
後は for のイベントループ内で矢印キーを押した時の挙動を追加しています。
画面上と左は座標がわかるので、矢印を押しすぎた時の対応(pos_x等の変数を 0 にする)は簡単ですが、右と下の座標は現時点ではわかりません。
そこで、スクリーンのサイズを取得する為に下記のように書き換えます。
package main import ( "github.com/gdamore/tcell/v2" ) func main() { screen, err := tcell.NewScreen() if err != nil { panic(err) } if err := screen.Init(); err != nil { panic(err) } defer screen.Fini() pos_x, pos_y := 5, 10 screen_x, screen_y := screen.Size() for { ev := screen.PollEvent() // イベントを取得する switch ev := ev.(type) { case *tcell.EventKey: switch ev.Key() { case tcell.KeyEscape: // ESCキーが押されたら終了する return case tcell.KeyUp: pos_y-- if pos_y <= 0 { pos_y = 0 } case tcell.KeyDown: pos_y++ if pos_y >= screen_y-1 { pos_y = screen_y - 1 } case tcell.KeyLeft: pos_x-- if pos_x <= 0 { pos_x = 0 } case tcell.KeyRight: pos_x++ if pos_x >= screen_x-1 { pos_x = screen_x - 1 } } } screen.ShowCursor(pos_x, pos_y) screen.Show() } }
screen_x, screen_y := screen.Size()
で現在のスクリーンのサイズ(右端のx座標と下のy座標)を取得して、各々のキーの操作で使用します。
ただ、このコードでは、TUIアプリ起動時にウィンドウのサイズを変更した場合、右端のx座標と下のy座標が変更されてしまいますので、
package main import ( "github.com/gdamore/tcell/v2" ) func main() { screen, err := tcell.NewScreen() if err != nil { panic(err) } if err := screen.Init(); err != nil { panic(err) } defer screen.Fini() pos_x, pos_y := 5, 10 screen_x, screen_y := screen.Size() for { ev := screen.PollEvent() // イベントを取得する switch ev := ev.(type) { case *tcell.EventKey: switch ev.Key() { case tcell.KeyEscape: // ESCキーが押されたら終了する return case tcell.KeyUp: pos_y-- if pos_y <= 0 { pos_y = 0 } case tcell.KeyDown: pos_y++ if pos_y >= screen_y-1 { pos_y = screen_y - 1 } case tcell.KeyLeft: pos_x-- if pos_x <= 0 { pos_x = 0 } case tcell.KeyRight: pos_x++ if pos_x >= screen_x-1 { pos_x = screen_x - 1 } } case *tcell.EventResize: screen.Sync() screen_x, screen_y = screen.Size() } screen.ShowCursor(pos_x, pos_y) screen.Show() } }
case *tcell.EventResize: screen.Sync() screen_x, screen_y = screen.Size()
ウィンドウのリサイズのイベントを追加して、再度、右端のx座標と下のy座標を取得します。