Scintilla/Folding

Last-modified: 2008-03-02 (日) 08:06:21

折りたたみ

折りたたみにおける単位作業で、行は目に見えないか目に見えるようになる。
行を見ることができるかどうかは文書ではなく可視部の特性なので、可視部の各々は異なる行を表示することができる。
ユーザから見ると、折りたたみ点で行が隠されたり表示されたりしている。
一般的に折りたたみ点は、文書の階層構造を元に設定される。
Pythonでは階層が字下げによって定められるし、C++では波括弧文字で定められる。
文書オブジェクトの各行に"折りたたみ階層数"を接続することで、この階層構造が表現される。
折りたたみ階層数の大部分は解析器によって設定されるが、メッセージによって設定することも可能である。


ユーザの行動と折りたたみの実行・解除との対応付けはScintillaを扱う側のコードが責任を持つ。
一番よい方法は、SciTEのソースコードで本節のメッセージが使われているところを探してそこを見よ。
マーカと折りたたみ余白も、実装の完成に必要となる。
折りたたみを有効にするにはSCI_SETPROPERTY("fold", "1")というコードで"fold"特性を"1"にしなくてはならない。

  • SCI_VISIBLEFROMDOCLINE(int docLine)
  • SCI_DOCLINEFROMVISIBLE(int displayLine)
  • SCI_SHOWLINES(int lineStart, int lineEnd)
  • SCI_HIDELINES(int lineStart, int lineEnd)
  • SCI_GETLINEVISIBLE(int line)
  • SCI_SETFOLDLEVEL(int line, int level)
  • SCI_GETFOLDLEVEL(int line)
  • SCI_SETFOLDFLAGS(int flags)
  • SCI_GETLASTCHILD(int line, int level)
  • SCI_GETFOLDPARENT(int line)
  • SCI_SETFOLDEXPANDED(int line, bool expanded)
  • SCI_GETFOLDEXPANDED(int line)
  • SCI_TOGGLEFOLD(int line)
  • SCI_ENSUREVISIBLE(int line)
  • SCI_ENSUREVISIBLEENFORCEPOLICY(int line)

SCI_VISIBLEFROMDOCLINE(int docLine)

いくつかの行が折りたたまれているとき、以後の行は文書上の行位置とは違うところに表示される。
折りたたまれている行がないとき、このメッセージはdocLineを返す。
そうでない場合、このメッセージは隠されていない行数を返す。
折りたたまれて不可視になっている行が指定された場合、それより文書開始方向にある最初の可視行の番号を返す。
可視行のうち、文書内で先頭の行の番号が0となる。
docLineがもとの文書の行数範囲の外を指示していた場合は-1を返す。
行クリップが有効な場合はひとつの行が表示上の複数行になっていることがある。

SCI_DOCLINEFROMVISIBLE(int displayLine)

隠されている行がある場合、以後の行は文書上の行位置とは違うところに表示される。
このメッセージは表示されている行の番号から実際の文書上の行番号を求めて返す。
displayLineが0以下の時は0を返す。
可視行数以上の値が指定されたときは、文書の実際の行数を返す。

SCI_SHOWLINES(int lineStart, int lineEnd)

SCI_HIDELINES(int lineStart, int lineEnd)

SCI_GETLINEVISIBLE(int line)

最初の二つは指定範囲の行を可視化もしくは不可視化するものである。
画面の再描画も行う。
三つ目のメッセージは指定行の表示状態を返すもので、可視であれば1、不可視であれば0を返す。
これらのメッセージは折りたたみ階層数や折りたたみフラグに影響を与えない。

SCI_SETFOLDLEVEL(int line, int level)

SCI_GETFOLDLEVEL(int line)

指定行の折りたたみ階層数や関連フラグを含む32ビット値を設定または取得する。
折りたたみ階層数は0~SC_FOLDLEVELNUMBERMASK (4095)の値を取るが、初期状態ではSC_FOLDLEVELBASE (1024)が上限となっている。
追加のフラグが2ビットある。
SC_FOLDLEVELWHITEFLAGは空行であって少し異なる扱いにすることを示す。
この結果、空行には文字がないにもかかわらず階層数が示されていることになる。
たとえば、空行は通常折りたたみ点にすべきではない。
SC_FOLDLEVELHEADERFLAGは折りたたみ点を示すヘッダとなる。


