Handle dragging in the gutter

Including shift-click dragging better than the old editor!!!!!!
This commit is contained in:
Ben Ogle & Nathan Sobo
2014-06-18 17:48:28 -07:00
committed by Ben Ogle
parent 9083103bb3
commit 2edcc517b1
2 changed files with 92 additions and 9 deletions

View File

@@ -1042,6 +1042,76 @@ describe "EditorComponent", ->
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(6), shiftKey: true))
expect(editor.getSelectedScreenRange()).toEqual [[3, 4], [7, 0]]
describe "when the gutter is clicked and dragged", ->
beforeEach ->
delayAnimationFrames = true
describe "when dragging downward", ->
it "selects the rows between the start and end of the drag", ->
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(2)))
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(6)))
nextAnimationFrame()
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(6)))
expect(editor.getSelectedScreenRange()).toEqual [[2, 0], [7, 0]]
describe "when dragging upward", ->
it "selects the rows between the start and end of the drag", ->
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(6)))
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(2)))
nextAnimationFrame()
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(2)))
expect(editor.getSelectedScreenRange()).toEqual [[2, 0], [7, 0]]
describe "when the gutter is shift-clicked and dragged", ->
beforeEach ->
delayAnimationFrames = true
describe "when the shift-click is below the existing selection's tail", ->
describe "when dragging downward", ->
it "selects the rows between the existing selection's tail and the end of the drag", ->
editor.setSelectedScreenRange([[3, 4], [4, 5]])
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(7), shiftKey: true))
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(8)))
nextAnimationFrame()
expect(editor.getSelectedScreenRange()).toEqual [[3, 4], [9, 0]]
describe "when dragging upward", ->
it "selects the rows between the end of the drag and the tail of the existing selection", ->
editor.setSelectedScreenRange([[4, 4], [5, 5]])
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(7), shiftKey: true))
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(5)))
nextAnimationFrame()
expect(editor.getSelectedScreenRange()).toEqual [[4, 4], [6, 0]]
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(1)))
nextAnimationFrame()
expect(editor.getSelectedScreenRange()).toEqual [[1, 0], [4, 4]]
describe "when the shift-click is above the existing selection's tail", ->
describe "when dragging upward", ->
it "selects the rows between the end of the drag and the tail of the existing selection", ->
editor.setSelectedScreenRange([[4, 4], [5, 5]])
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(2), shiftKey: true))
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(1)))
nextAnimationFrame()
expect(editor.getSelectedScreenRange()).toEqual [[1, 0], [4, 4]]
describe "when dragging downward", ->
it "selects the rows between the existing selection's tail and the end of the drag", ->
editor.setSelectedScreenRange([[3, 4], [4, 5]])
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(1), shiftKey: true))
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(2)))
nextAnimationFrame()
expect(editor.getSelectedScreenRange()).toEqual [[2, 0], [3, 4]]
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(8)))
nextAnimationFrame()
expect(editor.getSelectedScreenRange()).toEqual [[3, 4], [9, 0]]
describe "focus handling", ->
inputNode = null

View File

@@ -504,23 +504,39 @@ EditorComponent = React.createClass
when 2 then editor.selectWord()
when 3 then editor.selectLine()
@selectToMousePositionUntilMouseUp(event)
@handleDragUntilMouseUp event, (screenPosition) ->
editor.selectToScreenPosition(screenPosition)
onGutterMouseDown: (event) ->
return unless event.button is 0 # only handle the left mouse button
{editor} = @props
{shiftKey, metaKey} = event
clickedRow = @screenPositionForMouseEvent(event).row
tailPosition = editor.getSelection().getTailScreenPosition()
if shiftKey
tailRow = editor.getSelection().getTailScreenPosition().row
if clickedRow < tailRow
if clickedRow < tailPosition.row
editor.selectToScreenPosition([clickedRow, 0])
else
editor.selectToScreenPosition([clickedRow + 1, 0])
else
tailRow = clickedRow
editor.setCursorScreenPosition([clickedRow, 0])
@handleDragUntilMouseUp event, (screenPosition) ->
dragRow = screenPosition.row
if shiftKey
if dragRow < tailPosition.row # up
editor.setSelectedScreenRange([[dragRow, 0], tailPosition])
else
editor.setSelectedScreenRange([tailPosition, [dragRow + 1, 0]])
else
if dragRow < tailRow # up
editor.setSelectedScreenRange([[dragRow, 0], [tailRow + 1, 0]])
else
editor.setSelectedScreenRange([[tailRow, 0], [dragRow + 1, 0]])
onStylesheetsChanged: (stylesheet) ->
@refreshScrollbars() if @containsScrollbarSelector(stylesheet)
@@ -579,15 +595,15 @@ EditorComponent = React.createClass
onCharacterWidthsChanged: (@scopedCharacterWidthsChangeCount) ->
@requestUpdate()
selectToMousePositionUntilMouseUp: (event) ->
handleDragUntilMouseUp: (event, dragHandler) ->
{editor} = @props
dragging = false
lastMousePosition = {}
animationLoop = =>
requestAnimationFrame =>
if dragging
@selectToMousePosition(lastMousePosition)
screenPosition = @screenPositionForMouseEvent(lastMousePosition)
dragHandler(screenPosition)
animationLoop()
onMouseMove = (event) ->
@@ -611,9 +627,6 @@ EditorComponent = React.createClass
window.addEventListener('mousemove', onMouseMove)
window.addEventListener('mouseup', onMouseUp)
selectToMousePosition: (event) ->
@props.editor.selectToScreenPosition(@screenPositionForMouseEvent(event))
requestScrollViewMeasurement: ->
return if @measurementPending