Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touch controls #57

Merged
merged 6 commits into from Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion css/master.css
Expand Up @@ -87,7 +87,12 @@ a, img {
border-left: none;
overflow: hidden;
white-space: nowrap;
transition: background-color .2s;
transition: background-color .2s, box-shadow .2s, transform .2s;
}
.grid-cell.moving {
background: white;
box-shadow: 0 5px 1rem rgba(0, 0, 0, .3);
transform: scale(1.1);
}
.grid-cell.selected {
background: #eee;
Expand Down
4 changes: 2 additions & 2 deletions src/components/CodeBox.js
Expand Up @@ -14,7 +14,7 @@ export default class CodeBox extends Component {
}
}

handleOverlayMouseDown = evt => {
handleOverlayPointerDown = evt => {
if (evt.target !== evt.currentTarget) return

let {onClose = () => {}} = this.props
Expand All @@ -35,7 +35,7 @@ export default class CodeBox extends Component {
<section
id="modal-overlay"
class={classNames({show})}
onMouseDown={this.handleOverlayMouseDown}
onPointerDown={this.handleOverlayPointerDown}
>
<section class="modal-box code-box">
<textarea
Expand Down
76 changes: 54 additions & 22 deletions src/components/Grid.js
Expand Up @@ -12,6 +12,7 @@ export default class Grid extends Component {
width: 0,
height: 0,
phantomArrow: null,
movingNodePosition: null,
cellTypesetSizes: {}
}
}
Expand All @@ -21,8 +22,8 @@ export default class Grid extends Component {

window.addEventListener('resize', () => this.updateSize())

document.addEventListener('mouseup', () => {
this.mouseDown = null
document.addEventListener('pointerup', evt => {
this.pointerDown = null

let {phantomArrow} = this.state

Expand Down Expand Up @@ -71,27 +72,32 @@ export default class Grid extends Component {

this.setState({phantomArrow: null})
}

this.setState({
movingNodePosition: null
})
})

document.addEventListener('mousemove', evt => {
if (this.mouseDown == null) return
document.addEventListener('pointermove', evt => {
if (this.pointerDown == null) return

evt.preventDefault()

this.pointerDown.moved = true
let newPosition = this.coordsToPosition([evt.clientX, evt.clientY])

if (this.mouseDown.mode === 'pan') {
let oldEvt = this.mouseDown.evt
if (this.pointerDown.mode === 'pan') {
let oldEvt = this.pointerDown.evt
let oldMouseCoords = [oldEvt.clientX, oldEvt.clientY]
let newMouseCoords = [evt.clientX, evt.clientY]
let movement = arrSubtract(newMouseCoords, oldMouseCoords)
let {onPan = () => {}} = this.props

onPan({
cameraPosition: arrSubtract(this.mouseDown.cameraPosition, movement)
cameraPosition: arrSubtract(this.pointerDown.cameraPosition, movement)
})
} else if (this.mouseDown.mode === 'move') {
let {nodeIndex} = this.mouseDown
} else if (this.pointerDown.mode === 'move') {
let {nodeIndex} = this.pointerDown
if (nodeIndex < 0) return

let existingNode = this.props.data.nodes.find(n =>
Expand All @@ -111,8 +117,12 @@ export default class Grid extends Component {
edges: this.props.data.edges
}
})
} else if (this.mouseDown.mode === 'arrow') {
let {position: from} = this.mouseDown

this.setState({
movingNodePosition: newPosition
})
} else if (this.pointerDown.mode === 'arrow') {
let {position: from} = this.pointerDown
let to = newPosition

if (
Expand Down Expand Up @@ -207,7 +217,7 @@ export default class Grid extends Component {
onPan({cameraPosition: [cx, cy]})
}

handleNodeMouseDown = evt => {
handleNodePointerDown = evt => {
if (evt.button !== 0) return

let {cameraPosition} = this.props
Expand All @@ -217,17 +227,31 @@ export default class Grid extends Component {
)
let node = this.props.data.nodes[nodeIndex]

this.mouseDown = {
evt.position = position

this.pointerDown = {
evt,
cameraPosition,
position,
nodeIndex,
node,
mode: this.props.mode
}

setTimeout(() => {
// After pointer hold for 1 sec, switch to move mode

if (
this.pointerDown != null &&
arrEquals(this.pointerDown.position, position) &&
!this.pointerDown.moved
) {
this.handleCellGrabberPointerDown(evt)
}
}, 800)
}

handleCellGrabberMouseDown = evt => {
handleCellGrabberPointerDown = evt => {
if (evt.button !== 0) return

evt.stopPropagation()
Expand All @@ -238,13 +262,17 @@ export default class Grid extends Component {
)
let node = this.props.data.nodes[nodeIndex]

this.mouseDown = {
this.pointerDown = {
evt,
position,
nodeIndex,
node,
mode: 'move'
}

this.setState({
movingNodePosition: position
})
}

handleCellAddLoopClick = evt => {
Expand All @@ -271,13 +299,13 @@ export default class Grid extends Component {
onDataChange({data: {nodes: newNodes, edges: newEdges}})
}

handleNodeMouseUp = evt => {
if (this.mouseDown == null) return
handleNodePointerUp = evt => {
if (this.pointerDown == null) return

let oldEvt = this.mouseDown.evt
let oldEvt = this.pointerDown.evt
if (evt.clientX !== oldEvt.clientX || evt.clientY !== oldEvt.clientY) return

let {position} = this.mouseDown
let {position} = this.pointerDown
let {onCellClick = () => {}} = this.props

onCellClick({position})
Expand Down Expand Up @@ -381,8 +409,8 @@ export default class Grid extends Component {
width: cols * cellSize,
height: rows * cellSize
}}
onMouseDown={this.handleNodeMouseDown}
onMouseUp={this.handleNodeMouseUp}
onPointerDown={this.handleNodePointerDown}
onPointerUp={this.handleNodePointerUp}
>
{Array(rows)
.fill()
Expand All @@ -405,9 +433,13 @@ export default class Grid extends Component {
position={position}
size={cellSize}
selected={selected}
moving={
this.state.movingNodePosition != null &&
arrEquals(position, this.state.movingNodePosition)
}
edit={selected && this.props.cellEditMode}
value={node && node.value}
onGrabberMouseDown={this.handleCellGrabberMouseDown}
onGrabberPointerDown={this.handleCellGrabberPointerDown}
onAddLoopClick={this.handleCellAddLoopClick}
onSubmit={this.props.onCellSubmit}
onChange={this.handleCellChange}
Expand Down
16 changes: 9 additions & 7 deletions src/components/GridCell.js
Expand Up @@ -10,7 +10,8 @@ export default class GridCell extends Component {
return (
nextProps.value !== this.props.value ||
nextProps.edit !== this.props.edit ||
nextProps.selected !== this.props.selected
nextProps.selected !== this.props.selected ||
nextProps.moving !== this.props.moving
)
}

Expand Down Expand Up @@ -51,11 +52,11 @@ export default class GridCell extends Component {
onSubmit({position: this.props.position})
}

handleGrabberMouseDown = evt => {
let {onGrabberMouseDown = () => {}} = this.props
handleGrabberPointerDown = evt => {
let {onGrabberPointerDown = () => {}} = this.props

evt.position = this.props.position
onGrabberMouseDown(evt)
onGrabberPointerDown(evt)
}

handleGrabberDragStart = evt => {
Expand Down Expand Up @@ -101,7 +102,8 @@ export default class GridCell extends Component {
<li
class={classNames('grid-cell', {
edit: this.props.edit,
selected: this.props.selected
selected: this.props.selected,
moving: this.props.moving
})}
data-position={this.props.position.join(',')}
>
Expand All @@ -121,7 +123,7 @@ export default class GridCell extends Component {
value={this.props.value}
onBlur={this.handleInputBlur}
onInput={this.handleInputChange}
onMouseDown={this.stopPropagation}
onPointerDown={this.stopPropagation}
onKeyDown={this.handleEditKeyDown}
/>
</form>
Expand All @@ -130,7 +132,7 @@ export default class GridCell extends Component {
<img
class="grabber"
src="./img/grabber.svg"
onMouseDown={this.handleGrabberMouseDown}
onPointerDown={this.handleGrabberPointerDown}
onDragStart={this.handleGrabberDragStart}
/>

Expand Down
8 changes: 1 addition & 7 deletions src/diagram.js
Expand Up @@ -4,13 +4,7 @@ import {
decompressFromEncodedURIComponent
} from 'lz-string'

import {
getId,
arrEquals,
arrSubtract,
b64DecodeUnicode,
b64EncodeUnicode
} from './helper'
import {getId, arrSubtract, b64DecodeUnicode, b64EncodeUnicode} from './helper'
import {parse} from './parser'

export function toJSON(diagram) {
Expand Down