Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor project #22

Merged
merged 8 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cmd/tetrigo/subcommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package main
import (
"fmt"

tea "github.com/charmbracelet/bubbletea"

"github.com/Broderick-Westrope/tetrigo/internal/config"
"github.com/Broderick-Westrope/tetrigo/internal/data"
"github.com/Broderick-Westrope/tetrigo/internal/tui"
"github.com/Broderick-Westrope/tetrigo/internal/tui/models/starter"
tea "github.com/charmbracelet/bubbletea"
"github.com/Broderick-Westrope/tetrigo/internal/tui/starter"
)

type MenuCmd struct{}
Expand Down
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ require (
github.com/charmbracelet/bubbles v0.18.0
github.com/charmbracelet/bubbletea v0.25.0
github.com/charmbracelet/lipgloss v0.9.1
github.com/charmbracelet/x/ansi v0.4.5
github.com/mattn/go-runewidth v0.0.16
github.com/mattn/go-sqlite3 v1.14.22
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b
github.com/muesli/reflow v0.3.0
github.com/muesli/termenv v0.15.2
github.com/stretchr/testify v1.9.0
)

Expand All @@ -24,9 +22,12 @@ require (
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.6 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/term v0.6.0 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg=
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM=
github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down Expand Up @@ -45,8 +47,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg=
github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
Expand Down
62 changes: 62 additions & 0 deletions internal/tui/components/game_keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package components

import (
"github.com/Broderick-Westrope/tetrigo/internal/config"
"github.com/Broderick-Westrope/tetrigo/internal/tui"
"github.com/charmbracelet/bubbles/key"
)

type GameKeyMap struct {
ForceQuit key.Binding
Exit key.Binding
Help key.Binding
Left key.Binding
Right key.Binding
Clockwise key.Binding
CounterClockwise key.Binding
SoftDrop key.Binding
HardDrop key.Binding
Hold key.Binding
}

func ConstructGameKeyMap(keys *config.Keys) *GameKeyMap {
return &GameKeyMap{
ForceQuit: tui.ConstructKeyBinding(keys.ForceQuit, "force quit"),
Exit: tui.ConstructKeyBinding(keys.Exit, "exit"),
Help: tui.ConstructKeyBinding(keys.Help, "help"),
Left: tui.ConstructKeyBinding(keys.Left, "move left"),
Right: tui.ConstructKeyBinding(keys.Right, "move right"),
Clockwise: tui.ConstructKeyBinding(keys.RotateClockwise, "rotate clockwise"),
CounterClockwise: tui.ConstructKeyBinding(keys.RotateCounterClockwise, "rotate counter-clockwise"),
SoftDrop: tui.ConstructKeyBinding(keys.Down, "toggle soft drop"),
HardDrop: tui.ConstructKeyBinding(keys.Up, "hard drop"),
Hold: tui.ConstructKeyBinding(keys.Submit, "hold"),
}
}

func (k *GameKeyMap) ShortHelp() []key.Binding {
return []key.Binding{
k.Exit,
k.Help,
}
}

func (k *GameKeyMap) FullHelp() [][]key.Binding {
return [][]key.Binding{
{
k.Exit,
k.Help,
k.Left,
},
{
k.Right,
k.Clockwise,
k.CounterClockwise,
},
{
k.SoftDrop,
k.HardDrop,
k.Hold,
},
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package game
package components

import (
"github.com/Broderick-Westrope/tetrigo/internal/config"
"github.com/charmbracelet/lipgloss"
)

type Styles struct {
type GameStyles struct {
Playfield lipgloss.Style
EmptyCell lipgloss.Style
TetriminoCellStyles map[byte]lipgloss.Style
Expand All @@ -29,8 +29,8 @@ type cellCharacters struct {
Tetriminos string
}

func CreateStyles(theme *config.Theme) *Styles {
s := Styles{
func CreateGameStyles(theme *config.Theme) *GameStyles {
s := GameStyles{
Playfield: lipgloss.NewStyle().Border(lipgloss.RoundedBorder()).Padding(0),
EmptyCell: lipgloss.NewStyle().Foreground(lipgloss.Color(theme.Colours.EmptyCell)),
TetriminoCellStyles: map[byte]lipgloss.Style{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package hpicker
package components

import (
"strconv"
Expand All @@ -8,31 +8,31 @@ import (
"github.com/charmbracelet/lipgloss"
)

var _ tea.Model = &Model{}
var _ tea.Model = &HPickerModel{}

// Model is the model for the horizontal picker component.
type Model struct {
// HPickerModel is the model for the horizontal picker component.
type HPickerModel struct {
// cursor is the index of the currently selected option.
selected int
// options is a list of the possible options for this component.
options []KeyValuePair
// keymap encodes the keybindings recognized by the component.
keymap *KeyMap
styles Styles
keymap *hPickerKeyMap
styles hPickerStyles
}

type KeyValuePair struct {
Key string
Value any
}

type Option func(*Model)
type Option func(*HPickerModel)

func NewModel(options []KeyValuePair, opts ...Option) *Model {
m := &Model{
func NewHPickerModel(options []KeyValuePair, opts ...Option) *HPickerModel {
m := &HPickerModel{
options: options,
keymap: defaultKeyMap(),
styles: DefaultStyles(),
keymap: defaultHPickerKeyMap(),
styles: defaultHPickerStyles(),
}

for _, opt := range opts {
Expand All @@ -43,7 +43,7 @@ func NewModel(options []KeyValuePair, opts ...Option) *Model {
}

func WithRange(minValue, maxValue int) Option {
return func(m *Model) {
return func(m *HPickerModel) {
m.options = make([]KeyValuePair, (maxValue-minValue)+1)
for i := minValue - 1; i < maxValue; i++ {
m.options[i].Key = strconv.Itoa(i + 1)
Expand All @@ -52,12 +52,12 @@ func WithRange(minValue, maxValue int) Option {
}
}

func (m *Model) Init() tea.Cmd {
func (m *HPickerModel) Init() tea.Cmd {
return nil
}

// Update is the Tea update function which binds keystrokes to pagination.
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m *HPickerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if msg, ok := msg.(tea.KeyMsg); ok {
switch {
case key.Matches(msg, m.keymap.Next):
Expand All @@ -71,7 +71,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}

// View renders the cursor to a string.
func (m *Model) View() string {
func (m *HPickerModel) View() string {
var prev lipgloss.Style
if m.isFirst() {
prev = m.styles.PrevDisabledStyle
Expand All @@ -95,28 +95,28 @@ func (m *Model) View() string {

// Prev is a helper function for navigating one option backward.
// It will not go page beyond the first option (i.e. option 0).
func (m *Model) Prev() {
func (m *HPickerModel) Prev() {
if !m.isFirst() {
m.selected--
}
}

// Next is a helper function for navigating one option forward.
// It will not go beyond the last option (i.e. len(options) - 1).
func (m *Model) Next() {
func (m *HPickerModel) Next() {
if !m.isLast() {
m.selected++
}
}

func (m *Model) isFirst() bool {
func (m *HPickerModel) isFirst() bool {
return m.selected == 0
}

func (m *Model) isLast() bool {
func (m *HPickerModel) isLast() bool {
return m.selected == len(m.options)-1
}

func (m *Model) GetSelection() KeyValuePair {
func (m *HPickerModel) GetSelection() KeyValuePair {
return m.options[m.selected]
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package hpicker
package components

import (
"github.com/charmbracelet/bubbles/key"
)

// KeyMap is the key bindings for different actions within the component.
type KeyMap struct {
// hPickerKeyMap is the key bindings for different actions within the component.
type hPickerKeyMap struct {
Prev key.Binding
Next key.Binding
}

func defaultKeyMap() *KeyMap {
return &KeyMap{
func defaultHPickerKeyMap() *hPickerKeyMap {
return &hPickerKeyMap{
Prev: key.NewBinding(
key.WithKeys("left"),
key.WithHelp("<-", "move left"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package hpicker
package components

import "github.com/charmbracelet/lipgloss"

type Styles struct {
type hPickerStyles struct {
NextIndicator string
NextStyle lipgloss.Style
NextDisabledStyle lipgloss.Style
Expand All @@ -14,8 +14,8 @@ type Styles struct {
SelectionStyle lipgloss.Style
}

func DefaultStyles() Styles {
return Styles{
func defaultHPickerStyles() hPickerStyles {
return hPickerStyles{
NextIndicator: " >",
NextStyle: lipgloss.NewStyle(),
NextDisabledStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("241")),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
package textinput
package components

import (
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
)

type Model struct {
type TextInputModel struct {
Child textinput.Model
}

func NewModel(placeholder string, width int, charLimit int) Model {
func NewTextInputModel(placeholder string, width int, charLimit int) TextInputModel {
c := textinput.New()
c.Placeholder = placeholder
c.Width = width
c.CharLimit = charLimit
c.Focus()

return Model{
return TextInputModel{
Child: c,
}
}

func (m Model) Init() tea.Cmd {
func (m TextInputModel) Init() tea.Cmd {
return nil
}

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m TextInputModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
m.Child, cmd = m.Child.Update(msg)
return m, cmd
}

func (m Model) View() string {
func (m TextInputModel) View() string {
return m.Child.View()
}
7 changes: 7 additions & 0 deletions internal/tui/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tui

import "errors"

var (
ErrInvalidTypeAssertion = errors.New("invalid type assertion")
)
Loading
Loading