mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-10-06 00:30:10 -06:00
changed svn layout
git-svn-id: svn://ultimatepp.org/upp/trunk@281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
commit
d2b54f7989
2872 changed files with 670392 additions and 0 deletions
560
uppsrc/CtrlLib/TabCtrl.cpp
Normal file
560
uppsrc/CtrlLib/TabCtrl.cpp
Normal file
|
|
@ -0,0 +1,560 @@
|
|||
#include "CtrlLib.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
CH_STYLE(TabCtrl, Style, StyleDefault)
|
||||
{
|
||||
font = StdFont();
|
||||
tabheight = font.Info().GetHeight() + 8;
|
||||
margin = 2;
|
||||
sel = Rect(2, 2, 2, 2);
|
||||
edge = Rect(6, 6, 6, 6);
|
||||
extendleft = 0;
|
||||
CtrlsImageLook(normal, CtrlsImg::I_TAB, 4);
|
||||
CtrlsImageLook(first, CtrlsImg::I_FTAB, 4);
|
||||
CtrlsImageLook(last, CtrlsImg::I_LTAB, 4);
|
||||
CtrlsImageLook(both, CtrlsImg::I_BTAB, 4);
|
||||
body = CtrlsImg::TABB();
|
||||
for(int i = 0; i < 4; i++)
|
||||
text_color[i] = SColorText();
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Item::Text(const String& _text)
|
||||
{
|
||||
text = _text;
|
||||
owner->Layout();
|
||||
return *this;
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Item::Picture(PaintRect d)
|
||||
{
|
||||
pict = d;
|
||||
owner->Layout();
|
||||
return *this;
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Item::SetCtrl(Ctrl *_ctrl)
|
||||
{
|
||||
if(ctrl)
|
||||
ctrl->Remove();
|
||||
ctrl = _ctrl;
|
||||
owner->Layout();
|
||||
return *this;
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Item::Slave(Ctrl *_slave)
|
||||
{
|
||||
if(slave)
|
||||
slave->Remove();
|
||||
slave = _slave;
|
||||
if(slave)
|
||||
owner->pane.Add(*slave);
|
||||
int q = owner->sel;
|
||||
owner->sel = -1;
|
||||
owner->Set(q);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Item::Enable(bool _en)
|
||||
{
|
||||
enabled = _en;
|
||||
owner->Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
TabCtrl::Item::Item()
|
||||
{
|
||||
ctrl = slave = NULL;
|
||||
enabled = true;
|
||||
key = 0;
|
||||
}
|
||||
|
||||
void TabCtrl::Item::Layout(int xp, int y, int cy)
|
||||
{
|
||||
Font fnt = owner->style->font;
|
||||
Size chsz = GetTextSize("M", fnt);
|
||||
x = xp;
|
||||
Size sz = pict.GetStdSize();
|
||||
if(sz.cx) {
|
||||
xp += chsz.cx / 2;
|
||||
pictpos.x = xp;
|
||||
pictpos.y = y + (cy - sz.cy) / 2;
|
||||
xp += sz.cx + chsz.cx / 2;
|
||||
}
|
||||
else
|
||||
xp += chsz.cx;
|
||||
sz = GetTextSize(text, fnt);
|
||||
if(sz.cx) {
|
||||
textpos.x = xp;
|
||||
textpos.y = y + (cy - sz.cy) / 2;
|
||||
xp += sz.cx;
|
||||
}
|
||||
if(ctrl) {
|
||||
xp += chsz.cx / 2;
|
||||
sz = ctrl->GetRect().GetSize();
|
||||
ctrl->SetRect(xp, y + (cy - sz.cy) / 2, sz.cx, sz.cy);
|
||||
xp += sz.cx + chsz.cx / 2;
|
||||
}
|
||||
else
|
||||
xp += chsz.cx;
|
||||
cx = xp - x;
|
||||
}
|
||||
|
||||
void TabCtrl::Item::Paint(Draw& w, int state)
|
||||
{
|
||||
Size sz = pict.GetStdSize();
|
||||
pict.Paint(w, pictpos.x, pictpos.y, sz.cx, sz.cy, owner->style->text_color[state], Null);
|
||||
w.DrawText(textpos.x, textpos.y, text, owner->style->font, owner->style->text_color[state]);
|
||||
}
|
||||
|
||||
void TabCtrl::SyncTabs()
|
||||
{
|
||||
int x = style->margin - x0;
|
||||
for(int i = 0; i < tab.GetCount(); i++) {
|
||||
Item& t = tab[i];
|
||||
t.Layout(x, style->sel.top * (i != sel),
|
||||
style->tabheight + style->sel.top * (i == sel));
|
||||
x += t.cx;
|
||||
}
|
||||
left.Show(x0 > 0);
|
||||
right.Show(tab.GetCount() && tab.Top().Right() > tabs.GetSize().cx);
|
||||
}
|
||||
|
||||
void TabCtrl::Layout()
|
||||
{
|
||||
for(int i = 0; i < tab.GetCount(); i++)
|
||||
if(tab[i].ctrl)
|
||||
tab[i].ctrl->Remove();
|
||||
for(int i = 0; i < tab.GetCount(); i++)
|
||||
if(tab[i].ctrl)
|
||||
Ctrl::Add(*tab[i].ctrl);
|
||||
Size sz = GetSize();
|
||||
int th = style->tabheight + style->sel.top;
|
||||
tabs.TopPos(0, th + style->sel.bottom)
|
||||
.HSizePos(0, style->sel.left + style->sel.right);
|
||||
SyncTabs();
|
||||
SyncHot();
|
||||
pane.VSizePos(style->tabheight + style->edge.top, style->edge.bottom)
|
||||
.HSizePos(style->edge.left, style->edge.right);
|
||||
left.LeftPos(0, 16).TopPos(th - 16, 16);
|
||||
right.RightPos(0, 16).TopPos(th - 16, 16);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
Size TabCtrl::ComputeSize(Size pane)
|
||||
{
|
||||
return Size(pane.cx + style->edge.left + style->edge.right,
|
||||
pane.cy + style->tabheight + style->edge.top + style->edge.bottom);
|
||||
}
|
||||
|
||||
int TabCtrl::TabsRight()
|
||||
{
|
||||
return tabs.GetSize().cx - style->sel.left - style->sel.right;
|
||||
}
|
||||
|
||||
void TabCtrl::Tabs::Paint(Draw& w)
|
||||
{
|
||||
static_cast<TabCtrl *>(GetParent())->PaintTabs(w);
|
||||
}
|
||||
|
||||
Rect TabCtrl::GetOpaqueRect()
|
||||
{
|
||||
return pane.GetRect();
|
||||
}
|
||||
|
||||
void TabCtrl::PaintTabs(Draw& w)
|
||||
{
|
||||
int tt = style->sel.top;
|
||||
int th = style->tabheight + tt;
|
||||
Size sz = GetSize();
|
||||
ChPaint(w, 0, th, sz.cx, sz.cy - th, style->body);
|
||||
Size chsz = GetTextSize("M", style->font);
|
||||
for(int phase = 0; phase < 2; phase++) {
|
||||
for(int i = tab.GetCount() - 1; i >= 0; i--)
|
||||
if((sel == i) == phase) {
|
||||
Item& t = tab[i];
|
||||
Rect r = RectC(t.x, tt, t.cx, th - tt);
|
||||
if(i)
|
||||
r.left -= style->extendleft;
|
||||
if(phase) {
|
||||
r.left -= style->sel.left;
|
||||
r.right += style->sel.right;
|
||||
r.top -= tt;
|
||||
r.bottom += style->sel.bottom;
|
||||
}
|
||||
int ndx = !IsEnabled() || !t.enabled ? CTRL_DISABLED :
|
||||
phase ? CTRL_PRESSED :
|
||||
i == hot ? CTRL_HOT : CTRL_NORMAL;
|
||||
ChPaint(w, r,
|
||||
(tab.GetCount() == 1 ? style->both : i == 0 ? style->first :
|
||||
i == tab.GetCount() - 1 ? style->last : style->normal)
|
||||
[ndx]
|
||||
);
|
||||
t.Paint(w, ndx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TabCtrl::Paint(Draw& w)
|
||||
{
|
||||
int th = style->tabheight + style->sel.top;
|
||||
Size sz = GetSize();
|
||||
ChPaint(w, 0, th, sz.cx, sz.cy - th, style->body);
|
||||
}
|
||||
|
||||
int TabCtrl::GetTab(Point p)
|
||||
{
|
||||
if(p.y >= 0 && p.y < style->tabheight)
|
||||
for(int i = 0; i < tab.GetCount(); i++)
|
||||
if(p.x < tab[i].Right())
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TabCtrl::CancelMode()
|
||||
{
|
||||
hot = -1;
|
||||
}
|
||||
|
||||
void TabCtrl::SyncHot()
|
||||
{
|
||||
Point p = GetMousePos() - GetScreenRect().TopLeft();
|
||||
int h = GetTab(p);
|
||||
if(h != hot) {
|
||||
hot = h;
|
||||
tabs.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void TabCtrl::MouseMove(Point p, dword keyflags)
|
||||
{
|
||||
SyncHot();
|
||||
}
|
||||
|
||||
void TabCtrl::LeftDown(Point p, dword keyflags)
|
||||
{
|
||||
if(!IsEditable())
|
||||
return;
|
||||
int h = GetTab(p);
|
||||
if(h >= 0 && tab[h].IsEnabled()) {
|
||||
Set(h);
|
||||
Action();
|
||||
}
|
||||
}
|
||||
|
||||
void TabCtrl::MouseLeave()
|
||||
{
|
||||
SyncHot();
|
||||
}
|
||||
|
||||
void TabCtrl::ScrollInto(int i)
|
||||
{
|
||||
if(i < 0)
|
||||
return;
|
||||
Item& t = tab[i];
|
||||
int tr = TabsRight();
|
||||
if(t.Right() > tr) {
|
||||
x0 += t.Right() - tr;
|
||||
tabs.Refresh();
|
||||
SyncTabs();
|
||||
}
|
||||
if(t.x < style->margin) {
|
||||
x0 += t.x - style->margin;
|
||||
tabs.Refresh();
|
||||
SyncTabs();
|
||||
}
|
||||
}
|
||||
|
||||
void TabCtrl::Left()
|
||||
{
|
||||
if(x0 <= 0)
|
||||
return;
|
||||
for(int i = tab.GetCount() - 1; i >= 0; i--)
|
||||
if(tab[i].x < style->margin) {
|
||||
ScrollInto(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TabCtrl::Right()
|
||||
{
|
||||
for(int i = 0; i < tab.GetCount(); i++)
|
||||
if(tab[i].Right() > tabs.GetRect().GetWidth() - style->sel.left - style->sel.right) {
|
||||
ScrollInto(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TabCtrl::Set(int i)
|
||||
{
|
||||
if(i != sel) {
|
||||
bool refocus = HasFocusDeep();
|
||||
sel = i;
|
||||
tabs.Refresh();
|
||||
SyncTabs();
|
||||
for(int i = 0; i < tab.GetCount(); i++)
|
||||
if(tab[i].slave)
|
||||
tab[i].slave->Show(sel == i);
|
||||
if(sel >= 0 && refocus)
|
||||
IterateFocusForward(tab[sel].slave, GetTopCtrl(), false, true);
|
||||
WhenSet();
|
||||
}
|
||||
ScrollInto(sel);
|
||||
}
|
||||
|
||||
void TabCtrl::SetData(const Value& data)
|
||||
{
|
||||
Set(data);
|
||||
}
|
||||
|
||||
Value TabCtrl::GetData() const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Add()
|
||||
{
|
||||
CancelMode();
|
||||
Item& t = tab.Add();
|
||||
t.owner = this;
|
||||
if(sel < 0)
|
||||
Set(0);
|
||||
Layout();
|
||||
return t;
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Add(const char *text)
|
||||
{
|
||||
return Add().Text(text);
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Add(const Image& m, const char *text)
|
||||
{
|
||||
return Add().Text(text).SetImage(m);
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Add(Ctrl& slave, const char *text)
|
||||
{
|
||||
return Add(text).Slave(&slave);
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Add(Ctrl& slave, const Image& m, const char *text)
|
||||
{
|
||||
return Add(slave, text).SetImage(m);
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Insert(int i)
|
||||
{
|
||||
CancelMode();
|
||||
int c = i < sel ? sel + 1 : sel;
|
||||
TabCtrl::Item& m = tab.Insert(i);
|
||||
m.owner = this;
|
||||
Layout();
|
||||
sel = -1;
|
||||
Set(c);
|
||||
return m;
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Insert(int i, const char *text)
|
||||
{
|
||||
return Insert(i).Text(text);
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Insert(int i, const Image& m, const char *text)
|
||||
{
|
||||
return Insert(i).Text(text).SetImage(m);
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Insert(int i, Ctrl& slave, const char *text)
|
||||
{
|
||||
return Insert(i, text).Slave(&slave);
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabCtrl::Insert(int i, Ctrl& slave, const Image& m, const char *text)
|
||||
{
|
||||
return Insert(i, slave, text).SetImage(m);
|
||||
}
|
||||
|
||||
|
||||
void TabCtrl::Remove(int i)
|
||||
{
|
||||
CancelMode();
|
||||
if(tab[i].ctrl)
|
||||
tab[i].ctrl->Remove();
|
||||
if(tab[i].slave)
|
||||
tab[i].slave->Remove();
|
||||
int c = i < sel ? sel - 1 : sel;
|
||||
tab.Remove(i);
|
||||
Layout();
|
||||
sel = -1;
|
||||
if(tab.GetCount())
|
||||
Set(minmax(c, 0, tab.GetCount() - 1));
|
||||
else {
|
||||
x0 = 0;
|
||||
sel = -1;
|
||||
accept_current = false;
|
||||
WhenSet();
|
||||
}
|
||||
}
|
||||
|
||||
void TabCtrl::Go(int d)
|
||||
{
|
||||
if(IsEditable() && tab.GetCount()) {
|
||||
int i = sel + d;
|
||||
while(i != sel) {
|
||||
if(i < 0)
|
||||
i = tab.GetCount() - 1;
|
||||
if(i >= tab.GetCount())
|
||||
i = 0;
|
||||
if(tab[i].IsEnabled()) {
|
||||
Set(i);
|
||||
break;
|
||||
}
|
||||
i += d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TabCtrl::Key(dword key, int repcnt)
|
||||
{
|
||||
switch(key) {
|
||||
case K_CTRL_TAB:
|
||||
GoNext();
|
||||
Action();
|
||||
return true;
|
||||
case K_SHIFT_CTRL_TAB:
|
||||
GoPrev();
|
||||
Action();
|
||||
return true;
|
||||
}
|
||||
return Ctrl::Key(key, repcnt);
|
||||
}
|
||||
|
||||
bool TabCtrl::HotKey(dword key)
|
||||
{
|
||||
switch(key) {
|
||||
case K_CTRL_TAB:
|
||||
GoNext();
|
||||
Action();
|
||||
return true;
|
||||
case K_SHIFT_CTRL_TAB:
|
||||
GoPrev();
|
||||
Action();
|
||||
return true;
|
||||
}
|
||||
return Ctrl::HotKey(key);
|
||||
}
|
||||
|
||||
bool TabCtrl::Accept()
|
||||
{
|
||||
if(tab.GetCount() == 0)
|
||||
return true;
|
||||
int ii = Get();
|
||||
if(accept_current)
|
||||
return !tab[ii].slave || tab[ii].slave -> Accept();
|
||||
for(int i = 0; i < tab.GetCount(); i++)
|
||||
if(tab[i].slave) {
|
||||
Set(i);
|
||||
if(!tab[i].slave->Accept())
|
||||
return false;
|
||||
}
|
||||
Set(ii);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TabCtrl::Reset()
|
||||
{
|
||||
for(int i = 0; i < tab.GetCount(); i++) {
|
||||
if(tab[i].ctrl)
|
||||
tab[i].ctrl->Remove();
|
||||
if(tab[i].slave)
|
||||
tab[i].slave->Remove();
|
||||
}
|
||||
tab.Clear();
|
||||
x0 = 0;
|
||||
CancelMode();
|
||||
sel = -1;
|
||||
Refresh();
|
||||
accept_current = false;
|
||||
WhenSet();
|
||||
}
|
||||
|
||||
TabCtrl::TabCtrl()
|
||||
{
|
||||
hot = -1;
|
||||
sel = -1;
|
||||
x0 = 0;
|
||||
accept_current = false;
|
||||
Ctrl::Add(tabs);
|
||||
Ctrl::Add(pane);
|
||||
tabs.BackPaint().IgnoreMouse();
|
||||
Ctrl::Add(left.SetImage(CtrlsImg::SLA()).ScrollStyle().NoWantFocus());
|
||||
left <<= THISBACK(Left);
|
||||
Ctrl::Add(right.SetImage(CtrlsImg::SRA()).ScrollStyle().NoWantFocus());
|
||||
right <<= THISBACK(Right);
|
||||
Transparent().NoWantFocus();
|
||||
tabs.Transparent().NoWantFocus();
|
||||
SetStyle(StyleDefault());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
void TabDlg::PlaceButton(Button& b, int& r)
|
||||
{
|
||||
if(b.GetParent()) {
|
||||
b.Remove();
|
||||
AddChild(&b, &tabctrl);
|
||||
b.RightPosZ(r, 64).BottomPosZ(4, 24);
|
||||
r += 72;
|
||||
}
|
||||
}
|
||||
|
||||
void TabDlg::Rearrange()
|
||||
{
|
||||
int r = 4;
|
||||
PlaceButton(apply, r);
|
||||
PlaceButton(cancel, r);
|
||||
PlaceButton(exit, r);
|
||||
PlaceButton(ok, r);
|
||||
SetRect(Rect(GetRect().TopLeft(), tabctrl.ComputeSize(sz) + Ctrl::LayoutZoom(Size(8, 40))));
|
||||
}
|
||||
|
||||
TabCtrl::Item& TabDlg::Add0(Ctrl& tab, const char *text)
|
||||
{
|
||||
Size tsz = max(tab.GetRect().GetSize(), sz);
|
||||
TabCtrl::Item& m = tabctrl.Add(tab, text);
|
||||
if(tsz != sz) {
|
||||
sz = tsz;
|
||||
Rearrange();
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
TabDlg& TabDlg::AButton(Button& b)
|
||||
{
|
||||
if(binit) {
|
||||
exit.Remove();
|
||||
binit = false;
|
||||
}
|
||||
Ctrl::Add(b);
|
||||
Rearrange();
|
||||
return *this;
|
||||
}
|
||||
|
||||
TabDlg::TabDlg()
|
||||
{
|
||||
binit = true;
|
||||
Ctrl::Add(tabctrl.HSizePosZ(4, 4).VSizePosZ(4, 36));
|
||||
sz = Size(0, 0);
|
||||
ok.Ok().SetLabel(t_("OK"));
|
||||
Acceptor(ok, IDOK);
|
||||
cancel.Cancel().SetLabel(t_("Cancel"));
|
||||
Rejector(cancel, IDCANCEL);
|
||||
apply.SetLabel(t_("Apply"));
|
||||
Acceptor(apply, IDYES);
|
||||
exit.SetLabel(t_("Close"));
|
||||
Acceptor(exit, IDEXIT);
|
||||
Ctrl::Add(exit);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
Loading…
Reference in a new issue