Change verticalScrollbar's height according to block decorations

This commit is contained in:
Antonio Scandurra
2015-11-26 15:34:45 +01:00
parent aca12a8dc8
commit c8254566ef
2 changed files with 67 additions and 1 deletions

View File

@@ -486,6 +486,39 @@ describe "TextEditorPresenter", ->
presenter = buildPresenter(scrollTop: 0, lineHeight: 10, explicitHeight: 500)
expect(presenter.getState().verticalScrollbar.scrollHeight).toBe 500
it "updates when new block decorations are measured, changed or destroyed", ->
presenter = buildPresenter(scrollTop: 0, lineHeight: 10)
expect(presenter.getState().verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 10
addBlockDecorationAtScreenRow = (screenRow) ->
editor.decorateMarker(
editor.markScreenPosition([screenRow, 0], invalidate: "never"),
type: "block",
item: document.createElement("div")
)
blockDecoration1 = addBlockDecorationAtScreenRow(0)
blockDecoration2 = addBlockDecorationAtScreenRow(3)
blockDecoration3 = addBlockDecorationAtScreenRow(7)
presenter.setBlockDecorationSize(blockDecoration1, 0, 35.8)
presenter.setBlockDecorationSize(blockDecoration2, 0, 50.3)
presenter.setBlockDecorationSize(blockDecoration3, 0, 95.2)
linesHeight = editor.getScreenLineCount() * 10
blockDecorationsHeight = Math.round(35.8 + 50.3 + 95.2)
expect(presenter.getState().verticalScrollbar.scrollHeight).toBe(linesHeight + blockDecorationsHeight)
presenter.setBlockDecorationSize(blockDecoration2, 0, 100.3)
blockDecorationsHeight = Math.round(35.8 + 100.3 + 95.2)
expect(presenter.getState().verticalScrollbar.scrollHeight).toBe(linesHeight + blockDecorationsHeight)
waitsForStateToUpdate presenter, -> blockDecoration3.destroy()
runs ->
blockDecorationsHeight = Math.round(35.8 + 100.3)
expect(presenter.getState().verticalScrollbar.scrollHeight).toBe(linesHeight + blockDecorationsHeight)
it "updates when the ::lineHeight changes", ->
presenter = buildPresenter(scrollTop: 0, lineHeight: 10)
expectStateUpdate presenter, -> presenter.setLineHeight(20)

View File

@@ -28,6 +28,7 @@ class TextEditorPresenter
@lineDecorationsByScreenRow = {}
@lineNumberDecorationsByScreenRow = {}
@customGutterDecorationsByGutterName = {}
@blockDecorationsDimensions = new Map
@screenRowsToMeasure = []
@transferMeasurementsToModel()
@transferMeasurementsFromModel()
@@ -71,6 +72,7 @@ class TextEditorPresenter
getPreMeasurementState: ->
@updating = true
@updateBlockDecorations() if @shouldUpdateBlockDecorations
@updateVerticalDimensions()
@updateScrollbarDimensions()
@@ -140,6 +142,7 @@ class TextEditorPresenter
@shouldUpdateHiddenInputState = false
@shouldUpdateContentState = false
@shouldUpdateDecorations = false
@shouldUpdateBlockDecorations = false
@shouldUpdateLinesState = false
@shouldUpdateTilesState = false
@shouldUpdateCursorsState = false
@@ -158,6 +161,7 @@ class TextEditorPresenter
@shouldUpdateHiddenInputState = true
@shouldUpdateContentState = true
@shouldUpdateDecorations = true
@shouldUpdateBlockDecorations = true
@shouldUpdateLinesState = true
@shouldUpdateTilesState = true
@shouldUpdateCursorsState = true
@@ -188,6 +192,8 @@ class TextEditorPresenter
@shouldUpdateLineNumbersState = true
@shouldUpdateDecorations = true
@shouldUpdateOverlaysState = true
@shouldUpdateBlockDecorations = true
@shouldUpdateVerticalScrollState = true
@shouldUpdateCustomGutterDecorationState = true
@emitDidUpdateState()
@@ -727,10 +733,19 @@ class TextEditorPresenter
@scrollHeight = scrollHeight
@updateScrollTop(@scrollTop)
getLinesHeight: ->
@lineHeight * @model.getScreenLineCount()
getBlockDecorationsHeight: ->
sizes = Array.from(@blockDecorationsDimensions.values())
sum = (a, b) -> a + b
height = sizes.map((size) -> size.height).reduce(sum, 0)
height
updateVerticalDimensions: ->
if @lineHeight?
oldContentHeight = @contentHeight
@contentHeight = @lineHeight * @model.getScreenLineCount()
@contentHeight = Math.round(@getLinesHeight() + @getBlockDecorationsHeight())
if @contentHeight isnt oldContentHeight
@updateHeight()
@@ -1364,6 +1379,24 @@ class TextEditorPresenter
@emitDidUpdateState()
setBlockDecorationSize: (decoration, width, height) ->
@blockDecorationsDimensions.set(decoration.id, {width, height})
@shouldUpdateBlockDecorations = true
@shouldUpdateVerticalScrollState = true
@emitDidUpdateState()
updateBlockDecorations: ->
blockDecorations = {}
for decoration in @model.getDecorations(type: "block")
blockDecorations[decoration.id] = decoration
@blockDecorationsDimensions.forEach (value, key) =>
unless blockDecorations.hasOwnProperty(key)
@blockDecorationsDimensions.delete(key)
@shouldUpdateVerticalScrollState = true
observeCursor: (cursor) ->
didChangePositionDisposable = cursor.onDidChangePosition =>
@shouldUpdateHiddenInputState = true if cursor.isLastCursor()