From ef851a822c4fbc51573a20698c930825ceaa96e9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 30 Nov 2015 10:12:44 +0100 Subject: [PATCH] :art: Move block decoration related stuff into its own presenter --- src/block-decorations-presenter.js | 75 ++++++++++++++++++++++++++++++ src/text-editor-presenter.coffee | 75 +++++++++++++++--------------- 2 files changed, 113 insertions(+), 37 deletions(-) create mode 100644 src/block-decorations-presenter.js diff --git a/src/block-decorations-presenter.js b/src/block-decorations-presenter.js new file mode 100644 index 000000000..373444c45 --- /dev/null +++ b/src/block-decorations-presenter.js @@ -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) + } +} diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index d9f65f3cb..0e7a2c56d 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -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 =>