PanelContainer: code cleanup

This commit is contained in:
Luke I. Wilson 2021-04-07 14:55:20 -05:00
parent 56b89c6079
commit e7e459b16f
2 changed files with 34 additions and 50 deletions

View File

@ -6,10 +6,10 @@ import "github.com/gdamore/tcell/v2"
type PanelKind uint8 type PanelKind uint8
const ( const (
PanelKindEmpty PanelKind = iota PanelKindEmpty PanelKind = iota
PanelKindSingle // Single item. Takes up all available space PanelKindSingle // Single item. Takes up all available space
PanelKindSplitVert // Items are above or below eachother PanelKindSplitVert // Items are above or below eachother
PanelKindSplitHor // Items are left or right of eachother PanelKindSplitHor // Items are left or right of eachother
) )
// A Panel represents a container for a split view between two items. The Kind // A Panel represents a container for a split view between two items. The Kind

View File

@ -22,10 +22,10 @@ type PanelContainer struct {
func NewPanelContainer(theme *Theme) *PanelContainer { func NewPanelContainer(theme *Theme) *PanelContainer {
root := &Panel{Kind: PanelKindEmpty} root := &Panel{Kind: PanelKindEmpty}
return &PanelContainer{ return &PanelContainer{
root: root, root: root,
floating: make([]*Panel, 0, 3), floating: make([]*Panel, 0, 3),
selected: &root, selected: &root,
theme: theme, theme: theme,
} }
} }
@ -41,6 +41,18 @@ func (c *PanelContainer) ClearSelected() Component {
return item return item
} }
// changeSelected sets c.selected to `new`. It also refocuses the Panel.
// Prefer to use this as opposed to performing the instructions manually.
func (c *PanelContainer) changeSelected(new **Panel) {
if c.focused {
(*c.selected).SetFocused(false)
}
c.selected = new
if c.focused {
(*c.selected).SetFocused(true)
}
}
// DeleteSelected deletes the selected Panel and returns its child Component. // DeleteSelected deletes the selected Panel and returns its child Component.
// If the selected Panel is the root Panel, ClearSelected() is called, instead. // If the selected Panel is the root Panel, ClearSelected() is called, instead.
func (c *PanelContainer) DeleteSelected() Component { func (c *PanelContainer) DeleteSelected() Component {
@ -55,10 +67,6 @@ func (c *PanelContainer) DeleteSelected() Component {
item := (**c.selected).Left item := (**c.selected).Left
p := (**c.selected).Parent p := (**c.selected).Parent
if c.focused {
(*c.selected).SetFocused(false) // Unfocus item
}
if p != nil { if p != nil {
if *c.selected == (*p).Left { // If we're deleting the parent's Left if *c.selected == (*p).Left { // If we're deleting the parent's Left
(*p).Left = (*p).Right (*p).Left = (*p).Right
@ -75,25 +83,22 @@ func (c *PanelContainer) DeleteSelected() Component {
} else { } else {
(*p).Kind = PanelKindEmpty (*p).Kind = PanelKindEmpty
} }
c.selected = &p
c.changeSelected(&p)
(*p).UpdateSplits() (*p).UpdateSplits()
} else if c.floatingMode { // Deleting a floating Panel without a parent } else if c.floatingMode { // Deleting a floating Panel without a parent
c.floating[0] = nil c.floating[0] = nil
copy(c.floating, c.floating[1:]) // Shift items to front copy(c.floating, c.floating[1:]) // Shift items to front
c.floating = c.floating[:len(c.floating)-1] // Shrink slice's len by one c.floating = c.floating[:len(c.floating)-1] // Shrink slice's len by one
if len(c.floating) <= 0 { if len(c.floating) <= 0 {
c.SetFloatingFocused(false) c.SetFloatingFocused(false)
} else { } else {
c.selected = &c.floating[0] c.changeSelected(&c.floating[0])
} }
} else { } else {
panic("Panel does not have parent and is not floating") panic("Panel does not have parent and is not floating")
} }
if c.focused {
(*c.selected).SetFocused(c.focused)
}
return item return item
} }
@ -129,14 +134,8 @@ func (c *PanelContainer) splitSelectedWithPanel(kind SplitKind, panel *Panel) {
(*c.selected).UpdateSplits() (*c.selected).UpdateSplits()
// Change selected from parent to the previously selected Panel on the Left // Change selected from parent to the previously selected Panel on the Left
if c.focused {
(*c.selected).SetFocused(false)
}
panel = (**c.selected).Left.(*Panel) panel = (**c.selected).Left.(*Panel)
c.selected = &panel c.changeSelected(&panel)
if c.focused {
(*c.selected).SetFocused(c.focused)
}
} }
// SplitSelected splits the selected Panel with the given Component `item`. // SplitSelected splits the selected Panel with the given Component `item`.
@ -197,25 +196,13 @@ func (c *PanelContainer) GetFloatingFocused() bool {
func (c *PanelContainer) SetFloatingFocused(v bool) bool { func (c *PanelContainer) SetFloatingFocused(v bool) bool {
if v { if v {
if len(c.floating) > 0 { if len(c.floating) > 0 {
if c.focused {
(*c.selected).SetFocused(false) // Unfocus in-tree window
}
c.lastNonFloatingSelected = c.selected c.lastNonFloatingSelected = c.selected
c.selected = &c.floating[0] c.changeSelected(&c.floating[0])
if c.focused {
(*c.selected).SetFocused(true)
}
c.floatingMode = true c.floatingMode = true
return true return true
} }
} else { } else {
if c.focused { c.changeSelected(c.lastNonFloatingSelected)
(*c.selected).SetFocused(false) // Unfocus floating window
}
c.selected = c.lastNonFloatingSelected
if c.focused {
(*c.selected).SetFocused(true) // Focus in-tree window
}
c.floatingMode = false c.floatingMode = false
} }
return false return false
@ -232,14 +219,12 @@ func (c *PanelContainer) FloatSelected() {
return return
} }
panel := *c.selected
c.DeleteSelected() c.DeleteSelected()
(**c.selected).Parent = nil
(*c.selected).UpdateSplits() (*c.selected).UpdateSplits()
panel.Parent = nil
panel.UpdateSplits()
c.floating = append(c.floating, panel) c.floating = append(c.floating, *c.selected)
c.raiseFloating(len(c.floating)-1) c.raiseFloating(len(c.floating) - 1)
} }
// UnfloatSelected moves any selected floating Panel to the normal tree that is // UnfloatSelected moves any selected floating Panel to the normal tree that is
@ -257,10 +242,9 @@ func (c *PanelContainer) UnfloatSelected(kind SplitKind) bool {
return false return false
} }
panel := *c.selected
c.DeleteSelected() c.DeleteSelected()
c.SetFloatingFocused(false) c.SetFloatingFocused(false)
c.splitSelectedWithPanel(kind, panel) c.splitSelectedWithPanel(kind, *c.selected)
// Try to return to floating focus // Try to return to floating focus
return c.SetFloatingFocused(true) return c.SetFloatingFocused(true)
@ -270,7 +254,7 @@ func (c *PanelContainer) selectNext(rightMost bool) {
var nextIsIt bool var nextIsIt bool
c.root.EachLeaf(rightMost, func(p *Panel) bool { c.root.EachLeaf(rightMost, func(p *Panel) bool {
if nextIsIt { if nextIsIt {
c.selected = &p c.changeSelected(&p)
nextIsIt = false nextIsIt = false
return true return true
} else if p == *c.selected { } else if p == *c.selected {
@ -284,7 +268,7 @@ func (c *PanelContainer) selectNext(rightMost bool) {
// of the tree. We need to wrap around to the first leaf. // of the tree. We need to wrap around to the first leaf.
if nextIsIt { if nextIsIt {
// This gets the first leaf in left-most or right-most order // This gets the first leaf in left-most or right-most order
c.root.EachLeaf(rightMost, func(p *Panel) bool { c.selected = &p; return true }) c.root.EachLeaf(rightMost, func(p *Panel) bool { c.changeSelected(&p); return true })
} }
} }
@ -298,7 +282,7 @@ func (c *PanelContainer) SelectPrev() {
func (c *PanelContainer) Draw(s tcell.Screen) { func (c *PanelContainer) Draw(s tcell.Screen) {
c.root.Draw(s) c.root.Draw(s)
for i := len(c.floating)-1; i >= 0; i-- { for i := len(c.floating) - 1; i >= 0; i-- {
c.floating[i].Draw(s) c.floating[i].Draw(s)
} }
} }