diff options
-rw-r--r-- | doc/ScintillaDoc.html | 50 | ||||
-rw-r--r-- | doc/ScintillaHistory.html | 4 | ||||
-rw-r--r-- | include/Scintilla.h | 5 | ||||
-rw-r--r-- | include/Scintilla.iface | 11 | ||||
-rw-r--r-- | src/Editor.cxx | 85 | ||||
-rw-r--r-- | src/Editor.h | 1 |
6 files changed, 151 insertions, 5 deletions
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 9621ea19e..1c2dd7c2f 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -82,7 +82,7 @@ <h1>Scintilla Documentation</h1> - <p>Last edited 18/January/2013 NH</p> + <p>Last edited 24/April/2013 NH</p> <p>There is <a class="jump" href="Design.html">an overview of the internal design of Scintilla</a>.<br /> @@ -5175,6 +5175,8 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ <a class="message" href="#SCI_GETALLLINESVISIBLE">SCI_GETALLLINESVISIBLE</a><br /> <a class="message" href="#SCI_SETFOLDLEVEL">SCI_SETFOLDLEVEL(int line, int level)</a><br /> <a class="message" href="#SCI_GETFOLDLEVEL">SCI_GETFOLDLEVEL(int line)</a><br /> + <a class="message" href="#SCI_SETAUTOMATICFOLD">SCI_SETAUTOMATICFOLD(int automaticFold)</a><br /> + <a class="message" href="#SCI_GETAUTOMATICFOLD">SCI_GETAUTOMATICFOLD</a><br /> <a class="message" href="#SCI_SETFOLDFLAGS">SCI_SETFOLDFLAGS(int flags)</a><br /> <a class="message" href="#SCI_GETLASTCHILD">SCI_GETLASTCHILD(int line, int level)</a><br /> <a class="message" href="#SCI_GETFOLDPARENT">SCI_GETFOLDPARENT(int line)</a><br /> @@ -5394,6 +5396,52 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ so that any range hidden underneath this line can be shown. </p> + <p><b id="SCI_SETAUTOMATICFOLD">SCI_SETAUTOMATICFOLD(int automaticFold)</b><br /> + <b id="SCI_GETAUTOMATICFOLD">SCI_GETAUTOMATICFOLD</b><br /> + Instead of implementing all the logic for handling folding in the container, Scintilla can provide behaviour + that is adequate for many applications. The <code>automaticFold</code> argument is a bit set defining + which of the 3 pieces of folding implementation should be enabled. Most applications should be able to use the + <code>SC_AUTOMATICFOLD_SHOW</code> and <code>SC_AUTOMATICFOLD_CHANGE</code> + flags unless they wish to implement quite different behavious such as defining their own fold structure. + <code>SC_AUTOMATICFOLD_CLICK</code> is more likely to be set off when an application would + like to add or change click behaviour such as showing method headers only when Shift+Alt is used in + conjunction with a click. + </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_AUTOMATICFOLD_SHOW</td> + <td align="left">1</td> + <td align="left">Automatically show lines as needed. + This avoids sending the <code>SCN_NEEDSHOWN</code> notification.</td> + </tr> + + <tr> + <td align="left">SC_AUTOMATICFOLD_CLICK</td> + <td align="left">2</td> + <td align="left">Handle clicks in fold margin automatically. + This avoids sending the <code>SCN_MARGINCLICK</code> notification for folding margins.</td> + </tr> + + <tr> + <td align="left">SC_AUTOMATICFOLD_CHANGE</td> + <td align="left">4</td> + <td align="left">Show lines as needed when fold structure is changed. + The <code>SCN_MODIFIED</code> notification is still sent unless it is disabled by the + container.</td> + </tr> + + </tbody> + </table> + <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/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index e6298995c..1288f76ac 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -442,6 +442,10 @@ Released 11 December 2013. </li> <li> + Basic implementations of common folding methods added to Scintilla to make it + easier for containers to implement folding. + </li> + <li> Haskell folder improved. <a href="http://sourceforge.net/p/scintilla/bugs/1459 /">Bug #1459 </a>. </li> diff --git a/include/Scintilla.h b/include/Scintilla.h index e94672ebd..79ff07999 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -449,6 +449,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_EXPANDCHILDREN 2239 #define SCI_FOLDALL 2662 #define SCI_ENSUREVISIBLE 2232 +#define SC_AUTOMATICFOLD_SHOW 0x0001 +#define SC_AUTOMATICFOLD_CLICK 0x0002 +#define SC_AUTOMATICFOLD_CHANGE 0x0004 +#define SCI_SETAUTOMATICFOLD 2663 +#define SCI_GETAUTOMATICFOLD 2664 #define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002 #define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004 #define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 416e628af..862a6e3a0 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -1130,6 +1130,17 @@ 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,) +enu AutomaticFold=SC_AUTOMATICFOLD_ +val SC_AUTOMATICFOLD_SHOW=0x0001 +val SC_AUTOMATICFOLD_CLICK=0x0002 +val SC_AUTOMATICFOLD_CHANGE=0x0004 + +# Set automatic folding behaviours. +set void SetAutomaticFold=2663(int automaticFold,) + +# Get automatic folding behaviours. +get int GetAutomaticFold=2664(,) + enu FoldFlag=SC_FOLDFLAG_ val SC_FOLDFLAG_LINEBEFORE_EXPANDED=0x0002 val SC_FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004 diff --git a/src/Editor.cxx b/src/Editor.cxx index 15e221f29..783633c2e 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -208,6 +208,7 @@ Editor::Editor() { recordingMacro = false; foldFlags = 0; + foldAutomatic = 0; wrapState = eWrapNone; wrapWidth = LineLayout::wrapWidthInfinite; @@ -4563,11 +4564,32 @@ bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) { x += vs.ms[margin].width; } if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) { + int position = pdoc->LineStart(LineFromLocation(pt)); + if ((vs.ms[marginClicked].mask & SC_MASK_FOLDERS) && (foldAutomatic & SC_AUTOMATICFOLD_CLICK)) { + int lineClick = pdoc->LineFromPosition(position); + if (shift && ctrl) { + FoldAll(SC_FOLDACTION_TOGGLE); + } else { + int levelClick = pdoc->GetLevel(lineClick); + if (levelClick & SC_FOLDLEVELHEADERFLAG) { + if (shift) { + // Ensure all children visible + FoldExpand(lineClick, SC_FOLDACTION_EXPAND, levelClick); + } else if (ctrl) { + FoldExpand(lineClick, SC_FOLDACTION_TOGGLE, levelClick); + } else { + // Toggle this line + FoldLine(lineClick, SC_FOLDACTION_TOGGLE); + } + } + } + return true; + } SCNotification scn = {0}; scn.nmhdr.code = SCN_MARGINCLICK; scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); - scn.position = pdoc->LineStart(LineFromLocation(pt)); + scn.position = position; scn.margin = marginClicked; NotifyParent(scn); return true; @@ -4706,11 +4728,11 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { insertingNewLine = true; } if (insertingNewLine && (mh.position != pdoc->LineStart(lineOfPos))) - NotifyNeedShown(mh.position, pdoc->LineStart(lineOfPos+1) - mh.position); + NeedShown(mh.position, pdoc->LineStart(lineOfPos+1) - mh.position); else - NotifyNeedShown(mh.position, 0); + NeedShown(mh.position, 0); } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { - NotifyNeedShown(mh.position, mh.length); + NeedShown(mh.position, mh.length); } } if (mh.linesAdded != 0) { @@ -4767,6 +4789,9 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { } } } + if ((mh.modificationType & SC_MOD_CHANGEFOLD) && (foldAutomatic & SC_AUTOMATICFOLD_CHANGE)) { + FoldChanged(mh.line, mh.foldLevelNow, mh.foldLevelPrev); + } // NOW pay the piper WRT "deferred" visual updates if (IsLastStep(mh)) { @@ -7153,6 +7178,51 @@ void Editor::FoldAll(int action) { Redraw(); } +void Editor::FoldChanged(int line, int levelNow, int levelPrev) { + if (levelNow & SC_FOLDLEVELHEADERFLAG) { + if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) { + // Adding a fold point. + if (cs.SetExpanded(line, true)) { + RedrawSelMargin(); + } + FoldExpand(line, SC_FOLDACTION_EXPAND, levelPrev); + } + } else if (levelPrev & SC_FOLDLEVELHEADERFLAG) { + if (!cs.GetExpanded(line)) { + // Removing the fold from one that has been contracted so should expand + // otherwise lines are left invisible with no way to make them visible + if (cs.SetExpanded(line, true)) { + RedrawSelMargin(); + } + FoldExpand(line, SC_FOLDACTION_EXPAND, levelPrev); + } + } + if (!(levelNow & SC_FOLDLEVELWHITEFLAG) && + ((levelPrev & SC_FOLDLEVELNUMBERMASK) > (levelNow & SC_FOLDLEVELNUMBERMASK))) { + if (cs.HiddenLines()) { + // See if should still be hidden + int parentLine = pdoc->GetFoldParent(line); + if ((parentLine < 0) || (cs.GetExpanded(parentLine) && cs.GetVisible(parentLine))) { + cs.SetVisible(line, line, true); + SetScrollBars(); + Redraw(); + } + } + } +} + +void Editor::NeedShown(int pos, int len) { + if (foldAutomatic & SC_AUTOMATICFOLD_SHOW) { + int lineStart = pdoc->LineFromPosition(pos); + int lineEnd = pdoc->LineFromPosition(pos+len); + for (int line = lineStart; line <= lineEnd; line++) { + EnsureLineVisible(line, false); + } + } else { + NotifyNeedShown(pos, len); + } +} + int Editor::GetTag(char *tagValue, int tagNumber) { const char *text = 0; int length = 0; @@ -8606,6 +8676,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETFOLDEXPANDED: return cs.GetExpanded(wParam); + case SCI_SETAUTOMATICFOLD: + foldAutomatic = wParam; + break; + + case SCI_GETAUTOMATICFOLD: + return foldAutomatic; + case SCI_SETFOLDFLAGS: foldFlags = wParam; Redraw(); diff --git a/src/Editor.h b/src/Editor.h index 935fe1513..5f0e5dad6 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -274,6 +274,7 @@ protected: // ScintillaBase subclass needs access to much of Editor bool recordingMacro; int foldFlags; + int foldAutomatic; ContractionState cs; // Hotspot support |