TabBar fixed (thanks massimo)

git-svn-id: svn://ultimatepp.org/upp/trunk@7012 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2014-03-08 18:35:05 +00:00
parent 692d86a1fe
commit 2af0d1f8b2
4 changed files with 96 additions and 48 deletions

View file

@ -369,17 +369,22 @@ void TabBar::CloseAll(int exception)
else if (exception >= 0 && CancelCloseSome(Vector<Value>(vv,0)))
return;
// 2014/03/06 - FIRST the callbacks, THEN remove the tab
// otherwise keys in WhenCloseSome() are invalid
// WhenCloseSome() is called ALWAYS even if all tabs are closed
WhenCloseSome(vv);
if (exception < 0)
WhenCloseAll();
for(int i = tabs.GetCount() - 1; i >= 0; i--)
if(i != exception)
{
TabClosed(tabs[i].key);
tabs.Remove(i);
}
SetCursor(0);
if (exception >= 0)
WhenCloseSome(vv);
else
WhenCloseAll();
MakeGroups();
Repos();
Refresh();
@ -425,18 +430,6 @@ void TabBar::GroupMenu(Bar &bar, int n)
bar.Add(t_("Close"), THISBACK1(DoCloseGroup, n));
}
TabBar::Tab::Tab()
{
id = -1;
stack = -1;
visible = true;
itn = 0;
items.SetCount(5);
pos = cross_pos = tab_pos = Point(0, 0);
cross_size = size = tab_size = Size(0, 0);
}
void TabBar::Tab::Set(const Tab& t)
{
id = t.id;
@ -616,10 +609,12 @@ void TabBar::MakeGroups()
void TabBar::DoGrouping(int n)
{
Value c = GetData();
group = n;
Repos();
SyncScrollBar();
SetCursor(-1);
SetData(c);
Refresh();
}
void TabBar::DoCloseGroup(int n)
@ -654,6 +649,8 @@ void TabBar::DoCloseGroup(int n)
// we didn't cancel globally, now we check CancelClose()
// for each tab -- group gets removed ONLY if ALL of
// group tabs are closed
vv.Clear();
Vector<int>vi;
for(int i = tabs.GetCount() - 1; i >= 0; i--) {
if(groupName == tabs[i].group && tabs.GetCount() > 1) {
Value v = tabs[i].key;
@ -661,20 +658,29 @@ void TabBar::DoCloseGroup(int n)
{
nTabs--;
WhenClose(v);
tabs.Remove(i);
// record keys and indexes of tabs to remove
vv << v;
vi << i;
}
}
// remove group if all of its tabs get closed
if(!nTabs) {
if(cnt == n)
group--;
if(cnt > 1)
groups.Remove(n);
}
MakeGroups();
Repos();
SetCursor(-1);
}
// and now do the true removal
WhenCloseSome(Vector<Value>(vv,0));
for(int i = 0; i < vv.GetCount(); i++)
{
TabClosed(vv[i]);
tabs.Remove(vi[i]);
}
// remove group if all of its tabs get closed
if(!nTabs) {
if(cnt == n)
group--;
if(cnt > 1)
groups.Remove(n);
}
MakeGroups();
Repos();
SetCursor(-1);
}
return;
}
@ -686,6 +692,7 @@ void TabBar::DoCloseGroup(int n)
Value v = tabs[i].value; // should be key ??
if (!CancelClose(v)) {
WhenClose(v);
TabClosed(v);
tabs.Remove(i);
}
}
@ -1076,7 +1083,11 @@ void TabBar::Paint(Draw &w)
IsVert() ? w.DrawRect(align == LEFT ? sz.cx - 1 : 0, 0, 1, sz.cy, Blend(SColorDkShadow, SColorShadow)):
w.DrawRect(0, align == TOP ? sz.cy - 1 : 0, sz.cx, 1, Blend(SColorDkShadow, SColorShadow));
if (!tabs.GetCount()) return;
if (!tabs.GetCount()) {
if (align == BOTTOM || align == RIGHT)
w.End();
return;
}
int limt = sc.GetPos() + (IsVert() ? sz.cy : sz.cx);
int first = 0;
@ -1167,12 +1178,12 @@ void TabBar::Paint(Draw &w)
w.DrawImage(p, mouse.y - isz.cy / 2, isz.cx, isz.cy, dragtab);
}
if (align == BOTTOM || align == RIGHT)
w.End();
// If not in a frame fill any spare area
if (!InFrame())
w.DrawRect(GetClientArea(), SColorFace());
if (align == BOTTOM || align == RIGHT)
w.EndOp();
}
Image TabBar::GetDragSample()
@ -1772,8 +1783,7 @@ TabBar& TabBar::SetScrollThickness(int sz)
void TabBar::Layout()
{
if (autoscrollhide && tabs.GetCount())
SyncScrollBar(false);
Repos();
SyncScrollBar(false);
}
int TabBar::FindValue(const Value &v) const
@ -1917,6 +1927,7 @@ void TabBar::SetIcon(int n, Image icon)
void TabBar::LeftDown(Point p, dword keyflags)
{
p = AdjustMouse(p);
SetCapture();
if(keyflags & K_SHIFT)
@ -1942,9 +1953,12 @@ void TabBar::LeftDown(Point p, dword keyflags)
vv.Add(v);
int ix = cross;
if (!CancelClose(v) && !CancelCloseSome(Vector<Value>(vv, 0))) {
Close(ix);
// 2014/03/06 - FIRST the callbacks, THEN remove the tab
// otherwise keys in WhenCloseSome() are invalid
WhenClose(v);
WhenCloseSome(vv);
TabClosed(v);
Close(ix);
}
if (tempCross >= 0 && tempCross < tabs.GetCount())
ProcessMouse(tempCross, p);
@ -1975,7 +1989,13 @@ void TabBar::LeftDouble(Point p, dword keysflags)
void TabBar::RightDown(Point p, dword keyflags)
{
if (contextmenu)
{
// 2014/03/07 needed on X11 otherwise may crash
// if focus is nowhere (probable bug somewhere else...)
if(!GetActiveCtrl())
GetParent()->SetFocus();
MenuBar::Execute(THISBACK(ContextMenu), GetMousePos());
}
}
void TabBar::MiddleDown(Point p, dword keyflags)
@ -1987,9 +2007,12 @@ void TabBar::MiddleDown(Point p, dword keyflags)
vv.Add(v);
if (!CancelClose(v) && ! CancelCloseSome(Vector<Value>(vv, 0))) {
Value v = tabs[highlight].key;
Close(highlight);
// 2014/03/06 - FIRST the callbacks, THEN remove the tab
// otherwise keys in WhenCloseSome() are invalid
WhenClose(v);
WhenCloseSome(vv);
TabClosed(v);
Close(highlight);
}
}
}
@ -2035,6 +2058,17 @@ void TabBar::MouseWheel(Point p, int zdelta, dword keyflags)
MouseMove(p, 0);
}
Point TabBar::AdjustMouse(Point const &p) const
{
int align = GetAlign();
if(align == TOP || align == LEFT)
return p;
Size ctrlsz = GetSize();
Size sz = GetBarSize(ctrlsz);
return Point(p.x - ctrlsz.cx + sz.cx, p.y - ctrlsz.cy + sz.cy);
}
bool TabBar::ProcessMouse(int i, const Point& p)
{
if(i >= 0 && i < tabs.GetCount() && tabs[i].HasMouse(p))
@ -2082,6 +2116,7 @@ void TabBar::SetColor(int n, Color c)
void TabBar::MouseMove(Point p, dword keyflags)
{
p = AdjustMouse(p);
if(HasCapture() && (keyflags & K_SHIFT))
{
Fix(p);
@ -2292,7 +2327,7 @@ bool TabBar::SetCursor0(int n, bool action)
if(Ctrl::HasMouse())
{
Sync();
Refresh();
MouseMove(GetMouseViewPos(), 0);
}
return true;
@ -2341,7 +2376,7 @@ void TabBar::CloseForce(int n, bool action)
//TODO: That must be refactored
highlight = -1;
drag_highlight = -1;
Sync();
Refresh();
MouseMove(GetMouseViewPos(), 0);
}
}
@ -2495,8 +2530,6 @@ void TabBar::Serialize(Stream& s)
int g = GetGroup();
s % g;
group = g;
Repos();
}
CH_STYLE(TabBar, Style, StyleDefault)

