From 101e23780e5f8bc97f5683f5901fbd31f56ce29e Mon Sep 17 00:00:00 2001 From: Benjamin Chausse Date: Sat, 28 Dec 2024 00:46:18 -0500 Subject: First attempt at auto-resize --- internal/picker/picker.go | 21 +++++++++++++++++++ internal/slider/slider.go | 7 +++++++ internal/switcher/switcher.go | 47 +++++++++++++++++++++++++++++++++++++++---- internal/ui/style.go | 20 ++++++++++++------ 4 files changed, 85 insertions(+), 10 deletions(-) diff --git a/internal/picker/picker.go b/internal/picker/picker.go index 1c39aaa..696bf2a 100644 --- a/internal/picker/picker.go +++ b/internal/picker/picker.go @@ -129,10 +129,31 @@ func (m Model) View() string { return strings.Join(sliderList, "\n") } +func (m Model) FixWidth(windowW int) (tea.Model, tea.Cmd) { + cmds := []tea.Cmd{} + currentW := ui.SliderMaxWidth + if (currentW + ui.BoxOffsetW) > windowW { + currentW -= (currentW + ui.BoxOffsetW) - windowW + } + if currentW < ui.SliderMinWidth { + currentW = ui.SliderMinWidth + } + for i, s := range m.sliders { + model, cmd := s.SetWidth(currentW) + cmds = append(cmds, cmd) + m.sliders[i] = model.(slider.Model) + } + return m, tea.Batch(cmds...) +} + func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { keys := newKeybinds() cmds := []tea.Cmd{} switch msg := msg.(type) { + case tea.WindowSizeMsg: + newModel, cmd := m.FixWidth(msg.Width) + cmds = append(cmds, cmd) + return newModel, tea.Batch(cmds...) case tea.KeyMsg: switch { case key.Matches(msg, keys.next): diff --git a/internal/slider/slider.go b/internal/slider/slider.go index dbf4093..7e1b76c 100644 --- a/internal/slider/slider.go +++ b/internal/slider/slider.go @@ -34,6 +34,13 @@ func New(label byte, maxVal int, opts ...progress.Option) Model { func (m Model) Title() string { return fmt.Sprintf("%c:", m.label) } +func (m Model) Width() int { return m.progress.Width } + +func (m Model) SetWidth(w int) (tea.Model, tea.Cmd) { + m.progress.Width = w + return m, nil +} + func (m Model) Init() tea.Cmd { // Triggering a frame message Update here will force the progress bar to // render immediately. This is necessary because progress bars only render diff --git a/internal/switcher/switcher.go b/internal/switcher/switcher.go index 8de31c6..cf16b6a 100644 --- a/internal/switcher/switcher.go +++ b/internal/switcher/switcher.go @@ -32,6 +32,7 @@ type Model struct { input textinput.Model notices notices.Model fullHelp bool // When false, only show help for the switcher (not children) + h, w int } func New() Model { @@ -101,6 +102,9 @@ func (m Model) Init() tea.Cmd { } func (m Model) View() string { + pickerStr := m.pickers[m.active].View() + w := lipgloss.Width(pickerStr) + tabs := make([]string, len(m.pickers)) for i, p := range m.pickers { if i == m.active { @@ -115,9 +119,6 @@ func (m Model) View() string { ui.Style().TabGeom.Render(ui.TabSepRight), }, " ") - pickerStr := m.pickers[m.active].View() - w := lipgloss.Width(pickerStr) - m.preview.SetWidth(w) previewStr := m.preview.View() @@ -147,13 +148,27 @@ func (m Model) View() string { helpStr, }, "\n")) - return strings.Join( + viewStr := strings.Join( []string{ tabStr, mainArea, inputStr, m.notices.View(), }, "\n") + + // if lipgloss.Width(viewStr) > m.w { + // return ui.Style().TooSmall. + // Align(lipgloss.Center). + // Width(m.w). + // Height(m.h). + // Render("Terminal too small!\nPlease increase terminal size...") + // } + + return lipgloss.NewStyle(). + // Align(lipgloss.Center). + // Width(m.w). + // Height(m.h). + Render(viewStr) } func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { @@ -166,6 +181,30 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.notices = newNotices.(notices.Model) cmds = append(cmds, cmd) + case tea.WindowSizeMsg: + m.w = msg.Width + m.h = msg.Height + for i, p := range m.pickers { + var cmd tea.Cmd + var model tea.Model + model, cmd = p.Update(msg) + m.pickers[i] = model.(picker.Model) + cmds = append(cmds, cmd) + } + // iterate over every model contained in the model using a struct + // assign the new model to the model and append the command to the commands + // return the model and the batched commands + newInput, cmd := m.input.Update(msg) + m.input = newInput + cmds = append(cmds, cmd) + newPreview, cmd := m.preview.Update(msg) + m.preview = newPreview.(preview.Model) + cmds = append(cmds, cmd) + newNotices, cmd := m.notices.Update(msg) + m.notices = newNotices.(notices.Model) + cmds = append(cmds, cmd) + return m, tea.Batch(cmds...) + case tea.KeyMsg: if m.input.Focused() && msg.String() != "ctrl+c" { diff --git a/internal/ui/style.go b/internal/ui/style.go index 75d2f70..bab94ca 100644 --- a/internal/ui/style.go +++ b/internal/ui/style.go @@ -10,6 +10,7 @@ const ( textNorm = "#A7AFB1" textFaint = "#6F797B" geomFg = "#ACB3B5" + textWarn = "#EA9139" TabSepLeft = "[" TabSepMid = " | " @@ -23,6 +24,7 @@ const ( SliderMinWidth = 22 // 1 ASCII change every 2.05 deg. avg SliderMaxWidth = 90 // 2 ASCII change per deg. + BoxOffsetW, BoxOffsetH = 2, 2 ) type sliderOpts struct { @@ -42,6 +44,7 @@ type StyleSheet struct { InputPrompt lg.Style InputText lg.Style Notice lg.Style + TooSmall lg.Style Quit lg.Style Boxed lg.Style Sliders sliderOpts @@ -65,15 +68,15 @@ func init() { style = StyleSheet{ TabSel: baseStyle.Inherit(lg.NewStyle(). - Foreground(lg.Color(textSel)). Underline(true). - Bold(true)), + Bold(true)). + Foreground(lg.Color(textSel)), TabNorm: baseStyle.Inherit(lg.NewStyle(). - Foreground(lg.Color(textFaint)). Underline(false). Faint(true). - Bold(false)), + Bold(false)). + Foreground(lg.Color(textFaint)), TabGeom: baseStyle.Inherit(lg.NewStyle(). Foreground(lg.Color(geomFg))), @@ -95,9 +98,14 @@ func init() { Notice: baseStyle.Inherit(lg.NewStyle(). Bold(true)), + TooSmall: baseStyle.Inherit(lg.NewStyle(). + Bold(true)). + Blink(true). + Foreground(lg.Color(textWarn)), + Quit: baseStyle.Inherit(lg.NewStyle(). - Foreground(lg.Color(textSel)). - Bold(true)), + Bold(true)). + Foreground(lg.Color(textSel)), Boxed: baseStyle.Inherit(lg.NewStyle(). Border(lg.RoundedBorder())), -- cgit v1.2.3