浏览代码

Layout fixes

Johan Rong 1 周之前
父节点
当前提交
119449de64
共有 4 个文件被更改,包括 114 次插入8 次删除
  1. 6 0
      internal/editor/action.go
  2. 28 4
      internal/editor/draw.go
  3. 9 0
      internal/editor/layout.go
  4. 71 4
      internal/layout/layout.go

+ 6 - 0
internal/editor/action.go

@@ -613,6 +613,12 @@ func DefaultActionManager() ActionManager {
 			Callback: func(m *Model, args []string) {
 				m.Mode = ModeNormal
 				m.LM.ActiveIdx = i
+
+				if bufIdx := m.LM.GetActiveBufferIdx(); bufIdx >= 0 && bufIdx < len(m.BM.Buffers) {
+					m.BM.CurrentIdx = bufIdx
+				} else if len(m.BM.Buffers) > 0 {
+					m.BM.CurrentIdx = 0
+				}
 			},
 		})
 	}

+ 28 - 4
internal/editor/draw.go

@@ -8,6 +8,7 @@ import (
 	"strings"
 	"strconv"
 	"github.com/gdamore/tcell/v3/color"
+	"slices"
 )
 
 func (m *Model) Draw() {
@@ -54,9 +55,23 @@ func (m *Model) DrawPalette(rect layout.Rect) {
 		splitStr = "V"
 	}
 	m.Screen.PutStrStyled(rect.Width - (len(modeStr) + 1) - 5, rect.Y, splitStr, m.Style.Background(color.Black))
+
+	populatedWorkspaces := []string{strconv.Itoa(m.LM.ActiveIdx + 1)}
+	for workspaceIdx, workspace := range m.LM.Workspaces {
+		if workspaceIdx == m.LM.ActiveIdx {
+			continue
+		}
+
+		if !workspace.IsEmpty() {
+			populatedWorkspaces = append(populatedWorkspaces, strconv.Itoa(workspaceIdx + 1))
+		}
+	}
+	slices.Sort(populatedWorkspaces)
+	workspacesStr := strings.Join(populatedWorkspaces, " ")
+	m.Screen.PutStrStyled(1,  rect.Y, workspacesStr, m.Style.Background(color.Black))
 	
-	logStr := m.DebugLog + ", " + strings.Join(m.AM.CM.Recorded, "+") + ", " + strconv.FormatBool(m.AM.CM.Recording)
-	m.Screen.PutStrStyled(1, rect.Y, logStr, m.Style.Background(color.Black))
+	//logStr := m.DebugLog + ", " + strings.Join(m.AM.CM.Recorded, "+") + ", " + strconv.FormatBool(m.AM.CM.Recording)
+	//m.Screen.PutStrStyled(1, rect.Y, logStr, m.Style.Background(color.Black))
 
 	if m.Mode == ModePalette {
 		m.Screen.PutStrStyled(0, rect.Y + 1, m.BM.PaletteBuffer.String(), m.Style)
@@ -126,11 +141,16 @@ func (m *Model) DrawContainer(c *layout.Container, rect layout.Rect) {
 
 func (m *Model) DrawContainerTabs(c *layout.ContainerBuffers, rect layout.Rect) {
 	tabs := []string{}
+	activeTabIdx := -1
 	for _, bufIdx := range c.Buffers {
 		if bufIdx >= len(m.BM.Buffers) {
 			continue
 		}
 
+		if c.ActiveIdx < len(c.Buffers) && c.Buffers[c.ActiveIdx] == bufIdx {
+			activeTabIdx = len(tabs)
+		}
+
 		buf := m.BM.Buffers[bufIdx]
 		if buf.Path == "" {
 			tabs = append(tabs, "Buffer " + strconv.Itoa(bufIdx))
@@ -140,13 +160,17 @@ func (m *Model) DrawContainerTabs(c *layout.ContainerBuffers, rect layout.Rect)
 	}
 
 	length := 0
-	for _, tab := range tabs {
+	for i, tab := range tabs {
 		if length + len(tab) + 2 > rect.Width {
 			m.Screen.PutStrStyled(rect.X + length, rect.Y, ">", m.Style.Foreground(color.White))
 			return
 		}
 
-		m.Screen.PutStrStyled(rect.X + length, rect.Y, tab, m.Style.Background(color.Black).Foreground(color.White))
+		style := m.Style.Background(color.Black).Foreground(color.DarkGray)
+		if i == activeTabIdx {
+			style = style.Foreground(color.White)
+		}
+		m.Screen.PutStrStyled(rect.X + length, rect.Y, tab, style)
 		length += len(tab) + 1
 	}
 }

+ 9 - 0
internal/editor/layout.go

@@ -37,6 +37,15 @@ func (m *Model) RemoveActiveBuffer() {
     }
 
     removedIdx := m.BM.CurrentIdx
+    if removedIdx < 0 || removedIdx >= len(m.BM.Buffers) {
+        return
+    }
+
+    ws, ok := m.LM.Workspaces[m.LM.ActiveIdx]
+    if !ok || !ws.RootContainer.ContainsBufferIdx(removedIdx) {
+        return
+    }
+
     newActiveIdx := m.LM.RemoveActiveBufferAndReindex(removedIdx)
     m.BM.Buffers = slices.Delete(m.BM.Buffers, removedIdx, removedIdx+1)
 

+ 71 - 4
internal/layout/layout.go

@@ -6,10 +6,14 @@ type LayoutManager struct {
 	CurrentSplit SplitType
 }
 
-type Workspace struct {
+type Workspace struct { // TODO: this is not necessary..
 	RootContainer Container
 }
 
+func (w Workspace) IsEmpty() bool {
+    return !isPopulated(w.RootContainer)
+}
+
 type SplitType int
 const (
 	SplitHorizontal SplitType = iota
@@ -19,10 +23,11 @@ const (
 func (s *SplitType) SetOpposite()  SplitType{
 	if *s == SplitHorizontal {
 		*s = SplitVertical
+        return SplitHorizontal
 	} else {
 		*s = SplitHorizontal
+        return SplitVertical
 	}
-	return *s
 }
 
 type ContainerNode interface {
@@ -47,7 +52,7 @@ func (Container) isContainerNode() {}
 func NewLayoutManager() LayoutManager {
 	return LayoutManager{
 		Workspaces: map[int]Workspace{0: NewWorkspace()},
-		CurrentSplit: SplitVertical,
+		CurrentSplit: SplitHorizontal,
 	}
 }
 
@@ -63,7 +68,7 @@ func NewContainerEmpty() Container {
             nil,
             nil,
         },
-        Split:          SplitVertical,
+        Split:          SplitHorizontal,
         ActiveChildIdx: 0,
     }
 }
@@ -233,9 +238,71 @@ func (c Container) RemoveActive() (ContainerNode, bool) {
     }
 }
 
+func (c Container) ContainsBufferIdx(target int) bool {
+    switch child := c.Children[c.ActiveChildIdx].(type) {
+    case ContainerBuffers:
+        for _, idx := range child.Buffers {
+            if idx == target {
+                return true
+            }
+        }
+    case Container:
+        if child.ContainsBufferIdx(target) {
+            return true
+        }
+    }
+
+    for _, node := range c.Children {
+        switch child := node.(type) {
+        case ContainerBuffers:
+            for _, idx := range child.Buffers {
+                if idx == target {
+                    return true
+                }
+            }
+        case Container:
+            if child.ContainsBufferIdx(target) {
+                return true
+            }
+        }
+    }
+
+    return false
+}
+
+func (c *Container) ActivateBufferIdx(target int) bool {
+    for i, child := range c.Children {
+        switch n := child.(type) {
+        case ContainerBuffers:
+            for j, idx := range n.Buffers {
+                if idx == target {
+                    c.ActiveChildIdx = i
+                    n.ActiveIdx = j
+                    c.Children[i] = n
+                    return true
+                }
+            }
+        case Container:
+            if n.ActivateBufferIdx(target) {
+                c.Children[i] = n
+                return true
+            }
+        }
+    }
+    return false
+}
+
 func (lm *LayoutManager) RemoveActiveBufferAndReindex(removedIdx int) int {
     ws := lm.Workspaces[lm.ActiveIdx]
 
+    if !ws.RootContainer.ContainsBufferIdx(removedIdx) {
+        return ws.RootContainer.GetActiveBufferIdx()
+    }
+
+    if !ws.RootContainer.ActivateBufferIdx(removedIdx) {
+        return ws.RootContainer.GetActiveBufferIdx()
+    }
+
     newRoot, isEmpty := ws.RootContainer.RemoveActive()
     if newRoot == nil || isEmpty {
         ws.RootContainer = NewContainerEmpty()