mirror of
https://github.com/BigJk/end_of_eden.git
synced 2026-02-06 10:48:09 +00:00
148 lines
4.3 KiB
Go
148 lines
4.3 KiB
Go
package mainmenu
|
|
|
|
import (
|
|
"runtime"
|
|
|
|
"github.com/BigJk/end_of_eden/system/audio"
|
|
"github.com/BigJk/end_of_eden/ui/style"
|
|
"github.com/charmbracelet/bubbles/list"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/charmbracelet/lipgloss"
|
|
zone "github.com/lrstanley/bubblezone"
|
|
"github.com/samber/lo"
|
|
)
|
|
|
|
type Choice string
|
|
|
|
const (
|
|
ChoiceWaiting = Choice("WAITING")
|
|
ChoiceContinue = Choice("CONTINUE")
|
|
ChoiceTutorial = Choice("TUTORIAL")
|
|
ChoiceNewGame = Choice("NEW_GAME")
|
|
ChoiceNewGameSOD = Choice("NEW_GAME_SOD")
|
|
ChoiceAbout = Choice("ABOUT")
|
|
ChoiceSettings = Choice("SETTINGS")
|
|
ChoiceMods = Choice("MODS")
|
|
ChoiceExit = Choice("EXIT")
|
|
)
|
|
|
|
type choiceItem struct {
|
|
zones *zone.Manager
|
|
title, desc string
|
|
key Choice
|
|
}
|
|
|
|
func (i choiceItem) Title() string { return i.zones.Mark("choice_"+string(i.key), i.title) }
|
|
func (i choiceItem) Description() string { return i.zones.Mark("choice_desc_"+string(i.key), i.desc) }
|
|
func (i choiceItem) FilterValue() string { return i.title }
|
|
|
|
type ChoicesModel struct {
|
|
zones *zone.Manager
|
|
choices []list.Item
|
|
list list.Model
|
|
selected Choice
|
|
}
|
|
|
|
func NewChoicesModel(zones *zone.Manager, hideSettings bool) ChoicesModel {
|
|
choices := []list.Item{
|
|
choiceItem{zones, "Continue", "Ready to continue dying?", ChoiceContinue},
|
|
choiceItem{zones, "Tutorial", "Learn the basics.", ChoiceTutorial},
|
|
choiceItem{zones, "New Game", "Start a new try.", ChoiceNewGame},
|
|
choiceItem{zones, "New Game: Seed of the Day", "Start a new try with the daily seed.", ChoiceNewGameSOD},
|
|
choiceItem{zones, "About", "Want to know more?", ChoiceAbout},
|
|
choiceItem{zones, "Settings", "Other settings won't let you survive...", ChoiceSettings},
|
|
choiceItem{zones, "Mods", "Make the game even more fun!", ChoiceMods},
|
|
choiceItem{zones, "Exit", "Got enough already?", ChoiceExit},
|
|
}
|
|
|
|
// Hide exit on web
|
|
if runtime.GOOS == "js" {
|
|
choices = lo.Filter(choices, func(value list.Item, i int) bool {
|
|
return value.(choiceItem).title != "Exit" || value.(choiceItem).title == "Mods"
|
|
})
|
|
}
|
|
|
|
if hideSettings {
|
|
choices = lo.Filter(choices, func(value list.Item, i int) bool {
|
|
return value.(choiceItem).key != ChoiceSettings
|
|
})
|
|
}
|
|
|
|
delegation := list.NewDefaultDelegate()
|
|
delegation.Styles.SelectedTitle = delegation.Styles.SelectedTitle.Foreground(style.BaseRed).BorderForeground(style.BaseRed)
|
|
delegation.Styles.SelectedDesc = delegation.Styles.SelectedDesc.Foreground(style.BaseRedDarker).BorderForeground(style.BaseRed)
|
|
|
|
model := ChoicesModel{
|
|
zones: zones,
|
|
choices: choices,
|
|
list: list.New(choices, delegation, 0, 0),
|
|
selected: ChoiceWaiting,
|
|
}
|
|
|
|
model.list.Title = "Main Menu"
|
|
model.list.SetFilteringEnabled(false)
|
|
model.list.SetShowFilter(false)
|
|
model.list.SetShowStatusBar(false)
|
|
//model.list.SetShowHelp(false)
|
|
model.list.Styles.Title = lipgloss.NewStyle().Background(style.BaseRedDarker).Foreground(style.BaseWhite).Padding(0, 2, 0, 2)
|
|
|
|
return model
|
|
}
|
|
|
|
func (m ChoicesModel) Clear() ChoicesModel {
|
|
m.selected = ChoiceWaiting
|
|
return m
|
|
}
|
|
|
|
func (m ChoicesModel) Init() tea.Cmd {
|
|
return nil
|
|
}
|
|
|
|
func (m ChoicesModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
switch msg := msg.(type) {
|
|
case tea.WindowSizeMsg:
|
|
h, v := style.ListStyle.GetFrameSize()
|
|
m.list.SetSize(msg.Width-h, msg.Height-v)
|
|
case tea.KeyMsg:
|
|
switch msg.Type {
|
|
case tea.KeyEnter:
|
|
choice, ok := m.list.SelectedItem().(choiceItem)
|
|
if ok {
|
|
if choice.key == ChoiceExit {
|
|
return m, tea.Quit
|
|
}
|
|
m.selected = choice.key
|
|
}
|
|
case tea.KeyDown:
|
|
fallthrough
|
|
case tea.KeyUp:
|
|
audio.Play("interface_move", -1.5)
|
|
}
|
|
case tea.MouseMsg:
|
|
if (msg.Action == tea.MouseActionRelease && msg.Button == tea.MouseButtonLeft) || msg.Action == tea.MouseActionMotion {
|
|
for i := range m.choices {
|
|
if m.zones.Get("choice_"+string(m.choices[i].(choiceItem).key)).InBounds(msg) || m.zones.Get("choice_desc_"+string(m.choices[i].(choiceItem).key)).InBounds(msg) {
|
|
if m.list.Index() != i {
|
|
audio.Play("interface_move", -1.5)
|
|
}
|
|
|
|
m.list.Select(i)
|
|
if msg.Action == tea.MouseActionRelease && msg.Button == tea.MouseButtonLeft {
|
|
m.selected = m.choices[i].(choiceItem).key
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var cmd tea.Cmd
|
|
m.list, cmd = m.list.Update(msg)
|
|
|
|
return m, cmd
|
|
}
|
|
|
|
func (m ChoicesModel) View() string {
|
|
return style.ListStyle.Render(m.list.View())
|
|
}
|