bazaar: various fixes: CtrlFinder assert bug, CtrlPos presistant ctrl selection, CtrlProp: manual reload button, LogPosCtrl: get rid of Ctrl base ref dependency

git-svn-id: svn://ultimatepp.org/upp/trunk@3797 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
kohait 2011-08-30 00:49:35 +00:00
parent 524700b81e
commit c7aaec5c78
13 changed files with 112 additions and 54 deletions

View file

@ -78,6 +78,15 @@ Ctrl* CtrlFinder::GetCtrl(Ctrl& c, Point& p, int& f, const CtrlFilterType& fil)
return q;
}
bool CtrlFinder::IsParentR(const Ctrl* p, const Ctrl* c)
{
while(c && p) {
if(c == p) return true;
c = c->GetParent();
}
return false;
}
void CtrlFinder::UpdatedSource()
{
Remove();

View file

@ -38,7 +38,7 @@ public:
Ctrl* GetSource() const { return pctrl; }
void ClearSource() { SetSource(NULL); }
void SetCtrl(Ctrl* c) { if(c && pctrl) ASSERT(c->GetParent() == ~pctrl); ctrl = c; UpdateRefresh(); }
void SetCtrl(Ctrl* c) { if(c && pctrl) { ASSERT(IsParentR(~pctrl, c)); } ctrl = c; UpdateRefresh(); }
Ctrl* GetCtrl() const { return ctrl; }
void ClearCtrl() { SetCtrl(NULL); }
@ -48,6 +48,7 @@ public:
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);
static bool IsParentR(const Ctrl* p, const Ctrl* c);
Callback3<Ctrl&, Point, dword> WhenLeftDown;
Callback3<Ctrl&, Point, dword> WhenRightDown;

View file

@ -90,7 +90,9 @@ void CtrlPos::Paint(Draw& w)
if(!IsTransparent())
w.DrawRect(0,0,sz.cx,sz.cy, SColorFace());
if(IsEnabled() && pctrl)
if(!IsEnabled()) return;
if(pctrl)
DrawHintFrame(w, *pctrl, *pctrl, LtGray());
if(!ctrl) return;
@ -147,7 +149,7 @@ void CtrlPos::LeftDown(Point p, dword keyflags)
if(GetAlignMode(_r, rr, p, pos, style->handsize))
{
pos = LogPosPopUp::ReAlign(c, pos);
pos = LogPosPopUp::MakeLogPos(pos, c);
c.SetPos(pos);
Action();
Refresh();
@ -322,12 +324,6 @@ void CtrlPos::Updated()
}
void CtrlPos::State(int reason)
{
if(reason != ENABLE) return;
if(!IsEnabled()) { ClearCtrl(); Refresh(); }
}
CtrlPos::CtrlPos()
: pressed(false), moving(false), mode(RectCtrl::NONE), g(4,4)
{

View file

@ -30,7 +30,6 @@ public:
virtual void LeftUp(Point p, dword keyflags);
virtual void RightDown(Point p, dword keyflags);
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
virtual void State(int reason);
virtual void Updated();
virtual Rect GetVoidRect() const { return Ctrl::GetVoidRect(); }

View file

@ -5,24 +5,38 @@ PropEditCtrl::PropEditCtrl()
CtrlLayout(*this);
ac.AddColumn("Property");
ac.AddColumn("Value");
//ac.WhenUpdateRow = THISBACK(OnUpdateRow);
ac.AddColumn("Reload").Ctrls(THISBACK(ReloadFactory));
ac.ColumnWidths("3 6 1");
//ac.WhenUpdateRow = THISBACK(OnUpdateCurrentRow); only invoked after cursor leaves the edited row, but we need live
}
void PropEditCtrl::ReloadFactory(int i, One<Ctrl>& o)
{
Button* b = new Button();
b->SetImage(CtrlImg::Toggle);
b->WhenAction = THISBACK1(ReloadAction, i);
o.Attach(b);
}
void PropEditCtrl::ReloadAction(int i)
{
int ii = am.Find(ac.Get(i, 0));
if(ii<0) return;
Value v;
if(!am[ii].get(v)) return;
ac.Set(i, 1, v);
}
void PropEditCtrl::Updated()
{
if(ctrl && sctrl == ctrl)
{
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);
}
return;
}
sctrl = ctrl;
for(int i = 0; i < ac.GetCount(); i++)
ReloadAction(i);
}
void PropEditCtrl::UpdateCtrl()
{
ac.Clear();
vsav.Clear();
am.Clear();
@ -59,13 +73,14 @@ void PropEditCtrl::Updated()
{
pc = DefaultValueEditor(v);
{
//LogPosCtrl needs instance to live show changes
//LogPosCtrl needs instance infos to live show changes
LogPosCtrl* ple = dynamic_cast<LogPosCtrl*>(pc);
if(ple) ple->Set(e);
}
}
else pc = new ValueCtrl();
(*pc) <<= THISBACK(OnUpdateRow);
(*pc) <<= THISBACK1(OnUpdateRow, k); //for live editing, unlike WhenUpdateRow
ac.SetCtrl(k, 1, pc); //owned
++k;
@ -85,7 +100,8 @@ void PropEditCtrl::Updated()
//FIXME needs to know which type
//meanwhile, we let user choose
ValueCtrl* pc = new ValueCtrl();
(*pc) <<= THISBACK(OnUpdateRow);
(*pc) <<= THISBACK1(OnUpdateRow, k); //for live editing, unlike WhenUpdateRow
ac.SetCtrl(k, 1, pc); //owned
++k;
@ -100,16 +116,21 @@ void PropEditCtrl::Updated()
//ac.UpdateRefresh();
}
void PropEditCtrl::OnUpdateRow()
void PropEditCtrl::OnUpdateRow(int i)
{
am[i].set(ac.Get(i, 1));
vsav.GetAdd(ac.Get(i, 0)).a = true; //dirty
Action();
if(!ctrl) return;
ctrl->UpdateActionRefresh(); //propagate user action
}
void PropEditCtrl::OnUpdateCurrentRow()
{
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();
ctrl->UpdateActionRefresh(); //propagate user action
OnUpdateRow(ii);
}
void PropEditCtrl::Undo()

