mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
227 lines
4.4 KiB
C++
227 lines
4.4 KiB
C++
#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()
|
|
{
|
|
valuedisplay = NULL;
|
|
dropfocus = false;
|
|
notnull = false;
|
|
AddButton().Main().WhenPush = THISBACK(Drop);
|
|
NoInitFocus();
|
|
tree.WhenSelect = THISBACK(Select);
|
|
tree.WhenCancel = THISBACK(Cancel);
|
|
dropwidth = 0;
|
|
}
|
|
|
|
};
|