mirror of
https://github.com/atom/atom.git
synced 2026-01-25 23:08:18 -05:00
🎨 Move block decoration related stuff into its own presenter
This commit is contained in:
75
src/block-decorations-presenter.js
Normal file
75
src/block-decorations-presenter.js
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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 =>
|
||||
|
||||
Reference in New Issue
Block a user