mirror of
https://github.com/RWejlgaard/org.git
synced 2026-05-06 04:34:45 +00:00
fix: allow scrolling in settings for shorter terminals (#3)
This commit is contained in:
parent
d45d8fd5c1
commit
eb5f9a16ce
1 changed files with 150 additions and 27 deletions
|
|
@ -56,12 +56,14 @@ func (m *uiModel) updateSettings(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
case key.Matches(msg, m.keys.Up):
|
case key.Matches(msg, m.keys.Up):
|
||||||
if m.settingsCursor > 0 {
|
if m.settingsCursor > 0 {
|
||||||
m.settingsCursor--
|
m.settingsCursor--
|
||||||
|
m.updateSettingsScrollOffset()
|
||||||
}
|
}
|
||||||
|
|
||||||
case key.Matches(msg, m.keys.Down):
|
case key.Matches(msg, m.keys.Down):
|
||||||
maxCursor := m.getSettingsItemCount() - 1
|
maxCursor := m.getSettingsItemCount() - 1
|
||||||
if m.settingsCursor < maxCursor {
|
if m.settingsCursor < maxCursor {
|
||||||
m.settingsCursor++
|
m.settingsCursor++
|
||||||
|
m.updateSettingsScrollOffset()
|
||||||
}
|
}
|
||||||
|
|
||||||
case key.Matches(msg, m.keys.ShiftUp):
|
case key.Matches(msg, m.keys.ShiftUp):
|
||||||
|
|
@ -137,6 +139,36 @@ func (m *uiModel) getSettingsItemCount() int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateSettingsScrollOffset adjusts the scroll offset to keep the cursor visible
|
||||||
|
func (m *uiModel) updateSettingsScrollOffset() {
|
||||||
|
// Calculate available height for content
|
||||||
|
// Reserve space for: title (2 lines), tabs (2 lines), instructions (3 lines),
|
||||||
|
// input field if focused (3 lines), status bar, and some padding
|
||||||
|
reservedLines := 10
|
||||||
|
if m.textinput.Focused() {
|
||||||
|
reservedLines += 3
|
||||||
|
}
|
||||||
|
|
||||||
|
availableHeight := m.height - reservedLines
|
||||||
|
if availableHeight < 3 {
|
||||||
|
availableHeight = 3 // Minimum visible items
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust scroll to keep cursor visible
|
||||||
|
if m.settingsCursor < m.settingsScroll {
|
||||||
|
// Cursor is above visible area, scroll up
|
||||||
|
m.settingsScroll = m.settingsCursor
|
||||||
|
} else if m.settingsCursor >= m.settingsScroll+availableHeight {
|
||||||
|
// Cursor is below visible area, scroll down
|
||||||
|
m.settingsScroll = m.settingsCursor - availableHeight + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure scroll offset doesn't go negative
|
||||||
|
if m.settingsScroll < 0 {
|
||||||
|
m.settingsScroll = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// startSettingsEdit starts editing a settings item
|
// startSettingsEdit starts editing a settings item
|
||||||
func (m *uiModel) startSettingsEdit() {
|
func (m *uiModel) startSettingsEdit() {
|
||||||
switch m.settingsSection {
|
switch m.settingsSection {
|
||||||
|
|
@ -460,7 +492,25 @@ func (m *uiModel) viewSettings() string {
|
||||||
func (m *uiModel) viewSettingsTags() string {
|
func (m *uiModel) viewSettingsTags() string {
|
||||||
var content strings.Builder
|
var content strings.Builder
|
||||||
|
|
||||||
|
// Calculate visible window
|
||||||
|
reservedLines := 10
|
||||||
|
if m.textinput.Focused() {
|
||||||
|
reservedLines += 3
|
||||||
|
}
|
||||||
|
availableHeight := m.height - reservedLines
|
||||||
|
if availableHeight < 3 {
|
||||||
|
availableHeight = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
endIdx := m.settingsScroll + availableHeight
|
||||||
|
totalItems := len(m.config.Tags.Tags) + 1 // +1 for "Add new tag"
|
||||||
|
|
||||||
for i, tag := range m.config.Tags.Tags {
|
for i, tag := range m.config.Tags.Tags {
|
||||||
|
// Skip items outside visible window
|
||||||
|
if i < m.settingsScroll || i >= endIdx {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
line := ""
|
line := ""
|
||||||
|
|
||||||
// Cursor
|
// Cursor
|
||||||
|
|
@ -479,12 +529,24 @@ func (m *uiModel) viewSettingsTags() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new tag option
|
// Add new tag option
|
||||||
if m.settingsCursor == len(m.config.Tags.Tags) && !m.textinput.Focused() {
|
addNewIdx := len(m.config.Tags.Tags)
|
||||||
content.WriteString("▶ ")
|
if addNewIdx >= m.settingsScroll && addNewIdx < endIdx {
|
||||||
} else {
|
if m.settingsCursor == len(m.config.Tags.Tags) && !m.textinput.Focused() {
|
||||||
content.WriteString(" ")
|
content.WriteString("▶ ")
|
||||||
|
} else {
|
||||||
|
content.WriteString(" ")
|
||||||
|
}
|
||||||
|
content.WriteString(m.styles.statusStyle.Render("+ Add new tag (press 'c')") + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add scroll indicator if needed
|
||||||
|
if totalItems > availableHeight {
|
||||||
|
scrollInfo := fmt.Sprintf("\n[Showing %d-%d of %d]",
|
||||||
|
m.settingsScroll+1,
|
||||||
|
min(endIdx, totalItems),
|
||||||
|
totalItems)
|
||||||
|
content.WriteString(m.styles.statusStyle.Render(scrollInfo))
|
||||||
}
|
}
|
||||||
content.WriteString(m.styles.statusStyle.Render("+ Add new tag (press 'c')") + "\n")
|
|
||||||
|
|
||||||
return content.String()
|
return content.String()
|
||||||
}
|
}
|
||||||
|
|
@ -493,30 +555,52 @@ func (m *uiModel) viewSettingsTags() string {
|
||||||
func (m *uiModel) viewSettingsStates() string {
|
func (m *uiModel) viewSettingsStates() string {
|
||||||
var content strings.Builder
|
var content strings.Builder
|
||||||
|
|
||||||
// First show the default new task state setting
|
// Calculate visible window
|
||||||
line := ""
|
reservedLines := 10
|
||||||
if m.settingsCursor == 0 && !m.textinput.Focused() {
|
if m.textinput.Focused() {
|
||||||
line += "▶ "
|
reservedLines += 3
|
||||||
} else {
|
|
||||||
line += " "
|
|
||||||
}
|
}
|
||||||
line += "Default new task state: "
|
availableHeight := m.height - reservedLines
|
||||||
if m.config.States.DefaultNewTaskState == "" {
|
if availableHeight < 3 {
|
||||||
line += m.styles.statusStyle.Render("(none)")
|
availableHeight = 3
|
||||||
} else {
|
}
|
||||||
// Try to get the color for this state
|
|
||||||
color := m.config.GetStateColor(m.config.States.DefaultNewTaskState)
|
endIdx := m.settingsScroll + availableHeight
|
||||||
stateStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(color))
|
totalItems := len(m.config.States.States) + 2 // +1 for default state, +1 for "Add new state"
|
||||||
line += stateStyle.Render(m.config.States.DefaultNewTaskState)
|
|
||||||
|
// First show the default new task state setting (item 0)
|
||||||
|
if 0 >= m.settingsScroll && 0 < endIdx {
|
||||||
|
line := ""
|
||||||
|
if m.settingsCursor == 0 && !m.textinput.Focused() {
|
||||||
|
line += "▶ "
|
||||||
|
} else {
|
||||||
|
line += " "
|
||||||
|
}
|
||||||
|
line += "Default new task state: "
|
||||||
|
if m.config.States.DefaultNewTaskState == "" {
|
||||||
|
line += m.styles.statusStyle.Render("(none)")
|
||||||
|
} else {
|
||||||
|
// Try to get the color for this state
|
||||||
|
color := m.config.GetStateColor(m.config.States.DefaultNewTaskState)
|
||||||
|
stateStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(color))
|
||||||
|
line += stateStyle.Render(m.config.States.DefaultNewTaskState)
|
||||||
|
}
|
||||||
|
content.WriteString(line + "\n\n")
|
||||||
}
|
}
|
||||||
content.WriteString(line + "\n\n")
|
|
||||||
|
|
||||||
// Then show all configured states
|
// Then show all configured states
|
||||||
for i, state := range m.config.States.States {
|
for i, state := range m.config.States.States {
|
||||||
|
itemIdx := i + 1 // Offset by 1 for the default state setting
|
||||||
|
|
||||||
|
// Skip items outside visible window
|
||||||
|
if itemIdx < m.settingsScroll || itemIdx >= endIdx {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
line := ""
|
line := ""
|
||||||
|
|
||||||
// Cursor (offset by 1 because of the default state setting)
|
// Cursor
|
||||||
if i+1 == m.settingsCursor && !m.textinput.Focused() {
|
if itemIdx == m.settingsCursor && !m.textinput.Focused() {
|
||||||
line += "▶ "
|
line += "▶ "
|
||||||
} else {
|
} else {
|
||||||
line += " "
|
line += " "
|
||||||
|
|
@ -531,12 +615,24 @@ func (m *uiModel) viewSettingsStates() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new state option
|
// Add new state option
|
||||||
if m.settingsCursor == len(m.config.States.States)+1 && !m.textinput.Focused() {
|
addNewIdx := len(m.config.States.States) + 1
|
||||||
content.WriteString("▶ ")
|
if addNewIdx >= m.settingsScroll && addNewIdx < endIdx {
|
||||||
} else {
|
if m.settingsCursor == addNewIdx && !m.textinput.Focused() {
|
||||||
content.WriteString(" ")
|
content.WriteString("▶ ")
|
||||||
|
} else {
|
||||||
|
content.WriteString(" ")
|
||||||
|
}
|
||||||
|
content.WriteString(m.styles.statusStyle.Render("+ Add new state (press 'c')") + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add scroll indicator if needed
|
||||||
|
if totalItems > availableHeight {
|
||||||
|
scrollInfo := fmt.Sprintf("\n[Showing %d-%d of %d]",
|
||||||
|
m.settingsScroll+1,
|
||||||
|
min(endIdx, totalItems),
|
||||||
|
totalItems)
|
||||||
|
content.WriteString(m.styles.statusStyle.Render(scrollInfo))
|
||||||
}
|
}
|
||||||
content.WriteString(m.styles.statusStyle.Render("+ Add new state (press 'c')") + "\n")
|
|
||||||
|
|
||||||
return content.String()
|
return content.String()
|
||||||
}
|
}
|
||||||
|
|
@ -545,6 +641,16 @@ func (m *uiModel) viewSettingsStates() string {
|
||||||
func (m *uiModel) viewSettingsKeybindings() string {
|
func (m *uiModel) viewSettingsKeybindings() string {
|
||||||
var content strings.Builder
|
var content strings.Builder
|
||||||
|
|
||||||
|
// Calculate visible window
|
||||||
|
reservedLines := 10
|
||||||
|
if m.textinput.Focused() {
|
||||||
|
reservedLines += 3
|
||||||
|
}
|
||||||
|
availableHeight := m.height - reservedLines
|
||||||
|
if availableHeight < 3 {
|
||||||
|
availableHeight = 3
|
||||||
|
}
|
||||||
|
|
||||||
// Get all keybindings
|
// Get all keybindings
|
||||||
keybindings := m.config.GetAllKeybindings()
|
keybindings := m.config.GetAllKeybindings()
|
||||||
|
|
||||||
|
|
@ -567,7 +673,15 @@ func (m *uiModel) viewSettingsKeybindings() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
endIdx := m.settingsScroll + availableHeight
|
||||||
|
totalItems := len(kbList)
|
||||||
|
|
||||||
for i, kb := range kbList {
|
for i, kb := range kbList {
|
||||||
|
// Skip items outside visible window
|
||||||
|
if i < m.settingsScroll || i >= endIdx {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
line := ""
|
line := ""
|
||||||
|
|
||||||
// Cursor
|
// Cursor
|
||||||
|
|
@ -584,6 +698,15 @@ func (m *uiModel) viewSettingsKeybindings() string {
|
||||||
content.WriteString(line + "\n")
|
content.WriteString(line + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add scroll indicator if needed
|
||||||
|
if totalItems > availableHeight {
|
||||||
|
scrollInfo := fmt.Sprintf("\n[Showing %d-%d of %d]",
|
||||||
|
m.settingsScroll+1,
|
||||||
|
min(endIdx, totalItems),
|
||||||
|
totalItems)
|
||||||
|
content.WriteString(m.styles.statusStyle.Render(scrollInfo))
|
||||||
|
}
|
||||||
|
|
||||||
return content.String()
|
return content.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue