From ffb0b9d6532d4c0c062b51ec0217e362fb421da9 Mon Sep 17 00:00:00 2001 From: mrjt Date: Mon, 27 Apr 2009 13:21:38 +0000 Subject: [PATCH] TabBar: Tab Stacking and sorting added Docking: Minor bug-fix, PopUpDockWindow confirmed as working, more complex dynamic allocation supported QuickTabsTest: Modified to use TabBar-derived QuickTabs git-svn-id: svn://ultimatepp.org/upp/trunk@1104 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/Docking/DockCont.cpp | 40 ++- bazaar/Docking/DockCont.h | 1 + bazaar/Docking/DockTabBar.cpp | 55 ++-- bazaar/Docking/DockTabBar.h | 11 +- bazaar/Docking/DockWindow.cpp | 58 +++- bazaar/Docking/DockableCtrl.h | 1 + bazaar/Docking/Docking.h | 22 +- bazaar/Docking/Docking.iml | 426 ++++++++++++++----------- bazaar/QuickTabsTest/QuickTabsTest.cpp | 52 ++- bazaar/QuickTabsTest/QuickTabsTest.h | 6 +- bazaar/QuickTabsTest/QuickTabsTest.lay | 6 +- bazaar/QuickTabsTest/QuickTabsTest.upp | 5 +- bazaar/QuickTabsTest/init | 2 +- bazaar/TabBar/TabBar.cpp | 298 ++++++++++++++--- bazaar/TabBar/TabBar.h | 43 ++- 15 files changed, 712 insertions(+), 314 deletions(-) diff --git a/bazaar/Docking/DockCont.cpp b/bazaar/Docking/DockCont.cpp index ac334ab79..2347b9e48 100644 --- a/bazaar/Docking/DockCont.cpp +++ b/bazaar/Docking/DockCont.cpp @@ -382,6 +382,7 @@ void DockCont::TabClosed(Value v) DockableCtrl *c = DockCast(v); base->SaveDockerPos(*c); c->Remove(); + c->WhenState(); } waitsync = true; Layout(); @@ -442,9 +443,29 @@ void DockCont::AddFrom(DockCont& cont, int except) void DockCont::Clear() { - for (int i = 0; i < tabbar.GetCount(); i++) - CtrlCast(tabbar.Get(i))->Close(); - tabbar.Clear(); + if (tabbar.GetCount()) { + // Copy tabbar values and clear to prevent this being called multple times if child + // if destroyed on closing. pfft + Vector v; + v.SetCount(tabbar.GetCount()); + for (int i = 0; i < tabbar.GetCount(); i++) + v[i] = tabbar.Get(i); + tabbar.Clear(); + // Remove ctrls and signal correct state change + for (int i = 0; i < v.GetCount(); i++) { + if (IsDockCont(v[i])) { + DockCont *dc = ContCast(v[i]); + dc->Remove(); + dc->State(*base, STATE_NONE); + } + else { + DockableCtrl *dc = DockCast(v[i]); + dc->Remove(); + dc->WhenState(); + } + } + + } handle.dc = NULL; } @@ -455,6 +476,17 @@ void DockCont::State(DockWindow& dock, DockCont::DockState state) SyncFrames(); SyncButtons(); Show(); + SignalStateChange(); +} + +void DockCont::SignalStateChange() +{ + for (int i = tabbar.GetCount()-1; i >= 0; i--) { + if (IsDockCont(tabbar.Get(i))) + ContCast(tabbar.Get(i))->SignalStateChange(); + else + DockCast(tabbar.Get(i))->WhenState(); + } } void DockCont::SyncButtons(DockableCtrl& dc) @@ -803,7 +835,7 @@ DockCont::DockCont() NoCenter().Sizeable(true).MaximizeBox(false).MinimizeBox(false); tabbar.AutoHideMin(1); - tabbar.WhenCursor = THISBACK(TabSelected); + tabbar<<= THISBACK(TabSelected); tabbar.WhenClose = THISBACK(TabClosed); tabbar.WhenCloseAll = THISBACK(RefreshLayout); tabbar.SetBottom(); diff --git a/bazaar/Docking/DockCont.h b/bazaar/Docking/DockCont.h index c112a31ea..ade62eeb9 100644 --- a/bazaar/Docking/DockCont.h +++ b/bazaar/Docking/DockCont.h @@ -181,6 +181,7 @@ public: void Lock(bool lock); void SyncFrames(); void SyncFrames(bool lock); + void SignalStateChange(); void Grouping(bool grouping) { tabbar.Grouping(grouping); GroupRefresh(); } void GroupRefresh(); diff --git a/bazaar/Docking/DockTabBar.cpp b/bazaar/Docking/DockTabBar.cpp index 46d8b7bc0..9d030de67 100644 --- a/bazaar/Docking/DockTabBar.cpp +++ b/bazaar/Docking/DockTabBar.cpp @@ -20,10 +20,12 @@ void DockTabBar::FrameAddSize(Size& sz) TabBar::FrameAddSize(sz); } -void DockTabBar::PaintTabData(Draw& w, Point p, const Size& sz, const Value& q, const Font& font, Color ink, dword style) +void DockTabBar::PaintTabData(Draw& w, const Rect &r, const Tab& tab, const Font &font, Color ink, dword style, int bl) { DockableCtrl *d; WString txt; + const Value &q = tab.data; + ink = (style == CTRL_DISABLED) ? SColorDisabled : ink; if (IsTypeRaw(q)) { @@ -37,31 +39,40 @@ void DockTabBar::PaintTabData(Draw& w, Point p, const Size& sz, const Value& q, txt = d->GetTitle(); } - TabCenterText(p, sz, font); + Point p = GetTextPosition(r, GetTextSize(txt, font).cy, bl); if(icons) { const Image& icon = (style == CTRL_DISABLED) ? DisabledImage(d->GetIcon()) : d->GetIcon(); - int al = GetAlign(); - Point ip = p; - Size isz = icon.GetSize(); - if (al == RIGHT) - ip.x -= isz.cx-1; - else if (al == LEFT) - ip.y -= isz.cy; - if (IsVert()) { - w.DrawImage(ip.x-1, ip.y, icon); - p.y += (isz.cy + TB_SPACEICON) * ((al == LEFT) ? -1 : 1); + if (!icon.IsEmpty()) { + int al = GetAlign(); + Size isz = icon.GetSize(); + Point ip; + switch (al) { + case LEFT: + ip = Point(r.left + (r.Width() - isz.cy) / 2, p.y - isz.cy); + p.y -= isz.cy + TB_SPACEICON; + break; + case TOP: + ip = Point(p.x, r.top + (r.Height() - isz.cy) / 2); + p.x += isz.cx + TB_SPACEICON; + break; + case RIGHT: + ip = Point(r.left + (r.Width() - isz.cy) / 2, p.y); + p.y += isz.cy + TB_SPACEICON; + break; + case BOTTOM: + ip = Point(p.x, r.top + (r.Height() - isz.cy) / 2); + p.x += isz.cx + TB_SPACEICON; + break; + }; + w.DrawImage(ip.x, ip.y, icon); } - else { - w.DrawImage(ip.x, ip.y-2, icon); - p.x += isz.cx + TB_SPACEICON; - } } if (showtext) w.DrawText(p.x, p.y, GetTextAngle(), txt, font, ink); } -Size DockTabBar::GetStdSize(Value& q) +Size DockTabBar::GetStdSize(const Value& q) { DockableCtrl *d; Value v; @@ -123,6 +134,8 @@ void AutoHideBar::AddCtrl(DockCont& c, const String& group) TabBar::Add(RawToValue(&c), group); if (GetCount() == autohide+1) RefreshParentLayout(); + else + Refresh(); } void AutoHideBar::RemoveCtrl(DockCont& c, int ix) @@ -182,7 +195,10 @@ void AutoHideBar::TabHighlight() void AutoHideBar::TabClose(Value v) { - RemoveCtrl(*(ValueTo(v)), -1); + DockCont &dc = *(ValueTo(v)); + RemoveCtrl(dc, -1); + dc.StateNotDocked(); + dc.SignalStateChange(); if (GetCount() == autohide-1) RefreshParentLayout(); } @@ -242,7 +258,7 @@ void AutoHideBar::HideAnimate(Ctrl *c) return; } } - + DockTabBar::KillCursor(); #ifdef PLATFORM_WIN32 Rect r = popup.GetRect(); AdjustSize(r, -r.GetSize()); @@ -251,7 +267,6 @@ void AutoHideBar::HideAnimate(Ctrl *c) popup.Close(); ctrl->Remove(); ctrl = NULL; - DockTabBar::SetCursor(-1); } void AutoHideBar::AdjustSize(Rect& r, const Size& sz) diff --git a/bazaar/Docking/DockTabBar.h b/bazaar/Docking/DockTabBar.h index 0f4c8f51e..5815995ea 100644 --- a/bazaar/Docking/DockTabBar.h +++ b/bazaar/Docking/DockTabBar.h @@ -30,18 +30,15 @@ protected: int autohide; bool icons:1; bool showtext:1; -// PasteClip *clip; - - virtual void PaintTabData(Draw& w, Point p, const Size& sz, const Value& q, const Font& font, - Color ink, dword style); - virtual Size GetStdSize(Value& q); + + virtual void PaintTabData(Draw& w, const Rect &t, const Tab& tab, const Font &font, + Color ink, dword style, int bl); + virtual Size GetStdSize(const Value &q); virtual void RightDown(Point p, dword keyflags); virtual void LeftDown(Point p, dword keyflags) { TabBar::LeftDown(p, keyflags &= ~K_SHIFT); } virtual void LeftUp(Point p, dword keyflags) { TabBar::LeftUp(p, keyflags &= ~K_SHIFT); } virtual void LeftDrag(Point p, dword keyflags); -// virtual void DragAndDrop(Point p, PasteClip& d); -// virtual void DragLeave(); }; class DockCont; diff --git a/bazaar/Docking/DockWindow.cpp b/bazaar/Docking/DockWindow.cpp index fee095d6e..5bec5172a 100644 --- a/bazaar/Docking/DockWindow.cpp +++ b/bazaar/Docking/DockWindow.cpp @@ -63,10 +63,10 @@ void DockWindow::AutoHide(int align, DockableCtrl& dc) Register(dc); DockCont *c = GetReleasedContainer(dc); c->StateAutoHide(*this); - hideframe[align].AddCtrl(*c, dc.GetGroup()); + hideframe[align].AddCtrl(*c, dc.GetGroup()); } -int DockWindow::FindDocker(Ctrl *dc) +int DockWindow::FindDocker(const Ctrl *dc) { for (int i = 0; i < dockers.GetCount(); i++) if (dc == (Ctrl *) dockers[i]) @@ -85,14 +85,21 @@ DockableCtrl& DockWindow::Register(DockableCtrl& dc) return *dockers[ix]; } -void DockWindow::Deregister(DockableCtrl& dc) +void DockWindow::Deregister(const DockableCtrl& dc) { int ix = FindDocker(&dc); - Close(dc); if (ix >= 0) { + DockableCtrl &dc = *dockers[ix]; dockers.Remove(ix); + Close(dc); dockerpos.Remove(ix); } + for (int i = 0; i < ctrls.GetCount(); i++) { + if (&dc == &ctrls[i]) { + ctrls.Remove(i); + break; + } + } } void DockWindow::Close(DockableCtrl& dc) @@ -1494,6 +1501,7 @@ void PopUpDockWindow::ContainerDragMove(DockCont& dc) Highlight(align, dc, target); } else { + PopUpHighlight(hide, 4); StopHighlight(IsAnimatedHighlight()); last_popup = NULL; } @@ -1501,8 +1509,14 @@ void PopUpDockWindow::ContainerDragMove(DockCont& dc) void PopUpDockWindow::ContainerDragEnd(DockCont& dc) { + int align = DOCK_NONE; + if (IsAutoHide() && showhide) + align = PopUpHighlight(hide, 4); HidePopUps(true, true); - DockWindow::ContainerDragEnd(dc); + if (align != DOCK_NONE) + AutoHideContainer(align, dc); + else + DockWindow::ContainerDragEnd(dc); last_target = NULL; last_popup = NULL; } @@ -1542,6 +1556,13 @@ void PopUpDockWindow::ShowOuterPopUps(DockCont& dc) if (dc.IsDockAllowed(DOCK_TOP)) ShowPopUp(outer[DOCK_TOP], prect.Offseted(cp.x - psz.cx, wrect.top + POPUP_SPACING)); if (dc.IsDockAllowed(DOCK_RIGHT)) ShowPopUp(outer[DOCK_RIGHT], prect.Offseted(wrect.right - POPUP_SPACING - psz.cx*2, cp.y - psz.cy)); if (dc.IsDockAllowed(DOCK_BOTTOM)) ShowPopUp(outer[DOCK_BOTTOM], prect.Offseted(cp.x - psz.cx, wrect.bottom - POPUP_SPACING - psz.cy*2)); + + if (IsAutoHide() && showhide) { + ShowPopUp(hide[DOCK_LEFT], prect.Offseted(wrect.left + POPUP_SPACING + style->outersize, cp.y - psz.cy)); + ShowPopUp(hide[DOCK_TOP], prect.Offseted(cp.x - psz.cx, wrect.top + POPUP_SPACING + style->outersize)); + ShowPopUp(hide[DOCK_RIGHT], prect.Offseted(wrect.right - POPUP_SPACING - psz.cx*2 - style->outersize, cp.y - psz.cy)); + ShowPopUp(hide[DOCK_BOTTOM], prect.Offseted(cp.x - psz.cx, wrect.bottom - POPUP_SPACING - psz.cy*2 - style->outersize)); + } } void PopUpDockWindow::ShowInnerPopUps(DockCont& dc, DockCont *target) @@ -1591,9 +1612,12 @@ void PopUpDockWindow::HidePopUps(bool _inner, bool _outer) if (_inner) for (int i = 0; i < 5; i++) inner[i].Close(); - if (_outer) + if (_outer) { for (int i = 0; i < 4; i++) - outer[i].Close(); + outer[i].Close(); + for (int i = 0; i < 4; i++) + hide[i].Close(); + } } PopUpDockWindow& PopUpDockWindow::SetStyle(const Style& s) @@ -1603,10 +1627,13 @@ PopUpDockWindow& PopUpDockWindow::SetStyle(const Style& s) inner[i].icon = &s.inner[i]; for (int i = 0; i < 4; i++) outer[i].icon = &s.outer[i]; + for (int i = 0; i < 4; i++) + hide[i].icon = &s.hide[i]; return *this; } PopUpDockWindow::PopUpDockWindow() +: showhide(true) { SetStyle(StyleDefault()); AnimateDelay(0); @@ -1614,16 +1641,21 @@ PopUpDockWindow::PopUpDockWindow() CH_STYLE(PopUpDockWindow, Style, StyleDefault) { - outer[0] = DockingImg::DockLeft(); - outer[1] = DockingImg::DockTop(); - outer[2] = DockingImg::DockRight(); - outer[3] = DockingImg::DockBottom(); - inner[0] = DockingImg::DockLeft(); inner[1] = DockingImg::DockTop(); inner[2] = DockingImg::DockRight(); inner[3] = DockingImg::DockBottom(); - inner[4] = DockingImg::DockTab(); + inner[4] = DockingImg::DockTab(); + + outer[0] = DockingImg::DockLeft(); + outer[1] = DockingImg::DockTop(); + outer[2] = DockingImg::DockRight(); + outer[3] = DockingImg::DockBottom(); + + hide[0] = DockingImg::HideLeft(); + hide[1] = DockingImg::HideTop(); + hide[2] = DockingImg::HideRight(); + hide[3] = DockingImg::HideBottom(); highlight = DockingImg::DockHL(); diff --git a/bazaar/Docking/DockableCtrl.h b/bazaar/Docking/DockableCtrl.h index 5d0261181..21d037c09 100644 --- a/bazaar/Docking/DockableCtrl.h +++ b/bazaar/Docking/DockableCtrl.h @@ -45,6 +45,7 @@ private: void StopHighlight() { Refresh(); } public: Callback1 WhenMenuBar; + Callback WhenState; virtual void WindowMenu(Bar& bar) { WhenMenuBar(bar); } diff --git a/bazaar/Docking/Docking.h b/bazaar/Docking/Docking.h index 2c85e8402..6fb78fe63 100644 --- a/bazaar/Docking/Docking.h +++ b/bazaar/Docking/Docking.h @@ -79,7 +79,7 @@ protected: // For finding drag-drop targets and computing boundary rect DockCont *GetMouseDockTarget(); DockCont *FindDockTarget(DockCont& dc, int& al); - int FindDocker(Ctrl *dc); + int FindDocker(const Ctrl *dc); Rect GetAlignBounds(int al, Rect r, bool center, bool allow_lr = true, bool allow_tb = true); int GetPointAlign(const Point p, Rect r, bool center, bool allow_lr = true, bool allow_tb = true); int GetQuad(Point p, Rect r); @@ -147,6 +147,12 @@ public: DockableCtrl& Dockable(Ctrl& ctrl, WString title); DockableCtrl& Dockable(Ctrl& ctrl, const char *title = 0) { return Dockable(ctrl, (WString)title); } + + template + DockableCtrl& CreateDockable(WString title) { return Register(ctrls.Create().Title(title)); } + template + DockableCtrl& CreateDockable(const char *title = 0) { return CreateDockable((WString)title); } + void DockLeft(DockableCtrl& dc, int pos = -1) { Dock(DOCK_LEFT, dc, pos); } void DockTop(DockableCtrl& dc, int pos = -1) { Dock(DOCK_TOP, dc, pos); } @@ -237,7 +243,7 @@ public: bool HasToolWindows() const { return childtoolwindows; } DockableCtrl& Register(DockableCtrl& dc); - void Deregister(DockableCtrl& dc); + void Deregister(const DockableCtrl& dc); const Vector& GetDockableCtrls() const { return dockers; } void DockManager(); @@ -263,7 +269,6 @@ public: void SetHighlightStyle(DockableCtrl::Style& s) { GetHighlightCtrl().SetStyle(s); } DockWindow(); - private: // Container management DockCont *GetContainer(Ctrl& dc) { return dynamic_cast(dc.GetParent()); } @@ -291,19 +296,17 @@ private: void ClearLayout(); }; -// WARNING! -// PopUpDockWindow is currently unstable, but will be supported in future revisions class PopUpDockWindow : public DockWindow { public: struct Style : ChStyle