Frage

I have this code, to initialize Scintilla with xml lexer:

procedure TfrmWeMain.DScintilla1MarginClick(ASender: TObject; AModifiers,
  APosition, AMargin: Integer);
  var line_number:integer;
begin

  line_number:= (ASender as TDScintilla).SendEditor(SCI_LINEFROMPOSITION, APosition, 0);

  case AMargin of
     1:
    begin
      (ASender as TDScintilla).SendEditor(SCI_TOGGLEFOLD, line_number, 0);
    end

  end;
end;

procedure TfrmWeMain.addDocument(filename:string);
var frmEditor:tFrameEditor;
ts:TTabSheet;
procedure setColors(lang:integer;fore:integer;const back:tcolor=clWindow; 
    const bold:boolean=false; const italic:boolean=false; 
    const underline:boolean=false; const font:string='Courier New'; 
    const size:integer=10);

begin
  frmEditor.sci.StyleSetBack(lang,colortorgb(back));
  frmEditor.sci.StyleSetFore(lang,colortorgb(fore));
  frmEditor.sci.StyleSetFont(lang,font);
  frmEditor.sci.StyleSetBold(lang,bold);
  frmEditor.sci.StyleSetItalic(lang,italic);
  frmEditor.sci.StyleSetUnderline(lang,underline);
  frmEditor.sci.StyleSetSize(lang,size);
end;

procedure setFolding;
begin
  frmEditor.sci.SetMarginTypeN(1,0);
  frmEditor.sci.SetMarginTypeN(1,SC_MARGIN_SYMBOL);
  frmEditor.sci.SetMarginMaskN(1,SC_MASK_FOLDERS);
  frmEditor.sci.SetMarginWidthN(0,40);
  frmEditor.sci.SetMarginWidthN(1,20);
  frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_PLUS);
  frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_MINUS);
  frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_EMPTY);
  frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_EMPTY);
  frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_EMPTY);
  frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_EMPTY);
  frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_EMPTY);
  frmEditor.sci.SendEditor(SCI_SETFOLDFLAGS, 16, 0); // 16      Draw line below if not expanded
  frmEditor.sci.OnMarginClick:=DScintilla1MarginClick;
  frmeditor.sci.StartStyling(0,0);
end;
begin

///...
 frmEditor.sci.SetLexer(SCLEX_XML);
 frmEditor.sci.SetCodePage(CP_UTF8);
 setColors(SCE_H_DEFAULT,clBlack);
 setColors(SCE_H_TAG,clPurple,clWindow,true);
 setColors(SCE_H_TAGUNKNOWN,clRed);
 setColors(SCE_H_ATTRIBUTE,clNavy);
 setColors(SCE_H_ATTRIBUTEUNKNOWN,clRed);
 setColors(SCE_H_NUMBER,clBlue);
 setColors(SCE_H_DOUBLESTRING,clBlue);
 setColors(SCE_H_SINGLESTRING,clBlue);
 setColors(SCE_H_OTHER,clBlack);
 setColors(SCE_H_COMMENT,clTeal);
 setColors(SCE_H_ENTITY,clPurple);
 setColors(SCE_H_TAGEND,clPurple);
 setColors(SCE_H_CDATA,clTeal);
 setFolding;

 ///...


end;

See the setFolding part of the code, it's that where the folding should get in motion, but it doesn't. I can't see the fold markers, neither the folding itself works.

I need to know what i am missing here, or what i am doing wrong. Code snippets in Delphi, C++, C# or pseudocode are welcome

War es hilfreich?

Lösung

Here you have the folding example for XML. You were quite close to get it to work, but you missed to set 2 important details, enable folding globally and for your language (see here for fold.html folding property for XML) and after that enable fold margin to be sensitive for mouse clicks, what actually enables the OnMarginClick event to be fired (see here).

For this example I've avoided to use the SendEditor messaging and used the full power of the DScintilla wrapper.

uses
  DScintillaTypes;

const
  MARGIN_LINE_NUMBERS = 0;
  MARGIN_CODE_FOLDING = 1;