View file

@ -19,9 +19,7 @@ public:
virtual void Updated();
virtual void Undo();
void OnUpdateRow();
void SetCtrl(Ctrl* c) { ctrl = c; UpdateRefresh(); }
void SetCtrl(Ctrl* c) { if(ctrl != c) { ctrl = c; UpdateCtrl(); } UpdateRefresh(); }
Ctrl* GetCtrl() const { return ctrl; }
void ClearCtrl() { SetCtrl(NULL); }
@ -29,7 +27,14 @@ public:
virtual void SetData(const Value& v) { SetCtrl(RawValue<Ctrl*>::Extract(v)); }
protected:
Ptr<Ctrl> ctrl, sctrl; //the current child, and a cache
void ReloadFactory(int i, One<Ctrl>& o);
void ReloadAction(int i);
void UpdateCtrl();
void OnUpdateRow(int i);
void OnUpdateCurrentRow();
Ptr<Ctrl> ctrl;
ArrayMap<String, Tuple2<bool, Value> > vsav;
AccessorMap am;
};
@ -47,7 +52,6 @@ public:
virtual void Rejector() { pec.Undo(); pec.ClearCtrl(); PopUpC::Rejector(); }
virtual void Acceptor() { pec.ClearCtrl(); PopUpC::Acceptor(); }
protected:
PropEditCtrl pec;
Button ok, cancel;
};

View file

@ -1,4 +1,4 @@
LAYOUT(PropEditLay, 400, 200)
ITEM(ArrayCtrl, ac, HSizePosZ(0, 0).VSizePosZ(0, 0))
ITEM(ArrayCtrl, ac, Header(false).HSizePosZ(0, 0).VSizePosZ(0, 0))
END_LAYOUT

View file

@ -37,7 +37,6 @@ public:
void PopUp(Ctrl* owner, Ctrl& e) { plc.SetCtrl(&e); PopUpC::PopUp(owner); }
virtual void Acceptor() { plc.ClearCtrl(); PopUpC::Acceptor(); }
protected:
PropListCtrl plc;
Button exit;
};

View file

@ -27,6 +27,7 @@ public:
void OnEdit();
void OnCtrlRight(Ctrl& c, Point p, dword keyflags);
void OnMoveAction();
public:
ToolBar mb;

View file

@ -44,3 +44,8 @@ void CtrlPropTest::OnCtrlRight(Ctrl& c, Point p, dword keyflags)
DoEdit(c);
}
void CtrlPropTest::OnMoveAction()
{
if(hk.GetCtrl() && hk.GetCtrl() == pe.pec.GetCtrl())
pe.pec.Update();
}

View file

@ -31,6 +31,8 @@ CtrlPropTest::CtrlPropTest()
hk.WhenRightDown = THISBACK(OnCtrlRight);
hk.SetSource(&vis);
hk.Disable();
hk <<= THISBACK(OnMoveAction);
InitDummies();
}

View file

