2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 15:55:40 +01:00
|
|
|
#include "tabber.hpp"
|
|
|
|
|
#include <WinUser.h>
|
2019-01-18 17:04:34 +01:00
|
|
|
#include "stdafx.hpp"
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
IMPLEMENT_DYNAMIC(Tabber, CTabCtrl)
|
|
|
|
|
BEGIN_MESSAGE_MAP(Tabber, CTabCtrl)
|
|
|
|
|
ON_WM_SIZE()
|
|
|
|
|
ON_WM_ERASEBKGND()
|
|
|
|
|
ON_NOTIFY_REFLECT(TCN_SELCHANGE, tcn_selChange)
|
2014-01-31 08:23:00 +13:00
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
static CRect tabsRect(CTabCtrl& t)
|
|
|
|
|
{
|
|
|
|
|
CRect r(0, 0, 0, 0);
|
|
|
|
|
int n = t.GetItemCount();
|
|
|
|
|
for (int k = 0; k < n; ++k) {
|
2014-01-31 08:23:00 +13:00
|
|
|
CRect c;
|
2019-01-18 17:04:34 +01:00
|
|
|
t.GetItemRect(k, &c);
|
|
|
|
|
if (c.left < r.left)
|
|
|
|
|
r.left = c.left;
|
|
|
|
|
if (c.right > r.right)
|
|
|
|
|
r.right = c.right;
|
|
|
|
|
if (c.top < r.top)
|
|
|
|
|
r.top = c.top;
|
|
|
|
|
if (c.bottom > r.bottom)
|
|
|
|
|
r.bottom = c.bottom;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
CRect Tabber::getInnerRect()
|
|
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
CRect r;
|
2019-01-18 17:04:34 +01:00
|
|
|
GetClientRect(&r);
|
|
|
|
|
int x = 2, y = 2, w = r.Width() - 4, h = r.Height() - 4;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
r = tabsRect(*this);
|
|
|
|
|
h -= r.Height();
|
|
|
|
|
y += r.Height();
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
r.left = x;
|
|
|
|
|
r.top = y;
|
|
|
|
|
r.right = x + w;
|
|
|
|
|
r.bottom = y + h;
|
2014-01-31 08:23:00 +13:00
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
Tabber::Tabber() : listener(0), curr(-1) {}
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
Tabber::~Tabber()
|
|
|
|
|
{
|
|
|
|
|
for (; tabs.size(); tabs.pop_back())
|
|
|
|
|
delete tabs.back();
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
void Tabber::OnSize(UINT type, int w, int h)
|
|
|
|
|
{
|
|
|
|
|
CTabCtrl::OnSize(type, w, h);
|
2014-01-31 08:23:00 +13:00
|
|
|
refresh();
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
BOOL Tabber::OnEraseBkgnd(CDC* dc)
|
|
|
|
|
{
|
|
|
|
|
CRect c;
|
|
|
|
|
GetClientRect(&c);
|
|
|
|
|
|
|
|
|
|
HBRUSH hb = (HBRUSH)GetClassLong(m_hWnd, GCL_HBRBACKGROUND);
|
|
|
|
|
CBrush br;
|
|
|
|
|
br.Attach(hb);
|
|
|
|
|
|
|
|
|
|
if (curr < 0)
|
|
|
|
|
dc->FillRect(&c, &br);
|
|
|
|
|
else {
|
|
|
|
|
CRect i = getInnerRect();
|
|
|
|
|
CRect t(c.left, c.top, i.right, i.top);
|
|
|
|
|
dc->FillRect(&t, &br);
|
|
|
|
|
CRect r(i.right, c.top, c.right, i.bottom);
|
|
|
|
|
dc->FillRect(&r, &br);
|
|
|
|
|
CRect b(i.left, i.bottom, c.right, c.bottom);
|
|
|
|
|
dc->FillRect(&b, &br);
|
|
|
|
|
CRect l(c.left, i.top, i.left, c.bottom);
|
|
|
|
|
dc->FillRect(&l, &br);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
void Tabber::setListener(TabberListener* l)
|
|
|
|
|
{
|
|
|
|
|
listener = l;
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
void Tabber::refresh()
|
|
|
|
|
{
|
|
|
|
|
if (curr < 0)
|
|
|
|
|
return;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
CRect r = getInnerRect();
|
|
|
|
|
CWnd* wnd = getTabWnd(curr);
|
|
|
|
|
wnd->MoveWindow(r.left, r.top, r.Width(), r.Height());
|
|
|
|
|
wnd->ShowWindow(SW_SHOWNA);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
Tabber::Tab* Tabber::getTab(int index) const
|
|
|
|
|
{
|
|
|
|
|
if (index < 0 || index >= tabs.size())
|
|
|
|
|
return 0;
|
|
|
|
|
Tabs::const_iterator it = tabs.begin();
|
|
|
|
|
while (index--)
|
|
|
|
|
++it;
|
2014-01-31 08:23:00 +13:00
|
|
|
return *it;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
void Tabber::tcn_selChange(NMHDR* p, LRESULT* result)
|
|
|
|
|
{
|
|
|
|
|
setCurrent(GetCurSel());
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
void Tabber::insert(int index, CWnd* w, const string& t)
|
|
|
|
|
{
|
|
|
|
|
if (index < 0 || index > tabs.size())
|
|
|
|
|
return;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
Tabs::iterator it = tabs.begin();
|
|
|
|
|
for (int k = 0; k < index; ++k)
|
|
|
|
|
++it;
|
|
|
|
|
Tab* tab = new Tab(w, t);
|
|
|
|
|
tabs.insert(it, tab);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
InsertItem(index, t.c_str());
|
|
|
|
|
if (curr < 0)
|
|
|
|
|
setCurrent(index);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
void Tabber::remove(int index)
|
|
|
|
|
{
|
|
|
|
|
if (index < 0 || index >= tabs.size())
|
|
|
|
|
return;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
CWnd* w = getTabWnd(index);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
Tabs::iterator it = tabs.begin();
|
|
|
|
|
for (int k = 0; k < index; ++k)
|
|
|
|
|
++it;
|
|
|
|
|
delete *it;
|
|
|
|
|
tabs.erase(it);
|
|
|
|
|
DeleteItem(index);
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
if (curr >= tabs.size())
|
|
|
|
|
curr = tabs.size() - 1;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
|
|
|
|
refresh();
|
2019-01-18 17:04:34 +01:00
|
|
|
if (curr >= 0)
|
|
|
|
|
SetCurSel(curr);
|
|
|
|
|
if (w)
|
|
|
|
|
w->ShowWindow(SW_HIDE);
|
|
|
|
|
if (listener)
|
|
|
|
|
listener->currentSet(this, curr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Tabber::setCurrent(int index)
|
|
|
|
|
{
|
|
|
|
|
if (index < 0 || index >= tabs.size())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (index != curr) {
|
|
|
|
|
CWnd* w = getTabWnd(curr);
|
|
|
|
|
curr = index;
|
2014-01-31 08:23:00 +13:00
|
|
|
refresh();
|
2019-01-18 17:04:34 +01:00
|
|
|
SetCurSel(curr);
|
|
|
|
|
if (w)
|
|
|
|
|
w->ShowWindow(SW_HIDE);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
if (listener)
|
|
|
|
|
listener->currentSet(this, curr);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
void Tabber::setTabText(int index, const string& t)
|
|
|
|
|
{
|
|
|
|
|
if (index < 0 || index >= tabs.size())
|
|
|
|
|
return;
|
2014-01-31 08:23:00 +13:00
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
string s = t + '\0';
|
|
|
|
|
TCITEM tc = {TCIF_TEXT};
|
|
|
|
|
tc.pszText = (char*)s.data();
|
|
|
|
|
SetItem(index, &tc);
|
2014-01-31 08:23:00 +13:00
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
int Tabber::size() const
|
|
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
return tabs.size();
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
int Tabber::getCurrent() const
|
|
|
|
|
{
|
2014-01-31 08:23:00 +13:00
|
|
|
return curr;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
CWnd* Tabber::getTabWnd(int index) const
|
|
|
|
|
{
|
|
|
|
|
Tab* t = getTab(index);
|
2014-01-31 08:23:00 +13:00
|
|
|
return t ? t->wnd : 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 17:04:34 +01:00
|
|
|
string Tabber::getTabText(int index) const
|
|
|
|
|
{
|
|
|
|
|
Tab* t = getTab(index);
|
2014-01-31 08:23:00 +13:00
|
|
|
return t ? t->text : "";
|
|
|
|
|
}
|