blitz3d/blitzide/tabber.cpp

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 : "";
}