Skip to content

Commit

Permalink
Replacing adornments also replace all other kinds of adornments. Allo…
Browse files Browse the repository at this point in the history
…ws collapsing of nested regions of text containing other adornments.
  • Loading branch information
refactoringdr committed Sep 27, 2024
1 parent dce9431 commit 053602e
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,14 @@ BrTextEditorSegmentSplitterExamples >> appendingInReplacingAdornmentTextSplit [
split: text
from: 1
to: text size.
self assert: segments size equals: 4.
self assert: segments size equals: 3.
self assert: segments first isText.
self assert: segments first textStart equals: 1.
self assert: segments first textEnd equals: 3.
self assert: segments first text asString equals: '12'.
self assert: (segments second isKindOf: BrTextEditorLineSegmentAdornmentPiece).
self assert: segments second adornmentAttribute equals: appending.
self assert: segments second text asString equals: '34'.
self assert: (segments third isKindOf: BrTextEditorLineSegmentAdornmentPiece).
self assert: segments third adornmentAttribute equals: replacing.
self assert: segments third text asString equals: '56'.
self assert: segments second adornmentAttribute equals: replacing.
self assert: segments second text asString equals: '56'.
self assert: segments last isText.
self assert: segments last textStart equals: 7.
self assert: segments last textEnd equals: 11.
Expand Down
77 changes: 41 additions & 36 deletions src/Brick-Editor/BrTextEditorLineSegmentHolder.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -30,57 +30,62 @@ BrTextEditorLineSegmentHolder class >> defaultSegmentLayout: aBlock [
{ #category : #'private - segment' }
BrTextEditorLineSegmentHolder >> buildSegment: anEditorSegment [
| newPieceElements thePieces hasSelection hasCursor |

segment := anEditorSegment.

hasSelection := self hasSelection.
hasCursor := self hasCursor.

BlFrameTelemetry
time: [ 'Update segment properties' ]
during: [ segment updateSegmentProperties ].

pieceElements := self newPiecesMap.
pieceElements := BrTextEditorLineSegmentPieceDictionaryMap new.
newPieceElements := OrderedCollection new.

thePieces := BlFrameTelemetry
time: [ 'Get pieces' ]
during: [ segment pieces ].

thePieces := BlFrameTelemetry time: [ 'Get pieces' ] during: [ segment pieces ].

BlFrameTelemetry
time: [ 'Create piece elements' ]
during: [
thePieces withIndexDo: [ :aPiece :eachIndex |
| thePieceElements |

thePieceElements := BlFrameTelemetry
time: [ 'Create piece elements at {1} for {2}' format: { eachIndex. aPiece class name } ]
during: [ (aPiece createElement: self infiniteElement) asOrderedCollection ].

newPieceElements addAll: thePieceElements.
pieceElements atPiece: aPiece putElements: thePieceElements ] ].
during: [ thePieces
withIndexDo: [ :aPiece :eachIndex |
| thePieceElements |
thePieceElements := BlFrameTelemetry
time: [ 'Create piece elements at {1} for {2}'
format: {eachIndex.
aPiece class name} ]
during: [ (aPiece createElement: self infiniteElement)
asOrderedCollection ].

newPieceElements addAll: thePieceElements.
pieceElements atPiece: aPiece putElements: thePieceElements ] ].

(hasCursor or: [ hasSelection ])
ifTrue: [
BlFrameTelemetry
ifTrue: [ BlFrameTelemetry
timeSync: [ 'Set cursor, selection' ]
during: [
pieceElements piecesAndTheirElementsDo: [ :aPiece :aPieceElement |
hasCursor
ifTrue: [
BlFrameTelemetry
timeSync: [ 'Set cursor' ]
during: [ aPiece setCursor: aPieceElement of: anEditorSegment in: self infiniteElement ] ].

BlFrameTelemetry
timeSync: [ 'Set focus' ]
during: [ aPiece updateFocus: self infiniteElement isFocused of: aPieceElement in: self infiniteElement ].

hasSelection
ifTrue: [
BlFrameTelemetry
timeSync: [ 'Set selection' ]
during: [ aPiece updateSelection: aPieceElement of: anEditorSegment in: self infiniteElement ] ] ] ] ].
during: [ pieceElements
piecesAndTheirElementsDo: [ :aPiece :aPieceElement |
hasCursor
ifTrue: [ BlFrameTelemetry
timeSync: [ 'Set cursor' ]
during: [ aPiece
setCursor: aPieceElement
of: anEditorSegment
in: self infiniteElement ] ].

BlFrameTelemetry
timeSync: [ 'Set focus' ]
during: [ aPiece
updateFocus: self infiniteElement isFocused
of: aPieceElement
in: self infiniteElement ].

hasSelection
ifTrue: [ BlFrameTelemetry
timeSync: [ 'Set selection' ]
during: [ aPiece
updateSelection: aPieceElement
of: anEditorSegment
in: self infiniteElement ] ] ] ] ].

BlFrameTelemetry
timeSync: [ 'Remove segment children' ]
Expand Down
4 changes: 1 addition & 3 deletions src/Brick-Editor/BrTextEditorParagraphSegmentHolder.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ BrTextEditorParagraphSegmentHolder >> buildSegment: anEditorSegment [
"Initialize an itemElement for a given editor segment.
Please note, that itemElement may be reused from a previous segment, which means it is
important to also assign defaults such as empty selection or no cursors"

segment := anEditorSegment.
itemElement segment: segment.

Expand All @@ -42,7 +41,7 @@ BrTextEditorParagraphSegmentHolder >> buildSegment: anEditorSegment [

segment updateSegmentProperties.

pieceElements := self newPiecesMap.
pieceElements := BrTextEditorLineSegmentPieceDictionaryMap new.
newPieceElements := OrderedCollection new.

thePieces := segment pieces.
Expand All @@ -52,7 +51,6 @@ BrTextEditorParagraphSegmentHolder >> buildSegment: anEditorSegment [
| thePieceElements |
thePieceElements := (aPiece createElement: self infiniteElement)
asOrderedCollection.

newPieceElements addAll: thePieceElements.
pieceElements atPiece: aPiece putElements: thePieceElements ].

Expand Down
14 changes: 6 additions & 8 deletions src/Brick-Editor/BrTextEditorSegmentHolder.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ BrTextEditorSegmentHolder >> hasSelection [
^ false
]

{ #category : #'private - segment' }
BrTextEditorSegmentHolder >> newPiecesMap [
^ BrTextEditorLineSegmentPieceDictionaryMap new
]

{ #category : #updating }
BrTextEditorSegmentHolder >> onCursorChanged [
"Is sent when text editor's cursor changes.
Expand Down Expand Up @@ -98,7 +93,7 @@ BrTextEditorSegmentHolder >> updateCursorPresent: hasCursor selectionPresent: ha
{ #category : #'private - segment' }
BrTextEditorSegmentHolder >> updatePieceElements [
| newPieceElements newPieceMap |
newPieceMap := self newPiecesMap.
newPieceMap := BrTextEditorLineSegmentPieceDictionaryMap new.
newPieceElements := OrderedCollection new.

BlFrameTelemetry
Expand All @@ -113,9 +108,12 @@ BrTextEditorSegmentHolder >> updatePieceElements [
| thePieceElements |
thePieceElements := pieceElements
at: eachSegmentPiece
pieceAndElementsDo: [ "We should transfer the knowledge of the cursors to the new segment piece,
pieceAndElementsDo: [ :eachPiece :theSegmentElements |

"We should transfer the knowledge of the cursors to the new segment piece,
otherwise cursors may not be removed from the corresponding elements
https://github.com/feenkcom/gtoolkit/issues/892":eachPiece :theSegmentElements |
https://github.com/feenkcom/gtoolkit/issues/892"

eachSegmentPiece currentCursors: eachPiece currentCursors.

theSegmentElements
Expand Down
28 changes: 20 additions & 8 deletions src/Brick-Editor/BrTextEditorSegmentSplitterObject.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@ BrTextEditorSegmentSplitterObject >> endIntervalWith: endingAttributes [
(endingAttributes
allSatisfy: [ :each | each isAdornment and: [ each shouldOverlay ] ])
ifTrue: [ ^ self ].
self hasReplacement ifFalse: [ self outputTextTo: intervalLast ].
endingAttributes
do: [ :each |
(each isAdornment and: [ each shouldReplace or: [ each shouldAppend ] ])
ifTrue: [ self
outputAdornment: each
from: (intervalFirst min: start)
to: intervalLast ] ].
self hasReplacement
ifTrue: [ endingAttributes
do: [ :each |
(each isAdornment and: [ each shouldReplace ])
ifTrue: [ self
outputAdornment: each
from: (intervalFirst min: start)
to: intervalLast ] ] ]
ifFalse: [ self outputTextTo: intervalLast.
endingAttributes
do: [ :each |
(each isAdornment and: [ each shouldAppend ])
ifTrue: [ self
outputAdornment: each
from: (intervalFirst min: start)
to: intervalLast ] ] ].
start := intervalLast + 1
]

Expand Down Expand Up @@ -117,6 +125,10 @@ BrTextEditorSegmentSplitterObject >> startIntervalWith: startingAttributes [
anySatisfy: [ :each | each isAdornment and: [ each shouldReplace ] ] ])
ifTrue: [ ^ self ].
self outputTextTo: intervalFirst - 1.
"Replace attributes trump overlay attributes"
(startingAttributes
anySatisfy: [ :each | each isAdornment and: [ each shouldReplace ] ])
ifTrue: [ ^ self ].
startingAttributes
do: [ :each |
(each isAdornment and: [ each shouldOverlay ])
Expand Down

0 comments on commit 053602e

Please sign in to comment.