procedure TForm1.DScintilla1MarginClick(ASender: TObject; AModifiers,
  APosition, AMargin: Integer);
var
  Line: Integer;
begin
  Line := DScintilla1.LineFromPosition(APosition);

  if AMargin = MARGIN_CODE_FOLDING then
    DScintilla1.ToggleFold(Line);
end;

procedure TForm1.FormCreate(Sender: TObject);

  procedure SetColors(const Style: Integer; const Fore: Integer;
    const Back: TColor = clWindow; const Bold: Boolean = False;
    const Italic: Boolean = False; const Underline: Boolean = False;
    const Font: string = 'Courier New'; const Size: Integer = 10);
  begin
    DScintilla1.StyleSetBack(Style, ColorToRGB(Back));
    DScintilla1.StyleSetFore(Style, ColorToRGB(Fore));
    DScintilla1.StyleSetFont(Style, Font);
    DScintilla1.StyleSetSize(Style, Size);
    DScintilla1.StyleSetBold(Style, Bold);
    DScintilla1.StyleSetItalic(Style, Italic);
    DScintilla1.StyleSetUnderline(Style, Underline);
  end;

begin
  DScintilla1.SetLexer(SCLEX_XML);
  DScintilla1.SetCodePage(CP_UTF8);

  // this is very important and enables the folding globally
  // and then the language specific, see [1] for details

  DScintilla1.SetProperty('fold', '1');
  DScintilla1.SetProperty('fold.html', '1');

  // I used here constant placeholders, for line numbering
  // margin it's the MARGIN_LINE_NUMBERS and for code folding
  // margin it's the MARGIN_CODE_FOLDING constant

  DScintilla1.SetMarginWidthN(MARGIN_CODE_FOLDING, 0);
  DScintilla1.SetMarginTypeN(MARGIN_CODE_FOLDING, SC_MARGIN_SYMBOL);
  DScintilla1.SetMarginMaskN(MARGIN_CODE_FOLDING, SC_MASK_FOLDERS);
  DScintilla1.SetMarginWidthN(MARGIN_LINE_NUMBERS, 40);
  DScintilla1.SetMarginWidthN(MARGIN_CODE_FOLDING, 20);

  // markers for code folding

  DScintilla1.MarkerDefine(SC_MARKNUM_FOLDER, SC_MARK_PLUS);
  DScintilla1.MarkerDefine(SC_MARKNUM_FOLDEROPEN, SC_MARK_MINUS);
  DScintilla1.MarkerDefine(SC_MARKNUM_FOLDEREND, SC_MARK_EMPTY);
  DScintilla1.MarkerDefine(SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_EMPTY);
  DScintilla1.MarkerDefine(SC_MARKNUM_FOLDEROPENMID, SC_MARK_EMPTY);
  DScintilla1.MarkerDefine(SC_MARKNUM_FOLDERSUB, SC_MARK_EMPTY);
  DScintilla1.MarkerDefine(SC_MARKNUM_FOLDERTAIL, SC_MARK_EMPTY);

  // also very important, this will enable the OnMarginClick event
  // to fire, if you set the ASensitive parameter to False or omit
  // this line, the OnMarginClick will never fire

  DScintilla1.SetMarginSensitiveN(MARGIN_CODE_FOLDING, True);

  // and some visual settings

  SetColors(SCE_H_DEFAULT, clBlack);
  SetColors(SCE_H_TAG, clPurple, clWindow, True);
  SetColors(SCE_H_TAGUNKNOWN, clRed);
  SetColors(SCE_H_ATTRIBUTE, clNavy);
  SetColors(SCE_H_ATTRIBUTEUNKNOWN, clRed);
  SetColors(SCE_H_NUMBER, clBlue);
  SetColors(SCE_H_DOUBLESTRING, clBlue);
  SetColors(SCE_H_SINGLESTRING, clBlue);
  SetColors(SCE_H_OTHER, clBlack);
  SetColors(SCE_H_COMMENT, clTeal);
  SetColors(SCE_H_ENTITY, clPurple);
  SetColors(SCE_H_TAGEND, clPurple);
  SetColors(SCE_H_CDATA, clTeal);
end;

Hope this helps :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top