add help screen, use keymap

This commit is contained in:
stryan 2022-05-28 17:46:28 -04:00
parent ffbf8afca3
commit a386ae1872
2 changed files with 125 additions and 48 deletions

78
keymap.go Normal file
View File

@ -0,0 +1,78 @@
package main
import "github.com/charmbracelet/bubbles/key"
type keyMap struct {
Up key.Binding
Down key.Binding
Left key.Binding
Right key.Binding
Help key.Binding
Quit key.Binding
Gather key.Binding
Pickup key.Binding
Destroy key.Binding
Place key.Binding
Craft key.Binding
}
// ShortHelp returns keybindings to be shown in the mini help view. It's part
// of the key.Map interface.
func (k keyMap) ShortHelp() []key.Binding {
return []key.Binding{k.Help, k.Quit}
}
// FullHelp returns keybindings for the expanded help view. It's part of the
// key.Map interface.
func (k keyMap) FullHelp() [][]key.Binding {
return [][]key.Binding{
{k.Up, k.Down, k.Left, k.Right, k.Gather, k.Place, k.Craft, k.Destroy, k.Pickup, k.Help, k.Quit}, //second column
}
}
var keys = keyMap{
Up: key.NewBinding(
key.WithKeys("up", "k"),
key.WithHelp("↑/k", "move up"),
),
Down: key.NewBinding(
key.WithKeys("down", "j"),
key.WithHelp("↓/j", "move down"),
),
Left: key.NewBinding(
key.WithKeys("left", "h"),
key.WithHelp("←/h", "move left"),
),
Right: key.NewBinding(
key.WithKeys("right", "l"),
key.WithHelp("→/l", "move right"),
),
Help: key.NewBinding(
key.WithKeys("?"),
key.WithHelp("?", "toggle help"),
),
Quit: key.NewBinding(
key.WithKeys("esc", "ctrl+c"),
key.WithHelp("ctrl+c", "quit"),
),
Gather: key.NewBinding(
key.WithKeys("g"),
key.WithHelp("g", "gather tile resource"),
),
Pickup: key.NewBinding(
key.WithKeys(","),
key.WithHelp(",", "pickup object"),
),
Destroy: key.NewBinding(
key.WithKeys("x"),
key.WithHelp("x", "destroy tile object "),
),
Place: key.NewBinding(
key.WithKeys("p"),
key.WithHelp("p", "place object"),
),
Craft: key.NewBinding(
key.WithKeys("c"),
key.WithHelp("c", "craft object"),
),
}

View File

