🎨 Move block decoration related stuff into its own presenter

This commit is contained in:
Antonio Scandurra
2015-11-30 10:12:44 +01:00
parent 0159d5c31e
commit ef851a822c
2 changed files with 113 additions and 37 deletions

View File

@@ -0,0 +1,75 @@
/** @babel */
const {Emitter} = require('event-kit')
module.exports =
class BlockDecorationsPresenter {
constructor (model) {
this.model = model
this.emitter = new Emitter()
this.blockDecorationsDimensionsById = new Map
this.blockDecorationsByScreenRow = new Map
this.heightsByScreenRow = new Map
}
onDidUpdateState (callback) {
return this.emitter.on('did-update-state', callback)
}
update () {
this.heightsByScreenRow.clear()
this.blockDecorationsByScreenRow.clear()
let blockDecorations = new Map
// TODO: move into DisplayBuffer
for (let decoration of this.model.getDecorations({type: "block"})) {
blockDecorations.set(decoration.id, decoration)
}
for (let [decorationId] of this.blockDecorationsDimensionsById) {
if (!blockDecorations.has(decorationId)) {
this.blockDecorationsDimensionsById.delete(decorationId)
}
}
for (let [decorationId, decoration] of blockDecorations) {
let screenRow = decoration.getMarker().getHeadScreenPosition().row
this.addBlockDecorationToScreenRow(screenRow, decoration)
if (this.hasMeasuredBlockDecoration(decoration)) {
this.addHeightToScreenRow(
screenRow,
this.blockDecorationsDimensionsById.get(decorationId).height
)
}
}
}
setBlockDecorationDimensions (decoration, width, height) {
this.blockDecorationsDimensionsById.set(decoration.id, {width, height})
this.emitter.emit('did-update-state')
}
blockDecorationsHeightForScreenRow (screenRow) {
return Number(this.heightsByScreenRow.get(screenRow)) || 0
}
addHeightToScreenRow (screenRow, height) {
let previousHeight = this.blockDecorationsHeightForScreenRow(screenRow)
let newHeight = previousHeight + height
this.heightsByScreenRow.set(screenRow, newHeight)
}
addBlockDecorationToScreenRow (screenRow, decoration) {
let decorations = this.blockDecorationsForScreenRow(screenRow) || []
decorations.push(decoration)
this.blockDecorationsByScreenRow.set(screenRow, decorations)
}
blockDecorationsForScreenRow (screenRow) {
return this.blockDecorationsByScreenRow.get(screenRow)
}
hasMeasuredBlockDecoration (decoration) {
return this.blockDecorationsDimensionsById.has(decoration.id)
}
}

View File

