mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-15 21:37:09 +09:00
Start working on splits
This commit is contained in:
@@ -90,6 +90,8 @@ type BufHandler struct {
|
|||||||
|
|
||||||
// Last search stores the last successful search for FindNext and FindPrev
|
// Last search stores the last successful search for FindNext and FindPrev
|
||||||
lastSearch string
|
lastSearch string
|
||||||
|
|
||||||
|
splitID uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBufHandler(buf *buffer.Buffer, win display.Window) *BufHandler {
|
func NewBufHandler(buf *buffer.Buffer, win display.Window) *BufHandler {
|
||||||
@@ -212,6 +214,19 @@ func (h *BufHandler) DoRuneInsert(r rune) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *BufHandler) vsplit(buf *buffer.Buffer) {
|
||||||
|
e := NewBufEditPane(0, 0, 0, 0, buf)
|
||||||
|
e.splitID = MainTab.GetNode(h.splitID).VSplit(h.Buf.Settings["splitright"].(bool))
|
||||||
|
MainTab.Panes = append(MainTab.Panes, e)
|
||||||
|
MainTab.Resize()
|
||||||
|
}
|
||||||
|
func (h *BufHandler) hsplit(buf *buffer.Buffer) {
|
||||||
|
e := NewBufEditPane(0, 0, 0, 0, buf)
|
||||||
|
e.splitID = MainTab.GetNode(h.splitID).HSplit(h.Buf.Settings["splitbottom"].(bool))
|
||||||
|
MainTab.Panes = append(MainTab.Panes, e)
|
||||||
|
MainTab.Resize()
|
||||||
|
}
|
||||||
|
|
||||||
// BufKeyActions contains the list of all possible key actions the bufhandler could execute
|
// BufKeyActions contains the list of all possible key actions the bufhandler could execute
|
||||||
var BufKeyActions = map[string]BufKeyAction{
|
var BufKeyActions = map[string]BufKeyAction{
|
||||||
"CursorUp": (*BufHandler).CursorUp,
|
"CursorUp": (*BufHandler).CursorUp,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package action
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||||
"github.com/zyedidia/micro/cmd/micro/shellwords"
|
"github.com/zyedidia/micro/cmd/micro/shellwords"
|
||||||
"github.com/zyedidia/micro/cmd/micro/util"
|
"github.com/zyedidia/micro/cmd/micro/util"
|
||||||
)
|
)
|
||||||
@@ -198,11 +199,25 @@ func Help(args []string) {
|
|||||||
// VSplit opens a vertical split with file given in the first argument
|
// VSplit opens a vertical split with file given in the first argument
|
||||||
// If no file is given, it opens an empty buffer in a new split
|
// If no file is given, it opens an empty buffer in a new split
|
||||||
func VSplit(args []string) {
|
func VSplit(args []string) {
|
||||||
|
buf, err := buffer.NewBufferFromFile(args[0], buffer.BTDefault)
|
||||||
|
if err != nil {
|
||||||
|
InfoBar.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.CurPane().vsplit(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HSplit opens a horizontal split with file given in the first argument
|
// HSplit opens a horizontal split with file given in the first argument
|
||||||
// If no file is given, it opens an empty buffer in a new split
|
// If no file is given, it opens an empty buffer in a new split
|
||||||
func HSplit(args []string) {
|
func HSplit(args []string) {
|
||||||
|
buf, err := buffer.NewBufferFromFile(args[0], buffer.BTDefault)
|
||||||
|
if err != nil {
|
||||||
|
InfoBar.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.CurPane().hsplit(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eval evaluates a lua expression
|
// Eval evaluates a lua expression
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||||
"github.com/zyedidia/micro/cmd/micro/display"
|
"github.com/zyedidia/micro/cmd/micro/display"
|
||||||
"github.com/zyedidia/micro/cmd/micro/info"
|
"github.com/zyedidia/micro/cmd/micro/info"
|
||||||
|
"github.com/zyedidia/micro/cmd/micro/views"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EditPane struct {
|
type EditPane struct {
|
||||||
@@ -27,6 +28,17 @@ func NewBufEditPane(x, y, width, height int, b *buffer.Buffer) *EditPane {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTabPane(width, height int, b *buffer.Buffer) *TabPane {
|
||||||
|
t := new(TabPane)
|
||||||
|
t.Node = views.NewRoot(0, 0, width, height)
|
||||||
|
|
||||||
|
e := NewBufEditPane(0, 0, width, height, b)
|
||||||
|
e.splitID = t.ID()
|
||||||
|
|
||||||
|
t.Panes = append(t.Panes, e)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
func NewInfoBar() *InfoPane {
|
func NewInfoBar() *InfoPane {
|
||||||
e := new(InfoPane)
|
e := new(InfoPane)
|
||||||
ib := info.NewBuffer()
|
ib := info.NewBuffer()
|
||||||
|
|||||||
35
cmd/micro/action/tab.go
Normal file
35
cmd/micro/action/tab.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package action
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/zyedidia/micro/cmd/micro/views"
|
||||||
|
"github.com/zyedidia/tcell"
|
||||||
|
)
|
||||||
|
|
||||||
|
var MainTab *TabPane
|
||||||
|
|
||||||
|
type TabPane struct {
|
||||||
|
*views.Node
|
||||||
|
Panes []*EditPane
|
||||||
|
active int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TabPane) HandleEvent(event tcell.Event) {
|
||||||
|
t.Panes[t.active].HandleEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TabPane) Resize() {
|
||||||
|
for _, p := range t.Panes {
|
||||||
|
log.Println(p.splitID)
|
||||||
|
v := t.GetNode(p.splitID).GetView()
|
||||||
|
pv := p.GetView()
|
||||||
|
pv.X, pv.Y = v.X, v.Y
|
||||||
|
p.SetView(pv)
|
||||||
|
p.Resize(v.W, v.H)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TabPane) CurPane() *EditPane {
|
||||||
|
return t.Panes[t.active]
|
||||||
|
}
|
||||||
@@ -48,6 +48,10 @@ func NewInfoWindow(b *info.InfoBuf) *InfoWindow {
|
|||||||
return iw
|
return iw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *InfoWindow) Resize(w, h int) {
|
||||||
|
i.width = w
|
||||||
|
}
|
||||||
|
|
||||||
// func (i *InfoWindow) YesNoPrompt() (bool, bool) {
|
// func (i *InfoWindow) YesNoPrompt() (bool, bool) {
|
||||||
// for {
|
// for {
|
||||||
// i.Clear()
|
// i.Clear()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package display
|
package display
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ type Window interface {
|
|||||||
GetView() *View
|
GetView() *View
|
||||||
SetView(v *View)
|
SetView(v *View)
|
||||||
GetMouseLoc(vloc buffer.Loc) buffer.Loc
|
GetMouseLoc(vloc buffer.Loc) buffer.Loc
|
||||||
|
Resize(w, h int)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The BufWindow provides a way of displaying a certain section
|
// The BufWindow provides a way of displaying a certain section
|
||||||
@@ -65,6 +67,11 @@ func (v *View) SetView(view *View) {
|
|||||||
v = view
|
v = view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *BufWindow) Resize(width, height int) {
|
||||||
|
w.Width, w.Height = width, height
|
||||||
|
w.lineHeight = make([]int, height)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *BufWindow) getStartInfo(n, lineN int) ([]byte, int, int, *tcell.Style) {
|
func (w *BufWindow) getStartInfo(n, lineN int) ([]byte, int, int, *tcell.Style) {
|
||||||
tabsize := util.IntOpt(w.Buf.Settings["tabsize"])
|
tabsize := util.IntOpt(w.Buf.Settings["tabsize"])
|
||||||
width := 0
|
width := 0
|
||||||
@@ -431,6 +438,7 @@ func (w *BufWindow) displayBuffer() {
|
|||||||
nColsBeforeStart--
|
nColsBeforeStart--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println(len(w.lineHeight), vloc.Y)
|
||||||
w.lineHeight[vloc.Y] = bloc.Y
|
w.lineHeight[vloc.Y] = bloc.Y
|
||||||
|
|
||||||
totalwidth := w.StartCol - nColsBeforeStart
|
totalwidth := w.StartCol - nColsBeforeStart
|
||||||
|
|||||||
@@ -187,7 +187,8 @@ func main() {
|
|||||||
|
|
||||||
b := LoadInput()[0]
|
b := LoadInput()[0]
|
||||||
width, height := screen.Screen.Size()
|
width, height := screen.Screen.Size()
|
||||||
ep := action.NewBufEditPane(0, 0, width, height-1, b)
|
|
||||||
|
action.MainTab = action.NewTabPane(width, height-1, b)
|
||||||
|
|
||||||
action.InitGlobals()
|
action.InitGlobals()
|
||||||
|
|
||||||
@@ -205,7 +206,9 @@ func main() {
|
|||||||
// Display everything
|
// Display everything
|
||||||
screen.Screen.Fill(' ', config.DefStyle)
|
screen.Screen.Fill(' ', config.DefStyle)
|
||||||
screen.Screen.HideCursor()
|
screen.Screen.HideCursor()
|
||||||
ep.Display()
|
for _, ep := range action.MainTab.Panes {
|
||||||
|
ep.Display()
|
||||||
|
}
|
||||||
action.InfoBar.Display()
|
action.InfoBar.Display()
|
||||||
screen.Screen.Show()
|
screen.Screen.Show()
|
||||||
|
|
||||||
@@ -220,7 +223,7 @@ func main() {
|
|||||||
if action.InfoBar.HasPrompt {
|
if action.InfoBar.HasPrompt {
|
||||||
action.InfoBar.HandleEvent(event)
|
action.InfoBar.HandleEvent(event)
|
||||||
} else {
|
} else {
|
||||||
ep.HandleEvent(event)
|
action.MainTab.Panes[0].HandleEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
354
cmd/micro/views/splits.go
Normal file
354
cmd/micro/views/splits.go
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SplitType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
STVert = 0
|
||||||
|
STHoriz = 1
|
||||||
|
STUndef = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
var idcounter uint64
|
||||||
|
|
||||||
|
func NewID() uint64 {
|
||||||
|
idcounter++
|
||||||
|
return idcounter
|
||||||
|
}
|
||||||
|
|
||||||
|
type View struct {
|
||||||
|
X, Y int
|
||||||
|
W, H int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
View
|
||||||
|
|
||||||
|
kind SplitType
|
||||||
|
|
||||||
|
parent *Node
|
||||||
|
children []*Node
|
||||||
|
|
||||||
|
// Nodes can be marked as non resizable if they shouldn't be rescaled
|
||||||
|
// when the terminal window is resized or when a new split is added
|
||||||
|
// Only the splits on the edges of the screen can be marked as non resizable
|
||||||
|
canResize bool
|
||||||
|
// A node may also be marked with proportional scaling. This means that when
|
||||||
|
// the window is resized the split maintains its proportions
|
||||||
|
propScale bool
|
||||||
|
|
||||||
|
id uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) ID() uint64 {
|
||||||
|
if n.IsLeaf() {
|
||||||
|
return n.id
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func (n *Node) CanResize() bool {
|
||||||
|
return n.canResize
|
||||||
|
}
|
||||||
|
func (n *Node) PropScale() bool {
|
||||||
|
return n.propScale
|
||||||
|
}
|
||||||
|
func (n *Node) SetResize(b bool) {
|
||||||
|
n.canResize = b
|
||||||
|
}
|
||||||
|
func (n *Node) SetPropScale(b bool) {
|
||||||
|
n.propScale = b
|
||||||
|
}
|
||||||
|
func (n *Node) GetView() View {
|
||||||
|
return n.View
|
||||||
|
}
|
||||||
|
func (n *Node) SetView(v View) {
|
||||||
|
n.X, n.Y, n.W, n.H = v.X, v.Y, v.W, v.H
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) GetNode(id uint64) *Node {
|
||||||
|
if n.id == id && n.IsLeaf() {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
for _, c := range n.children {
|
||||||
|
if c.id == id && c.IsLeaf() {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
gc := c.GetNode(id)
|
||||||
|
if gc != nil {
|
||||||
|
return gc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNode(kind SplitType, x, y, w, h int, parent *Node, id uint64) *Node {
|
||||||
|
n := new(Node)
|
||||||
|
n.kind = kind
|
||||||
|
n.canResize = true
|
||||||
|
n.propScale = true
|
||||||
|
n.X, n.Y, n.W, n.H = x, y, w, h
|
||||||
|
n.children = make([]*Node, 0)
|
||||||
|
n.parent = parent
|
||||||
|
n.id = id
|
||||||
|
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoot(x, y, w, h int) *Node {
|
||||||
|
n1 := NewNode(STUndef, x, y, w, h, nil, NewID())
|
||||||
|
|
||||||
|
return n1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) IsLeaf() bool {
|
||||||
|
return len(n.children) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) vResizeSplit(i int, size int) bool {
|
||||||
|
if i < 0 || i >= len(n.children)-1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
v1, v2 := n.children[i].GetView(), n.children[i+1].GetView()
|
||||||
|
toth := v1.H + v2.H
|
||||||
|
if size >= toth {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
v1.H, v2.H = size, toth-size
|
||||||
|
v2.Y = size
|
||||||
|
n.children[i].SetView(v1)
|
||||||
|
n.children[i+1].SetView(v2)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
func (n *Node) hResizeSplit(i int, size int) bool {
|
||||||
|
if i < 0 || i >= len(n.children)-1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
v1, v2 := n.children[i].GetView(), n.children[i+1].GetView()
|
||||||
|
totw := v1.W + v2.W
|
||||||
|
if size >= totw {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
v1.W, v2.W = size, totw-size
|
||||||
|
v2.X = size
|
||||||
|
n.children[i].SetView(v1)
|
||||||
|
n.children[i+1].SetView(v2)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) ResizeSplit(size int) bool {
|
||||||
|
ind := 0
|
||||||
|
for i, c := range n.parent.children {
|
||||||
|
if c.id == n.id {
|
||||||
|
ind = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if n.parent.kind == STVert {
|
||||||
|
return n.parent.vResizeSplit(ind, size)
|
||||||
|
}
|
||||||
|
return n.parent.hResizeSplit(ind, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) vVSplit(right bool) uint64 {
|
||||||
|
ind := 0
|
||||||
|
for i, c := range n.parent.children {
|
||||||
|
if c.id == n.id {
|
||||||
|
ind = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n.parent.hVSplit(ind, right)
|
||||||
|
}
|
||||||
|
func (n *Node) hHSplit(bottom bool) uint64 {
|
||||||
|
ind := 0
|
||||||
|
for i, c := range n.parent.children {
|
||||||
|
if c.id == n.id {
|
||||||
|
ind = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n.parent.vHSplit(ind, bottom)
|
||||||
|
}
|
||||||
|
func (n *Node) vHSplit(i int, right bool) uint64 {
|
||||||
|
if n.IsLeaf() {
|
||||||
|
newid := NewID()
|
||||||
|
hn1 := NewNode(STHoriz, n.X, n.Y, n.W, n.H/2, n, n.id)
|
||||||
|
hn2 := NewNode(STHoriz, n.X, n.Y+hn1.H, n.W, n.H/2, n, newid)
|
||||||
|
if !right {
|
||||||
|
hn1.id, hn2.id = hn2.id, hn1.id
|
||||||
|
}
|
||||||
|
|
||||||
|
n.children = append(n.children, hn1, hn2)
|
||||||
|
return newid
|
||||||
|
} else {
|
||||||
|
numr := 0
|
||||||
|
numnr := 0
|
||||||
|
nonrh := 0
|
||||||
|
for _, c := range n.children {
|
||||||
|
view := c.GetView()
|
||||||
|
if !c.CanResize() {
|
||||||
|
nonrh += view.H
|
||||||
|
numnr++
|
||||||
|
} else {
|
||||||
|
numr++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are no resizable splits make them all resizable
|
||||||
|
if numr == 0 {
|
||||||
|
numr = numnr
|
||||||
|
}
|
||||||
|
|
||||||
|
height := (n.H - nonrh) / (numr + 1)
|
||||||
|
|
||||||
|
newid := NewID()
|
||||||
|
hn := NewNode(STHoriz, n.X, 0, n.W, height, n, newid)
|
||||||
|
n.children = append(n.children, nil)
|
||||||
|
inspos := i
|
||||||
|
if right {
|
||||||
|
inspos++
|
||||||
|
}
|
||||||
|
copy(n.children[inspos+1:], n.children[inspos:])
|
||||||
|
n.children[inspos] = hn
|
||||||
|
|
||||||
|
y := 0
|
||||||
|
for _, c := range n.children {
|
||||||
|
view := c.GetView()
|
||||||
|
if c.CanResize() {
|
||||||
|
view.H = height
|
||||||
|
view.Y = y
|
||||||
|
} else {
|
||||||
|
view.Y = y
|
||||||
|
}
|
||||||
|
y += view.H
|
||||||
|
c.SetView(view)
|
||||||
|
}
|
||||||
|
return newid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (n *Node) hVSplit(i int, right bool) uint64 {
|
||||||
|
if n.IsLeaf() {
|
||||||
|
newid := NewID()
|
||||||
|
vn1 := NewNode(STVert, n.X, n.Y, n.W/2, n.H, n, n.id)
|
||||||
|
vn2 := NewNode(STVert, n.X+vn1.W, n.Y, n.W/2, n.H, n, newid)
|
||||||
|
if !right {
|
||||||
|
vn1.id, vn2.id = vn2.id, vn1.id
|
||||||
|
}
|
||||||
|
|
||||||
|
n.children = append(n.children, vn1, vn2)
|
||||||
|
return newid
|
||||||
|
} else {
|
||||||
|
numr := 0
|
||||||
|
numnr := 0
|
||||||
|
nonrw := 0
|
||||||
|
for _, c := range n.children {
|
||||||
|
view := c.GetView()
|
||||||
|
if !c.CanResize() {
|
||||||
|
nonrw += view.W
|
||||||
|
numnr++
|
||||||
|
} else {
|
||||||
|
numr++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are no resizable splits make them all resizable
|
||||||
|
if numr == 0 {
|
||||||
|
numr = numnr
|
||||||
|
}
|
||||||
|
|
||||||
|
width := (n.W - nonrw) / (numr + 1)
|
||||||
|
|
||||||
|
newid := NewID()
|
||||||
|
vn := NewNode(STVert, 0, n.Y, width, n.H, n, newid)
|
||||||
|
n.children = append(n.children, nil)
|
||||||
|
inspos := i
|
||||||
|
if right {
|
||||||
|
inspos++
|
||||||
|
}
|
||||||
|
copy(n.children[inspos+1:], n.children[inspos:])
|
||||||
|
n.children[inspos] = vn
|
||||||
|
|
||||||
|
x := 0
|
||||||
|
for _, c := range n.children {
|
||||||
|
view := c.GetView()
|
||||||
|
if c.CanResize() {
|
||||||
|
view.W = width
|
||||||
|
view.X = x
|
||||||
|
} else {
|
||||||
|
view.X = x
|
||||||
|
}
|
||||||
|
x += view.W
|
||||||
|
c.SetView(view)
|
||||||
|
}
|
||||||
|
return newid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) HSplit(bottom bool) uint64 {
|
||||||
|
if !n.IsLeaf() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if n.kind == STUndef {
|
||||||
|
n.kind = STVert
|
||||||
|
}
|
||||||
|
if n.kind == STVert {
|
||||||
|
return n.vHSplit(0, bottom)
|
||||||
|
}
|
||||||
|
return n.hHSplit(bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) VSplit(right bool) uint64 {
|
||||||
|
if !n.IsLeaf() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if n.kind == STUndef {
|
||||||
|
n.kind = STHoriz
|
||||||
|
}
|
||||||
|
if n.kind == STVert {
|
||||||
|
return n.vVSplit(right)
|
||||||
|
}
|
||||||
|
return n.hVSplit(0, right)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Resize(w, h int) {
|
||||||
|
propW, propH := float64(w)/float64(n.W), float64(h)/float64(n.H)
|
||||||
|
x, y := n.X, n.Y
|
||||||
|
for _, c := range n.children {
|
||||||
|
cW := int(float64(c.W) * propW)
|
||||||
|
cH := int(float64(c.H) * propH)
|
||||||
|
c.Resize(cW, cH)
|
||||||
|
c.X = x
|
||||||
|
c.Y = y
|
||||||
|
if n.kind == STHoriz {
|
||||||
|
x += cW
|
||||||
|
} else {
|
||||||
|
y += cH
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n.W, n.H = w, h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Unsplit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) String() string {
|
||||||
|
var strf func(n *Node, ident int) string
|
||||||
|
strf = func(n *Node, ident int) string {
|
||||||
|
marker := "|"
|
||||||
|
if n.kind == STHoriz {
|
||||||
|
marker = "-"
|
||||||
|
}
|
||||||
|
str := fmt.Sprint(strings.Repeat("\t", ident), marker, n.View, n.id)
|
||||||
|
if n.IsLeaf() {
|
||||||
|
str += "🍁"
|
||||||
|
}
|
||||||
|
str += "\n"
|
||||||
|
for _, c := range n.children {
|
||||||
|
str += strf(c, ident+1)
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
return strf(n, 0)
|
||||||
|
}
|
||||||
16
cmd/micro/views/splits_test.go
Normal file
16
cmd/micro/views/splits_test.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package views
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHSplit(t *testing.T) {
|
||||||
|
root := NewRoot(0, 0, 80, 80)
|
||||||
|
n1 := root.VSplit(true)
|
||||||
|
root.GetNode(n1).VSplit(true)
|
||||||
|
root.GetNode(root.id).ResizeSplit(7)
|
||||||
|
root.Resize(120, 120)
|
||||||
|
|
||||||
|
fmt.Println(root.String())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user