Add width to lines state based on the computed scrollWidth

This is based on the ::baseCharacterWidth property for now. To be fully
correct, we need to base the scrollWidth on the actual width of
individual characters.
This commit is contained in:
Nathan Sobo 2015-01-19 12:26:30 -07:00
parent a1c2e1bb66
commit f4d8ef8315
2 changed files with 67 additions and 1 deletions

View File

@ -79,6 +79,23 @@ describe "TextEditorPresenter", ->
# rows beyond the end of the content are not rendered
it "uses the computed scrollWidth as the length of each line", ->
line0 = editor.tokenizedLineForScreenRow(0)
line1 = editor.tokenizedLineForScreenRow(1)
line2 = editor.tokenizedLineForScreenRow(2)
maxLineLength = editor.getMaxScreenLineLength()
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, clientWidth: 50, scrollTop: 0, baseCharacterWidth: 10, lineHeight: 10, lineOverdrawMargin: 0)
expect(presenter.state.lines[line0.id].width).toBe 10 * maxLineLength
expect(presenter.state.lines[line1.id].width).toBe 10 * maxLineLength
expect(presenter.state.lines[line2.id].width).toBe 10 * maxLineLength
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, clientWidth: 10 * maxLineLength + 20, scrollTop: 0, baseCharacterWidth: 10, lineHeight: 10, lineOverdrawMargin: 0)
expect(presenter.state.lines[line0.id].width).toBe 10 * maxLineLength + 20
expect(presenter.state.lines[line1.id].width).toBe 10 * maxLineLength + 20
expect(presenter.state.lines[line2.id].width).toBe 10 * maxLineLength + 20
describe "when ::scrollTop changes", ->
it "updates the lines that are visible on screen", ->
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 1)
@ -224,3 +241,41 @@ describe "TextEditorPresenter", ->
tokens: line3.tokens
top: 10 * 3
}
describe "when the ::clientWidth changes", ->
it "updates the width of the lines if it changes the ::scrollWidth", ->
line0 = editor.tokenizedLineForScreenRow(0)
line1 = editor.tokenizedLineForScreenRow(1)
line2 = editor.tokenizedLineForScreenRow(2)
maxLineLength = editor.getMaxScreenLineLength()
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, clientWidth: 50, scrollTop: 0, scrollWidth: 70, lineHeight: 10, baseCharacterWidth: 10, lineOverdrawMargin: 0)
expect(presenter.state.lines[line0.id].width).toBe 10 * maxLineLength
expect(presenter.state.lines[line1.id].width).toBe 10 * maxLineLength
expect(presenter.state.lines[line2.id].width).toBe 10 * maxLineLength
presenter.setClientWidth(10 * maxLineLength + 20)
expect(presenter.state.lines[line0.id].width).toBe 10 * maxLineLength + 20
expect(presenter.state.lines[line1.id].width).toBe 10 * maxLineLength + 20
expect(presenter.state.lines[line2.id].width).toBe 10 * maxLineLength + 20
describe "when the ::baseCharacterWidth changes", ->
it "updates the width of the lines if it changes the ::scrollWidth", ->
line0 = editor.tokenizedLineForScreenRow(0)
line1 = editor.tokenizedLineForScreenRow(1)
line2 = editor.tokenizedLineForScreenRow(2)
maxLineLength = editor.getMaxScreenLineLength()
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, clientWidth: 50, scrollTop: 0, scrollWidth: 70, lineHeight: 10, baseCharacterWidth: 10, lineOverdrawMargin: 0)
expect(presenter.state.lines[line0.id].width).toBe 10 * maxLineLength
expect(presenter.state.lines[line1.id].width).toBe 10 * maxLineLength
expect(presenter.state.lines[line2.id].width).toBe 10 * maxLineLength
presenter.setBaseCharacterWidth(15)
expect(presenter.state.lines[line0.id].width).toBe 15 * maxLineLength
expect(presenter.state.lines[line1.id].width).toBe 15 * maxLineLength
expect(presenter.state.lines[line2.id].width).toBe 15 * maxLineLength

View File

@ -2,7 +2,7 @@
module.exports =
class TextEditorPresenter
constructor: ({@model, @clientHeight, @scrollTop, @lineHeight, @lineOverdrawMargin}) ->
constructor: ({@model, @clientHeight, @clientWidth, @scrollTop, @lineHeight, @baseCharacterWidth, @lineOverdrawMargin}) ->
@disposables = new CompositeDisposable
@state = {}
@subscribeToModel()
@ -41,12 +41,14 @@ class TextEditorPresenter
lineState = @state.lines[line.id]
lineState.screenRow = row
lineState.top = row * @lineHeight
lineState.width = @getScrollWidth()
buildLineState: (row, line) ->
@state.lines[line.id] =
screenRow: row
tokens: line.tokens
top: row * @lineHeight
width: @getScrollWidth()
getStartRow: ->
startRow = Math.floor(@scrollTop / @lineHeight) - @lineOverdrawMargin
@ -56,11 +58,20 @@ class TextEditorPresenter
endRow = @getStartRow() + Math.ceil(@clientHeight / @lineHeight) + @lineOverdrawMargin
Math.min(@model.getScreenLineCount(), endRow)
getScrollWidth: ->
Math.max(@model.getMaxScreenLineLength() * @baseCharacterWidth, @clientWidth)
setScrollTop: (@scrollTop) ->
@updateLinesState()
setClientHeight: (@clientHeight) ->
@updateLinesState()
setClientWidth: (@clientWidth) ->
@updateLinesState()
setLineHeight: (@lineHeight) ->
@updateLinesState()
setBaseCharacterWidth: (@baseCharacterWidth) ->
@updateLinesState()