Skip to content

Commit 3e8ac4f

Browse files
FremyCompany_cpFremyCompany_cp
authored andcommitted
Working on a new SelectionHelper. The current one is too complex to maintain. Another *planned* change: ChildrenHelper will perform more of the operations, the subclasses will only have the right to "accept" or "reject" operations.
1 parent 84170b1 commit 3e8ac4f

File tree

10 files changed

+410
-41
lines changed

10 files changed

+410
-41
lines changed

FC.MathEditor/WpfMathEditor/Classes/ChildrenHelper.vb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@
4242

4343
This.StartBatchProcess()
4444

45+
Dim Index = Count + 1
4546
This.Attach(NewChild)
4647
Add_Internal(NewChild)
47-
This.RaiseChildAdded(NewChild)
48+
This.RaiseChildAdded(NewChild, Index)
4849

4950
This.RaiseChanged()
5051

@@ -68,8 +69,9 @@
6869

6970
This.StartBatchProcess()
7071

72+
Dim Index = IndexOf(OldChild)
7173
Remove_Internal(OldChild)
72-
This.RaiseChildRemoved(OldChild)
74+
This.RaiseChildRemoved(OldChild, Index)
7375
This.Detach(OldChild)
7476
This.RaiseChanged()
7577

@@ -91,9 +93,10 @@
9193

9294
This.StartBatchProcess()
9395

96+
Dim Index = IndexOf(OldChild) + 1
9497
This.Attach(NewChild)
9598
InsertAfter_Internal(NewChild, OldChild)
96-
This.RaiseChildAdded(NewChild)
99+
This.RaiseChildAdded(NewChild, Index)
97100
This.RaiseChanged()
98101

99102

FC.MathEditor/WpfMathEditor/Classes/MathElement.XmlTree.vb

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,14 @@ Partial Public MustInherit Class MathElement
306306
If _Parent IsNot Nothing Then Parent.RaiseChanged()
307307
End Sub
308308

309-
' TODO: RemovedFromParent
309+
' TODO: Reviewing completely the event usage (drawing a schema)
310+
311+
Public Event SubTreeModified As EventHandler(Of TreeEventArgs)
312+
Public Sub RaiseSubTreeModified(ByVal e As TreeEventArgs)
313+
RaiseEvent SubTreeModified(Me, e)
314+
RaiseEvent Changed(Me, EventArgs.Empty)
315+
End Sub
316+
310317
Public Event AttachedToParent As EventHandler
311318
Public Sub RaiseAttachedToParent()
312319
RaiseEvent AttachedToParent(Me, EventArgs.Empty)
@@ -333,28 +340,45 @@ Partial Public MustInherit Class MathElement
333340
End Sub
334341

335342
Public Event ChildAdded As EventHandler(Of TreeEventArgs)
336-
Public Sub RaiseChildAdded(ByVal Child As MathElement)
337-
RaiseEvent ChildAdded(Me, New TreeEventArgs(Child))
343+
Public Sub RaiseChildAdded(ByVal ChildElement As MathElement, ByVal ChildIndex As Integer)
344+
Dim e = New TreeEventArgs(ChildElement, Me, ChildIndex, TreeEventArgs.TreeAction.Added)
345+
RaiseEvent ChildAdded(Me, e)
346+
RaiseEvent SubTreeModified(Me, e)
338347
End Sub
339348

340349
Public Event ChildRemoved As EventHandler(Of TreeEventArgs)
341-
Public Sub RaiseChildRemoved(ByVal Child As MathElement)
342-
RaiseEvent ChildRemoved(Me, New TreeEventArgs(Child))
350+
Public Sub RaiseChildRemoved(ByVal ChildElement As MathElement, ByVal ChildIndex As Integer)
351+
Dim e = New TreeEventArgs(ChildElement, Me, ChildIndex, TreeEventArgs.TreeAction.Removed)
352+
RaiseEvent ChildRemoved(Me, e)
353+
RaiseEvent SubTreeModified(Me, e)
343354
End Sub
344355

345356
Public Class TreeEventArgs : Inherits EventArgs
346-
Public Property Argument As MathElement
347-
Public Sub New(ByVal Argument As MathElement)
348-
Me.Argument = Argument
357+
358+
Public Property ParentElement As MathElement
359+
Public Property ChildElement As MathElement
360+
Public Property ChildIndex As Integer
361+
Public Property Action As TreeAction
362+
363+
Public Enum TreeAction
364+
Added = +1 : Removed = -1 : Modified = 0
365+
End Enum
366+
367+
Public Sub New(ByVal ChildElement As MathElement, ByVal ParentElement As MathElement, ByVal ChildIndex As Integer, ByVal Action As TreeAction)
368+
Me.ChildElement = ChildElement
369+
Me.ParentElement = ParentElement
370+
Me.ChildIndex = ChildIndex
371+
Me.Action = Action
349372
End Sub
373+
350374
End Class
351375

