[Gutter] TextEditorPresenter: Consolidate common gutter state under @state.gutters

This commit is contained in:
Jess Lin 2015-04-01 15:31:50 -07:00
parent d54e48699b
commit 14e5d38354
4 changed files with 111 additions and 108 deletions

View File

@ -1767,97 +1767,6 @@ describe "TextEditorPresenter", ->
}
describe ".lineNumberGutter", ->
describe ".scrollHeight", ->
it "is initialized based on ::lineHeight, the number of lines, and ::explicitHeight", ->
presenter = buildPresenter()
expect(presenter.getState().lineNumberGutter.scrollHeight).toBe editor.getScreenLineCount() * 10
presenter = buildPresenter(explicitHeight: 500)
expect(presenter.getState().lineNumberGutter.scrollHeight).toBe 500
it "updates when the ::lineHeight changes", ->
presenter = buildPresenter()
expectStateUpdate presenter, -> presenter.setLineHeight(20)
expect(presenter.getState().lineNumberGutter.scrollHeight).toBe editor.getScreenLineCount() * 20
it "updates when the line count changes", ->
presenter = buildPresenter()
expectStateUpdate presenter, -> editor.getBuffer().append("\n\n\n")
expect(presenter.getState().lineNumberGutter.scrollHeight).toBe editor.getScreenLineCount() * 10
it "updates when ::explicitHeight changes", ->
presenter = buildPresenter()
expectStateUpdate presenter, -> presenter.setExplicitHeight(500)
expect(presenter.getState().lineNumberGutter.scrollHeight).toBe 500
it "adds the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10)
expectStateUpdate presenter, -> presenter.setScrollTop(300)
expect(presenter.getState().lineNumberGutter.scrollHeight).toBe presenter.contentHeight
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", true)
expect(presenter.getState().lineNumberGutter.scrollHeight).toBe presenter.contentHeight + presenter.clientHeight - (presenter.lineHeight * 3)
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false)
expect(presenter.getState().lineNumberGutter.scrollHeight).toBe presenter.contentHeight
describe ".scrollTop", ->
it "tracks the value of ::scrollTop", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 20)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe 10
expectStateUpdate presenter, -> presenter.setScrollTop(50)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe 50
it "never exceeds the computed scrollHeight minus the computed clientHeight", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10)
expectStateUpdate presenter, -> presenter.setScrollTop(100)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight
expectStateUpdate presenter, -> presenter.setExplicitHeight(60)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight
expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(5)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight
expectStateUpdate presenter, -> editor.getBuffer().delete([[8, 0], [12, 0]])
expect(presenter.getState().lineNumberGutter.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight
# Scroll top only gets smaller when needed as dimensions change, never bigger
scrollTopBefore = presenter.getState().verticalScrollbar.scrollTop
expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n')
expect(presenter.getState().lineNumberGutter.scrollTop).toBe scrollTopBefore
it "never goes negative", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10)
expectStateUpdate presenter, -> presenter.setScrollTop(-100)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe 0
it "adds the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10)
expectStateUpdate presenter, -> presenter.setScrollTop(300)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe presenter.contentHeight - presenter.clientHeight
atom.config.set("editor.scrollPastEnd", true)
expectStateUpdate presenter, -> presenter.setScrollTop(300)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe presenter.contentHeight - (presenter.lineHeight * 3)
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false)
expect(presenter.getState().lineNumberGutter.scrollTop).toBe presenter.contentHeight - presenter.clientHeight
describe ".backgroundColor", ->
it "is assigned to ::gutterBackgroundColor if present, and to ::backgroundColor otherwise", ->
presenter = buildPresenter(backgroundColor: "rgba(255, 0, 0, 0)", gutterBackgroundColor: "rgba(0, 255, 0, 0)")
expect(presenter.getState().lineNumberGutter.backgroundColor).toBe "rgba(0, 255, 0, 0)"
expectStateUpdate presenter, -> presenter.setGutterBackgroundColor("rgba(0, 0, 255, 0)")
expect(presenter.getState().lineNumberGutter.backgroundColor).toBe "rgba(0, 0, 255, 0)"
expectStateUpdate presenter, -> presenter.setGutterBackgroundColor("rgba(0, 0, 0, 0)")
expect(presenter.getState().lineNumberGutter.backgroundColor).toBe "rgba(255, 0, 0, 0)"
expectStateUpdate presenter, -> presenter.setBackgroundColor("rgba(0, 0, 255, 0)")
expect(presenter.getState().lineNumberGutter.backgroundColor).toBe "rgba(0, 0, 255, 0)"
describe ".maxLineNumberDigits", ->
it "is set to the number of digits used by the greatest line number", ->
presenter = buildPresenter()
@ -2191,6 +2100,97 @@ describe "TextEditorPresenter", ->
expect(presenter.getState().focused).toBe false
describe ".gutters", ->
describe ".scrollHeight", ->
it "is initialized based on ::lineHeight, the number of lines, and ::explicitHeight", ->
presenter = buildPresenter()
expect(presenter.getState().gutters.scrollHeight).toBe editor.getScreenLineCount() * 10
presenter = buildPresenter(explicitHeight: 500)
expect(presenter.getState().gutters.scrollHeight).toBe 500
it "updates when the ::lineHeight changes", ->
presenter = buildPresenter()
expectStateUpdate presenter, -> presenter.setLineHeight(20)
expect(presenter.getState().gutters.scrollHeight).toBe editor.getScreenLineCount() * 20
it "updates when the line count changes", ->
presenter = buildPresenter()
expectStateUpdate presenter, -> editor.getBuffer().append("\n\n\n")
expect(presenter.getState().gutters.scrollHeight).toBe editor.getScreenLineCount() * 10
it "updates when ::explicitHeight changes", ->
presenter = buildPresenter()
expectStateUpdate presenter, -> presenter.setExplicitHeight(500)
expect(presenter.getState().gutters.scrollHeight).toBe 500
it "adds the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10)
expectStateUpdate presenter, -> presenter.setScrollTop(300)
expect(presenter.getState().gutters.scrollHeight).toBe presenter.contentHeight
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", true)
expect(presenter.getState().gutters.scrollHeight).toBe presenter.contentHeight + presenter.clientHeight - (presenter.lineHeight * 3)
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false)
expect(presenter.getState().gutters.scrollHeight).toBe presenter.contentHeight
describe ".scrollTop", ->
it "tracks the value of ::scrollTop", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 20)
expect(presenter.getState().gutters.scrollTop).toBe 10
expectStateUpdate presenter, -> presenter.setScrollTop(50)
expect(presenter.getState().gutters.scrollTop).toBe 50
it "never exceeds the computed scrollHeight minus the computed clientHeight", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10)
expectStateUpdate presenter, -> presenter.setScrollTop(100)
expect(presenter.getState().gutters.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight
expectStateUpdate presenter, -> presenter.setExplicitHeight(60)
expect(presenter.getState().gutters.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight
expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(5)
expect(presenter.getState().gutters.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight
expectStateUpdate presenter, -> editor.getBuffer().delete([[8, 0], [12, 0]])
expect(presenter.getState().gutters.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight
# Scroll top only gets smaller when needed as dimensions change, never bigger
scrollTopBefore = presenter.getState().verticalScrollbar.scrollTop
expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n')
expect(presenter.getState().gutters.scrollTop).toBe scrollTopBefore
it "never goes negative", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10)
expectStateUpdate presenter, -> presenter.setScrollTop(-100)
expect(presenter.getState().gutters.scrollTop).toBe 0
it "adds the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10)
expectStateUpdate presenter, -> presenter.setScrollTop(300)
expect(presenter.getState().gutters.scrollTop).toBe presenter.contentHeight - presenter.clientHeight
atom.config.set("editor.scrollPastEnd", true)
expectStateUpdate presenter, -> presenter.setScrollTop(300)
expect(presenter.getState().gutters.scrollTop).toBe presenter.contentHeight - (presenter.lineHeight * 3)
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false)
expect(presenter.getState().gutters.scrollTop).toBe presenter.contentHeight - presenter.clientHeight
describe ".backgroundColor", ->
it "is assigned to ::gutterBackgroundColor if present, and to ::backgroundColor otherwise", ->
presenter = buildPresenter(backgroundColor: "rgba(255, 0, 0, 0)", gutterBackgroundColor: "rgba(0, 255, 0, 0)")
expect(presenter.getState().gutters.backgroundColor).toBe "rgba(0, 255, 0, 0)"
expectStateUpdate presenter, -> presenter.setGutterBackgroundColor("rgba(0, 0, 255, 0)")
expect(presenter.getState().gutters.backgroundColor).toBe "rgba(0, 0, 255, 0)"
expectStateUpdate presenter, -> presenter.setGutterBackgroundColor("rgba(0, 0, 0, 0)")
expect(presenter.getState().gutters.backgroundColor).toBe "rgba(255, 0, 0, 0)"
expectStateUpdate presenter, -> presenter.setBackgroundColor("rgba(0, 0, 255, 0)")
expect(presenter.getState().gutters.backgroundColor).toBe "rgba(0, 0, 255, 0)"
describe ".sortedDescriptions", ->
gutterDescriptionWithName = (presenter, name) ->
for gutterDesc in presenter.getState().gutters.sortedDescriptions

View File

@ -38,12 +38,11 @@ class CustomGutterComponent
@visible = true
updateSync: (state) ->
gutterProps = state.lineNumberGutter
@oldDimensionsAndBackgroundState ?= {}
newDimensionsAndBackgroundState = state.gutters
setDimensionsAndBackground(@oldDimensionsAndBackgroundState, newDimensionsAndBackgroundState, @decorationsNode)
decorationState = state.gutters.customDecorations[@getName()]
@oldState ?= {}
setDimensionsAndBackground(@oldState, gutterProps, @decorationsNode)
return if !decorationState
updatedDecorationIds = new Set

View File

@ -39,7 +39,8 @@ class LineNumberGutterComponent
@appendDummyLineNumber() unless @dummyLineNumberNode?
setDimensionsAndBackground(@oldState, @newState, @lineNumbersNode)
newDimensionsAndBackgroundState = state.gutters
setDimensionsAndBackground(@oldState, newDimensionsAndBackgroundState, @lineNumbersNode)
if @newState.maxLineNumberDigits isnt @oldState.maxLineNumberDigits
@updateDummyLineNumber()

View File

@ -121,10 +121,12 @@ class TextEditorPresenter
@updateLinesState()
@updateLineNumberGutterState()
@updateLineNumbersState()
@updateCommonGutterState()
@updateCustomGutterState()
@updateCustomGutterDecorationState()
@disposables.add @model.onDidChangeLineNumberGutterVisible =>
@updateLineNumberGutterState()
@updateCommonGutterState()
@updateCustomGutterState()
@disposables.add @model.onDidAddDecoration(@didAddDecoration.bind(this))
@disposables.add @model.onDidAddCursor(@didAddCursor.bind(this))
@ -160,12 +162,14 @@ class TextEditorPresenter
@configDisposables.add atom.config.onDidChange 'editor.showLineNumbers', configParams, ({newValue}) =>
@showLineNumbers = newValue
@updateLineNumberGutterState()
@updateCommonGutterState()
@updateCustomGutterState()
didChangeGrammar: ->
@observeConfig()
@updateContentState()
@updateLineNumberGutterState()
@updateCommonGutterState()
@updateCustomGutterState()
buildState: ->
@ -205,6 +209,7 @@ class TextEditorPresenter
@updateOverlaysState()
@updateLineNumberGutterState()
@updateLineNumbersState()
@updateCommonGutterState()
@updateCustomGutterState()
@updateCustomGutterDecorationState()
@ -219,11 +224,11 @@ class TextEditorPresenter
updateVerticalScrollState: -> @batch "shouldUpdateVerticalScrollState", ->
@state.content.scrollHeight = @scrollHeight
@state.lineNumberGutter.scrollHeight = @scrollHeight
@state.gutters.scrollHeight = @scrollHeight
@state.verticalScrollbar.scrollHeight = @scrollHeight
@state.content.scrollTop = @scrollTop
@state.lineNumberGutter.scrollTop = @scrollTop
@state.gutters.scrollTop = @scrollTop
@state.verticalScrollbar.scrollTop = @scrollTop
updateHorizontalScrollState: -> @batch "shouldUpdateHorizontalScrollState", ->
@ -380,13 +385,12 @@ class TextEditorPresenter
updateLineNumberGutterState: -> @batch "shouldUpdateLineNumberGutterState", ->
@state.lineNumberGutter.maxLineNumberDigits = @model.getLineCount().toString().length
@state.lineNumberGutter.backgroundColor = @getGutterBackgroundColor()
getGutterBackgroundColor: ->
if @gutterBackgroundColor isnt "rgba(0, 0, 0, 0)"
@gutterBackgroundColor
else
@backgroundColor
updateCommonGutterState: ->
@state.gutters.backgroundColor = if @gutterBackgroundColor isnt "rgba(0, 0, 0, 0)"
@gutterBackgroundColor
else
@backgroundColor
didAddGutter: (gutter) ->
gutterDisposables = new CompositeDisposable
@ -403,9 +407,6 @@ class TextEditorPresenter
updateCustomGutterState: ->
@batch "shouldUpdateCustomGutterState", ->
# For now, just match the background color of the line-number gutter.
# TODO: Allow gutters to have different background colors. (?)
@state.gutters.backgroundColor = @getGutterBackgroundColor()
@state.gutters.sortedDescriptions = []
if @model.isMini()
return
@ -808,12 +809,14 @@ class TextEditorPresenter
@backgroundColor = backgroundColor
@updateContentState()
@updateLineNumberGutterState()
@updateCommonGutterState()
@updateCustomGutterState()
setGutterBackgroundColor: (gutterBackgroundColor) ->
unless @gutterBackgroundColor is gutterBackgroundColor
@gutterBackgroundColor = gutterBackgroundColor
@updateLineNumberGutterState()
@updateCommonGutterState()
@updateCustomGutterState()
setLineHeight: (lineHeight) ->