mirror of
https://github.com/atom/atom.git
synced 2026-02-18 02:21:43 -05:00
Use presenter to render highlights
Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
@@ -5,94 +5,45 @@ React = require 'react-atom-fork'
|
||||
module.exports =
|
||||
HighlightComponent = React.createClass
|
||||
displayName: 'HighlightComponent'
|
||||
lastFlashCount: 0
|
||||
lastFlashClass: null
|
||||
|
||||
render: ->
|
||||
{startPixelPosition, endPixelPosition, decoration} = @props
|
||||
{editor, state} = @props
|
||||
|
||||
className = 'highlight'
|
||||
className += " #{decoration.class}" if decoration.class?
|
||||
className += " #{state.class}" if state.class?
|
||||
|
||||
div {className},
|
||||
if endPixelPosition.top is startPixelPosition.top
|
||||
@renderSingleLineRegions(decoration.deprecatedRegionClass)
|
||||
else
|
||||
@renderMultiLineRegions(decoration.deprecatedRegionClass)
|
||||
for region, i in state.regions
|
||||
regionClassName = 'region'
|
||||
regionClassName += " #{state.deprecatedRegionClass}" if state.deprecatedRegionClass?
|
||||
div className: regionClassName, key: i, style: region
|
||||
|
||||
componentDidUpdate: ->
|
||||
if @props.state.flashCount > @lastFlashCount
|
||||
@startFlashAnimation()
|
||||
@lastFlashCount = @props.state.flashCount
|
||||
@lastFlashClass = @props.state.flashClass
|
||||
|
||||
componentDidMount: ->
|
||||
{editor, decoration} = @props
|
||||
if decoration.id?
|
||||
@decoration = editor.decorationForId(decoration.id)
|
||||
@decorationDisposable = @decoration.onDidFlash @startFlashAnimation
|
||||
@startFlashAnimation()
|
||||
{key} = @props
|
||||
presenter.onDidFlashHighlight @startFlashAnimation.bind(this)
|
||||
|
||||
componentWillUnmount: ->
|
||||
@decorationDisposable?.dispose()
|
||||
@decorationDisposable = null
|
||||
|
||||
startFlashAnimation: ->
|
||||
return unless flash = @decoration.consumeNextFlash()
|
||||
|
||||
node = @getDOMNode()
|
||||
node.classList.remove(flash.class)
|
||||
|
||||
if @lastFlashClass?
|
||||
clearTimeout(@flashTimeoutId)
|
||||
node.classList.remove(@lastFlashClass)
|
||||
@lastFlashClass = null
|
||||
|
||||
requestAnimationFrame =>
|
||||
node.classList.add(flash.class)
|
||||
clearTimeout(@flashTimeoutId)
|
||||
removeFlashClass = -> node.classList.remove(flash.class)
|
||||
flashClass = @props.state.flashClass
|
||||
node.classList.add(flashClass)
|
||||
removeFlashClass = -> node.classList.remove(flashClass)
|
||||
@flashTimeoutId = setTimeout(removeFlashClass, flash.duration)
|
||||
|
||||
renderSingleLineRegions: (regionClass) ->
|
||||
{startPixelPosition, endPixelPosition, lineHeightInPixels} = @props
|
||||
|
||||
className = 'region'
|
||||
className += " #{regionClass}" if regionClass?
|
||||
|
||||
[
|
||||
div className: className, key: 0, style:
|
||||
top: startPixelPosition.top
|
||||
height: lineHeightInPixels
|
||||
left: startPixelPosition.left
|
||||
width: endPixelPosition.left - startPixelPosition.left
|
||||
]
|
||||
|
||||
renderMultiLineRegions: (regionClass) ->
|
||||
{startPixelPosition, endPixelPosition, lineHeightInPixels} = @props
|
||||
|
||||
className = 'region'
|
||||
className += " #{regionClass}" if regionClass?
|
||||
|
||||
regions = []
|
||||
index = 0
|
||||
|
||||
# First row, extending from selection start to the right side of screen
|
||||
regions.push(
|
||||
div className: className, key: index++, style:
|
||||
top: startPixelPosition.top
|
||||
left: startPixelPosition.left
|
||||
height: lineHeightInPixels
|
||||
right: 0
|
||||
)
|
||||
|
||||
# Middle rows, extending from left side to right side of screen
|
||||
if endPixelPosition.top - startPixelPosition.top > lineHeightInPixels
|
||||
regions.push(
|
||||
div className: className, key: index++, style:
|
||||
top: startPixelPosition.top + lineHeightInPixels
|
||||
height: endPixelPosition.top - startPixelPosition.top - lineHeightInPixels
|
||||
left: 0
|
||||
right: 0
|
||||
)
|
||||
|
||||
# Last row, extending from left side of screen to selection end
|
||||
regions.push(
|
||||
div className: className, key: index, style:
|
||||
top: endPixelPosition.top
|
||||
height: lineHeightInPixels
|
||||
left: 0
|
||||
width: endPixelPosition.left
|
||||
)
|
||||
|
||||
regions
|
||||
|
||||
shouldComponentUpdate: (newProps) ->
|
||||
not isEqualForProperties(newProps, @props, 'startPixelPosition', 'endPixelPosition', 'lineHeightInPixels', 'decoration')
|
||||
|
||||
@@ -12,13 +12,10 @@ HighlightsComponent = React.createClass
|
||||
@renderHighlights() if @props.performedInitialMeasurement
|
||||
|
||||
renderHighlights: ->
|
||||
{editor, highlightDecorations, lineHeightInPixels} = @props
|
||||
|
||||
{editor, presenter} = @props
|
||||
highlightComponents = []
|
||||
for markerId, {startPixelPosition, endPixelPosition, decorations} of highlightDecorations
|
||||
for decoration in decorations
|
||||
highlightComponents.push(HighlightComponent({editor, key: "#{markerId}-#{decoration.id}", startPixelPosition, endPixelPosition, decoration, lineHeightInPixels}))
|
||||
|
||||
for key, state of presenter.state.content.highlights
|
||||
highlightComponents.push(HighlightComponent({editor, key, state}))
|
||||
highlightComponents
|
||||
|
||||
componentDidMount: ->
|
||||
|
||||
@@ -40,7 +40,7 @@ LinesComponent = React.createClass
|
||||
|
||||
HighlightsComponent {
|
||||
editor, highlightDecorations, lineHeightInPixels, defaultCharWidth,
|
||||
scopedCharacterWidthsChangeCount, performedInitialMeasurement
|
||||
scopedCharacterWidthsChangeCount, performedInitialMeasurement, presenter
|
||||
}
|
||||
|
||||
getTransform: ->
|
||||
|
||||
@@ -115,6 +115,7 @@ class TextEditorPresenter
|
||||
@state.content.highlights = {}
|
||||
|
||||
for decoration in @model.getHighlightDecorations()
|
||||
continue unless decoration.getMarker().isValid()
|
||||
screenRange = decoration.getMarker().getScreenRange()
|
||||
if screenRange.intersectsRowRange(startRow, endRow - 1)
|
||||
if screenRange.start.row < startRow
|
||||
@@ -126,7 +127,12 @@ class TextEditorPresenter
|
||||
continue if screenRange.isEmpty()
|
||||
@state.content.highlights[decoration.id] =
|
||||
class: decoration.getProperties().class
|
||||
deprecatedRegionClass: decoration.getProperties().deprecatedRegionClass
|
||||
regions: @buildHighlightRegions(screenRange)
|
||||
flashCount: 0
|
||||
flashDuration: null
|
||||
flashClass: null
|
||||
@emitter.emit 'did-update-state'
|
||||
|
||||
buildHighlightRegions: (screenRange) ->
|
||||
lineHeightInPixels = @getLineHeight()
|
||||
@@ -331,24 +337,30 @@ class TextEditorPresenter
|
||||
{top, left, width, height}
|
||||
|
||||
observeLineDecoration: (decoration) ->
|
||||
markerDidChangeDisposable = decoration.getMarker().onDidChange(@updateLinesState.bind(this))
|
||||
didDestroyDisposable = decoration.onDidDestroy =>
|
||||
@disposables.remove(markerDidChangeDisposable)
|
||||
@disposables.remove(didDestroyDisposable)
|
||||
decorationDisposables = new CompositeDisposable
|
||||
decorationDisposables.add decoration.getMarker().onDidChange(@updateLinesState.bind(this))
|
||||
decorationDisposables.add decoration.onDidDestroy =>
|
||||
@disposables.remove(decorationDisposables)
|
||||
@updateLinesState()
|
||||
|
||||
@disposables.add(markerDidChangeDisposable)
|
||||
@disposables.add(didDestroyDisposable)
|
||||
@disposables.add(decorationDisposables)
|
||||
|
||||
observeHighlightDecoration: (decoration) ->
|
||||
markerDidChangeDisposable = decoration.getMarker().onDidChange(@updateHighlightsState.bind(this))
|
||||
didDestroyDisposable = decoration.onDidDestroy =>
|
||||
@disposables.remove(markerDidChangeDisposable)
|
||||
@disposables.remove(didDestroyDisposable)
|
||||
decorationDisposables = new CompositeDisposable
|
||||
decorationDisposables.add decoration.getMarker().onDidChange(@updateHighlightsState.bind(this))
|
||||
decorationDisposables.add decoration.onDidChangeProperties(@updateHighlightsState.bind(this))
|
||||
decorationDisposables.add decoration.onDidFlash(@highlightDidFlash.bind(this, decoration))
|
||||
decorationDisposables.add decoration.onDidDestroy =>
|
||||
@disposables.remove(decorationDisposables)
|
||||
@updateHighlightsState()
|
||||
@disposables.add(decorationDisposables)
|
||||
|
||||
@disposables.add(markerDidChangeDisposable)
|
||||
@disposables.add(didDestroyDisposable)
|
||||
highlightDidFlash: (decoration) ->
|
||||
flash = decoration.consumeNextFlash()
|
||||
decorationState = @state.content.highlights[decoration.id]
|
||||
decorationState.flashCount++
|
||||
decorationState.flashClass = flash.class
|
||||
decorationState.flashDuration = flash.duration
|
||||
@emitter.emit "did-update-state"
|
||||
|
||||
didAddDecoration: (decoration) ->
|
||||
if decoration.isType('line')
|
||||
|
||||
Reference in New Issue
Block a user