SCI_GETFOLDLEVEL(line) & SC_FOLDLEVELNUMBERMASKというコードで指定行の折りたたみ階層数を取得できる。
同様にSCI_GETFOLDLEVEL(line) & SC_FOLDLEVEL*FLAGでフラグを取得できる。
折りたたみ階層を設定するときは関連フラグも一度に設定しなくてはならない。
階層数thisLevelと折りたたみ点であることを示すフラグを設定するときはSCI_SETFOLDLEVEL(line, thisLevel | SC_FOLDLEVELHEADERFLAG)といったコードになる。


解析器を使っているときはSCI_SETFOLDLEVELを使う必要がないようにすべきである。
解析器に任せたほうがずっといい処理をすると思われるからである。
ユーザの折りたたみ要求を決めるためにSCI_GETFOLDLEVELを使う必要がある。
折りたたみ階層数を変更したら、折りたたみ余白もその変更に合わせて更新される。

 

[heart] 表: 折りたたみフラグ

効果
1実験 - 展開ならボックスを描画
2展開なら上を描画
4展開でないなら上を描画
8展開なら下を描画
16展開でないなら下を描画
64行マージンにおける16進折りたたみレベルを表示して、折りたたみのデバッグを支援する。
この特徴は再設計される必要がある。
 

このメッセーは再描画を伴う。

SCI_GETLASTCHILD(int startLine, int level)

startLineの行以降に折りたたみ階層数がlevel以下の行を探す。
見つけた場合はその一行前の行番号を返す。
levelに-1を指定したときは、startLineと同じ折りたたみ階層数とみなす。
SCI_GETLASTCHILD(from, -1)というコードでfromが折りたたみ点であるときに返される行番号は、可視行もしくは折りたたみによって不可視にされている行のうちの最後の行になる。

SCI_GETFOLDPARENT(int startLine)

startLineより文書先頭方向にあり、startLineより折りたたみ階層数が小さく、SC_FOLDLEVELHEADERFLAGで折りたたみ点として印づけられている行のうち最初の行の番号を返す。
該当行がない場合や、ヘッダフラグと折りたたみ階層数に齟齬がある場合は-1を返す。

SCI_TOGGLEFOLD(int line)

各折りたたみ点は展開時にすべての子孫階層を表示したり、閉じたときにすべての子孫階層を隠したりできる。
このメッセージは指定行がSC_FOLDLEVELHEADERFLAGを設定されていればその折りたたみ状態を切り替える。
折りたたみもしくは展開の状態が指定行に依存する行の状態も制御する。
このメッセージの後表示は更新される。

SCI_SETFOLDEXPANDED(int line, bool expanded)

SCI_GETFOLDEXPANDED(int line)

指定行一行の展開状態を設定または取得する。
このメッセージは行の可視状態や指定行に依存する行には影響を与えない。
折りたたみ余白のマーカは変更される。
文書の外を指すような行番号を指定するとfalse (0)が返される。


単にある行の折りたたみ状態を変更し、それに依存する行もまとめて変更したい場合はSCI_TOGGLEFOLDを使うほうが簡単である。
SCI_SETFOLDEXPANDEDはまとめて折りたたみを処理し終わるまで表示更新を待たせる場合に使うことがある。
使い方についてはSciTEBase::FoldAll()とSciTEBase::Expand()を参照せよ。

SCI_ENSUREVISIBLE(int line)

SCI_ENSUREVISIBLEENFORCEPOLICY(int line)

収縮する親行の1つより多くあるので、行は隠されるかもしれない。
これらのメッセージは折りたたみ階層構造を上位にたどり、閉じられている折りたたみを最上位階層まで開いていく。
結果、指定行は可視になる。
SCI_ENSUREVISIBLEENFORCEPOLICYを使うと、SCI_SETVISIBLEPOLICYで使う垂直方向のキャレットポリシーが適用される。