Date: 02-16-2022
Return to Index
created by gbSnippets
'Folding is simply the hiding (not deleting) of lines from view, as well as restoring
'the lines to view.
'Typically this is used to hide the content of procedures, making it easier to scroll
'through a document without having to look at every line of code. When found, the
'procedure can then be unfolded for viewing.
'The approach is straight-forward. Each line of code is assigned a folder level,
'indicating whether that are lines "below" it in the document hierarchy. In this
'code, the first line is at the top of the hierarchy and the next 3 lines can be
'folded out of view, leaving just the function delcaration visible.
Function Test() As Long 'top of hierarchy
x = 2 'lower in hierarchy
y = 3 'lower in hierarchy
End Function 'lower in hierarchy
'The above code would be folded to the following, single line.
Function Test() As Long
'If that's all you saw in Scintilla you'd wonder where the code went! Fortunately
'Scintilla allows the use of markers (symbols) in a margin which identify whether
'the code beneath a line has been folded. Also, Scintilla allows a user to click
'on the margins to fold or unfold code that is foldable.
'In code, each line is assigned a fold level, which simply indicated the depth
'of that line in the indentation hierarchy. Zero is the lower depth. The
'lexer (built-in or container) can select any fold level number, but a child
'of a line is considered to be a line whose fold level is greater than that of
'the line.
'Looking again at the code example, the following fold levels might be assigned
'by the lexer.
Function Test() As Long 'fold level = 0
x = 2 'fold level = 1 'child of first line
y = 3 'fold level = 1 'child of first line
End Function 'fold level = 1 'child of first line
'One additional setting is required before folding can be achieved. Each parent
'line (fold point) must be assigned a SC_FoldLevelHeaderFlag. Once the fold
'level and flag are assigned, toggling the visibility of lines beneath is done
'with SCI_ToggleFold
'Primary Code:
'To toggle the a fold point, use this message
SendMessage hSci, %SCI_ToggleFold, iLine, 0
'If iLine has its flag set, then the visibility of any line beneath it, down to
'but not including the next line that has a folding level less than or equal to
'the fold level of the selected line, will be toggled.
'Compilable Example: (Jose Includes)
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "Win32API.inc"
#Include "scintilla_gb.inc"
%ID_Sci = 1000 : %ID_BtnA = 1001
Global hDlg, hSci, hLib As DWord
Function PBMain() As Long
hLib = LoadLibrary("SCILEXER.DLL")
Dialog New Pixels, 0, "Scintilla Example",300,300,370,250, %WS_OverlappedWindow To hDlg
Control Add Button, hDlg, %ID_BtnA, "Toggle All", 5,10,115,20, %WS_Child Or %WS_Visible
Control Add "Scintilla", hDlg, %ID_Sci, "", 120,10,180,130, %WS_Child Or %WS_Visible
Control Handle hDlg, %ID_Sci To hSci 'get handle to Scintilla window
Dialog Show Modal hDlg Call DlgProc
End Function
CallBack Function DlgProc() As Long
Local pNSC As SCNotification Ptr ' // Scintilla notification messages
Local iLine, iExpanded As Long
Select Case CB.Msg
Case %WM_InitDialog
InitializeSci
PostMessage hSci, %SCI_SetSel, 0,0 'unselect initially
Case %WM_Command
Select Case CB.Ctl
Case %ID_BtnA : TestA
End Select
Case %WM_NOTIFY
Select Case CB.NmID
Case %ID_Sci
pNSC = CB.lParam
Select Case @pNSC.hdr.Code
Case %SCN_MarginClick
iLine = SendMessage( hSci, %SCI_LineFromPosition, @pNSC.position, 0)
SendMessage hSci, %SCI_ToggleFold, iLine, 0
iExpanded = SendMessage(hSci, %SCI_GetFoldExpanded, iLine, 0)
If iExpanded Then
SendMessage hSci, %SCI_MarkerDelete, iLine, %SC_MarkNum_Folder
SendMessage hSci, %SCI_MarkerAdd, iLine, %SC_MarkNum_FolderOpen
Else
SendMessage hSci, %SCI_MarkerDelete, iLine, %SC_MarkNum_FolderOpen
SendMessage hSci, %SCI_MarkerAdd, iLine, %SC_MarkNum_Folder
End If
End Select
End Select
Case %WM_Size
Control Set Size hDlg, %ID_Sci, Lo(Word, CB.lParam)-130, Hi(Word, CB.lParam)-20
Case %WM_Destroy
If hLib Then FreeLibrary hLib ' Free the Scintilla library
End Select
End Function
Sub InitializeSci
Local txt, KeyWords As String, iResult As Long
KeyWords = "case end function select sub"
txt = "Function Test(x as Long) As Long"
txt = txt + $CrLf + " Select Case x"
txt = txt + $CrLf + " Case 1 : y = 3"
txt = txt + $CrLf + " Case 2 : y = 4"
txt = txt + $CrLf + " End Select"
txt = txt + $CrLf + "End Function"
txt = txt + $crlf + "Sub TestB(x as Long)"
txt = txt + $CrLf + " Select Case x"
txt = txt + $CrLf + " Case 1 : y = 3"
txt = txt + $CrLf + " Case 2 : y = 4"
txt = txt + $CrLf + " End Select"
txt = txt + $CrLf + "End Sub" + Chr$(0)
SendMessage hSci, %SCI_StyleSetFore, %SCE_B_Keyword, Rgb(0, 0, 255) 'keyword FGcolor
SendMessage hSci, %SCI_StyleSetFore, %SCE_B_String, Rgb(255, 0, 255) 'string color
SendMessage hSci, %SCI_StyleSetFore, %SCE_B_Number, Rgb(192,100,0) 'number colors
SendMessage hSci, %SCI_SetKeyWords, 0, ByVal StrPTR(KeyWords) 'define PB keywords
SendMessage(hSci, %SCI_SetText, 0, StrPTR(txt)) 'set text
SendMessage hSci, %SCI_SetMarginWidthN, 0, 20 'display line numbers
SendMessage hSci, %SCI_SetMarginWidthN, 2, 20 'display line numbers
SendMessage hSci, %SCI_SetMarginMaskN, 2, %SC_Mask_Folders 'margin 2 set to hold folder symbols
SendMessage hSci, %SCI_SetMarginSensitiveN, 2, 1 'margin 2 set as sensitive to clicks
InitializeFolding
SetFoldLevels
End Sub
Sub InitializeFolding
'markers/symbols
SendMessage hSci, %SCI_MarkerDefine, %SC_MarkNum_FolderOpen, %SC_Mark_CircleMinus
SendMessage hSci, %SCI_MarkerDefine, %SC_MarkNum_Folder, %SC_Mark_CirclePlus
SendMessage hSci, %SCI_MarkerDefine, %SC_MarkNum_FolderSub, %SC_Mark_VLine
SendMessage hSci, %SCI_MarkerDefine, %SC_MarkNum_FolderTail, %SC_Mark_LCornerCurve
'colors
SendMessage hSci, %SCI_MarkerSetFore, %SC_MarkNum_Folder, %White
SendMessage hSci, %SCI_MarkerSetBack, %SC_MarkNum_Folder, %Black
SendMessage hSci, %SCI_MarkerSetFore, %SC_MarkNum_FolderOpen, %White
SendMessage hSci, %SCI_MarkerSetback, %SC_MarkNum_FolderOpen, %Black
SendMessage hSci, %SCI_MarkerSetBack, %SC_MarkNum_FolderSub, %Black
SendMessage hSci, %SCI_MarkerSetBack, %SC_MarkNum_FolderTail, %Black
End Sub
Sub SetFoldLevels
'assign fold levels
SendMessage hSci, %SCI_SetFoldLevel, 0, 1 Or %SC_FoldLevelHeaderFlag 'fold point
SendMessage hSci, %SCI_SetFoldLevel, 1, 2
SendMessage hSci, %SCI_SetFoldLevel, 2, 2
SendMessage hSci, %SCI_SetFoldLevel, 3, 2
SendMessage hSci, %SCI_SetFoldLevel, 4, 2
SendMessage hSci, %SCI_SetFoldLevel, 5, 2
SendMessage hSci, %SCI_SetFoldLevel, 6, 1 Or %SC_FoldLevelHeaderFlag 'fold point
SendMessage hSci, %SCI_SetFoldLevel, 7, 2
SendMessage hSci, %SCI_SetFoldLevel, 8, 2
SendMessage hSci, %SCI_SetFoldLevel, 9, 2
SendMessage hSci, %SCI_SetFoldLevel,10, 2
SendMessage hSci, %SCI_SetFoldLevel,11, 2
'assign markers
SendMessage hSci, %SCI_MarkerAdd, 0, %SC_MarkNum_FolderOpen
SendMessage hSci, %SCI_MarkerAdd, 1, %SC_MarkNum_FolderSub
SendMessage hSci, %SCI_MarkerAdd, 2, %SC_MarkNum_FolderSub
SendMessage hSci, %SCI_MarkerAdd, 3, %SC_MarkNum_FolderSub
SendMessage hSci, %SCI_MarkerAdd, 4, %SC_MarkNum_FolderSub
SendMessage hSci, %SCI_MarkerAdd, 5, %SC_MarkNum_FolderTail
SendMessage hSci, %SCI_MarkerAdd, 6, %SC_MarkNum_FolderOpen
SendMessage hSci, %SCI_MarkerAdd, 7, %SC_MarkNum_FolderSub
SendMessage hSci, %SCI_MarkerAdd, 8, %SC_MarkNum_FolderSub
SendMessage hSci, %SCI_MarkerAdd, 9, %SC_MarkNum_FolderSub
SendMessage hSci, %SCI_MarkerAdd, 10, %SC_MarkNum_FolderSub
SendMessage hSci, %SCI_MarkerAdd, 11, %SC_MarkNum_FolderTail
End Sub
Sub TestA
SendMessage hSci, %SCI_ToggleFold, 0, 1
SendMessage hSci, %SCI_ToggleFold, 7, 1
End Sub
'gbs_00669
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm