163 lines
3.4 KiB
C++
163 lines
3.4 KiB
C++
|
|
#include "stdafx.h"
|
|
#include "tabber.h"
|
|
|
|
IMPLEMENT_DYNAMIC( Tabber,CTabCtrl )
|
|
BEGIN_MESSAGE_MAP( Tabber,CTabCtrl )
|
|
ON_WM_SIZE()
|
|
ON_WM_ERASEBKGND()
|
|
ON_NOTIFY_REFLECT( TCN_SELCHANGE,tcn_selChange )
|
|
END_MESSAGE_MAP()
|
|
|
|
static CRect tabsRect( CTabCtrl &t ){
|
|
CRect r(0,0,0,0);
|
|
int n=t.GetItemCount();
|
|
for( int k=0;k<n;++k ){
|
|
CRect c;
|
|
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;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
CRect Tabber::getInnerRect(){
|
|
CRect r;
|
|
GetClientRect( &r );
|
|
int x=2,y=2,w=r.Width()-4,h=r.Height()-4;
|
|
|
|
r=tabsRect( *this );
|
|
h-=r.Height();y+=r.Height();
|
|
|
|
r.left=x;r.top=y;r.right=x+w;r.bottom=y+h;
|
|
return r;
|
|
}
|
|
|
|
Tabber::Tabber():
|
|
listener(0),curr(-1){
|
|
}
|
|
|
|
Tabber::~Tabber(){
|
|
for( ;tabs.size();tabs.pop_back() ) delete tabs.back();
|
|
}
|
|
|
|
void Tabber::OnSize( UINT type,int w,int h ){
|
|
CTabCtrl::OnSize( type,w,h );
|
|
refresh();
|
|
}
|
|
|
|
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 );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void Tabber::setListener( TabberListener *l ){
|
|
listener=l;
|
|
}
|
|
|
|
void Tabber::refresh(){
|
|
if( curr<0 ) return;
|
|
|
|
CRect r=getInnerRect();
|
|
CWnd *wnd=getTabWnd( curr );
|
|
wnd->MoveWindow( r.left,r.top,r.Width(),r.Height() );
|
|
wnd->ShowWindow( SW_SHOW );
|
|
wnd->SetFocus();
|
|
}
|
|
|
|
Tabber::Tab *Tabber::getTab( int index )const{
|
|
if( index<0 || index>=tabs.size() ) return 0;
|
|
Tabs::const_iterator it=tabs.begin();
|
|
while( index-- ) ++it;
|
|
return *it;
|
|
}
|
|
|
|
void Tabber::tcn_selChange( NMHDR *p,LRESULT *result ){
|
|
setCurrent( GetCurSel() );
|
|
}
|
|
|
|
void Tabber::insert( int index,CWnd *w,const string &t ){
|
|
if( index<0 || index>tabs.size() ) return;
|
|
|
|
Tabs::iterator it=tabs.begin();
|
|
for( int k=0;k<index;++k ) ++it;
|
|
Tab *tab=new Tab( w,t );
|
|
tabs.insert( it,tab );
|
|
|
|
InsertItem( index,t.c_str() );
|
|
if( curr<0 ) setCurrent( index );
|
|
}
|
|
|
|
void Tabber::remove( int index ){
|
|
if( index<0 || index>=tabs.size() ) return;
|
|
|
|
CWnd *w=getTabWnd( index );
|
|
|
|
Tabs::iterator it=tabs.begin();
|
|
for( int k=0;k<index;++k ) ++it;
|
|
delete *it;tabs.erase( it );
|
|
DeleteItem( index );
|
|
|
|
if( curr>=tabs.size() ) curr=tabs.size()-1;
|
|
|
|
refresh();
|
|
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;
|
|
|
|
refresh();
|
|
SetCurSel( curr );
|
|
if( w ) w->ShowWindow( SW_HIDE );
|
|
}
|
|
|
|
if( listener ) listener->currentSet( this,curr );
|
|
}
|
|
|
|
void Tabber::setTabText( int index,const string &t ){
|
|
if( index<0 || index>=tabs.size() ) return;
|
|
|
|
string s=t+'\0';
|
|
TCITEM tc={ TCIF_TEXT };
|
|
tc.pszText=(char*)s.data();
|
|
SetItem( index,&tc );
|
|
}
|
|
|
|
int Tabber::size()const{
|
|
return tabs.size();
|
|
}
|
|
|
|
int Tabber::getCurrent()const{
|
|
return curr;
|
|
}
|
|
|
|
CWnd *Tabber::getTabWnd( int index )const{
|
|
Tab *t=getTab( index );
|
|
return t ? t->wnd : 0;
|
|
}
|
|
|
|
string Tabber::getTabText( int index )const{
|
|
Tab *t=getTab( index );
|
|
return t ? t->text : "";
|
|
} |