mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-13 08:44:12 +03:00
Overlay decorations render
This commit is contained in:
parent
89ab0becc2
commit
c79db992d9
@ -7,6 +7,7 @@ React = require 'react-atom-fork'
|
||||
Decoration = require './decoration'
|
||||
CursorsComponent = require './cursors-component'
|
||||
HighlightsComponent = require './highlights-component'
|
||||
OverlayManager = require './overlay-manager'
|
||||
|
||||
DummyLineNode = $$(-> @div className: 'line', style: 'position: absolute; visibility: hidden;', => @span 'x')[0]
|
||||
AcceptFilter = {acceptNode: -> NodeFilter.FILTER_ACCEPT}
|
||||
@ -20,7 +21,7 @@ LinesComponent = React.createClass
|
||||
{performedInitialMeasurement, cursorBlinkPeriod, cursorBlinkResumeDelay} = @props
|
||||
|
||||
if performedInitialMeasurement
|
||||
{editor, highlightDecorations, scrollHeight, scrollWidth, placeholderText, backgroundColor} = @props
|
||||
{editor, overlayDecorations, highlightDecorations, scrollHeight, scrollWidth, placeholderText, backgroundColor} = @props
|
||||
{lineHeightInPixels, defaultCharWidth, scrollViewHeight, scopedCharacterWidthsChangeCount} = @props
|
||||
{scrollTop, scrollLeft, cursorPixelRects, mini} = @props
|
||||
style =
|
||||
@ -63,10 +64,15 @@ LinesComponent = React.createClass
|
||||
insertionPoint.setAttribute('select', '.overlayer')
|
||||
@getDOMNode().appendChild(insertionPoint)
|
||||
|
||||
insertionPoint = document.createElement('content')
|
||||
insertionPoint.setAttribute('select', 'atom-overlay')
|
||||
@overlayManager = new OverlayManager()
|
||||
@getDOMNode().appendChild(insertionPoint)
|
||||
|
||||
shouldComponentUpdate: (newProps) ->
|
||||
return true unless isEqualForProperties(newProps, @props,
|
||||
'renderedRowRange', 'lineDecorations', 'highlightDecorations', 'lineHeightInPixels', 'defaultCharWidth',
|
||||
'scrollTop', 'scrollLeft', 'showIndentGuide', 'scrollingVertically', 'visible',
|
||||
'overlayDecorations', 'scrollTop', 'scrollLeft', 'showIndentGuide', 'scrollingVertically', 'visible',
|
||||
'scrollViewHeight', 'mouseWheelScreenRow', 'scopedCharacterWidthsChangeCount', 'lineWidth', 'useHardwareAcceleration',
|
||||
'placeholderText', 'performedInitialMeasurement', 'backgroundColor', 'cursorPixelRects'
|
||||
)
|
||||
@ -92,6 +98,8 @@ LinesComponent = React.createClass
|
||||
@updateLines(@props.lineWidth isnt prevProps.lineWidth)
|
||||
@measureCharactersInNewLines() if visible and not scrollingVertically
|
||||
|
||||
@overlayManager?.render(@props)
|
||||
|
||||
clearScreenRowCaches: ->
|
||||
@screenRowsByLineId = {}
|
||||
@lineIdsByScreenRow = {}
|
||||
|
31
src/overlay-manager.coffee
Normal file
31
src/overlay-manager.coffee
Normal file
@ -0,0 +1,31 @@
|
||||
module.exports =
|
||||
class OverlayManager
|
||||
constructor: ->
|
||||
@overlays = {}
|
||||
|
||||
render: (props) ->
|
||||
{hostElement, editor, overlayDecorations, lineHeightInPixels} = props
|
||||
|
||||
existingDecorations = null
|
||||
for markerId, {startPixelPosition, endPixelPosition, decorations} of overlayDecorations
|
||||
for decoration in decorations
|
||||
@renderOverlay(hostElement, decoration, endPixelPosition)
|
||||
|
||||
existingDecorations ?= {}
|
||||
existingDecorations[decoration.id] = true
|
||||
|
||||
for id, overlay of @overlays
|
||||
unless existingDecorations? and id of existingDecorations
|
||||
hostElement.removeChild(overlay)
|
||||
delete @overlays[id]
|
||||
|
||||
return
|
||||
|
||||
renderOverlay: (hostElement, decoration, endPixelPosition) ->
|
||||
unless overlay = @overlays[decoration.id]
|
||||
overlay = @overlays[decoration.id] = document.createElement('atom-overlay')
|
||||
overlay.appendChild(atom.views.getView(decoration.item))
|
||||
hostElement.appendChild(overlay)
|
||||
|
||||
overlay.style.top = endPixelPosition.top + 'px'
|
||||
overlay.style.left = endPixelPosition.left + 'px'
|
@ -50,7 +50,7 @@ TextEditorComponent = React.createClass
|
||||
|
||||
render: ->
|
||||
{focused, showIndentGuide, showLineNumbers, visible} = @state
|
||||
{editor, mini, cursorBlinkPeriod, cursorBlinkResumeDelay} = @props
|
||||
{editor, mini, cursorBlinkPeriod, cursorBlinkResumeDelay, hostElement} = @props
|
||||
maxLineNumberDigits = editor.getLineCount().toString().length
|
||||
hasSelection = editor.getLastSelection()? and !editor.getLastSelection().isEmpty()
|
||||
style = {}
|
||||
@ -66,6 +66,7 @@ TextEditorComponent = React.createClass
|
||||
|
||||
decorations = editor.decorationsForScreenRowRange(renderedStartRow, renderedEndRow)
|
||||
highlightDecorations = @getHighlightDecorations(decorations)
|
||||
overlayDecorations = @getOverlayDecorations(decorations)
|
||||
lineDecorations = @getLineDecorations(decorations)
|
||||
placeholderText = editor.getPlaceholderText() if editor.isEmpty()
|
||||
visible = @isVisible()
|
||||
@ -110,7 +111,8 @@ TextEditorComponent = React.createClass
|
||||
|
||||
LinesComponent {
|
||||
ref: 'lines',
|
||||
editor, lineHeightInPixels, defaultCharWidth, tokenizedLines, lineDecorations, highlightDecorations,
|
||||
editor, lineHeightInPixels, defaultCharWidth, tokenizedLines,
|
||||
lineDecorations, highlightDecorations, overlayDecorations, hostElement,
|
||||
showIndentGuide, renderedRowRange, @pendingChanges, scrollTop, scrollLeft,
|
||||
@scrollingVertically, scrollHeight, scrollWidth, mouseWheelScreenRow,
|
||||
visible, scrollViewHeight, @scopedCharacterWidthsChangeCount, lineWidth, @useHardwareAcceleration,
|
||||
@ -351,7 +353,24 @@ TextEditorComponent = React.createClass
|
||||
endPixelPosition: editor.pixelPositionForScreenPosition(screenRange.end)
|
||||
decorations: []
|
||||
filteredDecorations[markerId].decorations.push decorationParams
|
||||
filteredDecorations
|
||||
|
||||
getOverlayDecorations: (decorationsByMarkerId) ->
|
||||
{editor} = @props
|
||||
filteredDecorations = {}
|
||||
for markerId, decorations of decorationsByMarkerId
|
||||
marker = editor.getMarker(markerId)
|
||||
screenRange = marker.getScreenRange()
|
||||
if marker.isValid()
|
||||
for decoration in decorations
|
||||
if decoration.isType('overlay')
|
||||
decorationParams = decoration.getProperties()
|
||||
filteredDecorations[markerId] ?=
|
||||
id: markerId
|
||||
startPixelPosition: editor.pixelPositionForScreenPosition(screenRange.start)
|
||||
endPixelPosition: editor.pixelPositionForScreenPosition(screenRange.end)
|
||||
decorations: []
|
||||
filteredDecorations[markerId].decorations.push decorationParams
|
||||
filteredDecorations
|
||||
|
||||
observeEditor: ->
|
||||
|
@ -12,6 +12,12 @@ atom-text-editor.mini {
|
||||
max-height: @component-line-height + 2; // +2 for borders
|
||||
}
|
||||
|
||||
atom-overlay {
|
||||
position: absolute;
|
||||
display: block;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
// TODO: remove this when the shadow DOM is the default
|
||||
atom-text-editor .highlight {
|
||||
background: none;
|
||||
|
Loading…
Reference in New Issue
Block a user