@@ -2,6 +2,7 @@
{Point, Range} = require 'text-buffer'
_ = require 'underscore-plus'
Decoration = require './decoration'
BlockDecorationsPresenter = require './block-decorations-presenter'
module.exports =
class TextEditorPresenter
@@ -28,9 +29,7 @@ class TextEditorPresenter
@lineDecorationsByScreenRow = {}
@lineNumberDecorationsByScreenRow = {}
@customGutterDecorationsByGutterName = {}
@blockDecorationsDimensionsById = {}
@blockDecorationsDimensionsByScreenRow = {}
@heightsByScreenRow = {}
@blockDecorationsPresenter = new BlockDecorationsPresenter(@model)
@screenRowsToMeasure = []
@transferMeasurementsToModel()
@transferMeasurementsFromModel()
@@ -74,7 +73,8 @@ class TextEditorPresenter
getPreMeasurementState: ->
@updating = true
@updateBlockDecorations()
@blockDecorationsPresenter.update()
@updateVerticalDimensions()
@updateScrollbarDimensions()
@@ -196,6 +196,35 @@ class TextEditorPresenter
@shouldUpdateCustomGutterDecorationState = true
@emitDidUpdateState()
@disposables.add @blockDecorationsPresenter.onDidUpdateState =>
@shouldUpdateVerticalScrollState = true
@emitDidUpdateState()
# @disposables.add @
# @disposables.add @model.onDidAddDecoration (decoration) =>
# return unless decoration.isType("block")
#
# didMoveDisposable = decoration.getMarker().onDidChange ({oldHeadScreenPosition, newHeadScreenPosition}) =>
# # @blockDecorationsMoveOperations.add()
# # @moveBlockDecoration(decoration, oldHeadScreenPosition, newHeadScreenPosition)
# @emitDidUpdateState()
# didChangeDisposable = decoration.onDidChangeProperties (properties) =>
# # @changePropertiesOperations.add()
# # @updateBlockDecoration(decoration)
# @emitDidUpdateState()
# didDestroyDisposable = decoration.onDidDestroy =>
# didMoveDisposable.dispose()
# didChangeDisposable.dispose()
# didDestroyDisposable.dispose()
#
# # @destroyOperations.add()
# # @destroyBlockDecoration(decoration)
# @emitDidUpdateState()
#
# # @addBlockDecoration(decoration)
# @emitDidUpdateState()
@disposables.add @model.onDidChangeGrammar(@didChangeGrammar.bind(this))
@disposables.add @model.onDidChangePlaceholderText =>
@shouldUpdateContentState = true
@@ -477,7 +506,7 @@ class TextEditorPresenter
lineState = tileState.lines[line.id]
lineState.screenRow = screenRow
lineState.decorationClasses = @lineDecorationClassesForRow(screenRow)
lineState.blockDecorations = @blockDecorationsByScreenRow[screenRow]
lineState.blockDecorations = this.blockDecorationsPresenter.blockDecorationsForScreenRow(screenRow)
else
tileState.lines[line.id] =
screenRow: screenRow
@@ -494,7 +523,7 @@ class TextEditorPresenter
tabLength: line.tabLength
fold: line.fold
decorationClasses: @lineDecorationClassesForRow(screenRow)
blockDecorations: @blockDecorationsByScreenRow[screenRow]
blockDecorations: this.blockDecorationsPresenter.blockDecorationsForScreenRow(screenRow)
for id, line of tileState.lines
delete tileState.lines[id] unless visibleLineIds.hasOwnProperty(id)
@@ -693,7 +722,7 @@ class TextEditorPresenter
line = @model.tokenizedLineForScreenRow(screenRow)
decorationClasses = @lineNumberDecorationClassesForRow(screenRow)
foldable = @model.isFoldableAtScreenRow(screenRow)
blockDecorationsHeight = @getScreenRowHeight(screenRow) - @lineHeight
blockDecorationsHeight = @blockDecorationsPresenter.blockDecorationsHeightForScreenRow(screenRow)
tileState.lineNumbers[line.id] = {screenRow, bufferRow, softWrapped, decorationClasses, foldable, blockDecorationsHeight}
visibleLineNumberIds[line.id] = true
@@ -704,7 +733,7 @@ class TextEditorPresenter
return
getScreenRowHeight: (screenRow) ->
@heightsByScreenRow[screenRow] or @lineHeight
@lineHeight + @blockDecorationsPresenter.blockDecorationsHeightForScreenRow(screenRow)
getScreenRowsHeight: (startRow, endRow) ->
height = 0
@@ -755,7 +784,6 @@ class TextEditorPresenter
updateVerticalDimensions: ->
if @lineHeight?
oldContentHeight = @contentHeight
allBlockDecorations = _.values(@blockDecorationsDimensionsById)
@contentHeight = @getScreenRowsHeight(0, @model.getScreenLineCount())
if @contentHeight isnt oldContentHeight
@@ -1391,34 +1419,7 @@ class TextEditorPresenter
@emitDidUpdateState()
setBlockDecorationDimensions: (decoration, width, height) ->
screenRow = decoration.getMarker().getHeadScreenPosition().row
dimensions = {width, height}
@blockDecorationsDimensionsById[decoration.id] = dimensions
@shouldUpdateVerticalScrollState = true
@emitDidUpdateState()
updateBlockDecorations: ->
@heightsByScreenRow = {}
@blockDecorationsByScreenRow = {}
blockDecorations = {}
# TODO: move into DisplayBuffer
for decoration in @model.getDecorations(type: "block")
blockDecorations[decoration.id] = decoration
for decorationId of @blockDecorationsDimensionsById
unless blockDecorations.hasOwnProperty(decorationId)
delete @blockDecorationsDimensionsById[decorationId]
for decorationId, decoration of blockDecorations
screenRow = decoration.getMarker().getHeadScreenPosition().row
@blockDecorationsByScreenRow[screenRow] ?= []
@blockDecorationsByScreenRow[screenRow].push(decoration)
continue unless @blockDecorationsDimensionsById.hasOwnProperty(decorationId)
@heightsByScreenRow[screenRow] ?= @lineHeight
@heightsByScreenRow[screenRow] += @blockDecorationsDimensionsById[decorationId].height
@blockDecorationsPresenter.setBlockDecorationDimensions(arguments...)
observeCursor: (cursor) ->
didChangePositionDisposable = cursor.onDidChangePosition =>