X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Fsplit_tree.go;h=66c85eb04a67b36215e5808795a19d7ef794a05c;hb=3ecdd96931ac75039105b5a4ac2fdd3b5526dbf6;hp=aab5237dd8a05722cf621ae28740e4abd30a1e81;hpb=4972db4bf6c74e5c543188431e4236ed4b8222a0;p=micro.git diff --git a/cmd/micro/split_tree.go b/cmd/micro/split_tree.go index aab5237d..66c85eb0 100644 --- a/cmd/micro/split_tree.go +++ b/cmd/micro/split_tree.go @@ -1,24 +1,30 @@ 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 @@ -27,6 +33,7 @@ func NewLeafNode(v *View, parent *SplitTree) *LeafNode { return n } +// A SplitTree is a Node itself and it contains other nodes type SplitTree struct { kind SplitType @@ -36,12 +43,15 @@ type SplitTree struct { 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 { @@ -56,6 +66,7 @@ func (l *LeafNode) VSplit(buf *Buffer) { 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) @@ -68,6 +79,7 @@ func (l *LeafNode) VSplit(buf *Buffer) { } } +// HSplit creates a horizontal split func (l *LeafNode) HSplit(buf *Buffer) { tab := tabs[l.parent.tabNum] if l.parent.kind == HorizontalSplit { @@ -81,6 +93,7 @@ func (l *LeafNode) HSplit(buf *Buffer) { } else { s := new(SplitTree) s.kind = HorizontalSplit + s.tabNum = l.parent.tabNum s.parent = l.parent newView := NewView(buf) newView.TabNum = l.parent.tabNum @@ -94,6 +107,7 @@ func (l *LeafNode) HSplit(buf *Buffer) { } } +// Delete deletes a split func (l *LeafNode) Delete() { i := search(l.parent.children, l) @@ -115,6 +129,7 @@ func (l *LeafNode) Delete() { } } +// 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 { @@ -130,21 +145,59 @@ func (s *SplitTree) Cleanup() { } } +// 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 } if n.view.Buf.Settings["statusline"].(bool) { n.view.height-- @@ -154,17 +207,23 @@ func (s *SplitTree) ResizeSplits() { 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() } @@ -193,7 +252,10 @@ func findView(haystack []*View, needle *View) int { 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 {