@ -26,6 +26,16 @@ Rect LogPosPopUp::CtrlRect(Ctrl::LogPos pos, Size sz)
return r;
}
Rect LogPosPopUp::CtrlRectZ(Ctrl::LogPos pos, Size sz)
{
Rect r = CtrlRect(pos, sz);
r.left = HorzLayoutZoom(r.left);
r.right = HorzLayoutZoom(r.right);
r.top = VertLayoutZoom(r.top);
r.bottom = VertLayoutZoom(r.bottom);
return r;
}
Ctrl::Logc MakeLogc(int align, int a, int b, int sz)
{
int isz = b - a;
@ -51,16 +61,17 @@ Ctrl::LogPos LogPosPopUp::MakeLogPos(Ctrl::LogPos p, const Rect& r, Size sz)
return MakeLogPos(p.x.GetAlign(), p.y.GetAlign(), r, sz);
}
Ctrl::LogPos LogPosPopUp::ReAlign(const Ctrl& c, const Ctrl::LogPos& npos)
Ctrl::LogPos LogPosPopUp::MakeLogPos(Ctrl::LogPos p, const Ctrl::LogPos& pos, Size sz)
{
if(!c.GetParent()) return npos;
//convert ctrl's pos to its rect in parent
//and reconvert to logpos using new align
Size sz = c.GetParent()->GetSize();
Ctrl::LogPos pos = c.GetPos();
Rect r = CtrlRect(pos, sz);
pos = MakeLogPos(npos, r, sz);
return pos;
return MakeLogPos(p, r, sz);
}
Ctrl::LogPos LogPosPopUp::MakeLogPos(Ctrl::LogPos p, const Ctrl& c)
{
if(!c.GetParent()) return p;
//reconvert to logpos using new align
return MakeLogPos(p, c.GetPos(), c.GetParent()->GetSize());
}
void LogPosPopUp::Set(const Ctrl::LogPos& p)
@ -260,6 +271,8 @@ LogPosCtrl::LogPosCtrl() : push(false)
lc.WhenSizeChange = THISBACK(OnSizeChange);
lc.WhenAlignChange = THISBACK(OnAlignChange);
bsz.SetNull();
}
void LogPosCtrl::LeftDown(Point p, dword keyflags)
@ -307,12 +320,11 @@ void LogPosCtrl::Updated()
void LogPosCtrl::OnSizeChange()
{
if(!posparent) return;
}
void LogPosCtrl::OnAlignChange()
{
if(!posparent) return;
lc.Set(LogPosPopUp::ReAlign(*posparent, lc.Get()));
if(bsz.IsNullInstance()) return;
lc.Set(LogPosPopUp::MakeLogPos(lc.Get(), pos, bsz));
lc.Update(); //feedback to lc
}

View file

@ -21,9 +21,11 @@ public:
LogPosPopUp();
static Rect CtrlRect(Ctrl::LogPos pos, Size sz);
static Rect CtrlRectZ(Ctrl::LogPos pos, Size sz);
static Ctrl::LogPos MakeLogPos(int ax, int ay, const Rect& r, Size sz);
static Ctrl::LogPos MakeLogPos(Ctrl::LogPos p, const Rect& r, Size sz);
static Ctrl::LogPos ReAlign(const Ctrl& c, const Ctrl::LogPos& npos);
static Ctrl::LogPos MakeLogPos(Ctrl::LogPos p, const Ctrl::LogPos& pos, Size sz);
static Ctrl::LogPos MakeLogPos(Ctrl::LogPos p, const Ctrl& c);
virtual void Updated();
virtual Value GetData() const { return RawToValue(pos); }
@ -60,12 +62,17 @@ public:
virtual void LeftDown(Point p, dword keyflags);
virtual void Updated();
void SetBaseSize(const Size& sz) { bsz = sz; }
void ClearBaseSize() { bsz = Null; }
Size GetBaseSize() const { return bsz; }
virtual Value GetData() const { return RawToValue(pos); }
virtual void SetData(const Value& v) { if(!v.Is<Ctrl::LogPos>()) return; pos = RawValue<Ctrl::LogPos>::Extract(v); Update(); }
Ctrl::LogPos Get() const { return pos; }
void Set(const Ctrl::LogPos& p) { pos = p; Update(); }
void Set(Ctrl& c) { posparent = &c; pos = c.GetPos(); Update(); }
void Set(const Ctrl::LogPos& p, const Size& sz = Null) { pos = p; bsz = sz; Update(); }
void Set(Ctrl& c) { pos = c.GetPos(); bsz = c.GetParent() ? c.GetParent()->GetSize() : Null; Update(); }
void Drop();
protected:
@ -78,7 +85,9 @@ protected:
Ctrl::LogPos pos, savedpos;
bool push;
LogPosPopUp lc;
Ptr<Ctrl> posparent;
//base info, for recalculation
Size bsz;
};
#endif