diff options
Diffstat (limited to 'tui/layout.go')
| -rw-r--r-- | tui/layout.go | 131 |
1 files changed, 20 insertions, 111 deletions
diff --git a/tui/layout.go b/tui/layout.go index 0681e8e..e2c3e0f 100644 --- a/tui/layout.go +++ b/tui/layout.go @@ -2,7 +2,6 @@ package tui import ( "github.com/rivo/uniseg" - "strings" "unicode" ) @@ -16,9 +15,6 @@ type Box struct { Scroll *ScrollState text []textRun computedLines [][]textRun - cursorLine int - cursorCol int - hasCursor bool children []*Box computedPosition int computedSize [2]int @@ -36,43 +32,12 @@ func (s BoxSize) isFlexible() bool { return s == Fill } -type Direction int -const ( - Down = iota - Up - Right - Left -) - -func (d Direction) axis() int { - switch d { - case Down, Up: - return 1 - default: - return 0 - } -} - -func (d Direction) reverse() bool { - switch d { - case Down, Right: - return false - default: - return true - } -} - type textRun struct { text string style *Style hasCursor bool } -type rect struct { - min [2]int - max [2]int -} - type ScrollState struct { at string offset int @@ -81,6 +46,8 @@ type ScrollState struct { atLast bool } +var Selected string + func (s *ScrollState) ToStart() { *s = ScrollState {} } @@ -237,85 +204,32 @@ func (b *Box) computeText(axis int) { } else { var ( limit = b.computedSize[0] - line []textRun - text, word strings.Builder - lineWidth, wordWidth int - hasCursor bool - cursorAt int - run textRun + line, word builder ) - flushText := func() { - if text.Len() != 0 { - line = append(line, textRun {text.String(), run.style, false}) - } - text.Reset() - } - flushLine := func() { - flushText() - b.computedLines = append(b.computedLines, line) - lineWidth = 0 - line = nil - } - breakWord := func() { - if lineWidth + wordWidth > limit { - flushLine() - } - g := uniseg.NewGraphemes(word.String()) - pos := 0 - for g.Next() { - if hasCursor && pos == cursorAt { - b.cursorLine = len(b.computedLines) - b.cursorCol = lineWidth - b.hasCursor = true - hasCursor = false - } - - if g.Width() > limit { - continue - } - if lineWidth == 0 && g.Str() == " " { - continue - } - text.WriteString(g.Str()) - if g.Width() + lineWidth > limit { - flushLine() - } - lineWidth += g.Width() - - pos++ - } - wordWidth = 0 - word.Reset() - } for _, run := range b.text { if run.hasCursor { - hasCursor = true - cursorAt = wordWidth + word.addRun(run) + word.addRun(textRun {"", nil, false}) } g := uniseg.NewGraphemes(run.text) for g.Next() { - if g.LineBreak() == uniseg.LineCanBreak { - breakWord() + word.add(g.Str(), run.style) + if word.width >= limit { + line.addRuns(word.flush()) + } else if line.width + word.width >= limit { + b.computedLines = append(b.computedLines, line.flush()) } - if lineWidth != 0 || !unicode.IsSpace(g.Runes()[0]) { - word.WriteString(g.Str()) - wordWidth += g.Width() + if unicode.IsSpace(g.Runes()[0]) { + line.addRuns(word.flush()) } - _, end := g.Positions() - if end == len(run.text) { - breakWord() - break - } - if g.LineBreak() == uniseg.LineMustBreak { - breakWord() - flushLine() + if g.Str() == "\n" { + line.addRuns(word.flush()) + b.computedLines = append(b.computedLines, line.flush()) } } - flushText() - } - if len(line) != 0 || text.Len() != 0 { - flushLine() } + line.addRuns(word.flush()) + b.computedLines = append(b.computedLines, line.flush()) if b.Height == TextSize { b.computedSize[axis] = len(b.computedLines) + b.marginsSize(axis) } @@ -458,17 +372,12 @@ func (b *Box) drawComputed(parentRect rect, parentStyle Style) { } else { s = style } + if t.hasCursor { + ShowCursor(x, y) + } x += WriteAt(x, y, t.text, s) } } - if b.hasCursor { - cx := b.cursorCol + b.computedRect.min[0] + b.Margins[0] - cy := b.cursorLine + b.computedRect.min[1] + b.Margins[2] - if cx >= viewRect.min[0] && cx < viewRect.max[0] && - cy >= viewRect.min[1] && cy < viewRect.max[1] { - ShowCursor(cx, cy) - } - } for _, c := range b.children { c.drawComputed(viewRect, style) } |
