1
0

layout.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package layout
  2. type LayoutManager struct {
  3. Workspaces map[int]Workspace
  4. ActiveIdx int
  5. CurrentSplit SplitType
  6. }
  7. type Workspace struct {
  8. RootContainer Container
  9. }
  10. type SplitType int
  11. const (
  12. SplitHorizontal SplitType = iota
  13. SplitVertical
  14. )
  15. func (s *SplitType) SetOpposite() SplitType{
  16. if *s == SplitHorizontal {
  17. *s = SplitVertical
  18. } else {
  19. *s = SplitHorizontal
  20. }
  21. return *s
  22. }
  23. type ContainerNode interface {
  24. isContainerNode()
  25. }
  26. type ContainerBuffers struct {
  27. Buffers []int
  28. ActiveIdx int
  29. }
  30. func (ContainerBuffers) isContainerNode() {}
  31. type Container struct {
  32. Children [2]ContainerNode
  33. Split SplitType
  34. ActiveChildIdx int
  35. }
  36. func (Container) isContainerNode() {}
  37. func NewLayoutManager() LayoutManager {
  38. return LayoutManager{
  39. Workspaces: map[int]Workspace{0: NewWorkspace()},
  40. CurrentSplit: SplitVertical,
  41. }
  42. }
  43. func NewWorkspace() Workspace {
  44. return Workspace{
  45. RootContainer: NewContainerEmpty(),
  46. }
  47. }
  48. func NewContainerEmpty() Container {
  49. return Container{
  50. Children: [2]ContainerNode{
  51. ContainerBuffers{
  52. Buffers: []int{0},
  53. ActiveIdx: 0,
  54. },
  55. ContainerBuffers{
  56. Buffers: []int{0},
  57. ActiveIdx: 0,
  58. },
  59. },
  60. Split: SplitVertical,
  61. ActiveChildIdx: 0,
  62. }
  63. }
  64. func (c *Container) WalkAndMutateActive(fn func(cb *ContainerBuffers) ContainerNode) {
  65. switch child := c.Children[c.ActiveChildIdx].(type) {
  66. case ContainerBuffers:
  67. c.Children[c.ActiveChildIdx] = fn(&child)
  68. case Container:
  69. child.WalkAndMutateActive(fn)
  70. c.Children[c.ActiveChildIdx] = child
  71. default:
  72. cb := ContainerBuffers{Buffers: []int{}, ActiveIdx: 0}
  73. c.Children[c.ActiveChildIdx] = fn(&cb)
  74. }
  75. }
  76. func (lm *LayoutManager) InsertBuffer(bufferIdx int, newNode bool) {
  77. workspace := lm.Workspaces[lm.ActiveIdx]
  78. workspace.RootContainer.WalkAndMutateActive(func(cb *ContainerBuffers) ContainerNode {
  79. if !newNode || len(cb.Buffers) == 0 {
  80. cb.Buffers = append(cb.Buffers, bufferIdx)
  81. cb.ActiveIdx = len(cb.Buffers) - 1
  82. return *cb
  83. }
  84. cbNew := ContainerBuffers{
  85. Buffers: []int{bufferIdx},
  86. ActiveIdx: 0,
  87. }
  88. return Container{
  89. Children: [2]ContainerNode{*cb, cbNew},
  90. Split: lm.CurrentSplit.SetOpposite(),
  91. ActiveChildIdx: 1,
  92. }
  93. })
  94. lm.Workspaces[lm.ActiveIdx] = workspace
  95. }