From 164aace2193ad95bad57a4dfbf684b74bd0f0a3a Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 25 Aug 2014 15:37:48 +0000 Subject: [PATCH] ide: Navigator git-svn-id: svn://ultimatepp.org/upp/trunk@7602 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/ide/Assist.cpp | 18 +++- uppsrc/ide/Navigator.cpp | 210 +++++++++++++++++++++++++++++---------- uppsrc/ide/icon.ico | Bin 2862 -> 2862 bytes uppsrc/ide/ide.h | 25 +++-- 4 files changed, 190 insertions(+), 63 deletions(-) diff --git a/uppsrc/ide/Assist.cpp b/uppsrc/ide/Assist.cpp index c68f321be..4aaf092c8 100644 --- a/uppsrc/ide/Assist.cpp +++ b/uppsrc/ide/Assist.cpp @@ -46,26 +46,38 @@ AssistEditor::AssistEditor() navigating = false; int cy = search.GetMinSize().cy; - navigatorpane.Add(search.TopPos(0, cy).HSizePos()); + navigatorpane.Add(search.TopPos(0, cy).HSizePos(0, cy + 4)); + navigatorpane.Add(sortitems.TopPos(0, cy).RightPos(0, cy)); navigatorpane.Add(navigator_splitter.VSizePos(cy, 0).HSizePos()); scope.NoHeader(); scope.AddColumn().SetDisplay(Single()); scope.NoWantFocus(); scope.WhenSel = THISBACK(Scope); - navigator_splitter.Vert(scope, list); - navigator_splitter.SetPos(2000); + navigator_splitter.Vert() << scope << list << navlines; + navigator_splitter.SetPos(1500, 0); + navigator_splitter.SetPos(8000, 1); + navigator_splitter.SetPos(500, 2); list.NoHeader(); list.AddRowNumColumn().SetDisplay(navidisplay); list.SetLineCy(max(16, GetStdFontCy())); list.NoWantFocus(); list.WhenLeftClick = THISBACK(NavigatorClick); + list.WhenSel = THISBACK(SyncNavLines); list.WhenLineEnabled = THISBACK(ListLineEnabled); + navlines.NoHeader().NoWantFocus(); + navlines.WhenLeftClick = THISBACK(GoToNavLine); + navlines.AddColumn().SetDisplay(Single()); + search <<= THISBACK(TriggerSearch); search.SetFilter(CharFilterNavigator); search.WhenEnter = THISBACK(NavigatorEnter); + sortitems.Image(BrowserImg::Sort()); + sortitems <<= THISBACK(NaviSort); + sorting = false; + navigator = true; WhenAnnotationMove = THISBACK(SyncAnnotationPopup); diff --git a/uppsrc/ide/Navigator.cpp b/uppsrc/ide/Navigator.cpp index e2c023904..4875946c3 100644 --- a/uppsrc/ide/Navigator.cpp +++ b/uppsrc/ide/Navigator.cpp @@ -19,18 +19,92 @@ void AssistEditor::SyncCursor() search.NullText("Symbol/lineno " + k); search.Tip(IsNull(search) ? String() : "Clear " + k); - if(navigating) - return; - int q = linefo.Find(GetCppFileIndex(theide->editfile)); - if(q < 0) - return; - SortedVectorMap& m = linefo[q]; - q = m.FindUpperBound(GetLine(GetCursor()) + 1) - 1; - if(q >= 0 && q < m.GetCount()) { + if(!navigating) { + navlines.KillCursor(); + int q = linefo.Find(GetCppFileIndex(theide->editfile)); + if(q < 0) + return; navigating = true; - list.SetCursor(m[q]); + SortedVectorMap& m = linefo[q]; + q = m.FindUpperBound(GetLine(GetCursor()) + 1) - 1; + if(q >= 0 && q < m.GetCount()) + list.SetCursor(m[q]); navigating = false; } + SyncLines(); +} + +void AssistEditor::SyncLines() +{ + int ln = GetLine(GetCursor()) + 1; + int fi = GetCppFileIndex(theide->editfile); + int q = -1; + for(int i = 0; i < navlines.GetCount(); i++) { + const NavLine& l = navlines.Get(i, 0).To(); + if(l.file == fi && l.line <= ln && i < navlines.GetCount()) + q = i; + } + if(q >= 0) + navlines.SetCursor(q); +} + +void AssistEditor::SyncNavLines() +{ + int sc = navlines.GetScroll(); + navlines.Clear(); + int ii = list.GetCursor(); + if(ii >= 0 && ii < litem.GetCount()) { + int ln = GetLine(GetCursor()) + 1; + Vector l = GetNavLines(*litem[ii]); + for(int i = 0; i < l.GetCount(); i++) { + String p = GetCppFile(l[i].file); + navlines.Add(RawToValue(l[i])); + } + navlines.ScrollTo(sc); + SyncLines(); + } +} + +void PaintTeXt(Draw& w, int& x, int y, const String& text, Font font, Color ink) +{ + Size sz = GetTextSize(text, font); + w.DrawText(x, y, text, font, ink); + x += sz.cx; +} + +int AssistEditor::LineDisplay::DoPaint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const +{ + w.DrawRect(r, paper); + const NavLine& l = q.To(); + int x = r.left; + String p = GetCppFile(l.file); + int y = r.top + (r.GetHeight() - StdFont().GetCy()) / 2; + PaintTeXt(w, x, y, GetFileName(GetFileFolder(p)) + "/", StdFont(), ink); + PaintTeXt(w, x, y, GetFileName(p), StdFont().Bold(), ink); + PaintTeXt(w, x, y, " (", StdFont(), ink); + PaintTeXt(w, x, y, AsString(l.line), StdFont().Bold(), ink); + PaintTeXt(w, x, y, ")", StdFont(), ink); + return x; +} + +void AssistEditor::LineDisplay::Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const +{ + DoPaint(w, r, q, ink, paper, style); +} + +Size AssistEditor::LineDisplay::GetStdSize(const Value& q) const +{ + NilDraw w; + return Size(DoPaint(w, Size(999999, 999999), q, White(), White(), 0), StdFont().Bold().GetCy()); +} + +void AssistEditor::GoToNavLine() +{ + int ii = navlines.GetClickPos().y; + if(ii >= 0 && ii < navlines.GetCount() && theide) { + const NavLine& l = navlines.Get(ii, 0).To(); + theide->GotoPos(GetCppFile(l.file), l.line); + } } void AssistEditor::SelectionChanged() @@ -40,6 +114,37 @@ void AssistEditor::SelectionChanged() SyncParamInfo(); } +bool AssistEditor::NavLine::operator<(const NavLine& b) const +{ + String p1 = GetCppFile(file); + String p2 = GetCppFile(b.file); + return CombineCompare(!impl, !b.impl) + (GetFileExt(p1), GetFileExt(p2)) // .h > .c + (GetFileName(p1), GetFileName(p2)) + (p1, p2) + (line, b.line) < 0; +} + +Vector AssistEditor::GetNavLines(const NavItem& m) +{ + Vector l; + int q = CodeBase().Find(m.nest); + if(q < 0) + return l; + const Array& a = CodeBase()[q]; + for(int i = 0; i < a.GetCount(); i++) { + const CppItem& mm = a[i]; + if(mm.qitem == m.qitem) { + NavLine& nl = l.Add(); + nl.impl = mm.impl; + nl.file = mm.file; + nl.line = mm.line; + } + } + Sort(l); + return l; +} + void AssistEditor::Navigate() { if(navigating) @@ -49,37 +154,20 @@ void AssistEditor::Navigate() if(theide && ii >= 0 && ii < litem.GetCount()) { int ln = GetLine(GetCursor()) + 1; const NavItem& m = *litem[ii]; - if(m.kind == KIND_LINE || IsNull(search) && m.line != ln) { + if(m.kind == KIND_LINE || IsNull(search)) theide->GotoPos(Null, m.line); - navigating = false; - return; - } - int q = CodeBase().Find(m.nest); - if(q < 0) { - navigating = false; - return; - } - const Array& a = CodeBase()[q]; - Vector l; - for(int i = 0; i < a.GetCount(); i++) { - const CppItem& mm = a[i]; - if(mm.qitem == m.qitem) { - NavLine& nl = l.Add(); - nl.impl = mm.impl; - nl.file = mm.file; - nl.line = mm.line; + else { + Vector l = GetNavLines(m); + int q = l.GetCount() - 1; + for(int i = q; i >= 0; i--) { + if(GetCppFile(l[i].file) == theide->editfile && l[i].line == ln) { + q = (i + l.GetCount() - 1) % l.GetCount(); + break; + } } + if(q >= 0 && q < l.GetCount()) + theide->GotoPos(GetCppFile(l[q].file), l[q].line); } - Sort(l); - q = 0; - for(int i = 0; i < l.GetCount(); i++) { - if(GetCppFile(l[i].file) == theide->editfile && l[i].line == ln) { - q = (i + 1) % l.GetCount(); - break; - } - } - if(q >= 0 && q < l.GetCount()) - theide->GotoPos(GetCppFile(l[q].file), l[q].line); } navigating = false; } @@ -249,12 +337,6 @@ Size AssistEditor::NavigatorDisplay::GetStdSize(const Value& q) const return Size(DoPaint(w, Size(999999, 999999), q, White(), White(), 0), Draw::GetStdFontCy()); } -force_inline -bool AssistEditor::NavItem::operator<(const NavItem& b) const -{ - return CombineCompare(decl_file, b.decl_file)(decl_line, b.decl_line); -} - void AssistEditor::TriggerSearch() { search_trigger.KillSet(100, THISBACK(Search)); @@ -279,8 +361,21 @@ void AssistEditor::NavGroup(bool local) } } +force_inline +bool AssistEditor::SortByLines(const NavItem *a, const NavItem *b) +{ + return CombineCompare(a->decl_file, b->decl_file)(a->decl_line, b->decl_line) < 0; +} + +force_inline +bool AssistEditor::SortByNames(const NavItem *a, const NavItem *b) +{ + return CombineCompare(a->name, b->name)(a->qitem, b->qitem) < 0; +} + void AssistEditor::Search() { + sortitems.Check(sorting); int sc = scope.GetScroll(); String key = scope.GetKey(); String s = TrimBoth(~search); @@ -391,22 +486,23 @@ void AssistEditor::Search() nitem = imap.PickValues(); NavGroup(false); SortByKey(gitem); - for(int i = 0; i < gitem.GetCount(); i++) { - scope.Add(gitem.GetKey(i)); - Sort(gitem[i]); - } + Index sc; + for(int i = 0; i < gitem.GetCount(); i++) + Sort(gitem[i], sorting ? SortByLines : SortByNames); } scope.Clear(); scope.Add(Null); - for(int i = 0; i < gitem.GetCount(); i++) - scope.Add(gitem.GetKey(i)); + Index done; + for(int i = 0; i < gitem.GetCount(); i++) { + String s = gitem.GetKey(i); + if(done.Find(s) < 0) { + done.Add(s); + scope.Add(gitem.GetKey(i)); + } + } scope.ScrollTo(sc); if(!navigator_global || !scope.FindSetCursor(key)) scope.GoBegin(); - if(navigator_global) - navigator_splitter.NoZoom(); - else - navigator_splitter.Zoom(1); } int AssistEditor::PaintFileName(Draw& w, const Rect& r, String h, Color ink) @@ -488,4 +584,10 @@ void AssistEditor::ListLineEnabled(int i, bool& b) if(findarg(kind, KIND_FILE, KIND_NEST) >= 0) b = false; } -} \ No newline at end of file +} + +void AssistEditor::NaviSort() +{ + sorting = !sorting; + Search(); +} diff --git a/uppsrc/ide/icon.ico b/uppsrc/ide/icon.ico index 76862d1673d6e9f03af0cc31d45b6671514f98f4..da67a307592909d4bc06eee45ecb30e925c7a54f 100644 GIT binary patch literal 2862 zcmeHJy-wUf5FY=<-c+Pa6_h6Qha$P7ATNM)PY@}}6F_@Xiljryad2+(EH2W}^EgP$ ze6ybQ-r88cfFea=(CqB|eBaK_f(21R866yu$k&|cBk#Ol5dG$u`bP=TtJg$Fs9`;1 zO=KlH;kth)md}cH>iD?Ua=^B2D>{Qq>Q<|jg`ysK<$xdNMjEjYMmPl)yN*N7=ZJDg zcsWmMxL&Pi3u2nOBfc@)o8at|)tse!NHIOq8tk{P6S65sJ@ zU(UJ-di+RD&;t7O6YF>)pYxB*A3WoDJRx{--x+uz>FV7afOUA}{A|L`-M;JD%?jtC zw&&>M(#sGZM+SUx!E^Yy+5J1BHtTi8-;h|tJodl~gldEp4B zF+Ed#2SunqcczM)W5ag|&)I*E-?4qg%#%9Hd|{R(rmi!?Mx-hVQ`WU9Iv>HZtXIid<~?lFY|gN5msd;Fv;8FY R$NF?zBeOon8p%`V^Z(u}N literal 2862 zcmcguv5wO~5S`e@*c9X_se&lrl;S9Ykm#;}A3)fmM?$~{Ku3H5DRc-z?#|79K)xac z4ShZb$;_MGS#LH@F4Dn`G?|^5_uh`z)+$6jis|5h#NH-EPk80>8$=ge)BLbUl-?pb z1cv<{dry9ejv052*6?1T@7g}ZHe6_y%cb}pT7s*ps(}L!zG@)%dmV!`FlHDB7b~kF z`*TIL1HSAh7{+UKYF2H{p6t(nXc@O&@f{Mn-^UspaM$mdOh!6perQ>g(6`T1 z%9?~$zkX8|HFT2&8m>27Ge;h>{&PMY5-k?SvA)C}yn9bapT;zJSr{a^1+U>)!^&5J z0X8&n;r&bYQrtHFT3tTPwTkQkjnGuLUrp%IxDv-p)U`&%b@DB*zgn3O0Q;+lgdm6R zV0=QiPbTe*%vE|<^d&GKW`~BG(c>=`Lw*$nzlx#L^!eaG>|6sObFH1j-W%cJQO3)D;=t>7e5Q&IX;*8b@uH1DLS*q_zmo; G=kyoIqi9wD diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index e03d12133..e8d048566 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -296,6 +296,7 @@ struct AssistEditor : CodeEditor { StaticRect navigatorpane; ArrayCtrl scope; ArrayCtrl list; + ArrayCtrl navlines; Splitter navigator_splitter; EditString search; @@ -304,11 +305,7 @@ struct AssistEditor : CodeEditor { int file:31; int line; - bool operator <(const NavLine& b) const { - return CombineCompare(!impl, !b.impl) - (GetFileName(GetCppFile(file)), GetFileName(GetCppFile(b.file))) - (line, b.line); - } + bool operator<(const NavLine& b) const; }; struct NavItem { @@ -333,7 +330,6 @@ struct AssistEditor : CodeEditor { bool decl; Vector linefo; - bool operator<(const NavItem& b) const; void Set(const CppItem& m); }; @@ -344,6 +340,12 @@ struct AssistEditor : CodeEditor { virtual void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const; virtual Size GetStdSize(const Value& q) const; }; + + struct LineDisplay : Display { + int DoPaint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const; + virtual void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const; + virtual Size GetStdSize(const Value& q) const; + }; struct NavigatorDisplay : Display { const Vector& item; @@ -367,12 +369,18 @@ struct AssistEditor : CodeEditor { bool navigating; TimeCallback search_trigger; bool navigator_global; + ToolButton sortitems; + bool sorting; void TriggerSearch(); void NavGroup(bool local); void Search(); void Scope(); void ListLineEnabled(int i, bool& b); + void NaviSort(); + + static bool SortByLines(const NavItem *a, const NavItem *b); + static bool SortByNames(const NavItem *a, const NavItem *b); Splitter popup; ArrayCtrl assist; @@ -462,10 +470,15 @@ struct AssistEditor : CodeEditor { void SyncCursor(); + Vector GetNavLines(const NavItem& m); + void Navigate(); void NavigatorClick(); void NavigatorEnter(); void SyncNavigator(); + void SyncLines(); + void SyncNavLines(); + void GoToNavLine(); bool IsNavigator() const { return navigator; } void Navigator(bool navigator);