Skip to content

Commit

Permalink
Use tab to cycle through edges #39
Browse files Browse the repository at this point in the history
  • Loading branch information
yishn committed Jan 23, 2020
1 parent 1f36afd commit 2ba1330
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/components/App.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {h, render, Component} from 'preact'
import copyText from 'copy-text-to-clipboard'
import * as diagram from '../diagram'
import {arrAdd} from '../helper'
import {arrAdd, lexicalCompare} from '../helper'

import Grid from './Grid'
import Properties from './Properties'
Expand Down Expand Up @@ -60,6 +60,41 @@ export default class App extends Component {
? null
: {selectedCell: arrAdd(state.selectedCell, arrowControl[evt.key])}
)
} else if (evt.key === 'Tab' && this.state.selectedArrow != null) {
// Neutralize browser focus mechanism and instead cycle through arrows

evt.preventDefault()
evt.stopPropagation()

let diff = evt.shiftKey ? -1 : 1

this.setState(state => {
if (state.selectedArrow == null) return

let {nodes, edges} = state.diagram
let length = edges.length
let findNodePositionById = id =>
nodes.find(node => node.id === id).position

// Constructing a natural tab order for edges

let indices = [...Array(length)]
.map((_, i) => [
i,
[edges[i].from, edges[i].to]
.map(findNodePositionById)
.reduce((sum, x) => arrAdd(sum, x), [0, 0])
])
.sort(([_, arr1], [__, arr2]) => lexicalCompare(arr1, arr2))
.map(([i, _]) => i)

let metaIndex = indices.indexOf(state.selectedArrow)

return {
selectedArrow:
indices[(((metaIndex + diff) % length) + length) % length]
}
})
} else if (evt.key === 'Enter') {
this.setState(state =>
state.cellEditMode || state.selectedArrow != null
Expand Down
14 changes: 14 additions & 0 deletions src/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ export function clamp(min, max, x) {
return Math.max(min, Math.min(max, x))
}

export function lexicalCompare(arr1, arr2) {
if (arr1.length != arr2.length) {
return arr1.length - arr2.length
} else if (arr1.length === 0) {
return 0
}

return arr1[0] < arr2[0]
? -1
: arr1[0] > arr2[0]
? 1
: lexicalCompare(arr1.slice(1), arr2.slice(1))
}

export function arrEquals(a, b) {
return a.length === b.length && a.every((x, i) => x === b[i])
}
Expand Down

0 comments on commit 2ba1330

Please sign in to comment.