package main type SplitType bool const ( VerticalSplit = false HorizontalSplit = true ) type Node interface { VSplit(buf *Buffer) HSplit(buf *Buffer) String() string } type LeafNode struct { view *View parent *SplitTree } func NewLeafNode(v *View, parent *SplitTree) *LeafNode { n := new(LeafNode) n.view = v n.view.splitNode = n n.parent = parent return n } type SplitTree struct { kind SplitType parent *SplitTree children []Node x int y int width int height int tabNum int } func (l *LeafNode) VSplit(buf *Buffer) { tab := tabs[l.parent.tabNum] if l.parent.kind == VerticalSplit { newView := NewView(buf) newView.TabNum = l.parent.tabNum newView.Num = len(tab.views) l.parent.children = append(l.parent.children, NewLeafNode(newView, l.parent)) tab.curView++ tab.views = append(tab.views, newView) } else { s := new(SplitTree) s.kind = VerticalSplit s.parent = l.parent newView := NewView(buf) newView.TabNum = l.parent.tabNum newView.Num = len(tab.views) s.children = []Node{l, NewLeafNode(newView, s)} l.parent.children[search(l.parent.children, l)] = s tab.curView++ tab.views = append(tab.views, newView) } } func (l *LeafNode) HSplit(buf *Buffer) { tab := tabs[l.parent.tabNum] if l.parent.kind == HorizontalSplit { newView := NewView(buf) newView.TabNum = l.parent.tabNum newView.Num = len(tab.views) l.parent.children = append(l.parent.children, NewLeafNode(newView, l.parent)) tab.curView++ tab.views = append(tab.views, newView) } else { s := new(SplitTree) s.kind = HorizontalSplit s.parent = l.parent newView := NewView(buf) newView.TabNum = l.parent.tabNum newView.Num = len(tab.views) s.children = []Node{l, NewLeafNode(newView, s)} l.parent.children[search(l.parent.children, l)] = s tab.curView++ tab.views = append(tab.views, newView) } } func (s *SplitTree) ResizeSplits() { for i, node := range s.children { if n, ok := node.(*LeafNode); ok { if s.kind == VerticalSplit { n.view.width = s.width / len(s.children) n.view.height = s.height n.view.x = s.x + n.view.width*i n.view.y = s.y } else { n.view.height = s.height / len(s.children) n.view.width = s.width n.view.y = s.y + n.view.height*i n.view.x = s.x } } else if n, ok := node.(*SplitTree); ok { if s.kind == VerticalSplit { n.width = s.width / len(s.children) n.height = s.height n.x = s.x + n.width*i n.y = s.y } else { n.height = s.height / len(s.children) n.width = s.width n.y = s.y + n.height*i n.x = s.x } n.ResizeSplits() } } } func (l *LeafNode) String() string { return l.view.Buf.Name } func search(haystack []Node, needle Node) int { for i, x := range haystack { if x == needle { return i } } return 0 } func (s *SplitTree) VSplit(buf *Buffer) {} func (s *SplitTree) HSplit(buf *Buffer) {} func (s *SplitTree) String() string { str := "[" for _, child := range s.children { str += child.String() + ", " } return str + "]" }