1
0

draw.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package editor
  2. import (
  3. "moose/internal/layout"
  4. "moose/internal/buffer"
  5. "fmt"
  6. "strings"
  7. "github.com/gdamore/tcell/v3/color"
  8. )
  9. func (m *Model) Draw() {
  10. m.DrawWorkspace(&m.LM.Workspaces[m.LM.ActiveIdx], layout.RectFromScren(m.Screen))
  11. }
  12. func (m *Model) DrawWorkspace(w *layout.Workspace, rect layout.Rect) {
  13. m.DrawContainer(&w.RootContainer, rect)
  14. }
  15. func (m *Model) DrawContainer(c *layout.Container[layout.ContainerBuffers], rect layout.Rect) {
  16. length := len(c.Children)
  17. rect = layout.RectDivide(rect, c.Split, length)
  18. for i, child := range c.Children {
  19. switch child.(type) {
  20. case layout.ContainerBuffers: {
  21. cb := child.(layout.ContainerBuffers)
  22. m.DrawContainerBuffers(&cb, layout.RectDisplace(rect, c.Split, i))
  23. }
  24. case layout.Container[layout.ContainerBuffers]: {
  25. c := child.(layout.Container[layout.ContainerBuffers])
  26. m.DrawContainer(&c, layout.RectDisplace(rect, c.Split, i))
  27. }
  28. }
  29. }
  30. }
  31. func (m *Model) DrawContainerBuffers(c *layout.ContainerBuffers, rect layout.Rect) {
  32. m.DrawBuffer(&m.BM.Buffers[c.Buffers[c.ActiveIdx]], c.Buffers[c.ActiveIdx] == m.BM.CurrentIdx, rect)
  33. }
  34. func (m *Model) DrawBuffer(buf *buffer.Buffer, isActive bool, rect layout.Rect) {
  35. primary := buf.CM.Cursors[buf.CM.PrimaryIdx]
  36. curLine, _ := buffer.LineCol(buf, primary.Offset)
  37. buf.ScrollToShow(curLine, rect.Height)
  38. startOffset := buffer.OffsetForLine(buf, buf.TopLine)
  39. endOffset := buf.Rope.Len()
  40. if endLine := buf.TopLine + rect.Height; endLine < buffer.LineCount(buf) {
  41. endOffset = buffer.OffsetForLine(buf, endLine)
  42. }
  43. visible := string(buf.Rope.Slice(startOffset, endOffset))
  44. table := strings.SplitAfter(visible, "\n")
  45. for j, line := range table {
  46. if j + 1 > rect.Height { break }
  47. nums := fmt.Sprintf("%4d ", j + buf.TopLine)
  48. r := []rune(nums + expandTabs(line))
  49. if len(r) + 1 > rect.Width {
  50. r = r[:rect.Width]
  51. }
  52. m.Screen.PutStrStyled(rect.X, rect.Y + j, string(r), m.Style)
  53. }
  54. if isActive {
  55. for _, cur := range buf.CM.Cursors {
  56. line, col := buffer.LineCol(buf, cur.Offset)
  57. screenLine := line - buf.TopLine
  58. if screenLine < 0 || screenLine + 1 > rect.Height { continue }
  59. visCol := visualCol(buffer.LineText(buf, line), col)
  60. if visCol + 1 > rect.Width { continue }
  61. ch := buffer.RuneAt(buf, cur.Offset)
  62. if m.Mode == ModeWrite {
  63. m.Screen.SetContent(rect.X + visCol + 5, rect.Y + screenLine, ch, nil, m.Style.Reverse(true))
  64. } else {
  65. m.Screen.SetContent(rect.X + visCol + 5, rect.Y + screenLine, ch, nil, m.Style.Reverse(true).Foreground(color.Gray))
  66. }
  67. }
  68. }
  69. }