Files
Desktop_BLVStudio_EN/BLV_Studio/Node.vb

416 lines
11 KiB
VB.net
Raw Normal View History

2025-12-11 14:22:51 +08:00
Option Explicit On
Public Class Node
#Region "公共变量"
Private mstrKey As String
Private mstrText As String
Private mstrTag As String
Private mblnExpanded As Boolean
Private mintChildrenCount As Integer
Private mintVisibleNodesCount As Integer
Private mintLevel As Integer
Private mobjNodes As Nodes
Private mobjParent As Node
Private mobjPrevNode As Node
Private mobjNextNode As Node
#End Region
#Region "Friend 属性"
Friend ReadOnly Property AbsIndex() As Integer
Get
Dim i As Integer
Dim tmpNode As Node
tmpNode = Me
i = 1
Do
If tmpNode.PrevNode Is Nothing Then
If mobjParent IsNot Nothing Then
i = i + mobjParent.AbsIndex
End If
Exit Do
Else
tmpNode = tmpNode.PrevNode
i = i + 1 + tmpNode.ChildrenCount
End If
Loop
Return i
End Get
End Property
Friend Property PrevNode() As Node
Get
Return mobjPrevNode
End Get
Set(ByVal value As Node)
mobjPrevNode = value
End Set
End Property
Friend Property NextNode() As Node
Get
Return mobjNextNode
End Get
Set(ByVal value As Node)
mobjNextNode = value
End Set
End Property
Friend ReadOnly Property Root() As Node
Get
If mobjParent Is Nothing Then
Return Me
Else
Return mobjParent.Root
End If
End Get
End Property
Friend ReadOnly Property VisibleNodesCount() As Integer
Get
Return mintVisibleNodesCount
End Get
End Property
#End Region
#Region "Public属性"
Public Property Parent() As Node
Get
Return mobjParent
End Get
Set(ByVal value As Node)
mobjParent = value
End Set
End Property
Public ReadOnly Property Level() As Integer
Get
Return mintLevel
End Get
End Property
Public Property Key() As String
Get
Return mstrKey
End Get
Set(ByVal Value As String)
mstrKey = Value
End Set
End Property
Public Property Text() As String
Get
Return mstrText
End Get
Set(ByVal Value As String)
mstrText = Value
End Set
End Property
Public Property Tag() As String
Get
Return mstrTag
End Get
Set(ByVal Value As String)
mstrTag = Value
End Set
End Property
Public ReadOnly Property HasChildren() As Boolean
Get
If mobjNodes Is Nothing Then
Return False
Else
Return True
End If
End Get
End Property
Public ReadOnly Property Nodes() As Nodes
Get
If mobjNodes Is Nothing Then
mobjNodes = New Nodes(Me)
End If
Return mobjNodes
End Get
End Property
Public ReadOnly Property Expanded() As Boolean
Get
Return mblnExpanded
End Get
End Property
Public ReadOnly Property Visible() As Boolean
Get
If mintLevel = 0 Then
Return True
End If
Dim i As Integer
Dim tmpNode As Node
tmpNode = mobjParent
For i = mintLevel To 1 Step -1
If Not tmpNode.Expanded Then
Return False
End If
tmpNode = tmpNode.Parent
Next
Return True
End Get
End Property
Public ReadOnly Property ChildrenCount() As Integer
Get
Return mintChildrenCount
End Get
End Property
#End Region
#Region "Private方法"
Private Sub CopyNode(ByVal SourceNode As Node, ByVal TargetNode As Node)
'复制所有的子节点
If Not SourceNode.Expanded Then
TargetNode.Collapse()
End If
If SourceNode.ChildrenCount > 0 Then
Dim i As Integer
Dim strText As String
Dim strTag As String
Dim objNode As Node
For i = 1 To SourceNode.Nodes.Count
With SourceNode.Nodes.Item(i)
strText = .Text
strTag = .Tag
End With
objNode = TargetNode.Nodes.Add(strText, strTag)
If Not SourceNode.Nodes.Item(i).Expanded Then
objNode.Collapse()
End If
CopyNode(SourceNode.Nodes.Item(i), objNode)
Next
End If
End Sub
#End Region
#Region "Friend 方法"
Friend Sub UpdateChindrenCount(ByVal diff As Integer)
'更新子节点数
mintChildrenCount = mintChildrenCount + diff
If mobjParent IsNot Nothing Then
mobjParent.UpdateChindrenCount(diff)
End If
End Sub
Friend Sub UpdateVisibleNodesCount(ByVal diff As Integer)
'更新可见节点数
mintVisibleNodesCount = mintVisibleNodesCount + diff
If mobjParent IsNot Nothing Then
If mobjParent.Expanded Then
mobjParent.UpdateVisibleNodesCount(diff)
End If
End If
End Sub
Friend Function FindNextVisibleNode() As Node
Return FindNextVisibleNode(False)
End Function
Friend Function FindNextVisibleNode(ByVal FindNext As Boolean) As Node
Dim i As Integer
Dim CollapsedNode As Node = Nothing
'检查所有父节点是否包含Collapsed节点
If mintLevel > 0 Then
Dim tmpNode As Node
tmpNode = mobjParent
For i = mintLevel To 1 Step -1
If Not tmpNode.Expanded Then
CollapsedNode = tmpNode
End If
tmpNode = tmpNode.Parent
Next
End If
If CollapsedNode IsNot Nothing Then
Return CollapsedNode.FindNextVisibleNode
End If
'FindNext是指要排除自己的子节点,从下一个节点开始搜索
If (Not FindNext) AndAlso mblnExpanded AndAlso mintChildrenCount > 0 Then
Return mobjNodes.FirstNode
End If
If mobjNextNode Is Nothing Then
If mobjParent Is Nothing OrElse mintLevel = 1 Then
Return Nothing
Else
Return mobjParent.FindNextVisibleNode(True)
End If
Else
Return mobjNextNode
End If
End Function
Friend Function FindLastVisibleChildNode() As Node
If mintVisibleNodesCount = 1 Then
Return Me
Else
Return mobjNodes.LastNode.FindLastVisibleChildNode
End If
End Function
Friend Function FindPrevVisibleNode() As Node
Dim i As Integer
Dim CollapsedNode As Node = Nothing
'检查所有父节点是否包含Collapsed节点
If mintLevel > 0 Then
Dim tmpNode As Node
tmpNode = mobjParent
For i = mintLevel To 1 Step -1
If Not tmpNode.Expanded Then
CollapsedNode = tmpNode
End If
tmpNode = tmpNode.Parent
Next
End If
If CollapsedNode IsNot Nothing Then
Return CollapsedNode
End If
If mobjPrevNode IsNot Nothing Then
Return mobjPrevNode.FindLastVisibleChildNode
Else
If mobjParent Is Nothing Then
Return Nothing
Else
Return mobjParent
End If
End If
End Function
#End Region
#Region "Public方法"
Public Sub New()
mstrKey = ""
mstrText = ""
mstrTag = ""
mintLevel = 0
mblnExpanded = True
mintChildrenCount = 0
mintVisibleNodesCount = 1
End Sub
Public Sub New(ByVal Key As String, ByVal Text As String, ByVal Tag As String, ByVal Level As Integer, ByVal Parent As Node)
mstrKey = Key
mstrText = Text
mstrTag = Tag
mintLevel = Level
mobjParent = Parent
mblnExpanded = True
mintChildrenCount = 0
mintVisibleNodesCount = 1
End Sub
Public Sub Collapse()
If (mintLevel = 0) OrElse (Not mblnExpanded) Then
Return
End If
mblnExpanded = False
UpdateVisibleNodesCount(1 - mintVisibleNodesCount)
End Sub
Public Sub Expand()
If mblnExpanded Then
Return
End If
Dim i As Integer
mblnExpanded = True
If mobjNodes IsNot Nothing Then
For i = 1 To mobjNodes.Count
UpdateVisibleNodesCount(mobjNodes.Item(i).VisibleNodesCount)
Next
End If
End Sub
Public Sub ExpandAll()
Expand()
Dim i As Integer
If mobjNodes IsNot Nothing Then
For i = 1 To mobjNodes.Count
mobjNodes.Item(i).ExpandAll()
Next
End If
End Sub
Public Sub LevelUp()
'升级规则成为父节点的NextNode
If mobjParent.Level = 1 Then
Return
End If
Dim objNode As Node = mobjParent.Parent.Nodes.InsertAfter(mobjParent.Key, mstrText, mstrTag)
CopyNode(Me, objNode)
mobjParent.Nodes.Remove(mstrKey)
End Sub
Public Sub LevelDown()
'降级规则成为PrevNode的最后一个子节点
If mobjPrevNode Is Nothing Then
Return
End If
Dim objNode As Node = mobjPrevNode.Nodes.Add(mstrText, mstrTag)
CopyNode(Me, objNode)
mobjParent.Nodes.Remove(mstrKey)
End Sub
Public Sub MoveUp()
'上移规则和PrevNode交换位置
If mobjPrevNode Is Nothing Then
Return
End If
Dim objNode As Node = mobjParent.Nodes.InsertBefore(mobjPrevNode.Key, mstrText, mstrTag)
CopyNode(Me, objNode)
mobjParent.Nodes.Remove(mstrKey)
End Sub
Public Sub MoveDown()
'下移规则和NextNode交换位置
If mobjNextNode Is Nothing Then
Return
End If
Dim objNode As Node = mobjParent.Nodes.InsertAfter(mobjNextNode.Key, mstrText, mstrTag)
CopyNode(Me, objNode)
mobjParent.Nodes.Remove(mstrKey)
End Sub
Public Function FindNode(ByVal Index As Integer) As Node
'根据绝对位置定位Node
If Index = 1 Then
Return Me
End If
Dim i As Integer = Index - 1
If Me.ChildrenCount >= i Then
Return Me.Nodes.FirstNode.FindNode(i)
Else
i = i - Me.ChildrenCount
If Me.NextNode Is Nothing Then
Return Nothing
Else
Return Me.NextNode.FindNode(i)
End If
End If
End Function
#End Region
End Class