352376
Private Sub MathElement_ChildAdded(ByVal sender As Object, ByVal e As TreeEventArgs) Handles Me.ChildAdded
353-
e.Argument.RaiseAddedToParent()
377+
e.ChildElement.RaiseAddedToParent()
354378
End Sub
355379

356380
Private Sub MathElement_ChildRemoved(ByVal sender As Object, ByVal e As TreeEventArgs) Handles Me.ChildRemoved
357-
e.Argument.RaiseRemovedFromParent()
381+
e.ChildElement.RaiseRemovedFromParent()
358382
End Sub
359383

360384
Private Sub MathElement_DetachedFromDocument(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DetachedFromDocument
@@ -368,4 +392,8 @@ Partial Public MustInherit Class MathElement
368392
Child.RaiseDetachedFromDocument()
369393
Next
370394
End Sub
395+
396+
Private Sub MathElement_SubTreeModified(ByVal sender As Object, ByVal e As TreeEventArgs) Handles Me.SubTreeModified
397+
Me.Parent.RaiseSubTreeModified(e)
398+
End Sub
371399
End Class

FC.MathEditor/WpfMathEditor/Classes/SelectionHelper.Actions.vb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@
2121
End Get
2222
End Property
2323

24+
Public Sub CollapseToEnd()
25+
Dim NewPoint = New Selection(EndPoint.CommonAncestror, EndPoint.CommonAncestror.Children.Before(EndPoint.SelectionStart), EndPoint.SelectionStart)
26+
SetSelection(NewPoint, PointToChange:=SelectionHelper.SelectionPointType.StartPoint)
27+
End Sub
28+
29+
Public Sub CollapseToStart()
30+
' TODO: Implement CollapseToStart
31+
Throw New NotImplementedException()
32+
End Sub
33+
2434
Public Sub MoveNext(Optional ByVal MovedPoint As SelectionPointType = SelectionPointType.Selection)
2535
Dim Sel As Selection = GetSelection(MovedPoint)
2636
Dim E = Sel.CommonAncestror.ParentLayoutEngineChild

FC.MathEditor/WpfMathEditor/Classes/SelectionHelper.vb

Lines changed: 111 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
Partial Public Class SelectionHelper
22
Implements IEnumerable(Of MathElement)
33

4-
Private This As MathDocument
4+
Protected This As MathDocument
5+
Private WithEvents CA_SEL, CA_START, CA_END As MathElement
6+
57
Public Sub New(ByVal This As MathDocument)
68
Me.This = This
7-
SetSelection(This, Nothing, Nothing)
9+
SetSelection(This, This.LastChild, Nothing)
810
End Sub
911

1012
Private IsSelectionChanging As Boolean
@@ -43,41 +45,51 @@
4345
Private Sub SetSelection(ByVal StartPoint As Selection, ByVal EndPoint As Selection)
4446

4547
' Compute _Selection
46-
Dim CA = StartPoint.SelectionStart.GetCommonAncestrorWith(EndPoint.SelectionEnd)
4748
Dim SS = StartPoint.SelectionStart
48-
Dim SE = StartPoint.SelectionEnd
49+
Dim SE = EndPoint.SelectionEnd
50+
51+
' Collapse selection points
52+
StartPoint = New Selection(StartPoint.CommonAncestror, SS, StartPoint.CommonAncestror.Children.After(SS))
53+
EndPoint = New Selection(EndPoint.CommonAncestror, EndPoint.CommonAncestror.Children.After(SE), SE)
54+
55+
Dim CA = If(SS, SE)
56+
If StartPoint.CommonAncestror Is EndPoint.CommonAncestror Then
57+
CA = StartPoint.CommonAncestror
58+
Else
59+
CA = StartPoint.CommonAncestror.GetCommonAncestrorWith(EndPoint.CommonAncestror)
4960

50-
While SS.Parent IsNot CA
51-
SS = SS.Parent
52-
End While
61+
While SS.Parent IsNot CA
62+
SS = SS.Parent
63+
End While
5364

54-
While SE.Parent IsNot SE
55-
SE = SE.Parent
56-
End While
65+
While SE.Parent IsNot SE
66+
SE = SE.Parent
67+
End While
5768

58-
' Insert StartPoint and EndPoint if needed
59-
Dim Dir = SelectionDirection.LTR
69+
End If
6070

61-
If SE.IsBefore(SS) Then
71+
' Invert StartPoint and EndPoint if needed
72+
Dim Dir As SelectionDirection = SelectionDirection.LTR
73+
If (SE IsNot Nothing) AndAlso (SS IsNot Nothing) AndAlso (SE Is SS OrElse SE.IsBefore(SS)) Then
6274
Dir = SelectionDirection.RTL
63-
Dim Temp = StartPoint
64-
StartPoint = EndPoint
65-
EndPoint = Temp
75+
Dim ST = SE.PreviousSibling
76+
SE = SS.NextSibling : SS = ST
6677
End If
6778

6879
' Set the selection
6980
SetSelection_Internal(New Selection(CA, SS, SE), StartPoint, EndPoint)
81+
_Dir = Dir
7082

7183
End Sub
7284

73-
Public Sub SetSelection(ByVal Point As Selection, Optional ByVal PointToChange As SelectionPointType = SelectionPointType.Selection)
85+
Public Sub SetSelection(ByVal NewPoint As Selection, Optional ByVal PointToChange As SelectionPointType = SelectionPointType.Selection)
7486
Select Case PointToChange
7587
Case SelectionPointType.Selection
76-
SetSelection(Point.CommonAncestror, Point.SelectionStart, Point.SelectionEnd)
88+
SetSelection(NewPoint.CommonAncestror, NewPoint.SelectionStart, NewPoint.SelectionEnd)
7789
Case SelectionPointType.StartPoint
78-
SetSelection(Point, EndPoint)
90+
SetSelection(NewPoint, EndPoint)
7991
Case SelectionPointType.EndPoint
80-
SetSelection(StartPoint, Point)
92+
SetSelection(StartPoint, NewPoint)
8193
Case Else
8294
Throw New ArgumentException("Unknown value for the selection point type", "PointToChange")
8395
End Select
@@ -97,20 +109,39 @@
97109
End Function
98110

99111
Public Sub SetSelection(ByVal CommonAncestror As MathElement, ByVal SelectionStart As MathElement, ByVal SelectionEnd As MathElement)
112+
100113
' Check if the selection is valid
101114
If (
102-
(CommonAncestror.ParentDocument Is This) _
115+
(CommonAncestror IsNot Nothing) _
116+
AndAlso (CommonAncestror.ParentDocument Is This) _
103117
AndAlso (SelectionStart Is Nothing OrElse SelectionStart.Parent Is CommonAncestror) _
104118
AndAlso (SelectionEnd Is Nothing OrElse SelectionEnd.Parent Is CommonAncestror)
105119
) Then
106120

121+
' Invert StartPoint and EndPoint if needed
122+
Dim SS = SelectionStart, SE = SelectionEnd, CA = CommonAncestror
123+
If (SS Is Nothing) OrElse (SE IsNot Nothing AndAlso (SE Is SS OrElse SE.IsBefore(SS))) Then
124+
_Dir = SelectionDirection.RTL
125+
Dim ST = If(SE Is Nothing, Nothing, SE.PreviousSibling)
126+
SE = SS : SS = SE
127+
Else
128+
_Dir = SelectionDirection.LTR
129+
End If
130+
131+
' Perform the selection change
107132
SetSelection_Internal(
108-
New Selection(CommonAncestror, SelectionStart, SelectionEnd),
109-
New Selection(CommonAncestror, SelectionStart, CommonAncestror.Children.After(SelectionStart)),
110-
New Selection(CommonAncestror, CommonAncestror.Children.Before(SelectionEnd), SelectionEnd)
133+
New Selection(CA, SS, SE),
134+
New Selection(CA, SS, CA.Children.After(SS)),
135+
New Selection(CA, CA.Children.Before(SE), SE)
111136
)
112137

138+
Else
139+
140+
' Notify of an error
141+
Throw New ArgumentException("Selection was invalid.")
142+
113143
End If
144+
114145
End Sub
115146

116147
Private Sub SetSelection_Internal(ByVal Selection As Selection, ByVal StartPoint As Selection, ByVal EndPoint As Selection)
@@ -122,11 +153,13 @@
122153
Selection.SelectionStart = Temp
123154
_Dir = SelectionDirection.RTL
124155
Else
156+
' TODO: Some SetSelection perfor the _Dir modification themselves...
125157
_Dir = SelectionDirection.LTR
126158
End If
127159

128160
' Raise the BeforeSelectionChanged event
129161
If Not IsSelectionChanging Then
162+
' TODO: What about IsSelectionChanging and SelectionChanged ????
130163
RaiseEvent BeforeSelectionChanged(Me, EventArgs.Empty)
131164
End If
132165

@@ -135,6 +168,10 @@
135168
_StartPoint = StartPoint
136169
_EndPoint = EndPoint
137170

171+
CA_START = StartPoint.CommonAncestror
172+
CA_END = EndPoint.CommonAncestror
173+
CA_SEL = Selection.CommonAncestror
174+
138175
End Sub
139176

140177
Public Sub ReverseSelection()
@@ -214,4 +251,54 @@
214251
Private Function GetGenericEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
215252
Return GetEnumerator()
216253
End Function
254+
255+
Private Sub CA_END_ChildAdded(ByVal sender As Object, ByVal e As MathElement.TreeEventArgs) Handles CA_END.ChildAdded
256+
If EndPoint.SelectionEnd Is Nothing Then
257+
SetSelection(New Selection(CA_END, CA_END.LastChild, Nothing), PointToChange:=SelectionPointType.EndPoint)
258+
Else
259+
SetSelection(New Selection(CA_END, CA_END.Children.Before(_EndPoint.SelectionEnd), _EndPoint.SelectionEnd), PointToChange:=SelectionPointType.EndPoint)
260+
End If
261+
End Sub
262+
263+
Private Sub CA_END_ChildRemoved(ByVal sender As Object, ByVal e As MathElement.TreeEventArgs) Handles CA_END.ChildRemoved
264+
265+
'
266+
' Verify that the newly removed child don't make the Selection EndPoint invalid!
267+
'
268+
If (_EndPoint.SelectionEnd Is Nothing) OrElse (CA_END.Children.Contains(_EndPoint.SelectionEnd)) Then
269+
SetSelection(New Selection(CA_END, CA_END.Children.Before(_EndPoint.SelectionEnd), _EndPoint.SelectionEnd), PointToChange:=SelectionPointType.EndPoint)
270+
Else
271+
If (_EndPoint.SelectionStart Is Nothing) OrElse (CA_END.Children.Contains(_EndPoint.SelectionStart)) Then
272+
SetSelection(New Selection(CA_END, _EndPoint.SelectionStart, CA_END.Children.After(_EndPoint.SelectionStart)), PointToChange:=SelectionPointType.EndPoint)
273+
Else
274+
SetSelection(New Selection(CA_END, CA_END.LastChild, Nothing), PointToChange:=SelectionPointType.EndPoint)
275+
End If
276+
End If
277+
278+
End Sub
279+
280+
Private Sub CA_START_ChildAdded(ByVal sender As Object, ByVal e As MathElement.TreeEventArgs) Handles CA_START.ChildAdded
281+
If StartPoint.SelectionStart Is Nothing Then
282+
SetSelection(New Selection(CA_START, Nothing, CA_START.FirstChild), PointToChange:=SelectionPointType.StartPoint)
283+
Else
284+
SetSelection(New Selection(CA_START, _StartPoint.SelectionStart, CA_START.Children.After(_StartPoint.SelectionStart)), PointToChange:=SelectionPointType.StartPoint)
285+
End If
286+
End Sub
287+
288+
Private Sub CA_START_ChildRemoved(ByVal sender As Object, ByVal e As MathElement.TreeEventArgs) Handles CA_START.ChildRemoved
289+
290+
'
291+
' Verify that the newly removed child don't make the Selection StartPoint invalid!
292+
'
293+
If (_StartPoint.SelectionStart Is Nothing) OrElse (CA_START.Children.Contains(_StartPoint.SelectionStart)) Then
294+
SetSelection(New Selection(CA_START, _StartPoint.SelectionStart, CA_START.Children.After(_StartPoint.SelectionStart)), PointToChange:=SelectionPointType.StartPoint)
295+
Else
296+
If (_StartPoint.SelectionEnd Is Nothing) OrElse (CA_END.Children.Contains(_StartPoint.SelectionEnd)) Then
297+
SetSelection(New Selection(CA_START, CA_START.Children.Before(_StartPoint.SelectionEnd), _StartPoint.SelectionEnd), PointToChange:=SelectionPointType.StartPoint)
298+
Else
299+
SetSelection(New Selection(CA_END, CA_END.LastChild, Nothing), PointToChange:=SelectionPointType.StartPoint)
300+
End If
301+
End If
302+
303+
End Sub
217304
End Class

0 commit comments

Comments
 (0)