#include "CtrlLib.h" NAMESPACE_UPP #define LLOG(x) // LOG(x) void PopUpTable::CancelMode() { if(open) { DoClose(); WhenCancel(); } } void PopUpTable::DoClose() { open = false; Close(); } void PopUpTable::Deactivate() { if(open) { DoClose(); IgnoreMouseClick(); WhenCancel(); } } void PopUpTable::LeftUp(Point p, dword keyflags) { ArrayCtrl::LeftUp(p, keyflags); DoClose(); WhenSelect(); } bool PopUpTable::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; case K_UP: if(!IsCursor()) { SetCursor(GetCount() - 1); return true; } break; case K_DOWN: if(!IsCursor()) { SetCursor(0); return true; } break; } return ArrayCtrl::Key(key, n); } void PopUpTable::PopUp(Ctrl *owner, int x, int top, int bottom, int width) { DoClose(); int h = AddFrameSize(width, min(droplines, GetCount()) * GetLineCy()).cy; Rect rt = RectC(x, bottom, width, h); Rect area = Ctrl::GetWorkArea(); bool up = false; if(rt.bottom > area.bottom) { up = true; rt.top = top - h; rt.bottom = rt.top + h; } open = false; Ctrl popup; 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_GlobalStyle() >= GUISTYLE_XP); SetFocus(); Ctrl::ProcessEvents(); Animate(popup, rt, GUIEFFECT_SLIDE); Ctrl::Remove(); } CenterCursor(); SetRect(rt); Ctrl::PopUp(owner, true, true, GUI_GlobalStyle() >= GUISTYLE_XP); SetFocus(); open = true; } void PopUpTable::PopUp(Ctrl *owner, int width) { Rect r = owner->GetScreenRect(); r.right = r.left + width; PopUp(owner, r.left, r.top, r.bottom, width); } void PopUpTable::PopUp(Ctrl *owner) { Rect r = owner->GetScreenRect(); PopUp(owner, r.left, r.top, r.bottom, r.Width()); } void PopUpTable::Normal() { AddColumn().Accel(); NoHeader(); HeaderTab(0).SetMargin(0); MouseMoveCursor(); NoGrid(); AutoHideSb(); SetLineCy(Draw::GetStdFontCy()); } PopUpTable::PopUpTable() { SetFrame(BlackFrame()); droplines = 16; open = false; } PopUpTable::~PopUpTable() {} Size DropList::GetMinSize() const { return AddFrameSize(0, StdFont().Info().GetHeight() + 4); } void DropList::GotFocus() { Refresh(); } void DropList::LostFocus() { Refresh(); } void DropList::Paint(Draw& w) { LLOG("DropList::Paint"); Value v; if(displayall) v = value; int i = key.Find(value); const Display& d = valuedisplay ? *valuedisplay : i >= 0 ? list.GetDisplay(i, 0) : list.GetDisplay(0); if(i >= 0) v = list.Get(i, 0); v = valueconvert->Format(v); Size sz = GetSize(); bool f = HasFocus() && !push; Rect r = Rect(sz); Rect cr; cr.left = cr.top = 1; cr.right = sz.cx - 1; cr.bottom = sz.cy - 1; DrawRectMinusRect(w, r, cr, SColorPaper); w.DrawRect(cr, f ? SColorHighlight : push ? Blend(SColorHighlight, SColorFace, 235) : IsShowEnabled() && !IsReadOnly() ? SColorPaper : SColorFace); cr.top = (sz.cy - list.GetLineCy()) / 2; cr.bottom = cr.top + list.GetLineCy(); int m = list.HeaderTab(0).GetMargin(); cr.left += m; cr.right -= m; if(cr.left < cr.right) d.Paint(w, cr, v, f ? SColorHighlightText : IsShowEnabled() ? SColorText : SColorDisabled, Null, f ? Display::CURSOR : Display::FOCUS|Display::CURSOR); } void DropList::LeftDown(Point p, dword keyflags) { if(WhenClick) { if(Ctrl::ClickFocus()) SetWantFocus(); if(IsReadOnly()) return; push = true; Refresh(); } else { if(IsReadOnly()) return; Push(); } } void DropList::MouseMove(Point, dword style) { if(IsReadOnly() || !WhenClick) return; bool b = style & K_MOUSELEFT; if(b != push) { push = b; Refresh(); } } void DropList::MouseLeave() { if(!WhenClick) return; push = false; Refresh(); } void DropList::LeftUp(Point p, dword) { push = false; if(Rect(GetSize()).Contains(p)) WhenClick(); Refresh(); } void DropList::Change(int q) { if(key.GetCount() == 0) return; int i = key.Find(value); i += q; if(i >= key.GetCount()) i = key.GetCount() - 1; if(i < 0) i = 0; if(value != key[i]) { value = key[i]; UpdateActionRefresh(); } } bool DropList::Key(dword k, int) { if(IsReadOnly()) return false; switch(k) { case K_ALT_DOWN: Push(); break; case K_DOWN: case K_RIGHT: Change(1); break; case K_UP: case K_LEFT: Change(-1); break; default: if(k >= 32 && k < 256) { bool b = list.Key(k, 1); if(list.GetCursor() >= 0 && list.GetCursor() < key.GetCount() && key[list.GetCursor()] != value) Select(); return b; } return false; } return true; } void DropList::MouseWheel(Point, int zdelta, dword) { Change(zdelta < 0 ? 1 : -1); } void DropList::Drop() { if(IsReadOnly()) return; if(dropfocus) SetFocus(); WhenDrop(); list.SetCursor(key.Find(value)); list.PopUp(this); } void DropList::Select() { int c = list.GetCursor(); if(c >= 0) value = key[c]; if(dropfocus) SetFocus(); UpdateActionRefresh(); } void DropList::Cancel() { if(dropfocus) SetFocus(); } void DropList::ClearList() { key.Clear(); list.Clear(); Refresh(); list.Refresh(); EnableDrop(false); } void DropList::Clear() { ClearList(); value = Value(); Update(); } DropList& DropList::Add(const Value& _key, const Value& text) { key.Add(_key); list.Add(text); Refresh(); list.Refresh(); EnableDrop(); return *this; } void DropList::Trim(int n) { if(GetIndex() >= n) SetIndex(0); key.Trim(n); list.SetCount(n); Refresh(); list.Refresh(); EnableDrop(n); } void DropList::SetData(const Value& data) { if(value != data) { value = data; UpdateRefresh(); } } Value DropList::GetData() const { return value; } Value DropList::GetValue() const { int i = FindKey(value); return i < 0 ? Null : GetValue(i); } void DropList::SetValue(int i, const Value& v) { list.Set(i, 0, v); EnableDrop(); } void DropList::SetValue(const Value& v) { int i = FindKey(value); if(i >= 0) SetValue(i, v); } DropList& DropList::SetConvert(const Convert& cv) { list.ColumnAt(0).SetConvert(cv); valueconvert = &cv; Refresh(); return *this; } DropList& DropList::SetDisplay(int i, const Display& d) { list.SetDisplay(i, 0, d); Refresh(); return *this; } DropList& DropList::SetDisplay(const Display& d) { list.ColumnAt(0).SetDisplay(d); Refresh(); return *this; } DropList& DropList::SetDisplay(const Display& d, int lcy) { SetDisplay(d); SetLineCy(lcy); Refresh(); return *this; } DropList& DropList::ValueDisplay(const Display& d) { valuedisplay = &d; Refresh(); return *this; } void DropList::Adjust() { int i = FindKey(value); if(i < 0 && GetCount()) SetIndex(0); } void DropList::Adjust(const Value& k) { int i = FindKey(value); if(i < 0 && GetCount()) SetData(k); } Value DropList::Format(const Value& q) const { int i = FindKey(q); return valueconvert->Format(i < 0 ? Null : GetValue(i)); } DropList::DropList() { WhenPush = callback(this, &DropList::Drop); list.Normal(); list.WhenSelect = callback(this, &DropList::Select); list.WhenCancel = callback(this, &DropList::Cancel); EnableDrop(false); displayall = false; valueconvert = &NoConvert(); valuedisplay = NULL; dropfocus = false; push = false; } DropList::~DropList() {} void Add(DropList& list, const VectorMap& values) { for(int i = 0; i < values.GetCount(); i++) list.Add(values.GetKey(i), values[i]); } void Add(MapConvert& convert, const VectorMap& values) { for(int i = 0; i < values.GetCount(); i++) convert.Add(values.GetKey(i), values[i]); } void Add(DropList& list, const MapConvert& convert) { for(int i = 0; i < convert.GetCount(); i++) list.Add(convert.GetKey(i), convert.GetValue(i)); } END_UPP_NAMESPACE