Add niceties to time page
This commit is contained in:
@ -330,11 +330,17 @@ func (m *Model) UpdateViewport() {
|
||||
}
|
||||
|
||||
// SelectedRow returns the selected row.
|
||||
// Returns nil if cursor is on a gap row or out of bounds.
|
||||
func (m Model) SelectedRow() Row {
|
||||
if m.cursor < 0 || m.cursor >= len(m.rows) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Don't return gap rows as selected
|
||||
if m.rows[m.cursor].IsGap {
|
||||
return nil
|
||||
}
|
||||
|
||||
return m.rows[m.cursor]
|
||||
}
|
||||
|
||||
@ -388,15 +394,61 @@ func (m Model) Cursor() int {
|
||||
}
|
||||
|
||||
// SetCursor sets the cursor position in the table.
|
||||
// Skips gap rows by moving to the nearest non-gap row.
|
||||
func (m *Model) SetCursor(n int) {
|
||||
m.cursor = clamp(n, 0, len(m.rows)-1)
|
||||
|
||||
// Skip gap rows - try moving down first, then up
|
||||
if m.cursor < len(m.rows) && m.rows[m.cursor].IsGap {
|
||||
// Try moving down to find non-gap
|
||||
found := false
|
||||
for i := m.cursor; i < len(m.rows); i++ {
|
||||
if !m.rows[i].IsGap {
|
||||
m.cursor = i
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// If not found down, try moving up
|
||||
if !found {
|
||||
for i := m.cursor; i >= 0; i-- {
|
||||
if !m.rows[i].IsGap {
|
||||
m.cursor = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m.UpdateViewport()
|
||||
}
|
||||
|
||||
// MoveUp moves the selection up by any number of rows.
|
||||
// It can not go above the first row.
|
||||
// It can not go above the first row. Skips gap rows.
|
||||
func (m *Model) MoveUp(n int) {
|
||||
originalCursor := m.cursor
|
||||
m.cursor = clamp(m.cursor-n, 0, len(m.rows)-1)
|
||||
|
||||
// Skip gap rows
|
||||
for m.cursor >= 0 && m.cursor < len(m.rows) && m.rows[m.cursor].IsGap {
|
||||
m.cursor--
|
||||
}
|
||||
|
||||
// If we went past the beginning, find the first non-gap row
|
||||
if m.cursor < 0 {
|
||||
for i := 0; i < len(m.rows); i++ {
|
||||
if !m.rows[i].IsGap {
|
||||
m.cursor = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no non-gap row found, restore original cursor
|
||||
if m.cursor < 0 || (m.cursor < len(m.rows) && m.rows[m.cursor].IsGap) {
|
||||
m.cursor = originalCursor
|
||||
}
|
||||
|
||||
switch {
|
||||
case m.start == 0:
|
||||
m.viewport.SetYOffset(clamp(m.viewport.YOffset, 0, m.cursor))
|
||||
@ -409,9 +461,31 @@ func (m *Model) MoveUp(n int) {
|
||||
}
|
||||
|
||||
// MoveDown moves the selection down by any number of rows.
|
||||
// It can not go below the last row.
|
||||
// It can not go below the last row. Skips gap rows.
|
||||
func (m *Model) MoveDown(n int) {
|
||||
originalCursor := m.cursor
|
||||
m.cursor = clamp(m.cursor+n, 0, len(m.rows)-1)
|
||||
|
||||
// Skip gap rows
|
||||
for m.cursor >= 0 && m.cursor < len(m.rows) && m.rows[m.cursor].IsGap {
|
||||
m.cursor++
|
||||
}
|
||||
|
||||
// If we went past the end, find the last non-gap row
|
||||
if m.cursor >= len(m.rows) {
|
||||
for i := len(m.rows) - 1; i >= 0; i-- {
|
||||
if !m.rows[i].IsGap {
|
||||
m.cursor = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no non-gap row found, restore original cursor
|
||||
if m.cursor >= len(m.rows) || (m.cursor >= 0 && m.rows[m.cursor].IsGap) {
|
||||
m.cursor = originalCursor
|
||||
}
|
||||
|
||||
m.UpdateViewport()
|
||||
|
||||
switch {
|
||||
@ -452,6 +526,16 @@ func (m Model) headersView() string {
|
||||
}
|
||||
|
||||
func (m *Model) renderRow(r int) string {
|
||||
// Special rendering for gap rows
|
||||
if m.rows[r].IsGap {
|
||||
gapText := m.rows[r].GetString("gap_display")
|
||||
gapStyle := lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("240")).
|
||||
Align(lipgloss.Center).
|
||||
Width(m.Width())
|
||||
return gapStyle.Render(gapText)
|
||||
}
|
||||
|
||||
var s = make([]string, 0, len(m.cols))
|
||||
for i, col := range m.cols {
|
||||
if m.cols[i].Width <= 0 {
|
||||
|
||||
Reference in New Issue
Block a user