mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
Start on cursor rendering
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
EditorComponent = require '../src/editor-component'
|
||||
|
||||
describe "EditorComponent", ->
|
||||
[editor, component, node, lineHeight] = []
|
||||
[editor, component, node, lineHeight, charWidth] = []
|
||||
|
||||
beforeEach ->
|
||||
editor = atom.project.openSync('sample.js')
|
||||
@@ -10,10 +10,9 @@ describe "EditorComponent", ->
|
||||
component = React.renderComponent(EditorComponent({editor}), container)
|
||||
node = component.getDOMNode()
|
||||
|
||||
fontSize = 20
|
||||
lineHeight = 1.3 * fontSize
|
||||
node.style.lineHeight = 1.3
|
||||
node.style.fontSize = fontSize + 'px'
|
||||
node.style.fontSize = '20px'
|
||||
{lineHeight, charWidth} = component.measureLineDimensions()
|
||||
|
||||
it "renders only the currently-visible lines", ->
|
||||
node.style.height = 4.5 * lineHeight + 'px'
|
||||
@@ -28,7 +27,7 @@ describe "EditorComponent", ->
|
||||
spyOn(window, 'requestAnimationFrame').andCallFake (fn) -> fn()
|
||||
component.onVerticalScroll()
|
||||
|
||||
expect(node.querySelector('.lines').style['-webkit-transform']).toBe "translateY(#{-2.5 * lineHeight}px)"
|
||||
expect(node.querySelector('.scrollable-content').style['-webkit-transform']).toBe "translateY(#{-2.5 * lineHeight}px)"
|
||||
|
||||
lines = node.querySelectorAll('.line')
|
||||
expect(lines.length).toBe 5
|
||||
@@ -38,3 +37,15 @@ describe "EditorComponent", ->
|
||||
spacers = node.querySelectorAll('.spacer')
|
||||
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])
|
||||
|
||||
node.style.height = 4.5 * lineHeight + 'px'
|
||||
component.updateAllDimensions()
|
||||
|
||||
cursorNodes = node.querySelectorAll('.cursor')
|
||||
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
|
||||
|
||||
@@ -10,22 +10,37 @@ module.exports =
|
||||
React.createClass
|
||||
pendingScrollTop: null
|
||||
|
||||
statics: {DummyLineNode}
|
||||
|
||||
render: ->
|
||||
div className: 'editor',
|
||||
div className: 'scroll-view', ref: 'scrollView',
|
||||
div className: 'overlayer',
|
||||
InputComponent ref: 'hiddenInput', className: 'hidden-input', onInput: @onInput
|
||||
@renderVisibleLines()
|
||||
InputComponent ref: 'hiddenInput', className: 'hidden-input', onInput: @onInput
|
||||
@renderScrollableContent()
|
||||
div className: 'vertical-scrollbar', ref: 'verticalScrollbar', onScroll: @onVerticalScroll,
|
||||
div outlet: 'verticalScrollbarContent', style: {height: @getScrollHeight()}
|
||||
|
||||
renderScrollableContent: ->
|
||||
height = @props.editor.getScreenLineCount() * @state.lineHeight
|
||||
WebkitTransform = "translateY(#{-@state.scrollTop}px)"
|
||||
|
||||
div className: 'scrollable-content', style: {height, WebkitTransform},
|
||||
@renderOverlayer()
|
||||
@renderVisibleLines()
|
||||
|
||||
renderOverlayer: ->
|
||||
{lineHeight, charWidth} = @state
|
||||
|
||||
div className: 'overlayer',
|
||||
for selection in @props.editor.getSelections()
|
||||
SelectionComponent({selection, lineHeight, charWidth})
|
||||
|
||||
renderVisibleLines: ->
|
||||
[startRow, endRow] = @getVisibleRowRange()
|
||||
precedingHeight = startRow * @state.lineHeight
|
||||
lineCount = @props.editor.getScreenLineCount()
|
||||
followingHeight = (lineCount - endRow) * @state.lineHeight
|
||||
followingHeight = (@props.editor.getScreenLineCount() - endRow) * @state.lineHeight
|
||||
|
||||
div className: 'lines', ref: 'lines', style: {WebkitTransform: "translateY(#{-@state.scrollTop}px)"}, [
|
||||
div className: 'lines', ref: 'lines', [
|
||||
div className: 'spacer', key: 'top-spacer', style: {height: precedingHeight}
|
||||
(for tokenizedLine in @props.editor.linesForScreenRows(startRow, endRow - 1)
|
||||
LineComponent({tokenizedLine, key: tokenizedLine.id}))...
|
||||
@@ -62,8 +77,6 @@ React.createClass
|
||||
event.preventDefault()
|
||||
|
||||
onInput: (char, replaceLastChar) ->
|
||||
console.log char, replaceLastChar
|
||||
|
||||
@props.editor.insertText(char)
|
||||
|
||||
onScreenLinesChanged: ({start, end}) ->
|
||||
@@ -82,21 +95,21 @@ React.createClass
|
||||
@props.editor.getLineCount() * @state.lineHeight
|
||||
|
||||
updateAllDimensions: ->
|
||||
lineHeight = @measureLineHeight()
|
||||
{height, width} = @measureScrollViewDimensions()
|
||||
|
||||
@setState({lineHeight, height, width})
|
||||
{lineHeight, charWidth} = @measureLineDimensions()
|
||||
@setState({height, width, lineHeight, charWidth})
|
||||
|
||||
measureScrollViewDimensions: ->
|
||||
scrollViewNode = @refs.scrollView.getDOMNode()
|
||||
{height: scrollViewNode.clientHeight, width: scrollViewNode.clientWidth}
|
||||
|
||||
measureLineHeight: ->
|
||||
measureLineDimensions: ->
|
||||
linesNode = @refs.lines.getDOMNode()
|
||||
linesNode.appendChild(DummyLineNode)
|
||||
lineHeight = DummyLineNode.getBoundingClientRect().height
|
||||
charWidth = DummyLineNode.firstChild.getBoundingClientRect().width
|
||||
linesNode.removeChild(DummyLineNode)
|
||||
lineHeight
|
||||
{lineHeight, charWidth}
|
||||
|
||||
LineComponent = React.createClass
|
||||
render: ->
|
||||
@@ -151,3 +164,26 @@ InputComponent = React.createClass
|
||||
|
||||
focus: ->
|
||||
@getDOMNode().focus()
|
||||
|
||||
SelectionComponent = React.createClass
|
||||
render: ->
|
||||
console.log "render selection component"
|
||||
|
||||
{selection, lineHeight, charWidth} = @props
|
||||
{cursor} = selection
|
||||
div className: 'selection',
|
||||
CursorComponent({cursor, lineHeight, charWidth})
|
||||
|
||||
CursorComponent = React.createClass
|
||||
render: ->
|
||||
{cursor, lineHeight, charWidth} = @props
|
||||
{row, column} = cursor.getScreenPosition()
|
||||
|
||||
console.log "char width", charWidth
|
||||
|
||||
div className: 'cursor', style: {
|
||||
height: lineHeight,
|
||||
width: charWidth
|
||||
top: row * lineHeight
|
||||
left: column * charWidth
|
||||
}
|
||||
|
||||
@@ -200,3 +200,13 @@
|
||||
color: @text-color-subtle;
|
||||
}
|
||||
}
|
||||
|
||||
.react-wrapper > .editor {
|
||||
.scrollable-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cursor {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user