1 /***************************************************************************
2 STabCtl part of KDEStudio
4 copyright : (C) 1999 by Judin Maximus
5 email : novaprint@mtu-net.ru
6 ***************************************************************************/
12 #include <qpushbutton.h>
16 BarPainter::BarPainter( STabBar
* parent
)
20 buffer
= new QPixmap(0,0);
23 BarPainter::~BarPainter()
28 void BarPainter::paintEvent( QPaintEvent
* )
30 if ( buffer
->isNull() ) return;
33 switch ( ((STabBar
*)parent())->tabPos
)
34 case STabBar::TAB_TOP
:{
35 bitBlt( this, 0, 0, buffer
, 0, 0, width(), height() );
37 case STabBar::TAB_RIGHT
:{
40 QPixmap xbuffer
= buffer
->xForm(m
);
41 bitBlt( this, 0, 0, &xbuffer
, 0, 0, width(), height() );
47 void BarPainter::resizeEvent( QResizeEvent
* )
50 switch ( ((STabBar
*)parent())->tabPos
)
51 case STabBar::TAB_TOP
:{
52 buffer
= new QPixmap( width(), height() );
54 case STabBar::TAB_RIGHT
:{
55 buffer
= new QPixmap( height(), width() );
61 void BarPainter::drawBuffer()
64 QColor c2
= colorGroup().dark();
65 QColor c4
= white
; // for paint top line;
71 switch ( ((STabBar
*)parent())->tabPos
)
72 case STabBar::TAB_TOP
:{
76 case STabBar::TAB_RIGHT
:{
78 c1
= colorGroup().dark();
88 paint
.setBrushOrigin(0,0);
89 QBrush bgBrush
= colorGroup().brush(QColorGroup::Background
);
90 paint
.fillRect( 0, 0, W
, H
, bgBrush
);
93 int curTab
= ((STabBar
*)parent())->_currentTab
;
95 int leftTab
= ((STabBar
*)parent())->leftTab
;
96 int curx
= -1; // start current tab ( selected )
99 bool iconShow
= ((STabBar
*)parent())->iconShow
;
101 QList
<TabBarData
> *mainData
= ((STabBar
*)parent())->mainData
;
102 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
105 int width
= mainData
->at(k
)->width
;
107 if ( mainData
->at(k
)->id
== curTab
){ // store current tab start x
115 if ( mainData
->at(k
)->pix
!= 0L && iconShow
){
117 switch ( ((STabBar
*)parent())->tabPos
)
118 case STabBar::TAB_TOP
:{
120 case STabBar::TAB_RIGHT
:{
125 paint
.drawPixmap( x1
+ 11, y1
+ 2 , mainData
->at(k
)->pix
->xForm(m
) );
128 int ty
= ( H
+ fontMetrics().height() ) / 2 - 2;
129 int tx
= ( mainData
->at(k
)->pix
!= 0L && iconShow
) ? 32:12;
131 paint
.setFont( parentWidget()->font() );
133 if ( mainData
->at(k
)->enabled
){
134 paint
.setPen( mainData
->at(k
)->textColor
);
135 paint
.drawText( x1
+ tx
, ty
+ y1
, mainData
->at(k
)->label
);
137 paint
.setPen( colorGroup().light() );
138 paint
.drawText( x1
+ tx
+ shadowX
, ty
+ y1
+ shadowY
, mainData
->at(k
)->label
);
139 paint
.setPen( colorGroup().mid() );
140 paint
.drawText( x1
+ tx
, ty
+ y1
, mainData
->at(k
)->label
);
144 paint
.moveTo( x1
, H
+ 1 -y1
);
145 paint
.lineTo( x1
, y1
);
148 paint
.lineTo( x1
+ width
- 1, y1
);
151 paint
.lineTo( x1
+ width
- 1, H
+1-y1
);
153 /***************************************************************/
155 paint
.moveTo( x1
+ 4, y1
+ H
- 5 );
156 paint
.lineTo( x1
+ 4, 3+y1
);
158 paint
.moveTo( x1
+ 7, y1
+ H
- 5 );
159 paint
.lineTo( x1
+ 7, 3+y1
);
162 paint
.moveTo( x1
+ 5, y1
+ H
- 5 );
163 paint
.lineTo( x1
+ 5, 3+y1
);
165 paint
.moveTo( x1
+ 8, y1
+ H
- 5 );
166 paint
.lineTo( x1
+ 8, 3+y1
);
167 /***************************************************************/
169 // fixed picture for leftTab
170 if ( leftTab
== (int)k
+ 1 ){
171 paint
.fillRect( x1
+ width
- 2, 0, 2, H
- 1, bgBrush
);
175 if ( (int)k
== leftTab
&& k
!= 0 )
179 paint
.fillRect( x1
, 0, 1, H
- 1, bgBrush
);
182 paint
.drawPoint( xx
+ 2, yy
);
183 paint
.drawPoint( xx
+ 1, yy
+ 1 );
184 paint
.moveTo( xx
+ 1, yy
+ 1 );
185 paint
.lineTo( xx
+ 1, yy
+ 3 );
186 paint
.drawPoint( xx
+ 2, yy
+ 4 );
187 paint
.lineTo( xx
+ 2, yy
+ 6 );
188 paint
.drawPoint( xx
+ 3, yy
+ 7 );
189 paint
.lineTo( xx
+ 3, yy
+ 9 );
190 paint
.drawPoint( xx
+ 2, yy
+ 10 );
191 paint
.drawPoint( xx
+ 2, yy
+ 11 );
197 if ( x
>= W
&& broken
== -1 ) broken
= k
; // store right broken tab
200 // modify ( paint ) selected tab
201 if ( curx
!= -1 && curTabNum
>= leftTab
){
205 paint
.moveTo( curx
, H
-1 );
206 paint
.lineTo( curx
, 0 );
208 paint
.lineTo( curx
+ curWidth
- 2, 0 );
211 paint
.moveTo( curx
+ curWidth
- 1, 0 );
212 paint
.lineTo( curx
+ curWidth
- 1, H
-1 );
214 paint
.fillRect( curx
+ 1, 1, 2, H
- 1, bgBrush
);
215 paint
.fillRect( curx
+ curWidth
- 4, 1, 3, H
- 1, bgBrush
);
216 paint
.fillRect( curx
+ 1, 1, curWidth
- 3, 2, bgBrush
);
219 if ( curTabNum
== leftTab
&& curTabNum
!= 0 )
223 paint
.fillRect( curx
, 0, 1, H
- 1, bgBrush
);
226 paint
.drawPoint( xx
+ 2, yy
);
227 paint
.drawPoint( xx
+ 1, yy
+ 1 );
228 paint
.moveTo( xx
+ 1, yy
+ 1 );
229 paint
.lineTo( xx
+ 1, yy
+ 3 );
230 paint
.drawPoint( xx
+ 2, yy
+ 4 );
231 paint
.lineTo( xx
+ 2, yy
+ 6 );
232 paint
.drawPoint( xx
+ 3, yy
+ 7 );
233 paint
.lineTo( xx
+ 3, yy
+ 9 );
234 paint
.drawPoint( xx
+ 2, yy
+ 10 );
235 paint
.drawPoint( xx
+ 2, yy
+ 11 );
240 // paint broken right
243 int yy
= broken
== curTabNum
? 0:2;
245 paint
.fillRect( xx
- 2, 0, 2, H
- 1, bgBrush
);
246 paint
.fillRect( xx
- 5, yy
+ 1, 5, H
- 2 - yy
, bgBrush
);
249 paint
.drawPoint( xx
- 2, yy
);
250 paint
.drawPoint( xx
- 1, yy
+ 1 );
251 paint
.moveTo( xx
- 1, yy
+ 1 );
252 paint
.lineTo( xx
- 1, yy
+ 3 );
253 paint
.drawPoint( xx
- 2, yy
+ 4 );
254 paint
.lineTo( xx
- 2, yy
+ 6 );
255 paint
.drawPoint( xx
- 3, yy
+ 7 );
256 paint
.lineTo( xx
- 3, yy
+ 9 );
257 paint
.drawPoint( xx
- 2, yy
+ 10 );
258 paint
.drawPoint( xx
- 2, yy
+ 11 );
265 int BarPainter::findBarByPos( int x
, int y
)
267 int dx
= 5; // overlaped
269 switch ( ((STabBar
*)parent())->tabPos
){
270 case STabBar::TAB_TOP
:
272 case STabBar::TAB_RIGHT
:
277 STabBar
* bar
= (STabBar
*)parent();
279 QList
<TabBarData
> *mainData
= bar
->mainData
;
280 if ( mainData
->isEmpty() ) return -1;
285 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
286 end
+= mainData
->at(k
)->width
;
289 findWidth
= mainData
->at(k
)->width
;
294 int idCurTab
= bar
->_currentTab
;
296 for ( uint k
= 0; k
< mainData
->count(); k
++ )
297 if ( mainData
->at(k
)->id
== idCurTab
){
302 // process first Tab manualy
303 if ( x
< dx
&& curTab
!= mainData
->at(0)->id
) return -1;
305 // process last Tab manyaly
307 if ( x
< (end
+ dx
) && curTab
== (int)mainData
->count() - 1 )
308 find
= mainData
->count() - 1;
310 if ( find
== -1 ) return -1;
314 if ( curTab
== (find
- 1) && x
< (end
- findWidth
+ dx
) ) find
-= 1;
316 if ( find
< (int)mainData
->count() - 1 )
317 if ( curTab
== (find
+ 1) && x
> (end
- dx
) ) find
+= 1;
319 return mainData
->at(find
)->id
;
322 void BarPainter::mousePressEvent( QMouseEvent
* e
)
324 int cur
= findBarByPos( e
->x(), e
->y() );
325 if ( e
->button() == RightButton
)
326 emit ((STabBar
*)parent())->rightButtonPress( cur
, e
->globalPos() );
331 void BarPainter::mouseReleaseEvent( QMouseEvent
* e
)
333 int cur
= findBarByPos( e
->x(), e
->y() );
334 if ( cur
!= -1 && cur
== mousePressTab
){
335 ((STabBar
*)parent())->setCurrentTab( cur
);
339 /***************************************************************************/
341 STabBar::STabBar( QWidget
* parent
, const char * name
)
342 :QWidget( parent
, name
)
345 #include "b_left.xpm"
346 left_xpm
= new QPixmap( b_left_xpm
);
350 right_xpm
= new QPixmap( left_xpm
->xForm(m
) );
354 down_xpm
= new QPixmap( left_xpm
->xForm(m
) );
358 up_xpm
= new QPixmap( down_xpm
->xForm(m
) );
359 /****************************************************************/
364 barPainter
= new BarPainter( this );
367 mainData
= new QList
<TabBarData
>;
368 mainData
->setAutoDelete( true );
372 left
= new QPushButton(this); left
->hide();
373 left
->setAutoRepeat( true );
374 connect( left
, SIGNAL(clicked()), SLOT( leftClicked()) );
375 right
= new QPushButton(this); right
->hide();
376 right
->setAutoRepeat( true );
377 connect( right
, SIGNAL(clicked()), SLOT( rightClicked()) );
379 setFixedHeight( fontMetrics().height() + 10 );
392 void STabBar::paintEvent(QPaintEvent
*)
397 // find current ( selected ) tab data
398 TabBarData
* data
= 0L;
399 int curx
= 2 - barPainter
->delta
;
401 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
402 data
= mainData
->at(k
);
403 if ( data
->id
== _currentTab
){
404 curWidth
= data
->width
+ 4 ;
411 if ( curWidth
== 0 ) curx
= 0; // no tab selected
413 QBrush bgBrush
= colorGroup().brush(QColorGroup::Background
);
418 paint
.fillRect( 0, height()-1, width(), 1, bgBrush
);
419 paint
.setPen( white
);
420 paint
.moveTo( 0, height()-1 );
421 paint
.lineTo( curx
, height()-1 );
422 paint
.moveTo( QMIN( curx
+ curWidth
, width() - 50 ), height()-1 );
423 paint
.lineTo( width() - 1, height()-1 );
426 paint
.fillRect( width() - 1, 0, 1, height(), bgBrush
);
427 curx
= height() - curx
;
428 paint
.setPen( colorGroup().dark() );
429 paint
.drawPoint( width() - 1, height()-1 );
431 paint
.moveTo( width() - 1, height()-2 );
432 paint
.setPen( white
);
433 if ( curx
!= height() ) paint
.lineTo( width() - 1, curx
);
434 paint
.moveTo( width() - 1, QMAX( curx
- curWidth
, 50 ) );
435 paint
.lineTo( width() - 1, 0 );
439 barPainter
->repaint( false );
442 int STabBar::insertTab( const QString
&label
, int id
)
446 for ( uint k
= 0; k
< mainData
->count(); k
++ )
447 if ( mainData
->at(k
)->id
> id
) id
= mainData
->at(k
)->id
;
449 TabBarData
* data
= new TabBarData( id
, label
);
451 data
->width
= 4 + fontMetrics().width( label
) + 14;
452 mainData
->append( data
);
459 void STabBar::showTabIcon( bool show
)
461 if ( iconShow
== show
) return;
467 TabBarData
* STabBar::findData( int id
)
469 TabBarData
* data
= 0L;
470 for ( uint k
= 0; k
< mainData
->count(); k
++ )
471 if ( mainData
->at(k
)->id
== id
){
472 data
= mainData
->at(k
);
478 void STabBar::setPixmap( int id
, const QPixmap
&pix
)
480 TabBarData
* data
= findData( id
);
482 if ( data
->pix
!= 0L ) delete data
->pix
;
483 data
->pix
= new QPixmap( pix
);
484 if ( iconShow
) data
->width
+= 16 + 4;
489 void STabBar::setTextColor( int id
, const QColor
&color
)
491 TabBarData
* data
= findData( id
);
493 data
->textColor
= color
;
498 void STabBar::removeTab( int id
)
500 TabBarData
* data
= findData( id
);
502 if ( _currentTab
== data
->id
)
504 for ( uint k
= 0; k
< mainData
->count(); k
++ )
506 if ( mainData
->at(k
)->id
== data
->id
){
507 if ( mainData
->count() == 1 ){
510 setCurrentTab( mainData
->at(k
+1)->id
);
515 if ( mainData
->at(k
+1)->id
== data
->id
){
516 setCurrentTab( mainData
->at(k
)->id
);
521 mainData
->remove( data
);
527 void STabBar::setCurrentTab( int id
, bool allowDisable
)
529 TabBarData
* data
= findData( id
);
531 if ( (data
->enabled
|| allowDisable
) && _currentTab
!= data
->id
)
533 _currentTab
= data
->id
;
537 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
538 data
= mainData
->at(k
);
539 if ( data
->id
== id
){
548 while ( width() - 50 > 30 && ((-barPainter
->delta
+ curx
< 0) || (-barPainter
->delta
+ curx
> width() - 50)) ){
549 if ( -barPainter
->delta
+ curx
< 0 )
556 while ( height() - 50 > 30 && ((-barPainter
->delta
+ curx
< 0) || (-barPainter
->delta
+ curx
> height() - 50)) ){
557 if ( -barPainter
->delta
+ curx
< 0 )
564 emit
tabSelected( id
);
568 void STabBar::setTabEnabled( int id
, bool enabled
)
570 TabBarData
* data
= findData( id
);
571 if ( data
== 0L ) return;
573 if ( data
->enabled
!= enabled
)
575 data
->enabled
= enabled
;
576 if ( _currentTab
== data
->id
){
577 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
578 if ( mainData
->at(k
)->enabled
){
579 setCurrentTab( mainData
->at(k
)->id
);
585 data
= findData( _currentTab
);
586 if ( !data
->enabled
) setCurrentTab( id
);
592 bool STabBar::isTabEnabled( int id
)
594 TabBarData
* data
= findData( id
);
595 return data
== 0L ? false:data
->enabled
;
600 if ( _currentTab
== 0 )
601 if ( !mainData
->isEmpty() )
602 _currentTab
= mainData
->at(0)->id
;
604 if ( _currentTab
!= 0 ){
605 setCurrentTab( _currentTab
);
610 int STabBar::tabsWidth()
613 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
614 width
+= mainData
->at(k
)->width
;
616 return width
== 0 ? 0:width
+ 4;
619 void STabBar::resizeEvent(QResizeEvent
*)
621 int maxAllowWidth
= 0;
622 int maxAllowHeight
= 0;
625 if ( width() - 50 > tabsWidth() ){
626 barPainter
->delta
= 0;
629 maxAllowWidth
= width() - 50 + barPainter
->delta
;
630 barPainter
->move( -barPainter
->delta
, 0 );
631 barPainter
->resize( QMIN(tabsWidth(),maxAllowWidth
), height() - 1 );
634 if ( height() - 50 > tabsWidth() ){
635 barPainter
->delta
= 0;
638 maxAllowHeight
= height() - 50 + barPainter
->delta
;
639 barPainter
->resize( width() - 1, QMIN(tabsWidth(),maxAllowHeight
) );
640 barPainter
->move( 0, height() - barPainter
->height() + barPainter
->delta
);
644 if ( tabPos
== TAB_TOP
){
645 left
->setGeometry( width()-2*18-2, height()-20, 18, 18 );
646 right
->setGeometry( width()-18, height()-20, 18, 18 );
648 if ( barPainter
->delta
> 0 || tabsWidth() > maxAllowWidth
){
657 if ( tabPos
== TAB_RIGHT
){
658 left
->setGeometry( width()-20, 18+2, 18, 18 );
659 right
->setGeometry( width()-20, 0, 18, 18 );
661 if ( barPainter
->delta
> 0 || tabsWidth() > maxAllowHeight
){
671 void STabBar::leftClicked()
675 int dx
= mainData
->at( leftTab
)->width
;
676 barPainter
->delta
-= dx
;
677 barPainter
->move( barPainter
->x() + dx
, barPainter
->y() );
683 void STabBar::rightClicked()
685 if ( leftTab
!= (int)mainData
->count() - 1 ){
686 int dx
= mainData
->at( leftTab
)->width
;
687 barPainter
->delta
+= dx
;
689 barPainter
->move( barPainter
->x() - dx
, barPainter
->y() );
695 void STabBar::setTabPos( TabPos pos
)
703 void STabBar::updateHeight()
707 setMaximumWidth(32767);
709 setFixedHeight( fontMetrics().height() + 10 );
711 setFixedHeight( fontMetrics().height() + 4 );
714 setMaximumHeight(32767);
716 setFixedWidth( fontMetrics().height() + 10 );
718 setFixedWidth( fontMetrics().height() + 4 );
723 void STabBar::setButtonPixmap()
727 left
->setPixmap( *left_xpm
);
728 right
->setPixmap( *right_xpm
);
731 left
->setPixmap( *up_xpm
);
732 right
->setPixmap( *down_xpm
);
737 void STabBar::setFont( const QFont
&f
)
739 QWidget::setFont( f
);
743 void STabBar::setTabCaption( int id
, const QString
&caption
)
745 TabBarData
* data
= findData( id
);
747 data
->label
= caption
;
752 QString
STabBar::tabCaption( int id
)
754 TabBarData
* data
= findData( id
);
755 return data
== 0L ? QString(""):data
->label
;
758 void STabBar::tabsRecreate()
760 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
761 TabBarData
* data
= mainData
->at(k
);
762 data
->width
= 4 + fontMetrics().width( data
->label
) + 14;
763 if ( iconShow
&& data
->pix
!= 0L ) data
->width
+= 16 + 4;
769 const QColor
& STabBar::textColor( int id
)
771 TabBarData
* data
= findData( id
);
773 return data
->textColor
;