@ -7,20 +7,25 @@ import (
"time" "time"
sim "git.saintnet.tech/stryan/spacetea/simulator" sim "git.saintnet.tech/stryan/spacetea/simulator"
"github.com/charmbracelet/bubbles/help"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
) )
var style = lipgloss.NewStyle(). var style = lipgloss.NewStyle().
Width(24). Width(32).
Align(lipgloss.Center). Align(lipgloss.Center).
Foreground(lipgloss.Color("#F0FFFF")).
BorderStyle(lipgloss.NormalBorder()). BorderStyle(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("63")) BorderForeground(lipgloss.Color("63"))
type model struct { type model struct {
s *sim.Simulator s *sim.Simulator
input textinput.Model input textinput.Model
help help.Model
keys keyMap
next string next string
} }
@ -50,6 +55,8 @@ func initMainscreen() model {
return model{ return model{
s: simulator, s: simulator,
input: ti, input: ti,
help: help.New(),
keys: keys,
} }
} }
func (m model) Init() tea.Cmd { func (m model) Init() tea.Cmd {
@ -62,6 +69,8 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case beat: case beat:
//heartbeat //heartbeat
return m, heartbeat() return m, heartbeat()
case tea.WindowSizeMsg:
m.help.Width = msg.Width
case placeMsg: case placeMsg:
simc := fmt.Sprintf("place %v", string(msg)) simc := fmt.Sprintf("place %v", string(msg))
m.s.Input(simc) m.s.Input(simc)
@ -71,39 +80,28 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.s.Input(simc) m.s.Input(simc)
return m, nil return m, nil
case tea.KeyMsg: case tea.KeyMsg:
switch msg.Type { switch {
case tea.KeyCtrlC: case key.Matches(msg, m.keys.Help):
m.help.ShowAll = !m.help.ShowAll
return m, nil
case key.Matches(msg, m.keys.Quit):
m.s.Stop() m.s.Stop()
return m, tea.Quit return m, tea.Quit
case tea.KeyEnter: case key.Matches(msg, m.keys.Right):
m.s.Input(m.input.Value())
m.input.Reset()
return m, nil
case tea.KeyRight:
m.s.Input("right") m.s.Input("right")
return m, nil return m, nil
case tea.KeyLeft: case key.Matches(msg, m.keys.Left):
m.s.Input("left") m.s.Input("left")
return m, nil return m, nil
case tea.KeyUp: case key.Matches(msg, m.keys.Up):
m.s.Input("up") m.s.Input("up")
return m, nil return m, nil
case tea.KeyDown: case key.Matches(msg, m.keys.Down):
m.s.Input("down") m.s.Input("down")
return m, nil return m, nil
case tea.KeyCtrlF: case key.Matches(msg, m.keys.Gather):
if m.input.Focused() {
m.input.Blur()
} else {
m.input.Focus()
}
return m, nil
case tea.KeyRunes:
if !m.input.Focused() {
switch msg.String() {
case "g":
m.s.Input("get") m.s.Input("get")
case "p": case key.Matches(msg, m.keys.Place):
var res entrylist var res entrylist
for _, k := range sim.GlobalItems { for _, k := range sim.GlobalItems {
if m.s.Player.Resources[k.ID()] != 0 { if m.s.Player.Resources[k.ID()] != 0 {
@ -112,11 +110,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} }
sort.Sort(res) sort.Sort(res)
return newMenuModel(res, placeMenu), nil return newMenuModel(res, placeMenu), nil
case ",": case key.Matches(msg, m.keys.Pickup):
m.s.Input("pickup") m.s.Input("pickup")
case "x": case key.Matches(msg, m.keys.Destroy):
m.s.Input("destroy") m.s.Input("destroy")
case "c": case key.Matches(msg, m.keys.Craft):
var res entrylist var res entrylist
for k := range m.s.Player.Craftables { for k := range m.s.Player.Craftables {
res = append(res, sim.GlobalItems[k].(sim.ItemEntry)) res = append(res, sim.GlobalItems[k].(sim.ItemEntry))
@ -124,9 +122,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
sort.Sort(res) sort.Sort(res)
return newMenuModel(res, craftMenu), nil return newMenuModel(res, craftMenu), nil
} }
return m, nil
}
}
} }
m.input, cmd = m.input.Update(msg) m.input, cmd = m.input.Update(msg)
return m, cmd return m, cmd
@ -135,9 +130,13 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m model) View() string { func (m model) View() string {
var render string var render string
if m.help.ShowAll != true {
playerAndLog := lipgloss.JoinVertical(0, style.Render(fmt.Sprintf("%v", m.s.Player.String())), style.Render(fmt.Sprintf("%v", m.s.Player.Log()))) playerAndLog := lipgloss.JoinVertical(0, style.Render(fmt.Sprintf("%v", m.s.Player.String())), style.Render(fmt.Sprintf("%v", m.s.Player.Log())))
placeAndInput := lipgloss.JoinVertical(0, style.Render(m.s.Place.String()), style.Render(m.input.View())) placeAndInput := lipgloss.JoinVertical(0, style.Render(m.s.Place.String()), style.Render(m.help.View(m.keys)))
display := lipgloss.JoinHorizontal(0, placeAndInput, playerAndLog) display := lipgloss.JoinHorizontal(0, placeAndInput, playerAndLog)
render = fmt.Sprintf("%v\n%v\n", style.Render(fmt.Sprintf("Current Time: %v", strconv.Itoa(m.s.Time))), display) render = fmt.Sprintf("%v\n%v\n", style.Render(fmt.Sprintf("Current Time: %v", strconv.Itoa(m.s.Time))), display)
} else {
render = style.Render(m.help.View(m.keys))
}
return render return render
} }