View file

@ -180,7 +180,7 @@ public:
Array<TabItem> items;
int itn;
Tab();
Tab() : id(-1), stack(-1), visible(true), itn(0) { items.SetCount(5); }
Tab(const Tab& t) { Set(t); }
void Set(const Tab& t);
@ -336,6 +336,7 @@ protected:
virtual void Layout();
// Mouse handling/tab positioning
Point AdjustMouse(Point const &p) const;
bool ProcessMouse(int i, const Point& p);
bool ProcessStackMouse(int i, const Point& p);
void SetHighlight(int n);
@ -379,6 +380,8 @@ protected:
virtual String GetStackId(const Tab& a) { return a.group; }
// For sub-classes to recieve cursor changes without using WhenAction
virtual void CursorChanged() { }
// for sub-classes to receive tab closes without using WhenClose
virtual void TabClosed(Value key) { }
public:
typedef TabBar CLASSNAME;

View file

@ -75,8 +75,7 @@ void TabBarCtrl::SetCtrl(Value key)
int ix = ctrls.Find(key);
if (ix < 0)
return;
for (int i = 0; i < ctrls.GetCount(); i++)
ctrls[i]->Show(i == ix);
SetData(key);
}
void TabBarCtrl::SetCtrl(int ix)
@ -87,13 +86,25 @@ void TabBarCtrl::SetCtrl(int ix)
void TabBarCtrl::SetCtrl(Ctrl &ctrl)
{
for (int i = 0; i < ctrls.GetCount(); ++i)
ctrls[i]->Show(ctrls[i] == &ctrl);
for(int i = 0; i < ctrls.GetCount(); i++)
if(ctrls[i] == &ctrl)
{
SetData(ctrls.GetKey(i));
return;
}
SetData(-1);
}
void TabBarCtrl::CursorChanged()
{
SetCtrl(GetData());
Value ix = GetData();
for (int i = 0; i < ctrls.GetCount(); i++)
ctrls[i]->Show(ctrls.GetKey(i) == ix);
}
void TabBarCtrl::TabClosed(Value key)
{
ctrls.RemoveKey(key);
}
END_UPP_NAMESPACE

View file

@ -2,7 +2,7 @@ class TabBarCtrl : public TabBar
{
private:
VectorMap<Value, Ctrl *> ctrls;
ParentCtrl pane;
StaticRect pane;
public:
TabBarCtrl() { Ctrl::Add(pane); }
@ -27,4 +27,5 @@ public:
void SetCtrl(Ctrl &ctrl);
protected:
virtual void CursorChanged();
virtual void TabClosed(Value key);
};