Move the cursor on single click

This commit is contained in:
Nathan Sobo 2014-04-06 13:34:50 -06:00
parent b0ad5e2f69
commit 3a433f734c
4 changed files with 49 additions and 4 deletions

View File

@ -162,6 +162,22 @@ describe "EditorComponent", ->
expect(region3Rect.left).toBe 0
expect(region3Rect.width).toBe 10 * charWidth
describe "mouse interactions", ->
clientCoordinatesForScreenPosition = (screenPosition) ->
positionOffset = editor.pixelPositionForScreenPosition(screenPosition)
editorClientRect = node.getBoundingClientRect()
clientX = editorClientRect.left + positionOffset.left
clientY = editorClientRect.top + positionOffset.top - editor.getScrollTop()
{clientX, clientY}
describe "when a non-folded line is single-clicked", ->
it "moves the cursor to the nearest row and column", ->
node.style.height = 4.5 * lineHeightInPixels + 'px'
component.updateAllDimensions()
editor.setScrollTop(3.5 * lineHeightInPixels)
component.onMouseDown(clientCoordinatesForScreenPosition([4, 8]))
expect(editor.getCursorScreenPosition()).toEqual [4, 8]
it "transfers focus to the hidden input", ->
expect(document.activeElement).toBe document.body
node.focus()

View File

@ -383,6 +383,25 @@ class DisplayBuffer extends Model
column++
{top, left}
screenPositionForPixelPosition: (pixelPosition) ->
targetTop = pixelPosition.top
targetLeft = pixelPosition.left
row = Math.floor(targetTop / @getLineHeight())
row = Math.min(row, @getLastRow())
row = Math.max(0, row)
left = 0
column = 0
for token in @lineForRow(row).tokens
charWidths = @getScopedCharWidths(token.scopes)
for char in token.value
charWidth = charWidths[char] ? defaultCharWidth
break if targetLeft <= left + (charWidth / 2)
left += charWidth
column++
new Point(row, column)
# Gets the number of screen lines.
#
# Returns a {Number}.

View File

@ -38,7 +38,7 @@ EditorCompont = React.createClass
height = editor.getScrollHeight()
WebkitTransform = "translateY(#{-editor.getScrollTop()}px)"
div className: 'scrollable-content', style: {height, WebkitTransform},
div className: 'scrollable-content', style: {height, WebkitTransform}, onMouseDown: @onMouseDown,
@renderCursors()
@renderVisibleLines()
@renderUnderlayer()
@ -267,6 +267,17 @@ EditorCompont = React.createClass
@refs.verticalScrollbar.getDOMNode().scrollTop -= event.wheelDeltaY
event.preventDefault()
onMouseDown: (event) ->
{editor} = @props
{clientX, clientY} = event
editorClientRect = @refs.scrollView.getDOMNode().getBoundingClientRect()
pixelPosition =
top: clientY - editorClientRect.top + editor.getScrollTop()
left: clientX - editorClientRect.left
screenPosition = editor.screenPositionForPixelPosition(pixelPosition)
editor.setCursorScreenPosition(screenPosition)
clearVisibleRowOverrides: ->
@visibleRowOverrides = null
@forceUpdate()

View File

@ -153,7 +153,8 @@ class Editor extends Model
@delegatesMethods 'setLineHeight', 'getLineHeight', 'setDefaultCharWidth', 'setHeight',
'getHeight', 'setWidth', 'getWidth', 'setScrollTop', 'getScrollTop', 'getScrollBottom',
'setScrollBottom', 'setScrollLeft', 'getScrollLeft', 'getScrollHeight', 'getVisibleRowRange',
'intersectsVisibleRowRange', 'selectionIntersectsVisibleRowRange', toProperty: 'displayBuffer'
'intersectsVisibleRowRange', 'selectionIntersectsVisibleRowRange', 'pixelPositionForScreenPosition',
'screenPositionForPixelPosition', toProperty: 'displayBuffer'
@delegatesProperties '$lineHeight', '$defaultCharWidth', '$height', '$width',
'$scrollTop', '$scrollLeft', toProperty: 'displayBuffer'
@ -512,8 +513,6 @@ class Editor extends Model
# this editor.
shouldPromptToSave: -> @isModified() and not @buffer.hasMultipleEditors()
pixelPositionForScreenPosition: (screenPosition) -> @displayBuffer.pixelPositionForScreenPosition(screenPosition)
# Public: Convert a position in buffer-coordinates to screen-coordinates.
#
# The position is clipped via {::clipBufferPosition} prior to the conversion.