mirror of
https://github.com/mum4k/termdash.git
synced 2025-04-25 13:48:50 +08:00
Ability to focus the previous container using keyboard.
This commit is contained in:
parent
1fd4b044cf
commit
e4edc8f15a
@ -278,8 +278,11 @@ func (c *Container) updateFocusFromMouse(m *terminalapi.Mouse) {
|
||||
// changes the focused container.
|
||||
// Caller must hold c.mu.
|
||||
func (c *Container) updateFocusFromKeyboard(k *terminalapi.Keyboard) {
|
||||
if c.opts.global.keyFocusNext != nil && *c.opts.global.keyFocusNext == k.Key {
|
||||
switch {
|
||||
case c.opts.global.keyFocusNext != nil && *c.opts.global.keyFocusNext == k.Key:
|
||||
c.focusTracker.next()
|
||||
case c.opts.global.keyFocusPrevious != nil && *c.opts.global.keyFocusPrevious == k.Key:
|
||||
c.focusTracker.previous()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,20 +82,20 @@ func (ft *focusTracker) setActive(c *Container) {
|
||||
func (ft *focusTracker) next() {
|
||||
var (
|
||||
errStr string
|
||||
first *Container
|
||||
cont *Container
|
||||
firstCont *Container
|
||||
nextCont *Container
|
||||
focusNext bool
|
||||
)
|
||||
postOrder(rootCont(ft.container), &errStr, visitFunc(func(c *Container) error {
|
||||
if cont != nil {
|
||||
preOrder(rootCont(ft.container), &errStr, visitFunc(func(c *Container) error {
|
||||
if nextCont != nil {
|
||||
// Already found the next container, nothing to do.
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.isLeaf() && first == nil {
|
||||
if c.isLeaf() && firstCont == nil {
|
||||
// Remember the first eligible container in case we "wrap" over,
|
||||
// i.e. finish the iteration before finding the next container.
|
||||
first = c
|
||||
firstCont = c
|
||||
}
|
||||
|
||||
if ft.container == c {
|
||||
@ -106,18 +106,49 @@ func (ft *focusTracker) next() {
|
||||
}
|
||||
|
||||
if c.isLeaf() && focusNext {
|
||||
cont = c
|
||||
nextCont = c
|
||||
}
|
||||
return nil
|
||||
}))
|
||||
|
||||
if cont == nil && first != nil {
|
||||
if nextCont == nil && firstCont != nil {
|
||||
// If the traversal finishes without finding the next container, move
|
||||
// focus back to the first container.
|
||||
cont = first
|
||||
nextCont = firstCont
|
||||
}
|
||||
if cont != nil {
|
||||
ft.setActive(cont)
|
||||
if nextCont != nil {
|
||||
ft.setActive(nextCont)
|
||||
}
|
||||
}
|
||||
|
||||
// previous moves focus to the previous container.
|
||||
func (ft *focusTracker) previous() {
|
||||
var (
|
||||
errStr string
|
||||
prevCont *Container
|
||||
lastCont *Container
|
||||
visitedCurr bool
|
||||
)
|
||||
preOrder(rootCont(ft.container), &errStr, visitFunc(func(c *Container) error {
|
||||
if ft.container == c {
|
||||
visitedCurr = true
|
||||
}
|
||||
|
||||
if c.isLeaf() {
|
||||
if !visitedCurr {
|
||||
// Remember the last eligible container closest to the one
|
||||
// currently focused.
|
||||
prevCont = c
|
||||
}
|
||||
lastCont = c
|
||||
}
|
||||
return nil
|
||||
}))
|
||||
|
||||
if prevCont != nil {
|
||||
ft.setActive(prevCont)
|
||||
} else if lastCont != nil {
|
||||
ft.setActive(lastCont)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,6 +624,120 @@ func TestFocusTrackerNextAndPrevious(t *testing.T) {
|
||||
wantFocused: contLocLeft,
|
||||
wantProcessed: 5,
|
||||
},
|
||||
{
|
||||
desc: "keyPrevious does nothing when only root exists",
|
||||
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||
return New(
|
||||
ft,
|
||||
KeyFocusPrevious(keyPrevious),
|
||||
)
|
||||
},
|
||||
events: []*terminalapi.Keyboard{
|
||||
{Key: keyPrevious},
|
||||
},
|
||||
wantFocused: contLocRoot,
|
||||
wantProcessed: 1,
|
||||
},
|
||||
{
|
||||
desc: "keyPrevious focuses the last container",
|
||||
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||
return New(
|
||||
ft,
|
||||
SplitVertical(
|
||||
Left(),
|
||||
Right(),
|
||||
),
|
||||
KeyFocusPrevious(keyPrevious),
|
||||
)
|
||||
},
|
||||
events: []*terminalapi.Keyboard{
|
||||
{Key: keyPrevious},
|
||||
},
|
||||
wantFocused: contLocRight,
|
||||
wantProcessed: 1,
|
||||
},
|
||||
{
|
||||
desc: "two keyPrevious presses focuses the first container",
|
||||
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||
return New(
|
||||
ft,
|
||||
SplitVertical(
|
||||
Left(),
|
||||
Right(),
|
||||
),
|
||||
KeyFocusPrevious(keyPrevious),
|
||||
)
|
||||
},
|
||||
events: []*terminalapi.Keyboard{
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
},
|
||||
wantFocused: contLocLeft,
|
||||
wantProcessed: 2,
|
||||
},
|
||||
{
|
||||
desc: "three keyPrevious presses focuses the second container again",
|
||||
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||
return New(
|
||||
ft,
|
||||
SplitVertical(
|
||||
Left(),
|
||||
Right(),
|
||||
),
|
||||
KeyFocusPrevious(keyPrevious),
|
||||
)
|
||||
},
|
||||
events: []*terminalapi.Keyboard{
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
},
|
||||
wantFocused: contLocRight,
|
||||
wantProcessed: 3,
|
||||
},
|
||||
{
|
||||
desc: "four keyPrevious presses focuses the first container again",
|
||||
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||
return New(
|
||||
ft,
|
||||
SplitVertical(
|
||||
Left(),
|
||||
Right(),
|
||||
),
|
||||
KeyFocusPrevious(keyPrevious),
|
||||
)
|
||||
},
|
||||
events: []*terminalapi.Keyboard{
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
},
|
||||
wantFocused: contLocLeft,
|
||||
wantProcessed: 4,
|
||||
},
|
||||
{
|
||||
desc: "five keyPrevious presses focuses the second container again",
|
||||
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||
return New(
|
||||
ft,
|
||||
SplitVertical(
|
||||
Left(),
|
||||
Right(),
|
||||
),
|
||||
KeyFocusPrevious(keyPrevious),
|
||||
)
|
||||
},
|
||||
events: []*terminalapi.Keyboard{
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
{Key: keyPrevious},
|
||||
},
|
||||
wantFocused: contLocRight,
|
||||
wantProcessed: 5,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
|
Loading…
x
Reference in New Issue
Block a user