在StyledTextCtrl中自定义代码折叠
代码折叠功能是一个完善的编辑器不可缺少的功能,在StyledTextCtrl中可以自定义语法高亮,当然也可以自定义代码折叠(关于自定义语法高亮,大家爱可以读读limodou大侠的《StyledTextCtrl语法高亮使用的探讨》一文)。
StyledTextCtrl中的代码折叠的基础是每行的FoldLevel值,FoldLevel值的大小不同,就形成了不同的代码块,例如:

这样的折叠效果,每行的FoldLevel为:

第一列是行(从0开始是第一行),第二列是FoldLevel,第三列是FoldLevel原始值;第二列的FoldLevel由第三列FoldLevel原始值解码出来。
代码被设计成基于大括号折叠,对比两个图,可以找出规律:最外层的“{”FoldLevel是1024,第二个“{”是1025,第三个“{”是1026;它们的FoldLevel都大于8192(wx.stc.STC_FOLDLEVELHEADERFLAG),这表示了他们是折叠的开始。
剩下的行,凡属于代码块的行,都会比折叠的开始行要小。
控件就会根据每行的FoldLevel值不一样,产生了折叠效果。
这里有个设置每行FoldLevel值的代码片段,供产考:
def MakeFoldLevel(self, begin = 0):
beginPosition = 0
endPosition = self.editor.GetTextLength()
currentLine = self.editor.LineFromPosition(beginPosition)
currentLineLevel = self.editor.GetFoldLevel(currentLine) & wx.stc.STC_FOLDLEVELNUMBERMASK
prevLineLevel = currentLineLevel
i = 0
while beginPosition + i < endPosition:
pos = beginPosition + i
currentChr = chr(self.editor.GetCharAt(pos))
if self.editor.GetStyleAt(pos) == styleIndex['bracket']:
if currentChr == '{':
currentLineLevel += 1
elif currentChr == '}':
currentLineLevel -= 1
if (currentChr=="\n") or (currentChr=="\r" and chr(self.editor.GetCharAt(pos+1))!="\n"):
level = prevLineLevel
if currentLineLevel > prevLineLevel:
level |= wx.stc.STC_FOLDLEVELHEADERFLAG
if level != self.editor.GetFoldLevel(currentLine):
self.editor.SetFoldLevel(currentLine, level)
currentLine += 1
prevLineLevel = currentLineLevel
i += 1
if currentLineLevel<>prevLineLevel:
self.editor.SetFoldLevel(currentLine, prevLineLevel)
else:
self.editor.SetFoldLevel(currentLine, currentLineLevel)
这不是教程,只是对实现思路的探讨,更多内容请参考官方文档,谢谢关注 ^_^

