mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-11 22:03:09 -06:00
bazaar: CtrlFinder supports filtering of Ctrl's
git-svn-id: svn://ultimatepp.org/upp/trunk@3725 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
3eecbd8efa
commit
f4178626a7
7 changed files with 61 additions and 308 deletions
|
|
@ -1,6 +1,27 @@
|
|||
#include "CtrlFinder.h"
|
||||
|
||||
Ctrl* CtrlFinder::ChildAtPoint(Ctrl& par, Point& pt, int f)
|
||||
//this one filters
|
||||
void CtrlFinder::StdCtrlFilter(Ctrl*& q, Point& pt, int& f)
|
||||
{
|
||||
if((f & VIEW) && q->InView())
|
||||
{
|
||||
if( ((f & VISIBLE) && q->IsShown())
|
||||
|| ((f & INVISIBLE) && !q->IsShown())
|
||||
|| ((f & ENABLED) && q->IsEnabled())
|
||||
|| ((f & DISABLED) && !q->IsEnabled())
|
||||
) return;
|
||||
}
|
||||
|
||||
if((f & FRAME) && q->InFrame())
|
||||
if( ((f & VISIBLE) && q->IsShown())
|
||||
|| ((f & INVISIBLE) && !q->IsShown())
|
||||
|| ((f & ENABLED) && q->IsEnabled())
|
||||
|| ((f & DISABLED) && !q->IsEnabled())
|
||||
) return;
|
||||
q = NULL;
|
||||
}
|
||||
|
||||
Ctrl* CtrlFinder::ChildAtPoint(Ctrl& par, Point& pt, int& f, const CtrlFilterType& fil)
|
||||
{
|
||||
GuiLock __;
|
||||
Ctrl *q;
|
||||
|
|
@ -12,13 +33,13 @@ Ctrl* CtrlFinder::ChildAtPoint(Ctrl& par, Point& pt, int f)
|
|||
Point vp = p - view.TopLeft();
|
||||
for(q = par.GetLastChild(); q; q = q->GetPrev()) {
|
||||
if((f & VIEW) && q->InView())
|
||||
if((f & VISIBLE) && q->IsVisible())
|
||||
if((f & ENABLED) && q->IsEnabled())
|
||||
{
|
||||
Rect r = q->GetRect();
|
||||
if(r.Contains(vp)) {
|
||||
pt = vp - r.TopLeft();
|
||||
return q;
|
||||
Ctrl* w(q);
|
||||
fil(w, pt, f);
|
||||
if(w) return w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,26 +49,26 @@ Ctrl* CtrlFinder::ChildAtPoint(Ctrl& par, Point& pt, int f)
|
|||
if(f & FRAME)
|
||||
for(q = par.GetLastChild(); q; q = q->GetPrev()) {
|
||||
if((f & FRAME) && q->InFrame())
|
||||
if((f & VISIBLE) && q->IsVisible())
|
||||
if((f & ENABLED) && q->IsEnabled())
|
||||
{
|
||||
Rect r = q->GetRect();
|
||||
if(r.Contains(p)) {
|
||||
pt = p - r.TopLeft();
|
||||
return q;
|
||||
Ctrl* w(q);
|
||||
fil(w, pt, f);
|
||||
if(w) return w;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Ctrl* CtrlFinder::GetCtrl(Ctrl& c, Point& p, int f)
|
||||
Ctrl* CtrlFinder::GetCtrl(Ctrl& c, Point& p, int& f, const CtrlFilterType& fil)
|
||||
{
|
||||
Ctrl* q = ChildAtPoint(c, p, f);
|
||||
Ctrl* q = ChildAtPoint(c, p, f, fil);
|
||||
if(q && (f & DEEP))
|
||||
{
|
||||
Point pt(p);
|
||||
Ctrl* qc = GetCtrl(*q, pt, f);
|
||||
Ctrl* qc = GetCtrl(*q, pt, f, fil);
|
||||
if(qc)
|
||||
{
|
||||
p = pt;
|
||||
|
|
@ -85,7 +106,7 @@ void CtrlFinder::LeftDown(Point p, dword keyflags)
|
|||
ctrl = NULL;
|
||||
if(IsEmpty()) return;
|
||||
Point pt(p);
|
||||
ctrl = GetCtrl(Get(), pt, flags);
|
||||
ctrl = GetCtrl(Get(), pt, flags, filter);
|
||||
if(!ctrl) ctrl = &Get();
|
||||
WhenLeftDown(*ctrl, p, keyflags);
|
||||
Action();
|
||||
|
|
@ -95,7 +116,7 @@ void CtrlFinder::RightDown(Point p, dword keyflags)
|
|||
ctrl = NULL;
|
||||
if(IsEmpty()) return;
|
||||
Point pt(p);
|
||||
ctrl = GetCtrl(Get(), pt, flags);
|
||||
ctrl = GetCtrl(Get(), pt, flags, filter);
|
||||
if(!ctrl) ctrl = &Get();
|
||||
WhenRightDown(*ctrl, p, keyflags);
|
||||
Action();
|
||||
|
|
|
|||
|
|
@ -37,22 +37,29 @@ public:
|
|||
typedef MouseHookCtrl R;
|
||||
typedef Visiting<Ctrl> V;
|
||||
|
||||
typedef Callback3<Ctrl*&, Point&, int&> CtrlFilterType;
|
||||
|
||||
enum
|
||||
{
|
||||
VISIBLE = 0x1,
|
||||
ENABLED = 0x2,
|
||||
VIEW = 0x4,
|
||||
FRAME = 0x8,
|
||||
INVISIBLE = 0x2,
|
||||
|
||||
DEEP = 0x10,
|
||||
|
||||
DEF = VISIBLE | ENABLED | VIEW | FRAME | DEEP,
|
||||
};
|
||||
|
||||
Ctrl* ChildAtPoint(Ctrl& par, Point& pt, int f);
|
||||
Ctrl* GetCtrl(Ctrl& c, Point& p, int f = DEF);
|
||||
ENABLED = 0x4,
|
||||
DISABLED = 0x8,
|
||||
|
||||
CtrlFinder() : flags(DEF) {}
|
||||
VIEW = 0x10,
|
||||
FRAME = 0x20,
|
||||
|
||||
DEEP = 0x80,
|
||||
|
||||
DEF = VISIBLE | INVISIBLE | ENABLED | DISABLED | VIEW | FRAME | DEEP,
|
||||
};
|
||||
|
||||
static void StdCtrlFilter(Ctrl*& q, Point& pt, int& f);
|
||||
static Ctrl* ChildAtPoint(Ctrl& par, Point& pt, int& f, const CtrlFilterType& fil);
|
||||
static Ctrl* GetCtrl(Ctrl& c, Point& p, int& f, const CtrlFilterType& fil);
|
||||
|
||||
CtrlFinder() : flags(DEF), filter(STDBACK(StdCtrlFilter)) {}
|
||||
|
||||
virtual void Visit(Ctrl& c);
|
||||
virtual void Reload();
|
||||
|
|
@ -69,6 +76,7 @@ public:
|
|||
void ClearCtrl() { ctrl = NULL; }
|
||||
void SetCtrl(Ctrl& c) { /*ASSERT(c.GetParent());*/ ctrl = &c; }
|
||||
|
||||
CtrlFilterType filter; //set to NULL if should not be handled, change flags if desired
|
||||
int flags;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -202,7 +202,9 @@ void CtrlPos::MouseMove(Point p, dword keyflags)
|
|||
|
||||
c.Remove(); //prevent moving control from finding when searching new parent
|
||||
Point pt(p);
|
||||
Ctrl* pc = GetCtrl(Get(), pt, flags | DEEP);
|
||||
int ft(flags); flags |= (DEEP | NEST);
|
||||
Ctrl* pc = GetCtrl(Get(), pt, flags, filter);
|
||||
flags &= ~(DEEP | NEST); flags |= (ft & DEEP); //restore DEEP flag from save, NEST is ours
|
||||
if(!pc) pc = &Get();
|
||||
if(pc != q)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,12 @@ class CtrlPos : public CtrlFinder
|
|||
public:
|
||||
typedef CtrlPos CLASSNAME;
|
||||
typedef CtrlFinder V;
|
||||
|
||||
enum
|
||||
{
|
||||
NEST = 0x100,
|
||||
};
|
||||
|
||||
CtrlPos();
|
||||
|
||||
virtual void Clear();
|
||||
|
|
|
|||
|
|
@ -1,197 +0,0 @@
|
|||
#include "CtrlPropEdit.h"
|
||||
|
||||
PropListCtrl::PropListCtrl()
|
||||
{
|
||||
CtrlLayout(*this);
|
||||
}
|
||||
|
||||
void PropListCtrl::Reload()
|
||||
{
|
||||
V::Reload();
|
||||
Ctrl& e = Get();
|
||||
|
||||
Value v;
|
||||
bool b;
|
||||
String t;
|
||||
|
||||
b = Props<Ctrl>::Get(e, "listset", v);
|
||||
ValueArray vs = v;
|
||||
t << "Set Properties: (" << vs.GetCount() << ")\n" << v;
|
||||
gl.SetData(t);
|
||||
|
||||
v = Value();
|
||||
b = Props<Ctrl>::Get(e, "listget", v);
|
||||
t.Clear();
|
||||
ValueArray vg = v;
|
||||
t << "Get Properties: (" << vg.GetCount() << ")\n";
|
||||
{
|
||||
for(int i = 0; i < vg.GetCount(); i++)
|
||||
{
|
||||
String s = vg.Get(i);
|
||||
Value v;
|
||||
t << s << " = ";
|
||||
b = Props<Ctrl>::Get(e, s, v);
|
||||
if(b) t << v;
|
||||
else t << "##ERR##";
|
||||
t << "\n";
|
||||
}
|
||||
}
|
||||
sl.SetData(t);
|
||||
}
|
||||
|
||||
PropList::PropList()
|
||||
{
|
||||
SetRect(plc.GetRect());
|
||||
Add(plc.HSizePos().VSizePos(0,20));
|
||||
Add(exit.RightPos(0, 64).BottomPos(0, 20));
|
||||
exit.SetLabel("Close");
|
||||
exit <<= THISBACK(Acceptor);
|
||||
//cancel <<= THISBACK(Rejector);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
PropEditCtrl::PropEditCtrl()
|
||||
{
|
||||
CtrlLayout(*this);
|
||||
ac.AddColumn("Property");
|
||||
ac.AddColumn("Value");
|
||||
//ac.WhenUpdateRow = THISBACK(OnUpdateRow);
|
||||
}
|
||||
|
||||
void PropEditCtrl::Visit(Ctrl& e)
|
||||
{
|
||||
V::Visit(e);
|
||||
|
||||
ac.Clear();
|
||||
vsav.Clear();
|
||||
am.Clear();
|
||||
|
||||
bool b = Props<Ctrl>::SetupAccessorMap(e, am);
|
||||
if(!b) return;
|
||||
|
||||
int k = 0;
|
||||
for(int i = 0; i < am.GetCount(); i++)
|
||||
{
|
||||
String tag = am.GetKey(i);
|
||||
ValueAccessor& a = am[i];
|
||||
|
||||
Value v;
|
||||
if(a.get)
|
||||
{
|
||||
if(!a.get(v))
|
||||
continue;
|
||||
}
|
||||
ac.Set(k, 0, tag);
|
||||
ac.Set(k, 1, v); //forwarded to controls when specified
|
||||
|
||||
if(a.get && a.set)
|
||||
{
|
||||
Tuple2<bool, Value>& tv = vsav.Add(tag);
|
||||
tv.a = false;
|
||||
tv.b = v;
|
||||
|
||||
Ctrl* pc;
|
||||
if(!v.IsNull())
|
||||
{
|
||||
pc = DefaultValueEditor(v);
|
||||
{
|
||||
LogPosCtrl* ple = dynamic_cast<LogPosCtrl*>(pc);
|
||||
if(ple)
|
||||
ple->Set(e);
|
||||
}
|
||||
}
|
||||
else pc = new ValueCtrl();
|
||||
(*pc) <<= THISBACK(OnUpdateRow);
|
||||
|
||||
ac.SetCtrl(k, 1, pc); //owned
|
||||
++k;
|
||||
}
|
||||
else
|
||||
if(a.get)
|
||||
{
|
||||
StaticText* pc = new StaticText();
|
||||
pc->SetText(AsString(v));
|
||||
|
||||
ac.SetCtrl(k, 1, pc); //owned
|
||||
++k;
|
||||
}
|
||||
else
|
||||
if(a.set)
|
||||
{
|
||||
//FIXME needs to know which type
|
||||
//meanwhile, we let user choose
|
||||
ValueCtrl* pc = new ValueCtrl();
|
||||
(*pc) <<= THISBACK(OnUpdateRow);
|
||||
|
||||
ac.SetCtrl(k, 1, pc); //owned
|
||||
++k;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); //Property without accessors
|
||||
++k;
|
||||
}
|
||||
}
|
||||
ac.Layout();
|
||||
//ac.UpdateRefresh();
|
||||
}
|
||||
|
||||
void PropEditCtrl::Clear()
|
||||
{
|
||||
V::Clear();
|
||||
ac.Clear();
|
||||
vsav.Clear();
|
||||
}
|
||||
|
||||
void PropEditCtrl::Reload()
|
||||
{
|
||||
V::Reload();
|
||||
Ctrl& e = Get();
|
||||
for(int i = 0; i < ac.GetCount(); i++)
|
||||
{
|
||||
Value v;
|
||||
int ii = am.Find(ac.Get(i, 0));
|
||||
if(ii<0) continue;
|
||||
if(!am[ii].get(v)) continue;
|
||||
ac.Set(i, 1, v);
|
||||
}
|
||||
}
|
||||
|
||||
void PropEditCtrl::OnUpdateRow()
|
||||
{
|
||||
if(IsEmpty()) return;
|
||||
if(!ac.IsCursor()) return; //FIXME Option Focus issue
|
||||
int ii = am.Find(ac.Get(0));
|
||||
if(ii<0) return;
|
||||
am[ii].set(ac.Get(1));
|
||||
vsav.GetAdd(ac.Get(0)).a = true; //dirty
|
||||
Action();
|
||||
Get().UpdateActionRefresh();
|
||||
}
|
||||
|
||||
void PropEditCtrl::Restore()
|
||||
{
|
||||
if(!IsEmpty())
|
||||
{
|
||||
for(int i = 0; i < vsav.GetCount(); i++)
|
||||
if(vsav[i].a)
|
||||
{
|
||||
int ii = am.Find(vsav.GetKey(i));
|
||||
if(ii<0) continue;
|
||||
am[ii].set(vsav[i].b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropEdit::PropEdit()
|
||||
{
|
||||
SetRect(pec.GetRect());
|
||||
Add(pec.HSizePos().VSizePos(0,20));
|
||||
Add(ok.RightPos(60,60).BottomPos(0,20));
|
||||
Add(cancel.RightPos(0,60).BottomPos(0,20));
|
||||
ok <<= THISBACK(Acceptor);
|
||||
cancel <<= THISBACK(Rejector);
|
||||
ok.SetLabel("OK");
|
||||
cancel.SetLabel("Cancel");
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
#ifndef _CtrlProp_CtrlPropEdit_h_
|
||||
#define _CtrlProp_CtrlPropEdit_h_
|
||||
|
||||
#include "CtrlPropCommon.h"
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
using namespace Upp;
|
||||
|
||||
#include <LogPosCtrl/LogPosCtrl.h>
|
||||
#include <ValueCtrl/ValueCtrl.h>
|
||||
|
||||
#include <Gen/Gen.h>
|
||||
|
||||
#define LAYOUTFILE <CtrlProp/CtrlPropEdit.lay>
|
||||
#include <CtrlCore/lay.h>
|
||||
|
||||
class PropListCtrl : public WithPropListLay<ParentCtrl>, public Visiting<Ctrl>
|
||||
{
|
||||
public:
|
||||
typedef PropListCtrl CLASSNAME;
|
||||
typedef Visiting<Ctrl> V;
|
||||
PropListCtrl();
|
||||
|
||||
virtual void Reload();
|
||||
};
|
||||
|
||||
class PropList : public PopUpC
|
||||
{
|
||||
public:
|
||||
typedef PropList CLASSNAME;
|
||||
PropList();
|
||||
|
||||
void PopUp(Ctrl* owner, Ctrl& e) { plc.Visit(e); PopUpC::PopUp(owner); }
|
||||
virtual void Acceptor() { plc.Clear(); PopUpC::Acceptor(); }
|
||||
|
||||
protected:
|
||||
PropListCtrl plc;
|
||||
Button exit;
|
||||
};
|
||||
|
||||
class PropEditCtrl : public WithPropEditLay<ParentCtrl>, public Visiting<Ctrl>
|
||||
{
|
||||
public:
|
||||
typedef PropEditCtrl CLASSNAME;
|
||||
typedef Visiting<Ctrl> V;
|
||||
PropEditCtrl();
|
||||
|
||||
virtual void Visit(Ctrl& e);
|
||||
virtual void Reload();
|
||||
virtual void Clear();
|
||||
virtual void Restore();
|
||||
|
||||
void OnUpdateRow();
|
||||
|
||||
protected:
|
||||
ArrayMap<String, Tuple2<bool, Value> > vsav;
|
||||
AccessorMap am;
|
||||
};
|
||||
|
||||
class PropEdit : public PopUpC
|
||||
{
|
||||
public:
|
||||
typedef PropEdit CLASSNAME;
|
||||
PropEdit();
|
||||
|
||||
virtual void Deactivate() {} //let other popups open
|
||||
|
||||
void PopUp(Ctrl* owner, Ctrl& e) { pec.Visit(e); PopUpC::PopUp(owner); }
|
||||
|
||||
virtual void Rejector() { pec.Restore(); pec.Clear(); PopUpC::Rejector(); }
|
||||
virtual void Acceptor() { pec.Clear(); PopUpC::Acceptor(); }
|
||||
|
||||
protected:
|
||||
PropEditCtrl pec;
|
||||
Button ok, cancel;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
LAYOUT(PropListLay, 400, 200)
|
||||
ITEM(DocEdit, gl, WantFocus(false).SetEditable(false).LeftPosZ(0, 168).VSizePosZ(0, 0))
|
||||
ITEM(DocEdit, sl, WantFocus(false).SetEditable(false).HSizePosZ(168, 0).VSizePosZ(0, 0))
|
||||
END_LAYOUT
|
||||
|
||||
LAYOUT(PropEditLay, 400, 200)
|
||||
ITEM(ArrayCtrl, ac, HSizePosZ(0, 0).VSizePosZ(0, 0))
|
||||
END_LAYOUT
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue