页边(Margins)和标记(Markers)
来自http://www.cppprog.com/2009/1111/176.html
代码折叠是现代IDE和代码编辑器的必备功能,如果现在推出一个不支持折叠的编辑器,那是要被BS地~~。为了不被BS,很有必要先“研究”一下Scintilla的页边(Margins)和标记(Markers)功能。
- 页 边(Margins):页边是位于文本显示区左边的一竖条区域,它可以用于显示行号、书签、断点标记等东东。Scintilla最多可以有5个页边(从左 到右的编号为0~4),每个页边可以使用SCI_SETMARGINTYPEN命令确定是用于显示行号还是符号。我们可以用 SCI_SETMARGINWIDTHN命令控制一个页边的宽度,如果设置为0,则表示不显示该页边。默认是只显示宽度为16的1号页边。
- 标 记(Markers):标记,不用说也知道是用来标记文本位置(确切地说,是文本行)的。我们可以使用32种标记(编号0~31),我们可以自由决定这 32种标记的意义,如标记0用来表示断点、标记1~10表示书签、标记20表示语法错误行等等。不过,如果编辑器要支持代码折叠功能,我们得把标记 25~31留出来,把这7个标记作为代码折叠专用标记(后面还会讲到)。
告诉页边显示哪些标记
当页边不是设定为显示行号时(由SCI_SETMARGINTYPEN命令设置),那么它就会显示标记。刚才说过Scintilla有32种标记,一般来说不会让一个页边来显示所有的标记,而是只显示部分标记。
在一个页边里可以显示哪几种标记由SCI_SETMARGINMASKN命令设置,它的参数是一个32位掩码(mask)值,掩码值的第n位为1时表示该页边可显示n号标记。
所有页边相关的命令以SCI_SETMARGIN或SCI_GETMARGIN作为前缀,如:
- SCI_SETMARGINTYPEN(int margin, int type) 设置页边显示行号还是符号,type可以是SC_MARGIN_SYMBOL或SC_MARGIN_NUMBER
- SCI_SETMARGINWIDTHN(int margin, int pixelWidth) 设置页边宽度
- SCI_SETMARGINMASKN(int margin, int mask) 设置页边掩码
- SCI_SETMARGINSENSITIVEN(int margin, bool sensitive) 设置页边是否接受鼠标点击事件
所有标记相关的命令以SCI_MARKER作为前缀,如:
- SCI_MARKERADD(int line, int markerNumber) 在指定行加入一个markerNumber号标记
- SCI_MARKERDEFINE(int markerNumber, int markerSymbols) 定义markerNumber号标记的样式
- SCI_MARKERDELETE(int line, int markerNumber) 在指定行上的删除markerNumber号标记
- SCI_MARKERDELETEALL(int markerNumber) 删除文本中所有markerNumber号标记
- SCI_MARKERSETFORE(int markerNumber, int colour) 为markerNumber号标记指定前景色
- SCI_MARKERSETBACK(int markerNumber, int colour) 为markerNumber号标记指定背景色
演示代码
-
- void TForm1::example()
- {
-
- for(int i=0; i<10; i++)
- SendEditor(SCI_APPENDTEXT, 12, (sptr_t)"hello world ");
-
- SendEditor(SCI_SETMARGINTYPEN,0,SC_MARGIN_SYMBOL);
- SendEditor(SCI_SETMARGINWIDTHN,0, 9);
- SendEditor(SCI_SETMARGINMASKN,0, 0x01);
-
- SendEditor(SCI_SETMARGINTYPEN,1, SC_MARGIN_SYMBOL);
- SendEditor(SCI_SETMARGINWIDTHN,1, 9);
- SendEditor(SCI_SETMARGINMASKN,1, 0x06);
-
- SendEditor(SCI_SETMARGINTYPEN,2, SC_MARGIN_NUMBER);
- SendEditor(SCI_SETMARGINWIDTHN,2, 20);
-
- for(int i=0; i<10; i++)
- {
-
- SendEditor(SCI_MARKERADD, i, i%3);
- }
-
-
- SendEditor(SCI_MARKERSETFORE,0,0x0000ff);
- SendEditor(SCI_MARKERSETFORE,1,0x00ff00);
- SendEditor(SCI_MARKERSETFORE,2,0xff0000);
- }
显示效果是:
如果你不喜欢这些圆圈,可以用SCI_MARKERDEFINE命令改变标记的样式,可选的有:
SC_MARK_CIRCLE, SC_MARK_ROUNDRECT, SC_MARK_ARROW, SC_MARK_SMALLRECT,
SC_MARK_SHORTARROW, SC_MARK_EMPTY, SC_MARK_ARROWDOWN, SC_MARK_MINUS,
SC_MARK_PLUS, SC_MARK_VLINE, SC_MARK_LCORNER, SC_MARK_TCORNER, SC_MARK_BOXPLUS,
SC_MARK_BOXPLUSCONNECTED, SC_MARK_BOXMINUS, SC_MARK_BOXMINUSCONNECTED,
SC_MARK_LCORNERCURVE, SC_MARK_TCORNERCURVE, SC_MARK_CIRCLEPLUS,
SC_MARK_CIRCLEPLUSCONNECTED, SC_MARK_CIRCLEMINUS, SC_MARK_CIRCLEMINUSCONNECTED,
SC_MARK_BACKGROUND, SC_MARK_DOTDOTDOT, SC_MARK_ARROWS, SC_MARK_PIXMAP,
SC_MARK_FULLRECT, SC_MARK_LEFTRECT, SC_MARK_CHARACTER
默认是SC_MARK_CIRCLE,小圆圈。你可以试试其它的。(注意SC_MARK_CHARACTER比较特殊,它和一个ASCII码加起来决定标记显示为一个对应的ASCII字符)
有了这些基础,我们可以动手为Scintilla加入代码折叠功能了...