mirror of
https://github.com/zoriya/bubbles.git
synced 2026-08-16 01:43:21 +00:00
feat!(viewport): use getters and setters for width and height
This commit is contained in:
+17
-17
@@ -165,14 +165,14 @@ func WithRows(rows []Row) Option {
|
|||||||
// WithHeight sets the height of the table.
|
// WithHeight sets the height of the table.
|
||||||
func WithHeight(h int) Option {
|
func WithHeight(h int) Option {
|
||||||
return func(m *Model) {
|
return func(m *Model) {
|
||||||
m.viewport.Height = h - lipgloss.Height(m.headersView())
|
m.viewport.SetHeight(h - lipgloss.Height(m.headersView()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithWidth sets the width of the table.
|
// WithWidth sets the width of the table.
|
||||||
func WithWidth(w int) Option {
|
func WithWidth(w int) Option {
|
||||||
return func(m *Model) {
|
return func(m *Model) {
|
||||||
m.viewport.Width = w
|
m.viewport.SetWidth(w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,13 +211,13 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
|
|||||||
case key.Matches(msg, m.KeyMap.LineDown):
|
case key.Matches(msg, m.KeyMap.LineDown):
|
||||||
m.MoveDown(1)
|
m.MoveDown(1)
|
||||||
case key.Matches(msg, m.KeyMap.PageUp):
|
case key.Matches(msg, m.KeyMap.PageUp):
|
||||||
m.MoveUp(m.viewport.Height)
|
m.MoveUp(m.viewport.Height())
|
||||||
case key.Matches(msg, m.KeyMap.PageDown):
|
case key.Matches(msg, m.KeyMap.PageDown):
|
||||||
m.MoveDown(m.viewport.Height)
|
m.MoveDown(m.viewport.Height())
|
||||||
case key.Matches(msg, m.KeyMap.HalfPageUp):
|
case key.Matches(msg, m.KeyMap.HalfPageUp):
|
||||||
m.MoveUp(m.viewport.Height / 2) //nolint:mnd
|
m.MoveUp(m.viewport.Height() / 2) //nolint:mnd
|
||||||
case key.Matches(msg, m.KeyMap.HalfPageDown):
|
case key.Matches(msg, m.KeyMap.HalfPageDown):
|
||||||
m.MoveDown(m.viewport.Height / 2) //nolint:mnd
|
m.MoveDown(m.viewport.Height() / 2) //nolint:mnd
|
||||||
case key.Matches(msg, m.KeyMap.GotoTop):
|
case key.Matches(msg, m.KeyMap.GotoTop):
|
||||||
m.GotoTop()
|
m.GotoTop()
|
||||||
case key.Matches(msg, m.KeyMap.GotoBottom):
|
case key.Matches(msg, m.KeyMap.GotoBottom):
|
||||||
@@ -267,11 +267,11 @@ func (m *Model) UpdateViewport() {
|
|||||||
// Constant runtime, independent of number of rows in a table.
|
// Constant runtime, independent of number of rows in a table.
|
||||||
// Limits the number of renderedRows to a maximum of 2*m.viewport.Height
|
// Limits the number of renderedRows to a maximum of 2*m.viewport.Height
|
||||||
if m.cursor >= 0 {
|
if m.cursor >= 0 {
|
||||||
m.start = clamp(m.cursor-m.viewport.Height, 0, m.cursor)
|
m.start = clamp(m.cursor-m.viewport.Height(), 0, m.cursor)
|
||||||
} else {
|
} else {
|
||||||
m.start = 0
|
m.start = 0
|
||||||
}
|
}
|
||||||
m.end = clamp(m.cursor+m.viewport.Height, m.cursor, len(m.rows))
|
m.end = clamp(m.cursor+m.viewport.Height(), m.cursor, len(m.rows))
|
||||||
for i := m.start; i < m.end; i++ {
|
for i := m.start; i < m.end; i++ {
|
||||||
renderedRows = append(renderedRows, m.renderRow(i))
|
renderedRows = append(renderedRows, m.renderRow(i))
|
||||||
}
|
}
|
||||||
@@ -315,24 +315,24 @@ func (m *Model) SetColumns(c []Column) {
|
|||||||
|
|
||||||
// SetWidth sets the width of the viewport of the table.
|
// SetWidth sets the width of the viewport of the table.
|
||||||
func (m *Model) SetWidth(w int) {
|
func (m *Model) SetWidth(w int) {
|
||||||
m.viewport.Width = w
|
m.viewport.SetWidth(w)
|
||||||
m.UpdateViewport()
|
m.UpdateViewport()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHeight sets the height of the viewport of the table.
|
// SetHeight sets the height of the viewport of the table.
|
||||||
func (m *Model) SetHeight(h int) {
|
func (m *Model) SetHeight(h int) {
|
||||||
m.viewport.Height = h - lipgloss.Height(m.headersView())
|
m.viewport.SetHeight(h - lipgloss.Height(m.headersView()))
|
||||||
m.UpdateViewport()
|
m.UpdateViewport()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Height returns the viewport height of the table.
|
// Height returns the viewport height of the table.
|
||||||
func (m Model) Height() int {
|
func (m Model) Height() int {
|
||||||
return m.viewport.Height
|
return m.viewport.Height()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Width returns the viewport width of the table.
|
// Width returns the viewport width of the table.
|
||||||
func (m Model) Width() int {
|
func (m Model) Width() int {
|
||||||
return m.viewport.Width
|
return m.viewport.Width()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cursor returns the index of the selected row.
|
// Cursor returns the index of the selected row.
|
||||||
@@ -353,10 +353,10 @@ func (m *Model) MoveUp(n int) {
|
|||||||
switch {
|
switch {
|
||||||
case m.start == 0:
|
case m.start == 0:
|
||||||
m.viewport.SetYOffset(clamp(m.viewport.YOffset, 0, m.cursor))
|
m.viewport.SetYOffset(clamp(m.viewport.YOffset, 0, m.cursor))
|
||||||
case m.start < m.viewport.Height:
|
case m.start < m.viewport.Height():
|
||||||
m.viewport.YOffset = (clamp(clamp(m.viewport.YOffset+n, 0, m.cursor), 0, m.viewport.Height))
|
m.viewport.YOffset = (clamp(clamp(m.viewport.YOffset+n, 0, m.cursor), 0, m.viewport.Height()))
|
||||||
case m.viewport.YOffset >= 1:
|
case m.viewport.YOffset >= 1:
|
||||||
m.viewport.YOffset = clamp(m.viewport.YOffset+n, 1, m.viewport.Height)
|
m.viewport.YOffset = clamp(m.viewport.YOffset+n, 1, m.viewport.Height())
|
||||||
}
|
}
|
||||||
m.UpdateViewport()
|
m.UpdateViewport()
|
||||||
}
|
}
|
||||||
@@ -369,11 +369,11 @@ func (m *Model) MoveDown(n int) {
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case m.end == len(m.rows) && m.viewport.YOffset > 0:
|
case m.end == len(m.rows) && m.viewport.YOffset > 0:
|
||||||
m.viewport.SetYOffset(clamp(m.viewport.YOffset-n, 1, m.viewport.Height))
|
m.viewport.SetYOffset(clamp(m.viewport.YOffset-n, 1, m.viewport.Height()))
|
||||||
case m.cursor > (m.end-m.start)/2 && m.viewport.YOffset > 0:
|
case m.cursor > (m.end-m.start)/2 && m.viewport.YOffset > 0:
|
||||||
m.viewport.SetYOffset(clamp(m.viewport.YOffset-n, 1, m.cursor))
|
m.viewport.SetYOffset(clamp(m.viewport.YOffset-n, 1, m.cursor))
|
||||||
case m.viewport.YOffset > 1:
|
case m.viewport.YOffset > 1:
|
||||||
case m.cursor > m.viewport.YOffset+m.viewport.Height-1:
|
case m.cursor > m.viewport.YOffset+m.viewport.Height()-1:
|
||||||
m.viewport.SetYOffset(clamp(m.viewport.YOffset+1, 0, 1))
|
m.viewport.SetYOffset(clamp(m.viewport.YOffset+1, 0, 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -867,7 +867,7 @@ func (m Model) LineInfo() LineInfo {
|
|||||||
// scrolling behavior.
|
// scrolling behavior.
|
||||||
func (m *Model) repositionView() {
|
func (m *Model) repositionView() {
|
||||||
min := m.viewport.YOffset
|
min := m.viewport.YOffset
|
||||||
max := min + m.viewport.Height - 1
|
max := min + m.viewport.Height() - 1
|
||||||
|
|
||||||
if row := m.cursorLineNumber(); row < min {
|
if row := m.cursorLineNumber(); row < min {
|
||||||
m.viewport.LineUp(min - row)
|
m.viewport.LineUp(min - row)
|
||||||
@@ -933,7 +933,7 @@ func (m *Model) SetWidth(w int) {
|
|||||||
// borders, prompt and line numbers, we need to calculate it by subtracting
|
// borders, prompt and line numbers, we need to calculate it by subtracting
|
||||||
// the reserved width from them.
|
// the reserved width from them.
|
||||||
|
|
||||||
m.viewport.Width = inputWidth - reservedOuter
|
m.viewport.SetWidth(inputWidth - reservedOuter)
|
||||||
m.width = inputWidth - reservedOuter - reservedInner
|
m.width = inputWidth - reservedOuter - reservedInner
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -958,10 +958,10 @@ func (m Model) Height() int {
|
|||||||
func (m *Model) SetHeight(h int) {
|
func (m *Model) SetHeight(h int) {
|
||||||
if m.MaxHeight > 0 {
|
if m.MaxHeight > 0 {
|
||||||
m.height = clamp(h, minHeight, m.MaxHeight)
|
m.height = clamp(h, minHeight, m.MaxHeight)
|
||||||
m.viewport.Height = clamp(h, minHeight, m.MaxHeight)
|
m.viewport.SetHeight(clamp(h, minHeight, m.MaxHeight))
|
||||||
} else {
|
} else {
|
||||||
m.height = max(h, minHeight)
|
m.height = max(h, minHeight)
|
||||||
m.viewport.Height = max(h, minHeight)
|
m.viewport.SetHeight(max(h, minHeight))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-13
@@ -19,7 +19,7 @@ type Option func(*Model)
|
|||||||
// viewport. Pass as an argument to [New].
|
// viewport. Pass as an argument to [New].
|
||||||
func WithWidth(w int) Option {
|
func WithWidth(w int) Option {
|
||||||
return func(m *Model) {
|
return func(m *Model) {
|
||||||
m.Width = w
|
m.width = w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ func WithWidth(w int) Option {
|
|||||||
// viewport. Pass as an argument to [New].
|
// viewport. Pass as an argument to [New].
|
||||||
func WithHeight(h int) Option {
|
func WithHeight(h int) Option {
|
||||||
return func(m *Model) {
|
return func(m *Model) {
|
||||||
m.Height = h
|
m.height = h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,8 +43,8 @@ func New(opts ...Option) (m Model) {
|
|||||||
|
|
||||||
// Model is the Bubble Tea model for this viewport element.
|
// Model is the Bubble Tea model for this viewport element.
|
||||||
type Model struct {
|
type Model struct {
|
||||||
Width int
|
width int
|
||||||
Height int
|
height int
|
||||||
KeyMap KeyMap
|
KeyMap KeyMap
|
||||||
|
|
||||||
// Whether or not to respond to the mouse. The mouse must be enabled in
|
// Whether or not to respond to the mouse. The mouse must be enabled in
|
||||||
@@ -81,6 +81,26 @@ func (m Model) Init() (Model, tea.Cmd) {
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Height returns the height of the viewport.
|
||||||
|
func (m Model) Height() int {
|
||||||
|
return m.height
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetHeight sets the height of the viewport.
|
||||||
|
func (m *Model) SetHeight(h int) {
|
||||||
|
m.height = h
|
||||||
|
}
|
||||||
|
|
||||||
|
// Width returns the width of the viewport.
|
||||||
|
func (m Model) Width() int {
|
||||||
|
return m.width
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWidth sets the width of the viewport.
|
||||||
|
func (m *Model) SetWidth(w int) {
|
||||||
|
m.width = w
|
||||||
|
}
|
||||||
|
|
||||||
// AtTop returns whether or not the viewport is at the very top position.
|
// AtTop returns whether or not the viewport is at the very top position.
|
||||||
func (m Model) AtTop() bool {
|
func (m Model) AtTop() bool {
|
||||||
return m.YOffset <= 0
|
return m.YOffset <= 0
|
||||||
@@ -100,11 +120,11 @@ func (m Model) PastBottom() bool {
|
|||||||
|
|
||||||
// ScrollPercent returns the amount scrolled as a float between 0 and 1.
|
// ScrollPercent returns the amount scrolled as a float between 0 and 1.
|
||||||
func (m Model) ScrollPercent() float64 {
|
func (m Model) ScrollPercent() float64 {
|
||||||
if m.Height >= len(m.lines) {
|
if m.Height() >= len(m.lines) {
|
||||||
return 1.0
|
return 1.0
|
||||||
}
|
}
|
||||||
y := float64(m.YOffset)
|
y := float64(m.YOffset)
|
||||||
h := float64(m.Height)
|
h := float64(m.Height())
|
||||||
t := float64(len(m.lines))
|
t := float64(len(m.lines))
|
||||||
v := y / (t - h)
|
v := y / (t - h)
|
||||||
return math.Max(0.0, math.Min(1.0, v))
|
return math.Max(0.0, math.Min(1.0, v))
|
||||||
@@ -123,7 +143,7 @@ func (m *Model) SetContent(s string) {
|
|||||||
// maxYOffset returns the maximum possible value of the y-offset based on the
|
// maxYOffset returns the maximum possible value of the y-offset based on the
|
||||||
// viewport's content and set height.
|
// viewport's content and set height.
|
||||||
func (m Model) maxYOffset() int {
|
func (m Model) maxYOffset() int {
|
||||||
return max(0, len(m.lines)-m.Height)
|
return max(0, len(m.lines)-m.Height())
|
||||||
}
|
}
|
||||||
|
|
||||||
// visibleLines returns the lines that should currently be visible in the
|
// visibleLines returns the lines that should currently be visible in the
|
||||||
@@ -131,7 +151,7 @@ func (m Model) maxYOffset() int {
|
|||||||
func (m Model) visibleLines() (lines []string) {
|
func (m Model) visibleLines() (lines []string) {
|
||||||
if len(m.lines) > 0 {
|
if len(m.lines) > 0 {
|
||||||
top := max(0, m.YOffset)
|
top := max(0, m.YOffset)
|
||||||
bottom := clamp(m.YOffset+m.Height, top, len(m.lines))
|
bottom := clamp(m.YOffset+m.Height(), top, len(m.lines))
|
||||||
lines = m.lines[top:bottom]
|
lines = m.lines[top:bottom]
|
||||||
}
|
}
|
||||||
return lines
|
return lines
|
||||||
@@ -149,7 +169,7 @@ func (m *Model) ViewDown() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
m.LineDown(m.Height)
|
m.LineDown(m.Height())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ViewUp moves the view up by one height of the viewport. Basically, "page up".
|
// ViewUp moves the view up by one height of the viewport. Basically, "page up".
|
||||||
@@ -158,7 +178,7 @@ func (m *Model) ViewUp() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
m.LineUp(m.Height)
|
m.LineUp(m.Height())
|
||||||
}
|
}
|
||||||
|
|
||||||
// HalfViewDown moves the view down by half the height of the viewport.
|
// HalfViewDown moves the view down by half the height of the viewport.
|
||||||
@@ -167,7 +187,7 @@ func (m *Model) HalfViewDown() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
m.LineDown(m.Height / 2) //nolint:mnd
|
m.LineDown(m.Height() / 2) //nolint:mnd
|
||||||
}
|
}
|
||||||
|
|
||||||
// HalfViewUp moves the view up by half the height of the viewport.
|
// HalfViewUp moves the view up by half the height of the viewport.
|
||||||
@@ -176,7 +196,7 @@ func (m *Model) HalfViewUp() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
m.LineUp(m.Height / 2) //nolint:mnd
|
m.LineUp(m.Height() / 2) //nolint:mnd
|
||||||
}
|
}
|
||||||
|
|
||||||
// LineDown moves the view down by the given number of lines.
|
// LineDown moves the view down by the given number of lines.
|
||||||
@@ -283,7 +303,7 @@ func (m Model) updateAsModel(msg tea.Msg) Model {
|
|||||||
|
|
||||||
// View renders the viewport into a string.
|
// View renders the viewport into a string.
|
||||||
func (m Model) View() string {
|
func (m Model) View() string {
|
||||||
w, h := m.Width, m.Height
|
w, h := m.Width(), m.Height()
|
||||||
if sw := m.Style.GetWidth(); sw != 0 {
|
if sw := m.Style.GetWidth(); sw != 0 {
|
||||||
w = min(w, sw)
|
w = min(w, sw)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user