From 8ccb01870f9fcc0c88017bd9d2aee5ae4c8bfdd5 Mon Sep 17 00:00:00 2001 From: cxl Date: Sat, 11 Sep 2010 19:19:26 +0000 Subject: [PATCH] Improved DropList, ColorPopUp and DropTree animation git-svn-id: svn://ultimatepp.org/upp/trunk@2682 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Crash/Crash.upp | 2 +- uppsrc/CtrlLib/ColorPopup.cpp | 18 +- uppsrc/CtrlLib/CtrlUtil.cpp | 22 +- uppsrc/CtrlLib/CtrlUtil.h | 8 + uppsrc/CtrlLib/DropTree.cpp | 444 +++++++++++++++++----------------- uppsrc/CtrlLib/PopupTable.cpp | 24 +- uppsrc/CtrlLib/TreeCtrl.h | 2 + 7 files changed, 267 insertions(+), 253 deletions(-) diff --git a/uppsrc/Crash/Crash.upp b/uppsrc/Crash/Crash.upp index 0ea3826b6..f82ca8105 100644 --- a/uppsrc/Crash/Crash.upp +++ b/uppsrc/Crash/Crash.upp @@ -1,4 +1,4 @@ -description "Utility to examine content of .crash and .map files"; +description "Utility to examine content of .crash and .map files\377"; uses CtrlLib; diff --git a/uppsrc/CtrlLib/ColorPopup.cpp b/uppsrc/CtrlLib/ColorPopup.cpp index 76b6d99ea..4ff63a5fb 100644 --- a/uppsrc/CtrlLib/ColorPopup.cpp +++ b/uppsrc/CtrlLib/ColorPopup.cpp @@ -282,17 +282,21 @@ void ColorPopUp::PopUp(Ctrl *owner, Color c) Rect rt = RectC(x, y, sz.cx, sz.cy); if(GUI_PopUpEffect()) { - Ctrl popup; - popup.Add(BottomPos(0, rt.Height()).LeftPos(0, rt.Width())); - popup.SetRect(RectC(rt.left, rt.top, 3, 3)); - popup.PopUp(owner, true, true, GUI_GlobalStyle() >= GUISTYLE_XP); + sPaintRedirectCtrl pb; + pb.ctrl = this; + Add(pb.BottomPos(0, rt.Height()).LeftPos(0, rt.Width())); + SetRect(RectC(rt.left, rt.top, 1, 1)); + Ctrl::PopUp(owner, true, true, GUI_GlobalStyle() >= GUISTYLE_XP); SetFocus(); Ctrl::ProcessEvents(); - Animate(popup, rt, GUIEFFECT_SLIDE); + Animate(*this, rt, GUIEFFECT_SLIDE); + pb.Remove(); + } + else { + SetRect(rt); + Ctrl::PopUp(owner, true, true, true); } - SetRect(rt); - Ctrl::PopUp(owner, true, true, true); SetFocus(); if(!norampwheel) { diff --git a/uppsrc/CtrlLib/CtrlUtil.cpp b/uppsrc/CtrlLib/CtrlUtil.cpp index fc9e3c7d1..c590cbd73 100644 --- a/uppsrc/CtrlLib/CtrlUtil.cpp +++ b/uppsrc/CtrlLib/CtrlUtil.cpp @@ -18,7 +18,7 @@ void Animate(Ctrl& c, const Rect& target, int type) int anitime = 150; if(type) for(;;) { - dword t = (GetTickCount() - time0); + int t = int(GetTickCount() - time0); if(t > anitime) break; if(type == GUIEFFECT_SLIDE) { @@ -35,29 +35,11 @@ void Animate(Ctrl& c, const Rect& target, int type) r.right = (r.left + ((r.GetWidth() - target.GetWidth()) * t) / anitime); if(r.GetHeight() > target.GetHeight()) r.bottom = (r.top + ((r.GetHeight() - target.GetHeight()) * t) / anitime); -#if 0 - int q = 25 * t / 200; - q *= max(q - 10, 1); - if(r.left > target.left) - r.left = max(r.left - q, target.left); - if(r.top > target.top) - r.top = max(r.top - q, target.top); - if(r.right < target.right) - r.right = min(r.right + q, target.right); - if(r.bottom < target.bottom) - r.bottom = min(r.bottom + q, target.bottom); - if(r.GetWidth() > target.GetWidth()) - r.right = r.left + target.GetWidth(); - if(r.GetHeight() > target.GetHeight()) - r.bottom = r.top + target.GetHeight(); - if(r == target) - break; -#endif c.SetRect(r); } else if(type == GUIEFFECT_FADE) - c.SetAlpha((byte)(255 * t / 120)); + c.SetAlpha((byte)(255 * t / anitime)); else break; c.Sync(); diff --git a/uppsrc/CtrlLib/CtrlUtil.h b/uppsrc/CtrlLib/CtrlUtil.h index 33ff2df09..337b246ab 100644 --- a/uppsrc/CtrlLib/CtrlUtil.h +++ b/uppsrc/CtrlLib/CtrlUtil.h @@ -352,3 +352,11 @@ String UpdateGetDir(); void UpdateFile(String dst, String src); void MemoryProfileInfo(); + +struct sPaintRedirectCtrl : Ctrl { + Ctrl *ctrl; + + virtual void Paint(Draw& w) { + ctrl->Paint(w); + } +}; diff --git a/uppsrc/CtrlLib/DropTree.cpp b/uppsrc/CtrlLib/DropTree.cpp index e58c85e37..97e987f22 100644 --- a/uppsrc/CtrlLib/DropTree.cpp +++ b/uppsrc/CtrlLib/DropTree.cpp @@ -1,216 +1,228 @@ -#include "CtrlLib.h" - -namespace Upp { - -CH_VALUE(TreeDropEdge, ChBorder(BlackBorder())); - -CtrlFrame& TreeDropFrame() -{ - static LookFrame m(TreeDropEdge); - return m; -} - -PopUpTree::PopUpTree() { - SetFrame(TreeDropFrame()); - Accel(); - MouseMoveCursor(); - NoPopUpEx(); - SetDropLines(16); - open = autosize = false; - showpos = Null; - WhenOpen = WhenClose = THISBACK(OpenClose); -} - -PopUpTree::~PopUpTree() {} - -void PopUpTree::CancelMode() { - if(open) { - DoClose(); - WhenCancel(); - } - TreeCtrl::CancelMode(); -} - -void PopUpTree::DoClose() { - open = false; - Ctrl::Close(); -} - -void PopUpTree::Deactivate() { - if(open) { - DoClose(); - IgnoreMouseClick(); - WhenCancel(); - } -} - -void PopUpTree::Select() { - if(IsCursor() && !GetData().IsVoid()) { - DoClose(); - WhenSelect(); - } -} - -bool PopUpTree::Key(dword key, int n) { - switch(key) { - case K_ENTER: - case K_ALT_DOWN: - DoClose(); - WhenSelect(); - return true; - case K_ESCAPE: - DoClose(); - WhenCancel(); - return true; - } - return TreeCtrl::Key(key, n); -} - -void PopUpTree::PopUp(Ctrl *owner, int x, int top, int bottom, int width) { - DoClose(); - Rect area = Ctrl::GetWorkArea(); - int mh = min(maxheight, area.bottom - bottom); - int h = AddFrameSize(width, maxheight).cy; - showpos.x = x; - showpos.y = bottom; - showwidth = width; - up = false; - if(showpos.y + h > area.bottom) { - up = true; - showpos.y = top; - } - open = false; - Ctrl popup; - int ht = AddFrameSize(width, min(mh, autosize ? GetTreeSize().cy : INT_MAX)).cy; - Rect rt = RectC(showpos.x, showpos.y - (up ? ht : 0), showwidth, ht); - if(GUI_PopUpEffect()) { - if(up) { - popup.SetRect(Rect(rt.left, rt.bottom - 1, rt.right, rt.bottom)); - popup.Add(TopPos(0, rt.Height()).LeftPos(0, rt.Width())); - } - else { - popup.SetRect(Rect(rt.left, rt.top, rt.right, rt.top + 1)); - popup.Add(BottomPos(0, rt.Height()).LeftPos(0, rt.Width())); - } - CenterCursor(); - popup.PopUp(owner, true, true, GUI_DropShadows()); - SetFocus(); - Ctrl::ProcessEvents(); - Animate(popup, rt, GUIEFFECT_SLIDE); - Ctrl::Remove(); - } - CenterCursor(); - SetRect(rt); - Ctrl::PopUp(owner, true, true, GUI_DropShadows()); - SetFocus(); - open = true; -} - -void PopUpTree::OpenClose(int) -{ - if(autosize) { - SyncTree(); - Rect area = Ctrl::GetWorkArea(); - int mh = min(maxheight, area.bottom - showpos.y); - int ht = AddFrameSize(showwidth, min(mh, GetTreeSize().cy)).cy; - SetRect(RectC(showpos.x, showpos.y - (up ? ht : 0), showwidth, ht)); - } -} - -void PopUpTree::PopUp(Ctrl *owner, int width) -{ - Rect r = owner->GetScreenRect(); - r.right = r.left + width; - PopUp(owner, r.left, r.top, r.bottom, width); - if(IsNull(showpos)) - showpos = r.TopLeft(); - OpenClose(0); -} - -void PopUpTree::PopUp(Ctrl *owner) -{ - Rect r = owner->GetScreenRect(); - PopUp(owner, r.left, r.top, r.bottom, r.Width()); -} - -void DropTree::Sync() { - Image icon; - if(tree.IsCursor()) - icon = tree.GetNode(tree.GetCursor()).image; - icond.Set(valuedisplay ? *valuedisplay : tree.GetDisplay(tree.GetCursor()), icon); - MultiButton::SetDisplay(icond); - Set(tree.GetValue()); -} - -bool DropTree::Key(dword k, int) { - if(IsReadOnly()) return false; - if(k == K_ALT_DOWN) { - Drop(); - return true; - } - return false; -} - -void DropTree::Drop() { - if(IsReadOnly()) return; - if(dropfocus) - SetFocus(); - WhenDrop(); - tree.PopUp(this, GetRect().GetWidth()); -} - -void DropTree::Select() { - if(dropfocus) - SetFocus(); - Sync(); - UpdateAction(); -} - -void DropTree::Cancel() { - if(dropfocus) - SetFocus(); - Sync(); -} - -void DropTree::Clear() { - tree.Clear(); - tree <<= Null; - Sync(); - Update(); -} - -void DropTree::SetData(const Value& data) -{ - if(tree.Get() != data) { - tree <<= data; - Update(); - Sync(); - } -} - -Value DropTree::GetData() const -{ - return notnull && IsNull(tree.Get()) ? NotNullError() : tree.Get(); -} - -DropTree& DropTree::ValueDisplay(const Display& d) -{ - valuedisplay = &d; - Sync(); - return *this; -} - -DropTree::DropTree() -{ - displayall = false; - valuedisplay = NULL; - dropfocus = false; - notnull = false; - AddButton().Main().WhenPush = THISBACK(Drop); - NoInitFocus(); - tree.WhenSelect = THISBACK(Select); - tree.WhenCancel = THISBACK(Cancel); - dropwidth = 0; -} - -}; +#include "CtrlLib.h" + +namespace Upp { + +CH_VALUE(TreeDropEdge, ChBorder(BlackBorder())); + +CtrlFrame& TreeDropFrame() +{ + static LookFrame m(TreeDropEdge); + return m; +} + +PopUpTree::PopUpTree() { + SetFrame(TreeDropFrame()); + Accel(); + MouseMoveCursor(); + NoPopUpEx(); + SetDropLines(16); + open = autosize = false; + showpos = Null; + WhenOpen = WhenClose = THISBACK(OpenClose); +} + +PopUpTree::~PopUpTree() {} + +void PopUpTree::CancelMode() { + if(open) { + DoClose(); + WhenCancel(); + } + TreeCtrl::CancelMode(); +} + +void PopUpTree::DoClose() { + open = false; + Ctrl::Close(); +} + +void PopUpTree::Deactivate() { + if(open) { + DoClose(); + IgnoreMouseClick(); + WhenCancel(); + } +} + +void PopUpTree::Select() { + if(IsCursor() && !GetData().IsVoid()) { + DoClose(); + WhenSelect(); + } +} + +bool PopUpTree::Key(dword key, int n) { + switch(key) { + case K_ENTER: + case K_ALT_DOWN: + DoClose(); + WhenSelect(); + return true; + case K_ESCAPE: + DoClose(); + WhenCancel(); + return true; + } + return TreeCtrl::Key(key, n); +} + +void PopUpTree::PopUp(Ctrl *owner, int x, int top, int bottom, int width) { + DoClose(); + Rect area = Ctrl::GetWorkArea(); + int mh = min(maxheight, area.bottom - bottom); + int h = AddFrameSize(width, maxheight).cy; + showpos.x = x; + showpos.y = bottom; + showwidth = width; + up = false; + if(showpos.y + h > area.bottom) { + up = true; + showpos.y = top; + } + open = false; + + int ht = AddFrameSize(width, min(mh, autosize ? GetTreeSize().cy : INT_MAX)).cy; + Rect rt = RectC(showpos.x, showpos.y - (up ? ht : 0), showwidth, ht); + if(GUI_PopUpEffect()) { + bool vis = sb.x.IsShown(); + bool ah = sb.x.IsAutoHide(); + sb.AutoHide(false); + sb.Hide(); + sPaintRedirectCtrl pb; + pb.ctrl = this; + if(up) { + SetRect(Rect(rt.left, rt.bottom - 1, rt.right, rt.bottom)); + Ctrl::Add(pb.TopPos(0, rt.Height()).LeftPos(0, rt.Width())); + } + else { + SetRect(Rect(rt.left, rt.top, rt.right, rt.top + 1)); + Ctrl::Add(pb.BottomPos(0, rt.Height()).LeftPos(0, rt.Width())); + } + CenterCursor(); + Ctrl::PopUp(owner, true, true, GUI_DropShadows()); + SetFocus(); + Ctrl::ProcessEvents(); + Animate(*this, rt, GUIEFFECT_SLIDE); + Ctrl::Remove(); + sb.Show(vis); + sb.AutoHide(ah); + pb.Remove(); + open = true; + } + + CenterCursor(); + SetRect(rt); + if(!open) + Ctrl::PopUp(owner, true, true, GUI_DropShadows()); + SetFocus(); + open = true; +} + +void PopUpTree::OpenClose(int) +{ + if(autosize) { + SyncTree(); + Rect area = Ctrl::GetWorkArea(); + int mh = min(maxheight, area.bottom - showpos.y); + int ht = AddFrameSize(showwidth, min(mh, GetTreeSize().cy)).cy; + SetRect(RectC(showpos.x, showpos.y - (up ? ht : 0), showwidth, ht)); + } +} + +void PopUpTree::PopUp(Ctrl *owner, int width) +{ + Rect r = owner->GetScreenRect(); + r.right = r.left + width; + PopUp(owner, r.left, r.top, r.bottom, width); + if(IsNull(showpos)) + showpos = r.TopLeft(); + OpenClose(0); +} + +void PopUpTree::PopUp(Ctrl *owner) +{ + Rect r = owner->GetScreenRect(); + PopUp(owner, r.left, r.top, r.bottom, r.Width()); +} + +void DropTree::Sync() { + Image icon; + if(tree.IsCursor()) + icon = tree.GetNode(tree.GetCursor()).image; + icond.Set(valuedisplay ? *valuedisplay : tree.GetDisplay(tree.GetCursor()), icon); + MultiButton::SetDisplay(icond); + Set(tree.GetValue()); +} + +bool DropTree::Key(dword k, int) { + if(IsReadOnly()) return false; + if(k == K_ALT_DOWN) { + Drop(); + return true; + } + return false; +} + +void DropTree::Drop() { + if(IsReadOnly()) return; + if(dropfocus) + SetFocus(); + WhenDrop(); + tree.PopUp(this, GetRect().GetWidth()); +} + +void DropTree::Select() { + if(dropfocus) + SetFocus(); + Sync(); + UpdateAction(); +} + +void DropTree::Cancel() { + if(dropfocus) + SetFocus(); + Sync(); +} + +void DropTree::Clear() { + tree.Clear(); + tree <<= Null; + Sync(); + Update(); +} + +void DropTree::SetData(const Value& data) +{ + if(tree.Get() != data) { + tree <<= data; + Update(); + Sync(); + } +} + +Value DropTree::GetData() const +{ + return notnull && IsNull(tree.Get()) ? NotNullError() : tree.Get(); +} + +DropTree& DropTree::ValueDisplay(const Display& d) +{ + valuedisplay = &d; + Sync(); + return *this; +} + +DropTree::DropTree() +{ + displayall = false; + valuedisplay = NULL; + dropfocus = false; + notnull = false; + AddButton().Main().WhenPush = THISBACK(Drop); + NoInitFocus(); + tree.WhenSelect = THISBACK(Select); + tree.WhenCancel = THISBACK(Cancel); + dropwidth = 0; +} + +}; diff --git a/uppsrc/CtrlLib/PopupTable.cpp b/uppsrc/CtrlLib/PopupTable.cpp index 22722da3a..6b34d58fc 100644 --- a/uppsrc/CtrlLib/PopupTable.cpp +++ b/uppsrc/CtrlLib/PopupTable.cpp @@ -79,22 +79,28 @@ void PopUpTable::PopUp(Ctrl *owner, int x, int top, int bottom, int width) { rt.bottom = rt.top + h; } open = false; - Ctrl popup; if(GUI_PopUpEffect()) { + AutoHideSb(false); + HideSb(true); + sPaintRedirectCtrl pb; + pb.ctrl = this; if(up) { - popup.SetRect(Rect(rt.left, rt.bottom - 1, rt.right, rt.bottom)); - popup.Add(TopPos(0, rt.Height()).LeftPos(0, rt.Width())); + SetRect(Rect(rt.left, rt.bottom - 1, rt.right, rt.bottom)); + Ctrl::Add(pb.TopPos(0, rt.Height()).LeftPos(0, rt.Width())); } else { - popup.SetRect(Rect(rt.left, rt.top, rt.right, rt.top + 1)); - popup.Add(BottomPos(0, rt.Height()).LeftPos(0, rt.Width())); + SetRect(Rect(rt.left, rt.top, rt.right, rt.top + 1)); + Ctrl::Add(pb.BottomPos(0, rt.Height()).LeftPos(0, rt.Width())); } - CenterCursor(); - popup.PopUp(owner, true, true, GUI_DropShadows()); + Ctrl::PopUp(owner, true, true, GUI_DropShadows()); SetFocus(); Ctrl::ProcessEvents(); - Animate(popup, rt, GUIEFFECT_SLIDE); - Ctrl::Remove(); + Animate(*this, rt, GUIEFFECT_SLIDE); + pb.Remove(); + HideSb(false); + AutoHideSb(true); + CenterCursor(); + open = true; } if(!open) { CenterCursor(); diff --git a/uppsrc/CtrlLib/TreeCtrl.h b/uppsrc/CtrlLib/TreeCtrl.h index 0ae30aef7..46991968d 100644 --- a/uppsrc/CtrlLib/TreeCtrl.h +++ b/uppsrc/CtrlLib/TreeCtrl.h @@ -158,6 +158,8 @@ protected: virtual void SetOption(int id); void SyncTree(); virtual void Select(); + + friend class PopUpTree; public: Callback1 WhenOpen;