mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-14 02:57:52 +08:00
edit/ui: Add renderer for content with vertical scrollbar.
This commit is contained in:
parent
0cb066d326
commit
686e944cb1
|
@ -21,16 +21,27 @@ func Render(r Renderer, width int) *Buffer {
|
|||
return bb.Buffer()
|
||||
}
|
||||
|
||||
// NewStringRenderer returns a Renderer that shows the given string unstyled,
|
||||
// possibly trimmed to fit whatever width is available.
|
||||
// NewStringRenderer returns a Renderer that shows the given strings unstyled,
|
||||
// trimmed to fit whatever width is available.
|
||||
func NewStringRenderer(s string) Renderer {
|
||||
return stringRenderer{s}
|
||||
return NewLinesRenderer(s)
|
||||
}
|
||||
|
||||
type stringRenderer struct{ s string }
|
||||
// NewLinesRenderer returns a Renderer that shows the given lines unstyled,
|
||||
// each trimmed to fit whatever width is available.
|
||||
func NewLinesRenderer(lines ...string) Renderer {
|
||||
return linesRenderer{lines}
|
||||
}
|
||||
|
||||
func (r stringRenderer) Render(bb *BufferBuilder) {
|
||||
bb.WriteString(util.TrimWcwidth(r.s, bb.Width), "")
|
||||
type linesRenderer struct{ lines []string }
|
||||
|
||||
func (r linesRenderer) Render(bb *BufferBuilder) {
|
||||
for i, line := range r.lines {
|
||||
if i > 0 {
|
||||
bb.Newline()
|
||||
}
|
||||
bb.WriteString(util.TrimWcwidth(line, bb.Width), "")
|
||||
}
|
||||
}
|
||||
|
||||
// NewModeLineRenderer returns a Renderer for a mode line.
|
||||
|
@ -47,7 +58,7 @@ func (ml modeLineRenderer) Render(bb *BufferBuilder) {
|
|||
bb.WriteString(ml.title, styleForMode.String())
|
||||
bb.WriteSpaces(1, "")
|
||||
bb.WriteString(ml.filter, styleForFilter.String())
|
||||
bb.Dot = bb.Cursor()
|
||||
bb.SetDotToCursor()
|
||||
}
|
||||
|
||||
// NewModeLineWithScrollBarRenderer returns a Renderer for a mode line with a
|
||||
|
@ -72,3 +83,21 @@ func (ml modeLineWithScrollBarRenderer) Render(bb *BufferBuilder) {
|
|||
writeHorizontalScrollbar(bb, ml.n, ml.low, ml.high, scrollbarWidth)
|
||||
}
|
||||
}
|
||||
|
||||
// NewRendererWithVerticalScrollbar returns a Renderer that renders the given
|
||||
// base plus a vertical scrollbar at the right-hand side.
|
||||
func NewRendererWithVerticalScrollbar(base Renderer, n, low, high int) Renderer {
|
||||
return rendererWithVerticalScrollbar{base, n, low, high}
|
||||
}
|
||||
|
||||
type rendererWithVerticalScrollbar struct {
|
||||
base Renderer
|
||||
n, low, high int
|
||||
}
|
||||
|
||||
func (r rendererWithVerticalScrollbar) Render(bb *BufferBuilder) {
|
||||
bufBase := Render(r.base, bb.Width-1)
|
||||
bb.ExtendRight(bufBase, 0)
|
||||
bufScrollbar := renderVerticalScrollbar(r.n, r.low, r.high, len(bufBase.Lines))
|
||||
bb.ExtendRight(bufScrollbar, bb.Width-1)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,15 @@ func TestRender(t *testing.T) {
|
|||
Args(NewStringRenderer("string"), 3).
|
||||
Rets(NewBufferBuilder(3).WriteString("str", "").Buffer()),
|
||||
|
||||
Args(NewLinesRenderer("line 1", "line 2"), 10).
|
||||
Rets(
|
||||
NewBufferBuilder(10).WriteString("line 1", "").Newline().
|
||||
WriteString("line 2", "").Buffer()),
|
||||
Args(NewLinesRenderer("line 1", "line 2"), 3).
|
||||
Rets(
|
||||
NewBufferBuilder(3).WriteString("lin", "").Newline().
|
||||
WriteString("lin", "").Buffer()),
|
||||
|
||||
Args(NewModeLineRenderer("M", "f"), 10).
|
||||
Rets(
|
||||
NewBufferBuilder(10).
|
||||
|
@ -43,5 +52,18 @@ func TestRender(t *testing.T) {
|
|||
Write(' ', styleForScrollBarThumb.String()).
|
||||
WriteString("━━━━", styleForScrollBarArea.String()).
|
||||
Buffer()),
|
||||
|
||||
Args(NewRendererWithVerticalScrollbar(NewLinesRenderer("1", "2", "3"), 3, 0, 1), 5).
|
||||
Rets(
|
||||
NewBufferBuilder(5).
|
||||
WriteString("1 ", "").
|
||||
Write(' ', styleForScrollBarThumb.String()).
|
||||
Newline().
|
||||
WriteString("2 ", "").
|
||||
Write('│', styleForScrollBarArea.String()).
|
||||
Newline().
|
||||
WriteString("3 ", "").
|
||||
Write('│', styleForScrollBarArea.String()).
|
||||
Buffer()),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -11,6 +11,22 @@ func writeHorizontalScrollbar(bb *BufferBuilder, n, low, high, width int) {
|
|||
}
|
||||
}
|
||||
|
||||
func renderVerticalScrollbar(n, low, high, height int) *Buffer {
|
||||
slow, shigh := findScrollInterval(n, low, high, height)
|
||||
bb := NewBufferBuilder(1)
|
||||
for i := 0; i < height; i++ {
|
||||
if i > 0 {
|
||||
bb.Newline()
|
||||
}
|
||||
if slow <= i && i < shigh {
|
||||
bb.Write(' ', styleForScrollBarThumb.String())
|
||||
} else {
|
||||
bb.Write('│', styleForScrollBarArea.String())
|
||||
}
|
||||
}
|
||||
return bb.Buffer()
|
||||
}
|
||||
|
||||
func findScrollInterval(n, low, high, height int) (int, int) {
|
||||
f := func(i int) int {
|
||||
return int(float64(i)/float64(n)*float64(height) + 0.5)
|
||||
|
|
Loading…
Reference in New Issue
Block a user