Skip to content

Commit

Permalink
fixed #7030 - directional pane navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
Eugeny committed Oct 4, 2022
1 parent 48afeb9 commit 12f971d
Showing 1 changed file with 38 additions and 29 deletions.
67 changes: 38 additions & 29 deletions tabby-core/src/components/splitTab.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,44 +620,53 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
this.layout()
}

/**
* Moves focus in the given direction
*/
navigate (dir: SplitDirection): void {
if (!this.focusedTab) {
return
}
private getPaneRect (pane: BaseTabComponent): DOMRect {
const viewRef = this.viewRefs.get(pane)!
const element = viewRef.rootNodes[0] as HTMLElement
return element.getBoundingClientRect()
}

let rel: BaseTabComponent | SplitContainer = this.focusedTab
let parent = this.getParentOf(rel)
if (!parent) {
return
}
getNearestPaneInDirection (from: BaseTabComponent, direction: SplitDirection): BaseTabComponent {
const rect = this.getPaneRect(from)

const orientation = ['l', 'r'].includes(dir) ? 'h' : 'v'
let nearest: BaseTabComponent | null = null
let nearestDistance = Infinity

while (parent !== this.root && parent.orientation !== orientation) {
rel = parent
parent = this.getParentOf(rel)
if (!parent) {
return
}
}
let panes = this.getAllTabs().map(pane => ({ pane, rect: this.getPaneRect(pane) }))

if (parent.orientation !== orientation) {
return
if (direction === 'l') {
panes = panes.filter(pane => pane.rect.right <= rect.left)
} else if (direction === 'r') {
panes = panes.filter(pane => pane.rect.left >= rect.right)
} else if (direction === 't') {
panes = panes.filter(pane => pane.rect.bottom <= rect.top)
} else {
panes = panes.filter(pane => pane.rect.top >= rect.bottom)
}

const index = parent.children.indexOf(rel)
if (['l', 't'].includes(dir)) {
if (index > 0) {
this.focusAnyIn(parent.children[index - 1])
for (const pane of panes) {
if (pane.pane === from) {
continue
}
} else {
if (index < parent.children.length - 1) {
this.focusAnyIn(parent.children[index + 1])
const distance = Math.abs(rect.left + rect.width / 2 - pane.rect.left - pane.rect.width / 2) + Math.abs(rect.top + rect.height / 2 - pane.rect.top - pane.rect.height / 2)
if (distance < nearestDistance) {
nearest = pane.pane
nearestDistance = distance
}
}

return nearest ?? from
}

/**
* Moves focus in the given direction
*/
navigate (dir: SplitDirection): void {
if (!this.focusedTab) {
return
}

this.focus(this.getNearestPaneInDirection(this.focusedTab, dir))
}

navigateLinear (delta: number): void {
Expand Down

0 comments on commit 12f971d

Please sign in to comment.