Add autoscrolling with react editor view

Its implemented in the model to restrict touching of the DOM.
This commit is contained in:
Nathan Sobo
2014-04-02 18:32:19 -06:00
parent ba83b0ede0
commit e472d7b038
4 changed files with 61 additions and 4 deletions

View File

@@ -645,6 +645,38 @@ describe "Editor", ->
cursor2 = editor.addCursorAtBufferPosition([1,4])
expect(cursor2.marker).toBe cursor1.marker
describe "autoscroll", ->
beforeEach ->
editor.setVerticalScrollMargin(2)
editor.setLineHeight(10)
editor.setHeight(5.5 * 10)
it "scrolls down when the last cursor gets closer than ::verticalScrollMargin to the bottom of the editor", ->
expect(editor.getScrollTop()).toBe 0
expect(editor.getScrollBottom()).toBe 5.5 * 10
editor.setCursorScreenPosition([2, 0])
expect(editor.getScrollBottom()).toBe 5.5 * 10
editor.moveCursorDown()
expect(editor.getScrollBottom()).toBe 6 * 10
editor.moveCursorDown()
expect(editor.getScrollBottom()).toBe 7 * 10
it "scrolls up when the last cursor gets closer than ::verticalScrollMargin to the top of the editor", ->
editor.setCursorScreenPosition([11, 0])
editor.setScrollBottom(editor.getScrollHeight())
editor.moveCursorUp()
expect(editor.getScrollBottom()).toBe editor.getScrollHeight()
editor.moveCursorUp()
expect(editor.getScrollTop()).toBe 7 * 10
editor.moveCursorUp()
expect(editor.getScrollTop()).toBe 6 * 10
describe "selection", ->
selection = null

View File

@@ -27,7 +27,12 @@ class Cursor
{textChanged} = e
return if oldHeadScreenPosition.isEqual(newHeadScreenPosition)
# Supports old editor view
@needsAutoscroll ?= @isLastCursor() and !textChanged
# Supports react editor view
@autoscroll() if @needsAutoscroll
@goalColumn = null
movedEvent =
@@ -92,6 +97,19 @@ class Cursor
getBufferPosition: ->
@marker.getHeadBufferPosition()
autoscroll: ->
scrollMarginInPixels = @editor.getVerticalScrollMargin() * @editor.getLineHeight()
{top, height} = @getPixelRect()
bottom = top + height
desiredScrollTop = top - scrollMarginInPixels
desiredScrollBottom = bottom + scrollMarginInPixels
if desiredScrollTop < @editor.getScrollTop()
@editor.setScrollTop(desiredScrollTop)
else if desiredScrollBottom > @editor.getScrollBottom()
@editor.setScrollBottom(desiredScrollBottom)
# Public: If the marker range is empty, the cursor is marked as being visible.
updateVisibility: ->
@setVisible(@marker.getBufferRange().isEmpty())

View File

@@ -92,7 +92,9 @@ EditorCompont = React.createClass
@subscribe editor.$lineHeight.changes, @requestUpdate
listenForDOMEvents: ->
@refs.scrollView.getDOMNode().addEventListener 'mousewheel', @onMousewheel
scrollViewNode = @refs.scrollView.getDOMNode()
scrollViewNode.addEventListener 'mousewheel', @onMousewheel
scrollViewNode.addEventListener 'overflowchanged', @onOverflowChanged
@getDOMNode().addEventListener 'focus', @onFocus
listenForCustomEvents: ->

View File

@@ -144,15 +144,16 @@ class Editor extends Model
cursors: null
selections: null
suppressSelectionMerging: false
verticalScrollMargin: 2
@delegatesMethods 'suggestedIndentForBufferRow', 'autoIndentBufferRow', 'autoIndentBufferRows',
'autoDecreaseIndentForBufferRow', 'toggleLineCommentForBufferRow', 'toggleLineCommentsForBufferRows',
toProperty: 'languageMode'
@delegatesMethods 'setLineHeight', 'getLineHeight', 'setDefaultCharWidth', 'setHeight',
'getHeight', 'setWidth', 'getWidth', 'setScrollTop', 'getScrollTop', 'setScrollLeft',
'getScrollLeft', 'getScrollHeight', 'getVisibleRowRange', 'intersectsVisibleRowRange',
'selectionIntersectsVisibleRowRange', toProperty: 'displayBuffer'
'getHeight', 'setWidth', 'getWidth', 'setScrollTop', 'getScrollTop', 'getScrollBottom',
'setScrollBottom', 'setScrollLeft', 'getScrollLeft', 'getScrollHeight', 'getVisibleRowRange',
'intersectsVisibleRowRange', 'selectionIntersectsVisibleRowRange', toProperty: 'displayBuffer'
@delegatesProperties '$lineHeight', '$defaultCharWidth', '$height', '$width',
'$scrollTop', '$scrollLeft', toProperty: 'displayBuffer'
@@ -308,6 +309,10 @@ class Editor extends Model
# Public: Toggle soft wrap for this editor
toggleSoftWrap: -> @setSoftWrap(not @getSoftWrap())
getVerticalScrollMargin: -> @verticalScrollMargin
setVerticalScrollMargin: (@verticalScrollMargin) -> @verticalScrollMargin
# Public: Get the text representing a single level of indent.
#
# If soft tabs are enabled, the text is composed of N spaces, where N is the