fix: fs tree min width to be enough to not have line splits
This commit is contained in:
+33
-13
@@ -73,18 +73,23 @@ type PerformActionMsg struct {
|
|||||||
|
|
||||||
// ==================== FsNode definition ====================
|
// ==================== FsNode definition ====================
|
||||||
type FsTree struct {
|
type FsTree struct {
|
||||||
Root *FsNode
|
Root *FsNode
|
||||||
lines map[int]*FsNode // flattened view of nodes for easy line access, map so that I can handle blank padding
|
lines map[int]*FsNode // flattened view of nodes for easy line access, map so that I can handle blank padding
|
||||||
SelectedNode *FsNode
|
SelectedNode *FsNode
|
||||||
hoveredNode *FsNode
|
hoveredNode *FsNode
|
||||||
ErrMsg string
|
ErrMsg string
|
||||||
height int
|
height int
|
||||||
width int
|
width int
|
||||||
viewStart int
|
viewStart int
|
||||||
viewEnd int
|
viewEnd int
|
||||||
totalLines int
|
totalLines int
|
||||||
oldSelected *FsNode
|
oldSelected *FsNode
|
||||||
startOffset int
|
startOffset int
|
||||||
|
maxContentWidth int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *FsTree) ContentWidth() int {
|
||||||
|
return t.maxContentWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Bubble Tea Interface Implementation ====================
|
// ==================== Bubble Tea Interface Implementation ====================
|
||||||
@@ -92,13 +97,18 @@ func (t *FsTree) Init() tea.Cmd {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ContentSizeChangeMsg struct{}
|
||||||
|
|
||||||
func (t *FsTree) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (t *FsTree) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
switch m := msg.(type) {
|
switch m := msg.(type) {
|
||||||
case PerformActionMsg:
|
case PerformActionMsg:
|
||||||
err := t.PerformAction(m.Action, m.Name)
|
err := t.PerformAction(m.Action, m.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.ErrMsg = err.Error()
|
t.ErrMsg = err.Error()
|
||||||
|
return t, nil
|
||||||
}
|
}
|
||||||
|
// todo: standardise these messages
|
||||||
|
return t, func() tea.Msg { return ContentSizeChangeMsg{} }
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
t.width = m.Width
|
t.width = m.Width
|
||||||
t.height = m.Height
|
t.height = m.Height
|
||||||
@@ -446,6 +456,7 @@ func (t *FsTree) renderNode(node *FsNode, depth int, builder *strings.Builder) {
|
|||||||
|
|
||||||
// builds a cache of line num to rendered node in view
|
// builds a cache of line num to rendered node in view
|
||||||
func (t *FsTree) BuildLines() {
|
func (t *FsTree) BuildLines() {
|
||||||
|
t.maxContentWidth = 0
|
||||||
t.lines = make(map[int]*FsNode)
|
t.lines = make(map[int]*FsNode)
|
||||||
line := -1
|
line := -1
|
||||||
flatTree := make([]*FsNode, 0)
|
flatTree := make([]*FsNode, 0)
|
||||||
@@ -461,7 +472,7 @@ func (t *FsTree) BuildLines() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: isn't meant to be used directly
|
// isn't meant to be used directly
|
||||||
func (t *FsTree) buildLinesRec(node *FsNode, depth int, currentLine *int, flatTree *[]*FsNode) {
|
func (t *FsTree) buildLinesRec(node *FsNode, depth int, currentLine *int, flatTree *[]*FsNode) {
|
||||||
if node == nil {
|
if node == nil {
|
||||||
return
|
return
|
||||||
@@ -475,6 +486,14 @@ func (t *FsTree) buildLinesRec(node *FsNode, depth int, currentLine *int, flatTr
|
|||||||
*flatTree = append(*flatTree, node)
|
*flatTree = append(*flatTree, node)
|
||||||
(*currentLine)++
|
(*currentLine)++
|
||||||
|
|
||||||
|
// update max width
|
||||||
|
if depth > 0 {
|
||||||
|
w := depth + 2 + len(node.FileName())
|
||||||
|
if w > t.maxContentWidth {
|
||||||
|
t.maxContentWidth = w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if node.Expanded {
|
if node.Expanded {
|
||||||
for _, child := range node.Children {
|
for _, child := range node.Children {
|
||||||
t.buildLinesRec(child, depth+1, currentLine, flatTree)
|
t.buildLinesRec(child, depth+1, currentLine, flatTree)
|
||||||
@@ -539,6 +558,7 @@ func (t *FsTree) CreateNode(folder *FsNode, name string, nodeType FsNodeType) er
|
|||||||
}
|
}
|
||||||
t.SelectedNode = newNode
|
t.SelectedNode = newNode
|
||||||
t.BuildLines()
|
t.BuildLines()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
// layout constants
|
// layout constants
|
||||||
const (
|
const (
|
||||||
minFsTreeWidth = 5
|
|
||||||
minNoteViewWidth = 10
|
minNoteViewWidth = 10
|
||||||
dividerWidth = 1
|
dividerWidth = 1
|
||||||
dragHitArea = 2 // +/- chars around divider
|
dragHitArea = 2 // +/- chars around divider
|
||||||
@@ -11,9 +10,9 @@ const (
|
|||||||
fsTreeWidthPercent = 15
|
fsTreeWidthPercent = 15
|
||||||
)
|
)
|
||||||
|
|
||||||
// calculateLayout computes the widths for the file tree and note view
|
// getUpdatedWindowSizes computes the widths for the file tree and note view
|
||||||
// based on the terminal dimensions and the desired tree width.
|
// based on the terminal dimensions and the desired tree width.
|
||||||
func calculateLayout(totalWidth, requestedTreeWidth int) (treeWidth, noteWidth int) {
|
func getUpdatedWindowSizes(totalWidth, requestedTreeWidth, minTreeWidth int) (treeWidth, noteWidth int) {
|
||||||
treeWidth = requestedTreeWidth
|
treeWidth = requestedTreeWidth
|
||||||
|
|
||||||
if treeWidth == 0 {
|
if treeWidth == 0 {
|
||||||
@@ -26,8 +25,9 @@ func calculateLayout(totalWidth, requestedTreeWidth int) (treeWidth, noteWidth i
|
|||||||
if treeWidth > maxTreeWidth {
|
if treeWidth > maxTreeWidth {
|
||||||
treeWidth = maxTreeWidth
|
treeWidth = maxTreeWidth
|
||||||
}
|
}
|
||||||
if treeWidth < minFsTreeWidth {
|
|
||||||
treeWidth = minFsTreeWidth
|
if treeWidth < minTreeWidth {
|
||||||
|
treeWidth = minTreeWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
noteWidth = max(0, totalWidth-treeWidth-dividerWidth)
|
noteWidth = max(0, totalWidth-treeWidth-dividerWidth)
|
||||||
|
|||||||
@@ -79,7 +79,11 @@ func (m *model) loadTreeCmd(path string) tea.Cmd {
|
|||||||
func (m *model) layout(width, height int) {
|
func (m *model) layout(width, height int) {
|
||||||
m.terminalWidth = width
|
m.terminalWidth = width
|
||||||
m.terminalHeight = height
|
m.terminalHeight = height
|
||||||
m.fsTreeWidth, m.noteViewWidth = calculateLayout(width, m.fsTreeWidth)
|
minW := 0
|
||||||
|
if m.tree != nil {
|
||||||
|
minW = m.tree.ContentWidth()
|
||||||
|
}
|
||||||
|
m.fsTreeWidth, m.noteViewWidth = getUpdatedWindowSizes(width, m.fsTreeWidth, minW)
|
||||||
|
|
||||||
h := height
|
h := height
|
||||||
if m.showStatusBar || m.inputMode {
|
if m.showStatusBar || m.inputMode {
|
||||||
@@ -120,6 +124,8 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
case treeLoadedMsg:
|
case treeLoadedMsg:
|
||||||
m.tree = msg.tree
|
m.tree = msg.tree
|
||||||
m.loading = false
|
m.loading = false
|
||||||
|
m.fsTreeWidth = m.tree.ContentWidth()
|
||||||
|
m.fsTreeWidth, m.noteViewWidth = getUpdatedWindowSizes(m.terminalWidth, m.fsTreeWidth, m.tree.ContentWidth())
|
||||||
_, cmd := m.tree.Update(tea.WindowSizeMsg{
|
_, cmd := m.tree.Update(tea.WindowSizeMsg{
|
||||||
Height: m.contentHeight,
|
Height: m.contentHeight,
|
||||||
Width: m.fsTreeWidth,
|
Width: m.fsTreeWidth,
|
||||||
@@ -149,6 +155,12 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return m, cmd
|
return m, cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case fstree.ContentSizeChangeMsg:
|
||||||
|
// layout update needed, sent when a new note is created
|
||||||
|
m.fsTreeWidth, m.noteViewWidth = getUpdatedWindowSizes(m.terminalWidth, m.tree.ContentWidth(), m.tree.ContentWidth())
|
||||||
|
// TODO: this can be simplified a lot
|
||||||
|
return m, m.resizeChildren() // batches two updates
|
||||||
|
|
||||||
case fstree.RequestInputMsg:
|
case fstree.RequestInputMsg:
|
||||||
m.inputMode = true
|
m.inputMode = true
|
||||||
m.pendingAction = msg.Action
|
m.pendingAction = msg.Action
|
||||||
@@ -250,7 +262,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.isHoveringDivider = isHoveringDivider(msg.X, m.fsTreeWidth)
|
m.isHoveringDivider = isHoveringDivider(msg.X, m.fsTreeWidth)
|
||||||
|
|
||||||
if m.isDragging {
|
if m.isDragging {
|
||||||
m.fsTreeWidth, m.noteViewWidth = calculateLayout(m.terminalWidth, msg.X)
|
m.fsTreeWidth, m.noteViewWidth = getUpdatedWindowSizes(m.terminalWidth, msg.X, m.tree.ContentWidth())
|
||||||
|
|
||||||
// Update children with new sizes
|
// Update children with new sizes
|
||||||
return m, m.resizeChildren()
|
return m, m.resizeChildren()
|
||||||
|
|||||||
Reference in New Issue
Block a user