tcellでカーソルを上下左右に移動する


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座標を取得します。

同じカテゴリーの記事
マインクラフト用ビジュアルエディタを開発しています。
詳しくはinunosinsi/mcws_blockly - githubをご覧ください。