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:
kohait 2011-08-01 18:54:02 +00:00
parent 3eecbd8efa
commit f4178626a7
7 changed files with 61 additions and 308 deletions

View file

@ -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();

View file

@ -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:

View file

@ -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)
{

View file

@ -17,6 +17,12 @@ class CtrlPos : public CtrlFinder
public:
typedef CtrlPos CLASSNAME;
typedef CtrlFinder V;
enum
{
NEST = 0x100,
};
CtrlPos();
virtual void Clear();

View file

@ -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");
}

View file

@ -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

View file

@ -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