This commit is contained in:
Antonio Scandurra
2015-05-05 11:38:54 +02:00
parent 1e99a21547
commit 55a7508287
2 changed files with 71 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
module.exports =
class LinesPresenter
startRow: null
endRow: null
lineHeight: null
constructor: (@presenter) ->
@lines = {}
getState: ->
visibleLineIds = {}
row = @startRow
while row < @endRow
line = @presenter.model.tokenizedLineForScreenRow(row)
unless line?
throw new Error("No line exists for row #{row}. Last screen row: #{@model.getLastScreenRow()}")
visibleLineIds[line.id] = true
if @lines.hasOwnProperty(line.id)
lineState = @lines[line.id]
lineState.screenRow = row
lineState.top = (row - @startRow) * @lineHeight
lineState.decorationClasses = @presenter.lineDecorationClassesForRow(row)
else
@lines[line.id] =
screenRow: row
text: line.text
tokens: line.tokens
isOnlyWhitespace: line.isOnlyWhitespace()
endOfLineInvisibles: line.endOfLineInvisibles
indentLevel: line.indentLevel
tabLength: line.tabLength
fold: line.fold
top: (row - @startRow) * @lineHeight
decorationClasses: @presenter.lineDecorationClassesForRow(row)
row++
for id, line of @lines
delete @lines[id] unless visibleLineIds.hasOwnProperty(id)
@lines

View File

@@ -2,6 +2,7 @@
{Point, Range} = require 'text-buffer'
_ = require 'underscore-plus'
Decoration = require './decoration'
LinesPresenter = require './lines-presenter'
module.exports =
class TextEditorPresenter
@@ -20,6 +21,8 @@ class TextEditorPresenter
@measuredHorizontalScrollbarHeight = horizontalScrollbarHeight
@measuredVerticalScrollbarWidth = verticalScrollbarWidth
@gutterWidth ?= 0
@tileCount ?= 3
@linesPresentersByTileIndex = {}
@disposables = new CompositeDisposable
@emitter = new Emitter
@@ -74,6 +77,7 @@ class TextEditorPresenter
@updateHiddenInputState() if @shouldUpdateHiddenInputState
@updateContentState() if @shouldUpdateContentState
@updateDecorations() if @shouldUpdateDecorations
@updateTilesState() if @shouldUpdateLinesState
@updateLinesState() if @shouldUpdateLinesState
@updateCursorsState() if @shouldUpdateCursorsState
@updateOverlaysState() if @shouldUpdateOverlaysState
@@ -205,6 +209,7 @@ class TextEditorPresenter
content:
scrollingVertically: false
cursorsVisible: false
tiles: {}
lines: {}
highlights: {}
overlays: {}
@@ -229,6 +234,7 @@ class TextEditorPresenter
@updateHiddenInputState()
@updateContentState()
@updateDecorations()
@updateTilesState()
@updateLinesState()
@updateCursorsState()
@updateOverlaysState()
@@ -298,6 +304,30 @@ class TextEditorPresenter
@state.content.backgroundColor = if @model.isMini() then null else @backgroundColor
@state.content.placeholderText = if @model.isEmpty() then @model.getPlaceholderText() else null
updateTilesState: ->
return unless @startRow? and @endRow? and @lineHeight?
linesPerTile = @height / @lineHeight / @tileCount
startIndex = Math.floor(@startRow / linesPerTile)
endIndex = Math.ceil(@endRow / linesPerTile)
visibleIndexesRange = [startIndex..endIndex]
for index, tile of @state.content.tiles
unless index in visibleIndexesRange
delete @state.content.tiles[index]
delete @linesPresentersByTileIndex[index]
for index in visibleIndexesRange
presenter = @linesPresentersByTileIndex[index] ?= new LinesPresenter(@)
presenter.startRow = Math.floor(index * linesPerTile)
presenter.endRow = Math.ceil(Math.min(@endRow, (index + 1) * linesPerTile))
presenter.lineHeight = @lineHeight
tile = @state.content.tiles[index] ?= {}
tile.top = (index * linesPerTile * @lineHeight) - @scrollTop
tile.lines = presenter.getState()
updateLinesState: ->
return unless @startRow? and @endRow? and @lineHeight?