package main
+// SpltType specifies whether a split is horizontal or vertical
type SplitType bool
const (
- VerticalSplit = false
+ // VerticalSplit type
+ VerticalSplit = false
+ // HorizontalSplit type
HorizontalSplit = true
)
+// A Node on the split tree
type Node interface {
VSplit(buf *Buffer)
HSplit(buf *Buffer)
String() string
}
+// A LeafNode is an actual split so it contains a view
type LeafNode struct {
view *View
parent *SplitTree
}
+// NewLeafNode returns a new leaf node containing the given view
func NewLeafNode(v *View, parent *SplitTree) *LeafNode {
n := new(LeafNode)
n.view = v
return n
}
+// A SplitTree is a Node itself and it contains other nodes
type SplitTree struct {
kind SplitType
x int
y int
- width int
- height int
+ width int
+ height int
+ lockWidth bool
+ lockHeight bool
tabNum int
}
+// VSplit creates a vertical split
func (l *LeafNode) VSplit(buf *Buffer) {
tab := tabs[l.parent.tabNum]
if l.parent.kind == VerticalSplit {
s := new(SplitTree)
s.kind = VerticalSplit
s.parent = l.parent
+ s.tabNum = l.parent.tabNum
newView := NewView(buf)
newView.TabNum = l.parent.tabNum
newView.Num = len(tab.views)
}
}
+// HSplit creates a horizontal split
func (l *LeafNode) HSplit(buf *Buffer) {
tab := tabs[l.parent.tabNum]
if l.parent.kind == HorizontalSplit {
} else {
s := new(SplitTree)
s.kind = HorizontalSplit
+ s.tabNum = l.parent.tabNum
s.parent = l.parent
newView := NewView(buf)
newView.TabNum = l.parent.tabNum
}
}
+// Delete deletes a split
func (l *LeafNode) Delete() {
i := search(l.parent.children, l)
}
}
+// Cleanup rearranges all the parents after a split has been deleted
func (s *SplitTree) Cleanup() {
for i, node := range s.children {
if n, ok := node.(*SplitTree); ok {
}
}
+// ResizeSplits resizes all the splits correctly
func (s *SplitTree) ResizeSplits() {
- for i, node := range s.children {
+ lockedWidth := 0
+ lockedHeight := 0
+ lockedChildren := 0
+ for _, node := range s.children {
+ if n, ok := node.(*LeafNode); ok {
+ if s.kind == VerticalSplit {
+ if n.view.lockWidth {
+ lockedWidth += n.view.width
+ lockedChildren++
+ }
+ } else {
+ if n.view.lockHeight {
+ lockedHeight += n.view.height
+ lockedChildren++
+ }
+ }
+ } else if n, ok := node.(*SplitTree); ok {
+ if s.kind == VerticalSplit {
+ if n.lockWidth {
+ lockedWidth += n.width
+ lockedChildren++
+ }
+ } else {
+ if n.lockHeight {
+ lockedHeight += n.height
+ lockedChildren++
+ }
+ }
+ }
+ }
+ x, y := 0, 0
+ for _, node := range s.children {
if n, ok := node.(*LeafNode); ok {
if s.kind == VerticalSplit {
- n.view.width = s.width / len(s.children)
+ if !n.view.lockWidth {
+ n.view.width = (s.width - lockedWidth) / (len(s.children) - lockedChildren)
+ }
n.view.height = s.height
- n.view.x = s.x + n.view.width*i
+ n.view.x = s.x + x
n.view.y = s.y
+ x += n.view.width
} else {
- n.view.height = s.height / len(s.children)
+ if !n.view.lockHeight {
+ n.view.height = (s.height - lockedHeight) / (len(s.children) - lockedChildren)
+ }
n.view.width = s.width
- n.view.y = s.y + n.view.height*i
+ n.view.y = s.y + y
n.view.x = s.x
+ y += n.view.height
}
- // n.view.ToggleStatusLine()
- _, screenH := screen.Size()
- if settings["statusline"].(bool) || (n.view.y+n.view.height) != screenH-1 {
+ if n.view.Buf.Settings["statusline"].(bool) {
n.view.height--
}
n.view.matches = Match(n.view)
} else if n, ok := node.(*SplitTree); ok {
if s.kind == VerticalSplit {
- n.width = s.width / len(s.children)
+ if !n.lockWidth {
+ n.width = (s.width - lockedWidth) / (len(s.children) - lockedChildren)
+ }
n.height = s.height
- n.x = s.x + n.width*i
+ n.x = s.x + x
n.y = s.y
+ x += n.width
} else {
- n.height = s.height / len(s.children)
+ if !n.lockHeight {
+ n.height = (s.height - lockedHeight) / (len(s.children) - lockedChildren)
+ }
n.width = s.width
- n.y = s.y + n.height*i
+ n.y = s.y + y
n.x = s.x
+ y += n.height
}
n.ResizeSplits()
}
return 0
}
+// VSplit is here just to make SplitTree fit the Node interface
func (s *SplitTree) VSplit(buf *Buffer) {}
+
+// HSplit is here just to make SplitTree fit the Node interface
func (s *SplitTree) HSplit(buf *Buffer) {}
func (s *SplitTree) String() string {