PanelContainer: code cleanup
This commit is contained in:
parent
56b89c6079
commit
e7e459b16f
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user