Render all visible cursors

This commit is contained in:
Nathan Sobo 2014-04-01 17:06:59 -06:00
parent c44fd62eb1
commit e365e51a2b
2 changed files with 46 additions and 7 deletions

View File

@ -5,6 +5,8 @@ describe "EditorComponent", ->
[editor, component, node, lineHeight, charWidth] = []
beforeEach ->
spyOn(window, 'requestAnimationFrame').andCallFake (fn) -> fn()
editor = atom.project.openSync('sample.js')
container = document.querySelector('#jasmine-content')
component = React.renderComponent(EditorComponent({editor}), container)
@ -24,7 +26,6 @@ describe "EditorComponent", ->
expect(lines[4].textContent).toBe editor.lineForScreenRow(4).text
node.querySelector('.vertical-scrollbar').scrollTop = 2.5 * lineHeight
spyOn(window, 'requestAnimationFrame').andCallFake (fn) -> fn()
component.onVerticalScroll()
expect(node.querySelector('.scrollable-content').style['-webkit-transform']).toBe "translateY(#{-2.5 * lineHeight}px)"
@ -38,14 +39,36 @@ describe "EditorComponent", ->
expect(spacers[0].offsetHeight).toBe 2 * lineHeight
expect(spacers[1].offsetHeight).toBe (editor.getScreenLineCount() - 7) * lineHeight
it "renders the currently visible selections", ->
editor.setCursorScreenPosition([0, 5])
it "renders the currently visible cursors", ->
cursor1 = editor.getCursor()
cursor1.setScreenPosition([0, 5])
node.style.height = 4.5 * lineHeight + 'px'
component.updateAllDimensions()
cursorNodes = node.querySelectorAll('.cursor')
expect(cursorNodes.length).toBe 1
expect(cursorNodes[0].offsetHeight).toBe lineHeight
expect(cursorNodes[0].offsetWidth).toBe charWidth
expect(cursorNodes[0].offsetTop).toBe 0
expect(cursorNodes[0].offsetLeft).toBe 5 * charWidth
cursor3 = editor.addCursorAtScreenPosition([6, 11])
cursor2 = editor.addCursorAtScreenPosition([4, 10])
cursorNodes = node.querySelectorAll('.cursor')
expect(cursorNodes.length).toBe 2
expect(cursorNodes[0].offsetTop).toBe 0
expect(cursorNodes[0].offsetLeft).toBe 5 * charWidth
expect(cursorNodes[1].offsetTop).toBe 4 * lineHeight
expect(cursorNodes[1].offsetLeft).toBe 10 * charWidth
node.querySelector('.vertical-scrollbar').scrollTop = 2.5 * lineHeight
component.onVerticalScroll()
cursorNodes = node.querySelectorAll('.cursor')
expect(cursorNodes.length).toBe 2
expect(cursorNodes[0].offsetTop).toBe 6 * lineHeight
expect(cursorNodes[0].offsetLeft).toBe 11 * charWidth
expect(cursorNodes[1].offsetTop).toBe 4 * lineHeight
expect(cursorNodes[1].offsetLeft).toBe 10 * charWidth

View File

@ -4,6 +4,7 @@
SelectionComponent = require './selection-component'
InputComponent = require './input-component'
CustomEventMixin = require './custom-event-mixin'
SubscriberMixin = require './subscriber-mixin'
DummyLineNode = $$ ->
@div className: 'line', style: 'position: absolute; visibility: hidden;', -> @span 'x'
@ -14,7 +15,7 @@ EditorCompont = React.createClass
statics: {DummyLineNode}
mixins: [CustomEventMixin]
mixins: [CustomEventMixin, SubscriberMixin]
render: ->
div className: 'editor',
@ -36,7 +37,7 @@ EditorCompont = React.createClass
{lineHeight, charWidth} = @state
div className: 'overlayer',
for selection in @props.editor.getSelections()
for selection in @props.editor.getSelections() when @selectionIntersectsVisibleRowRange(selection)
SelectionComponent({selection, lineHeight, charWidth})
renderVisibleLines: ->
@ -59,8 +60,12 @@ EditorCompont = React.createClass
componentDidMount: ->
@listenForCustomEvents()
@props.editor.on 'screen-lines-changed', @onScreenLinesChanged
@refs.scrollView.getDOMNode().addEventListener 'mousewheel', @onMousewheel
{editor} = @props
@subscribe editor, 'screen-lines-changed', @onScreenLinesChanged
@subscribe editor, 'selection-added', @onSelectionAdded
@updateAllDimensions()
@props.editor.setVisible(true)
@refs.hiddenInput.focus()
@ -95,7 +100,10 @@ EditorCompont = React.createClass
onScreenLinesChanged: ({start, end}) ->
[visibleStart, visibleEnd] = @getVisibleRowRange()
@forceUpdate() unless end < visibleStart or visibleEnd <= start
@forceUpdate() if @intersectsVisibleRowRange(start, end + 1) # TODO: Use closed-open intervals for change events
onSelectionAdded: (selection) ->
@forceUpdate() if @selectionIntersectsVisibleRowRange(selection)
getVisibleRowRange: ->
return [0, 0] unless @state.lineHeight > 0
@ -105,6 +113,14 @@ EditorCompont = React.createClass
endRow = Math.ceil(startRow + heightInLines)
[startRow, endRow]
intersectsVisibleRowRange: (startRow, endRow) ->
[visibleStart, visibleEnd] = @getVisibleRowRange()
not (endRow <= visibleStart or visibleEnd <= startRow)
selectionIntersectsVisibleRowRange: (selection) ->
{start, end} = selection.getScreenRange()
@intersectsVisibleRowRange(start.row, end.row + 1)
getScrollHeight: ->
@props.editor.getLineCount() * @state.lineHeight