diff options
author | nyamatongwe <devnull@localhost> | 2013-04-21 16:13:28 +1000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2013-04-21 16:13:28 +1000 |
commit | 341e163afa67923ca42e083d176c726ea5ed5d3e (patch) | |
tree | cd5b0bc6f9bfd31848397972e4644a6ceb0b05ae | |
parent | b4c56acc3db4184664ce16ea80cbe6ea8d806bf4 (diff) | |
download | scintilla-mirror-341e163afa67923ca42e083d176c726ea5ed5d3e.tar.gz |
Implement commonly needed folding methods based on code from SciTE.
-rw-r--r-- | doc/ScintillaDoc.html | 54 | ||||
-rw-r--r-- | include/Scintilla.h | 7 | ||||
-rw-r--r-- | include/Scintilla.iface | 17 | ||||
-rw-r--r-- | src/Editor.cxx | 131 | ||||
-rw-r--r-- | src/Editor.h | 10 |
5 files changed, 192 insertions, 27 deletions
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 44b7449b7..9621ea19e 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -5183,6 +5183,10 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ <a class="message" href="#SCI_GETFOLDEXPANDED">SCI_GETFOLDEXPANDED(int line)</a><br /> <a class="message" href="#SCI_CONTRACTEDFOLDNEXT">SCI_CONTRACTEDFOLDNEXT(int lineStart)</a><br /> <a class="message" href="#SCI_TOGGLEFOLD">SCI_TOGGLEFOLD(int line)</a><br /> + <a class="message" href="#SCI_FOLDLINE">SCI_FOLDLINE(int line, int action)</a><br /> + <a class="message" href="#SCI_FOLDCHILDREN">SCI_FOLDCHILDREN(int line, int action)</a><br /> + <a class="message" href="#SCI_FOLDALL">SCI_FOLDALL(int action)</a><br /> + <a class="message" href="#SCI_EXPANDCHILDREN">SCI_EXPANDCHILDREN(int line, int level)</a><br /> <a class="message" href="#SCI_ENSUREVISIBLE">SCI_ENSUREVISIBLE(int line)</a><br /> <a class="message" href="#SCI_ENSUREVISIBLEENFORCEPOLICY">SCI_ENSUREVISIBLEENFORCEPOLICY(int line)</a><br /> @@ -5340,6 +5344,56 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ until you had finished. See <code>SciTEBase::FoldAll()</code> and <code>SciTEBase::Expand()</code> for examples of the use of these messages.</p> + <p><b id="SCI_FOLDLINE">SCI_FOLDLINE(int line, int action)</b><br /> + <b id="SCI_FOLDCHILDREN">SCI_FOLDCHILDREN(int line, int action)</b><br /> + <b id="SCI_FOLDALL">SCI_FOLDALL(int action)</b><br /> + These messages provide a higher-level approach to folding instead of setting expanded flags and showing + or hiding individual lines.</p> + <p>An individual fold can be contracted/expanded/toggled with <code>SCI_FOLDLINE</code>. + To affect all child folds as well call <code>SCI_FOLDCHILDREN</code>.</p> + <p>To affect the entire document call <code>SCI_FOLDALL</code>. With <code>SC_FOLDACTION_TOGGLE</code> + the first fold header in the document is examined to decide whether to expand or contract. + </p> + <table cellpadding="1" cellspacing="2" border="0" summary="Fold flags"> + <tbody> + <tr> + <th align="left">Symbol</th> + <th align="left">Value</th> + <th align="left">Effect</th> + </tr> + </tbody> + + <tbody valign="top"> + <tr> + <td align="left">SC_FOLDACTION_CONTRACT</td> + <td align="left">0</td> + <td align="left">Contract.</td> + </tr> + + <tr> + <td align="left">SC_FOLDACTION_EXPAND</td> + <td align="left">1</td> + <td align="left">Expand.</td> + </tr> + + <tr> + <td align="left">SC_FOLDACTION_TOGGLE</td> + <td align="left">2</td> + <td align="left">Toggle between contracted and expanded.</td> + </tr> + + </tbody> + </table> + <p></p> + + <p><b id="SCI_EXPANDCHILDREN">SCI_EXPANDCHILDREN(int line, int level)</b><br /> + This is used to respond to a change to a line causing its fold level or whether it is a header to change, + perhaps when adding or removing a '{'.</p> + <p>By the time the container has received the notification that the line has changed, + the fold level has already been set, so the container has to use the previous level in this call + so that any range hidden underneath this line can be shown. + </p> + <p><b id="SCI_CONTRACTEDFOLDNEXT">SCI_CONTRACTEDFOLDNEXT(int lineStart)</b><br /> Search efficiently for lines that are contracted fold headers. This is useful when saving the user's folding when switching documents or saving folding with a file. diff --git a/include/Scintilla.h b/include/Scintilla.h index b175fc80f..e94672ebd 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -441,6 +441,13 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETFOLDEXPANDED 2229 #define SCI_GETFOLDEXPANDED 2230 #define SCI_TOGGLEFOLD 2231 +#define SC_FOLDACTION_CONTRACT 0 +#define SC_FOLDACTION_EXPAND 1 +#define SC_FOLDACTION_TOGGLE 2 +#define SCI_FOLDLINE 2237 +#define SCI_FOLDCHILDREN 2238 +#define SCI_EXPANDCHILDREN 2239 +#define SCI_FOLDALL 2662 #define SCI_ENSUREVISIBLE 2232 #define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002 #define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index b2e8608ff..416e628af 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -1110,6 +1110,23 @@ get bool GetFoldExpanded=2230(int line,) # Switch a header line between expanded and contracted. fun void ToggleFold=2231(int line,) +enu FoldAction=SC_FOLDACTION +val SC_FOLDACTION_CONTRACT=0 +val SC_FOLDACTION_EXPAND=1 +val SC_FOLDACTION_TOGGLE=2 + +# Expand or contract a fold header. +fun void FoldLine=2237(int line, int action) + +# Expand or contract a fold header and its children. +fun void FoldChildren=2238(int line, int action) + +# Expand a fold header and all children. Use the level argument instead of the line's current level. +fun void ExpandChildren=2239(int line, int level) + +# Expand or contract all fold headers. +fun void FoldAll=2662(int action,) + # Ensure a particular line is visible by expanding any header line hiding it. fun void EnsureVisible=2232(int line,) diff --git a/src/Editor.cxx b/src/Editor.cxx index c2731a1e3..15e221f29 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -6962,34 +6962,42 @@ void Editor::SetAnnotationVisible(int visible) { /** * Recursively expand a fold, making lines visible except where they have an unexpanded parent. */ -void Editor::Expand(int &line, bool doExpand) { +int Editor::ExpandLine(int line) { int lineMaxSubord = pdoc->GetLastChild(line); line++; while (line <= lineMaxSubord) { - if (doExpand) - cs.SetVisible(line, line, true); + cs.SetVisible(line, line, true); int level = pdoc->GetLevel(line); if (level & SC_FOLDLEVELHEADERFLAG) { - if (doExpand && cs.GetExpanded(line)) { - Expand(line, true); + if (cs.GetExpanded(line)) { + line = ExpandLine(line); } else { - Expand(line, false); + line = pdoc->GetLastChild(line); } - } else { - line++; } + line++; + } + return lineMaxSubord; +} + +void Editor::SetFoldExpanded(int lineDoc, bool expanded) { + if (cs.SetExpanded(lineDoc, expanded)) { + RedrawSelMargin(); } } -void Editor::ToggleContraction(int line) { +void Editor::FoldLine(int line, int action) { if (line >= 0) { - if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) { - line = pdoc->GetFoldParent(line); - if (line < 0) - return; + if (action == SC_FOLDACTION_TOGGLE) { + if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) { + line = pdoc->GetFoldParent(line); + if (line < 0) + return; + } + action = (cs.GetExpanded(line)) ? SC_FOLDACTION_CONTRACT : SC_FOLDACTION_EXPAND; } - if (cs.GetExpanded(line)) { + if (action == SC_FOLDACTION_CONTRACT) { int lineMaxSubord = pdoc->GetLastChild(line); if (lineMaxSubord > line) { cs.SetExpanded(line, 0); @@ -7000,9 +7008,6 @@ void Editor::ToggleContraction(int line) { // This does not re-expand the fold EnsureCaretVisible(); } - - SetScrollBars(); - Redraw(); } } else { @@ -7011,11 +7016,35 @@ void Editor::ToggleContraction(int line) { GoToLine(line); } cs.SetExpanded(line, 1); - Expand(line, true); - SetScrollBars(); - Redraw(); + ExpandLine(line); + } + + SetScrollBars(); + Redraw(); + } +} + +void Editor::FoldExpand(int line, int action, int level) { + bool expanding = action == SC_FOLDACTION_EXPAND; + if (action == SC_FOLDACTION_TOGGLE) { + expanding = !cs.GetExpanded(line); + } + SetFoldExpanded(line, expanding); + if (expanding && (cs.HiddenLines() == 0)) + // Nothing to do + return; + int lineMaxSubord = pdoc->GetLastChild(line, level & SC_FOLDLEVELNUMBERMASK); + line++; + cs.SetVisible(line, lineMaxSubord, expanding); + while (line <= lineMaxSubord) { + int levelLine = pdoc->GetLevel(line); + if (levelLine & SC_FOLDLEVELHEADERFLAG) { + SetFoldExpanded(line, expanding); } + line++; } + SetScrollBars(); + Redraw(); } int Editor::ContractedFoldNext(int lineStart) { @@ -7057,7 +7086,7 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) { EnsureLineVisible(lineParent, enforcePolicy); if (!cs.GetExpanded(lineParent)) { cs.SetExpanded(lineParent, 1); - Expand(lineParent, true); + ExpandLine(lineParent); } } SetScrollBars(); @@ -7086,6 +7115,44 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) { } } +void Editor::FoldAll(int action) { + pdoc->EnsureStyledTo(pdoc->Length()); + int maxLine = pdoc->LinesTotal(); + bool expanding = action == SC_FOLDACTION_EXPAND; + if (action == SC_FOLDACTION_TOGGLE) { + // Discover current state + for (int lineSeek = 0; lineSeek < maxLine; lineSeek++) { + if (pdoc->GetLevel(lineSeek) & SC_FOLDLEVELHEADERFLAG) { + expanding = !cs.GetExpanded(lineSeek); + break; + } + } + } + if (expanding) { + cs.SetVisible(0, maxLine, true); + for (int line = 0; line < maxLine; line++) { + int levelLine = pdoc->GetLevel(line); + if (levelLine & SC_FOLDLEVELHEADERFLAG) { + SetFoldExpanded(line, true); + } + } + } else { + for (int line = 0; line < maxLine; line++) { + int level = pdoc->GetLevel(line); + if ((level & SC_FOLDLEVELHEADERFLAG) && + (SC_FOLDLEVELBASE == (level & SC_FOLDLEVELNUMBERMASK))) { + SetFoldExpanded(line, false); + int lineMaxSubord = pdoc->GetLastChild(line, -1); + if (lineMaxSubord > line) { + cs.SetVisible(line + 1, lineMaxSubord, false); + } + } + } + } + SetScrollBars(); + Redraw(); +} + int Editor::GetTag(char *tagValue, int tagNumber) { const char *text = 0; int length = 0; @@ -8533,9 +8600,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return cs.HiddenLines() ? 0 : 1; case SCI_SETFOLDEXPANDED: - if (cs.SetExpanded(wParam, lParam != 0)) { - RedrawSelMargin(); - } + SetFoldExpanded(wParam, lParam != 0); break; case SCI_GETFOLDEXPANDED: @@ -8547,7 +8612,23 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_TOGGLEFOLD: - ToggleContraction(wParam); + FoldLine(wParam, SC_FOLDACTION_TOGGLE); + break; + + case SCI_FOLDLINE: + FoldLine(wParam, lParam); + break; + + case SCI_FOLDCHILDREN: + FoldExpand(wParam, lParam, pdoc->GetLevel(wParam)); + break; + + case SCI_FOLDALL: + FoldAll(wParam); + break; + + case SCI_EXPANDCHILDREN: + FoldExpand(wParam, SC_FOLDACTION_EXPAND, lParam); break; case SCI_CONTRACTEDFOLDNEXT: diff --git a/src/Editor.h b/src/Editor.h index 4e6c7aee9..935fe1513 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -569,10 +569,16 @@ protected: // ScintillaBase subclass needs access to much of Editor void SetAnnotationVisible(int visible); - void Expand(int &line, bool doExpand); - void ToggleContraction(int line); + int ExpandLine(int line); + void SetFoldExpanded(int lineDoc, bool expanded); + void FoldLine(int line, int action); + void FoldExpand(int line, int action, int level); int ContractedFoldNext(int lineStart); void EnsureLineVisible(int lineDoc, bool enforcePolicy); + void FoldChanged(int line, int levelNow, int levelPrev); + void NeedShown(int pos, int len); + void FoldAll(int action); + int GetTag(char *tagValue, int tagNumber); int ReplaceTarget(bool replacePatterns, const char *text, int length=-1); |