From 881c6b4dedd620c6d5928e031a4efb398f117309 Mon Sep 17 00:00:00 2001 From: Tyrel Souza Date: Sat, 8 Oct 2022 23:09:19 -0400 Subject: [PATCH] gui module --- go.mod | 2 +- gui/gui.go | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 185 +-------------------------------------------------- 3 files changed, 193 insertions(+), 184 deletions(-) create mode 100644 gui/gui.go diff --git a/go.mod b/go.mod index 7c4b5e2..dcff9de 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module itor +module gitea.tyrel.dev/tyrel/itor go 1.19 diff --git a/gui/gui.go b/gui/gui.go new file mode 100644 index 0000000..45af4f1 --- /dev/null +++ b/gui/gui.go @@ -0,0 +1,190 @@ +package gui + +import ( + "fmt" + tea "github.com/charmbracelet/bubbletea" + "os" + "time" +) + +type Mode int64 + +const ( + Select Mode = iota + Create + Draw +) + +type Card struct { + Front string + Back string + LastCorrect time.Time +} + +type model struct { + cards []Card // items on the to-do list + cursor int // which to-do list item our cursor is pointing at + selected map[int]struct{} // which to-do items are selected + mode Mode +} + +func initialModel() model { + return model{ + cards: []Card{ + {Front: "Hello (JP)", Back: "Konnichi wa"}, + {Front: "Hello (SP)", Back: "Hola"}, + {Front: "Hello (DE)", Back: "Guten Tag"}, + }, + + selected: make(map[int]struct{}), + mode: Select, + } +} + +func (m *model) Init() tea.Cmd { + // Just return `nil`, which means "no I/O right now, please." + return nil +} +func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + if m.mode == Draw { + return m.updateDraw(msg) + } + // Select is default mode + return m.updateSelect(msg) +} + +func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + + // Is it a key press? + case tea.KeyMsg: + switch msg.String() { + + case "s": + m.switchMode(Select) + + // These keys should exit the program. + case "ctrl+c", "q": + return m, tea.Quit + } + } + + return m, nil +} + +func (m *model) switchMode(mode Mode) { + // TODO: initialization stuff + switch mode { + case Select: + m.mode = Select + case Draw: + m.mode = Draw + case Create: + m.mode = Create + } +} + +func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + + // Is it a key press? + case tea.KeyMsg: + switch msg.String() { + + // These keys should exit the program. + case "ctrl+c", "q": + return m, tea.Quit + + // The "up" and "k" keys move the cursor up + case "up", "k": + if m.cursor > 0 { + m.cursor-- + } + + // The "down" and "j" keys move the cursor down + case "down", "j": + if m.cursor < len(m.cards)-1 { + m.cursor++ + } + case "d": + m.switchMode(Draw) + + // The "enter" key and the spacebar (a literal space) toggle + // the selected state for the item that the cursor is pointing at. + case "enter", " ": + _, ok := m.selected[m.cursor] + if ok { + delete(m.selected, m.cursor) + } else { + m.selected[m.cursor] = struct{}{} + } + } + } + + // Return the updated model to the Bubble Tea runtime for processing. + // Note that we're not returning a command. + return m, nil +} + +func (m *model) cardListToString() string { + s := "" + for i, card := range m.cards { + if _, ok := m.selected[i]; ok { + s += fmt.Sprintf("%s [%s]\n", card.Front, card.Back) + } + } + return s +} +func (m *model) View() string { + if m.mode == Draw { + return m.viewDraw() + } + // Select is default mode + return m.viewSelect() +} + +func (m *model) viewDraw() string { + s := "Draw Mode:\n\n" + + s += m.cardListToString() + + return s +} + +func (m *model) viewSelect() string { + s := "Select cards to query:\n\n" + + // Iterate over our choices + for i, choice := range m.cards { + + // Is the cursor pointing at this choice? + cursor := " " // no cursor + if m.cursor == i { + cursor = ">" // cursor! + } + + // Is this choice selected? + checked := " " // not selected + if _, ok := m.selected[i]; ok { + checked = "✓" // selected! + } + + // Render the row + s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice.Front) + } + + // The footer + s += "\nPress c to Create (_unimplemented_).\nPress d to Draw.\nPress q to quit.\n" + + // Send the UI for rendering + return s +} + +func Run() { + initial := initialModel() + p := tea.NewProgram(&initial) + if err := p.Start(); err != nil { + fmt.Printf("Alas, there's been an error: %v", err) + os.Exit(1) + } +} diff --git a/main.go b/main.go index 01d2c29..8e2551d 100644 --- a/main.go +++ b/main.go @@ -1,190 +1,9 @@ package main import ( - "fmt" - tea "github.com/charmbracelet/bubbletea" - "os" - "time" + "gitea.tyrel.dev/tyrel/itor/gui" ) -type Mode int64 - -const ( - Select Mode = iota - Create - Draw -) - -type Card struct { - Front string - Back string - LastCorrect time.Time -} - -type model struct { - cards []Card // items on the to-do list - cursor int // which to-do list item our cursor is pointing at - selected map[int]struct{} // which to-do items are selected - mode Mode -} - -func initialModel() model { - return model{ - cards: []Card{ - {Front: "Hello (JP)", Back: "Konnichi wa"}, - {Front: "Hello (SP)", Back: "Hola"}, - {Front: "Hello (DE)", Back: "Guten Tag"}, - }, - - selected: make(map[int]struct{}), - mode: Select, - } -} - -func (m *model) Init() tea.Cmd { - // Just return `nil`, which means "no I/O right now, please." - return nil -} -func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - if m.mode == Draw { - return m.updateDraw(msg) - } - // Select is default mode - return m.updateSelect(msg) -} - -func (m *model) updateDraw(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - - // Is it a key press? - case tea.KeyMsg: - switch msg.String() { - - case "s": - m.switchMode(Select) - - // These keys should exit the program. - case "ctrl+c", "q": - return m, tea.Quit - } - } - - return m, nil -} - -func (m *model) switchMode(mode Mode) { - // TODO: initialization stuff - switch mode { - case Select: - m.mode = Select - case Draw: - m.mode = Draw - case Create: - m.mode = Create - } -} - -func (m *model) updateSelect(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - - // Is it a key press? - case tea.KeyMsg: - switch msg.String() { - - // These keys should exit the program. - case "ctrl+c", "q": - return m, tea.Quit - - // The "up" and "k" keys move the cursor up - case "up", "k": - if m.cursor > 0 { - m.cursor-- - } - - // The "down" and "j" keys move the cursor down - case "down", "j": - if m.cursor < len(m.cards)-1 { - m.cursor++ - } - case "d": - m.switchMode(Draw) - - // The "enter" key and the spacebar (a literal space) toggle - // the selected state for the item that the cursor is pointing at. - case "enter", " ": - _, ok := m.selected[m.cursor] - if ok { - delete(m.selected, m.cursor) - } else { - m.selected[m.cursor] = struct{}{} - } - } - } - - // Return the updated model to the Bubble Tea runtime for processing. - // Note that we're not returning a command. - return m, nil -} - -func (m *model) cardListToString() string { - s := "" - for i, card := range m.cards { - if _, ok := m.selected[i]; ok { - s += fmt.Sprintf("%s [%s]\n", card.Front, card.Back) - } - } - return s -} -func (m *model) View() string { - if m.mode == Draw { - return m.viewDraw() - } - // Select is default mode - return m.viewSelect() -} - -func (m *model) viewDraw() string { - s := "Draw Mode:\n\n" - - s += m.cardListToString() - - return s -} - -func (m *model) viewSelect() string { - s := "Select cards to query:\n\n" - - // Iterate over our choices - for i, choice := range m.cards { - - // Is the cursor pointing at this choice? - cursor := " " // no cursor - if m.cursor == i { - cursor = ">" // cursor! - } - - // Is this choice selected? - checked := " " // not selected - if _, ok := m.selected[i]; ok { - checked = "✓" // selected! - } - - // Render the row - s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice.Front) - } - - // The footer - s += "\nPress c to Create (_unimplemented_).\nPress d to Draw.\nPress q to quit.\n" - - // Send the UI for rendering - return s -} - func main() { - initial := initialModel() - p := tea.NewProgram(&initial) - if err := p.Start(); err != nil { - fmt.Printf("Alas, there's been an error: %v", err) - os.Exit(1) - } + gui.Run() }