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
*e
)
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);
90 QBrush bgBrush
= colorGroup().brush(QColorGroup::Background
);
92 QBrush
bgBrush(colorGroup().background());
94 paint
.fillRect( 0, 0, W
, H
, bgBrush
);
97 int curTab
= ((STabBar
*)parent())->_currentTab
;
99 int leftTab
= ((STabBar
*)parent())->leftTab
;
100 int curx
= -1; // start current tab ( selected )
103 bool iconShow
= ((STabBar
*)parent())->iconShow
;
105 QList
<TabBarData
> *mainData
= ((STabBar
*)parent())->mainData
;
106 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
109 int width
= mainData
->at(k
)->width
;
111 if ( mainData
->at(k
)->id
== curTab
){ // store current tab start x
119 if ( mainData
->at(k
)->pix
!= 0L && iconShow
){
121 switch ( ((STabBar
*)parent())->tabPos
)
122 case STabBar::TAB_TOP
:{
124 case STabBar::TAB_RIGHT
:{
129 paint
.drawPixmap( x1
+ 11, y1
+ 2 , mainData
->at(k
)->pix
->xForm(m
) );
132 int ty
= ( H
+ fontMetrics().height() ) / 2 - 2;
133 int tx
= ( mainData
->at(k
)->pix
!= 0L && iconShow
) ? 32:12;
135 paint
.setFont( parentWidget()->font() );
137 if ( mainData
->at(k
)->enabled
){
138 paint
.setPen( mainData
->at(k
)->textColor
);
139 paint
.drawText( x1
+ tx
, ty
+ y1
, mainData
->at(k
)->label
);
141 paint
.setPen( colorGroup().light() );
142 paint
.drawText( x1
+ tx
+ shadowX
, ty
+ y1
+ shadowY
, mainData
->at(k
)->label
);
143 paint
.setPen( colorGroup().mid() );
144 paint
.drawText( x1
+ tx
, ty
+ y1
, mainData
->at(k
)->label
);
148 paint
.moveTo( x1
, H
+ 1 -y1
);
149 paint
.lineTo( x1
, y1
);
152 paint
.lineTo( x1
+ width
- 1, y1
);
155 paint
.lineTo( x1
+ width
- 1, H
+1-y1
);
157 /***************************************************************/
159 paint
.moveTo( x1
+ 4, y1
+ H
- 5 );
160 paint
.lineTo( x1
+ 4, 3+y1
);
162 paint
.moveTo( x1
+ 7, y1
+ H
- 5 );
163 paint
.lineTo( x1
+ 7, 3+y1
);
166 paint
.moveTo( x1
+ 5, y1
+ H
- 5 );
167 paint
.lineTo( x1
+ 5, 3+y1
);
169 paint
.moveTo( x1
+ 8, y1
+ H
- 5 );
170 paint
.lineTo( x1
+ 8, 3+y1
);
171 /***************************************************************/
173 // fixed picture for leftTab
174 if ( leftTab
== (int)k
+ 1 ){
175 paint
.fillRect( x1
+ width
- 2, 0, 2, H
- 1, bgBrush
);
179 if ( (int)k
== leftTab
&& k
!= 0 )
183 paint
.fillRect( x1
, 0, 1, H
- 1, bgBrush
);
186 paint
.drawPoint( xx
+ 2, yy
);
187 paint
.drawPoint( xx
+ 1, yy
+ 1 );
188 paint
.moveTo( xx
+ 1, yy
+ 1 );
189 paint
.lineTo( xx
+ 1, yy
+ 3 );
190 paint
.drawPoint( xx
+ 2, yy
+ 4 );
191 paint
.lineTo( xx
+ 2, yy
+ 6 );
192 paint
.drawPoint( xx
+ 3, yy
+ 7 );
193 paint
.lineTo( xx
+ 3, yy
+ 9 );
194 paint
.drawPoint( xx
+ 2, yy
+ 10 );
195 paint
.drawPoint( xx
+ 2, yy
+ 11 );
201 if ( x
>= W
&& broken
== -1 ) broken
= k
; // store right broken tab
204 // modify ( paint ) selected tab
205 if ( curx
!= -1 && curTabNum
>= leftTab
){
209 paint
.moveTo( curx
, H
-1 );
210 paint
.lineTo( curx
, 0 );
212 paint
.lineTo( curx
+ curWidth
- 2, 0 );
215 paint
.moveTo( curx
+ curWidth
- 1, 0 );
216 paint
.lineTo( curx
+ curWidth
- 1, H
-1 );
218 paint
.fillRect( curx
+ 1, 1, 2, H
- 1, bgBrush
);
219 paint
.fillRect( curx
+ curWidth
- 4, 1, 3, H
- 1, bgBrush
);
220 paint
.fillRect( curx
+ 1, 1, curWidth
- 3, 2, bgBrush
);
223 if ( curTabNum
== leftTab
&& curTabNum
!= 0 )
227 paint
.fillRect( curx
, 0, 1, H
- 1, bgBrush
);
230 paint
.drawPoint( xx
+ 2, yy
);
231 paint
.drawPoint( xx
+ 1, yy
+ 1 );
232 paint
.moveTo( xx
+ 1, yy
+ 1 );
233 paint
.lineTo( xx
+ 1, yy
+ 3 );
234 paint
.drawPoint( xx
+ 2, yy
+ 4 );
235 paint
.lineTo( xx
+ 2, yy
+ 6 );
236 paint
.drawPoint( xx
+ 3, yy
+ 7 );
237 paint
.lineTo( xx
+ 3, yy
+ 9 );
238 paint
.drawPoint( xx
+ 2, yy
+ 10 );
239 paint
.drawPoint( xx
+ 2, yy
+ 11 );
244 // paint broken right
247 int yy
= broken
== curTabNum
? 0:2;
249 paint
.fillRect( xx
- 2, 0, 2, H
- 1, bgBrush
);
250 paint
.fillRect( xx
- 5, yy
+ 1, 5, H
- 2 - yy
, bgBrush
);
253 paint
.drawPoint( xx
- 2, yy
);
254 paint
.drawPoint( xx
- 1, yy
+ 1 );
255 paint
.moveTo( xx
- 1, yy
+ 1 );
256 paint
.lineTo( xx
- 1, yy
+ 3 );
257 paint
.drawPoint( xx
- 2, yy
+ 4 );
258 paint
.lineTo( xx
- 2, yy
+ 6 );
259 paint
.drawPoint( xx
- 3, yy
+ 7 );
260 paint
.lineTo( xx
- 3, yy
+ 9 );
261 paint
.drawPoint( xx
- 2, yy
+ 10 );
262 paint
.drawPoint( xx
- 2, yy
+ 11 );
269 int BarPainter::findBarByPos( int x
, int y
)
271 int dx
= 5; // overlaped
273 switch ( ((STabBar
*)parent())->tabPos
){
274 case STabBar::TAB_TOP
:
276 case STabBar::TAB_RIGHT
:
281 STabBar
* bar
= (STabBar
*)parent();
283 QList
<TabBarData
> *mainData
= bar
->mainData
;
284 if ( mainData
->isEmpty() ) return -1;
289 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
290 end
+= mainData
->at(k
)->width
;
293 findWidth
= mainData
->at(k
)->width
;
298 int idCurTab
= bar
->_currentTab
;
300 for ( uint k
= 0; k
< mainData
->count(); k
++ )
301 if ( mainData
->at(k
)->id
== idCurTab
){
306 // process first Tab manualy
307 if ( x
< dx
&& curTab
!= mainData
->at(0)->id
) return -1;
309 // process last Tab manyaly
311 if ( x
< (end
+ dx
) && curTab
== (int)mainData
->count() - 1 )
312 find
= mainData
->count() - 1;
314 if ( find
== -1 ) return -1;
318 if ( curTab
== (find
- 1) && x
< (end
- findWidth
+ dx
) ) find
-= 1;
320 if ( find
< (int)mainData
->count() - 1 )
321 if ( curTab
== (find
+ 1) && x
> (end
- dx
) ) find
+= 1;
323 return mainData
->at(find
)->id
;
326 void BarPainter::mousePressEvent( QMouseEvent
* e
)
328 int cur
= findBarByPos( e
->x(), e
->y() );
329 if ( e
->button() == RightButton
)
330 emit ((STabBar
*)parent())->rightButtonPress( cur
, e
->globalPos() );
335 void BarPainter::mouseReleaseEvent( QMouseEvent
* e
)
337 int cur
= findBarByPos( e
->x(), e
->y() );
338 if ( cur
!= -1 && cur
== mousePressTab
){
339 ((STabBar
*)parent())->setCurrentTab( cur
);
343 /***************************************************************************/
345 STabBar::STabBar( QWidget
* parent
, const char * name
)
346 :QWidget( parent
, name
)
349 #include "b_left.xpm"
350 left_xpm
= new QPixmap( b_left_xpm
);
354 right_xpm
= new QPixmap( left_xpm
->xForm(m
) );
358 down_xpm
= new QPixmap( left_xpm
->xForm(m
) );
362 up_xpm
= new QPixmap( down_xpm
->xForm(m
) );
363 /****************************************************************/
368 barPainter
= new BarPainter( this );
371 mainData
= new QList
<TabBarData
>;
372 mainData
->setAutoDelete( true );
376 left
= new QPushButton(this); left
->hide();
377 left
->setAutoRepeat( true );
378 connect( left
, SIGNAL(clicked()), SLOT( leftClicked()) );
379 right
= new QPushButton(this); right
->hide();
380 right
->setAutoRepeat( true );
381 connect( right
, SIGNAL(clicked()), SLOT( rightClicked()) );
383 setFixedHeight( fontMetrics().height() + 10 );
396 void STabBar::paintEvent(QPaintEvent
*)
401 // find current ( selected ) tab data
402 TabBarData
* data
= 0L;
403 int curx
= 2 - barPainter
->delta
;
405 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
406 data
= mainData
->at(k
);
407 if ( data
->id
== _currentTab
){
408 curWidth
= data
->width
+ 4 ;
415 if ( curWidth
== 0 ) curx
= 0; // no tab selected
417 #if QT_VERSION >= 200
418 QBrush bgBrush
= colorGroup().brush(QColorGroup::Background
);
420 QBrush
bgBrush(colorGroup().background());
426 paint
.fillRect( 0, height()-1, width(), 1, bgBrush
);
427 paint
.setPen( white
);
428 paint
.moveTo( 0, height()-1 );
429 paint
.lineTo( curx
, height()-1 );
430 paint
.moveTo( QMIN( curx
+ curWidth
, width() - 50 ), height()-1 );
431 paint
.lineTo( width() - 1, height()-1 );
434 paint
.fillRect( width() - 1, 0, 1, height(), bgBrush
);
435 curx
= height() - curx
;
436 paint
.setPen( colorGroup().dark() );
437 paint
.drawPoint( width() - 1, height()-1 );
439 paint
.moveTo( width() - 1, height()-2 );
440 paint
.setPen( white
);
441 if ( curx
!= height() ) paint
.lineTo( width() - 1, curx
);
442 paint
.moveTo( width() - 1, QMAX( curx
- curWidth
, 50 ) );
443 paint
.lineTo( width() - 1, 0 );
447 barPainter
->repaint( false );
450 int STabBar::insertTab( const QString
&label
, int id
)
454 for ( uint k
= 0; k
< mainData
->count(); k
++ )
455 if ( mainData
->at(k
)->id
> id
) id
= mainData
->at(k
)->id
;
457 TabBarData
* data
= new TabBarData( id
, label
);
459 data
->width
= 4 + fontMetrics().width( label
) + 14;
460 mainData
->append( data
);
467 void STabBar::showTabIcon( bool show
)
469 if ( iconShow
== show
) return;
475 TabBarData
* STabBar::findData( int id
)
477 TabBarData
* data
= 0L;
478 for ( uint k
= 0; k
< mainData
->count(); k
++ )
479 if ( mainData
->at(k
)->id
== id
){
480 data
= mainData
->at(k
);
486 void STabBar::setPixmap( int id
, const QPixmap
&pix
)
488 TabBarData
* data
= findData( id
);
490 if ( data
->pix
!= 0L ) delete data
->pix
;
491 data
->pix
= new QPixmap( pix
);
492 if ( iconShow
) data
->width
+= 16 + 4;
497 void STabBar::setTextColor( int id
, const QColor
&color
)
499 TabBarData
* data
= findData( id
);
501 data
->textColor
= color
;
506 void STabBar::removeTab( int id
)
508 TabBarData
* data
= findData( id
);
510 if ( _currentTab
== data
->id
)
512 for ( uint k
= 0; k
< mainData
->count(); k
++ )
514 if ( mainData
->at(k
)->id
== data
->id
){
515 if ( mainData
->count() == 1 ){
518 setCurrentTab( mainData
->at(k
+1)->id
);
523 if ( mainData
->at(k
+1)->id
== data
->id
){
524 setCurrentTab( mainData
->at(k
)->id
);
529 mainData
->remove( data
);
535 void STabBar::setCurrentTab( int id
, bool allowDisable
)
537 TabBarData
* data
= findData( id
);
539 if ( (data
->enabled
|| allowDisable
) && _currentTab
!= data
->id
)
541 _currentTab
= data
->id
;
545 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
546 data
= mainData
->at(k
);
547 if ( data
->id
== id
){
556 while ( width() - 50 > 30 && ((-barPainter
->delta
+ curx
< 0) || (-barPainter
->delta
+ curx
> width() - 50)) ){
557 if ( -barPainter
->delta
+ curx
< 0 )
564 while ( height() - 50 > 30 && ((-barPainter
->delta
+ curx
< 0) || (-barPainter
->delta
+ curx
> height() - 50)) ){
565 if ( -barPainter
->delta
+ curx
< 0 )
572 emit
tabSelected( id
);
576 void STabBar::setTabEnabled( int id
, bool enabled
)
578 TabBarData
* data
= findData( id
);
579 if ( data
== 0L ) return;
581 if ( data
->enabled
!= enabled
)
583 data
->enabled
= enabled
;
584 if ( _currentTab
== data
->id
){
585 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
586 if ( mainData
->at(k
)->enabled
){
587 setCurrentTab( mainData
->at(k
)->id
);
593 data
= findData( _currentTab
);
594 if ( !data
->enabled
) setCurrentTab( id
);
600 bool STabBar::isTabEnabled( int id
)
602 TabBarData
* data
= findData( id
);
603 return data
== 0L ? false:data
->enabled
;
608 if ( _currentTab
== 0 )
609 if ( !mainData
->isEmpty() )
610 _currentTab
= mainData
->at(0)->id
;
612 if ( _currentTab
!= 0 ){
613 setCurrentTab( _currentTab
);
618 int STabBar::tabsWidth()
621 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
622 width
+= mainData
->at(k
)->width
;
624 return width
== 0 ? 0:width
+ 4;
627 void STabBar::resizeEvent(QResizeEvent
*)
629 int maxAllowWidth
= 0;
630 int maxAllowHeight
= 0;
633 if ( width() - 50 > tabsWidth() ){
634 barPainter
->delta
= 0;
637 maxAllowWidth
= width() - 50 + barPainter
->delta
;
638 barPainter
->move( -barPainter
->delta
, 0 );
639 barPainter
->resize( QMIN(tabsWidth(),maxAllowWidth
), height() - 1 );
642 if ( height() - 50 > tabsWidth() ){
643 barPainter
->delta
= 0;
646 maxAllowHeight
= height() - 50 + barPainter
->delta
;
647 barPainter
->resize( width() - 1, QMIN(tabsWidth(),maxAllowHeight
) );
648 barPainter
->move( 0, height() - barPainter
->height() + barPainter
->delta
);
652 if ( tabPos
== TAB_TOP
){
653 left
->setGeometry( width()-2*18-2, height()-20, 18, 18 );
654 right
->setGeometry( width()-18, height()-20, 18, 18 );
656 if ( barPainter
->delta
> 0 || tabsWidth() > maxAllowWidth
){
665 if ( tabPos
== TAB_RIGHT
){
666 left
->setGeometry( width()-20, 18+2, 18, 18 );
667 right
->setGeometry( width()-20, 0, 18, 18 );
669 if ( barPainter
->delta
> 0 || tabsWidth() > maxAllowHeight
){
679 void STabBar::leftClicked()
683 int dx
= mainData
->at( leftTab
)->width
;
684 barPainter
->delta
-= dx
;
685 barPainter
->move( barPainter
->x() + dx
, barPainter
->y() );
691 void STabBar::rightClicked()
693 if ( leftTab
!= (int)mainData
->count() - 1 ){
694 int dx
= mainData
->at( leftTab
)->width
;
695 barPainter
->delta
+= dx
;
697 barPainter
->move( barPainter
->x() - dx
, barPainter
->y() );
703 void STabBar::setTabPos( TabPos pos
)
711 void STabBar::updateHeight()
715 setMaximumWidth(32767);
717 setFixedHeight( fontMetrics().height() + 10 );
719 setFixedHeight( fontMetrics().height() + 4 );
722 setMaximumHeight(32767);
724 setFixedWidth( fontMetrics().height() + 10 );
726 setFixedWidth( fontMetrics().height() + 4 );
731 void STabBar::setButtonPixmap()
735 left
->setPixmap( *left_xpm
);
736 right
->setPixmap( *right_xpm
);
739 left
->setPixmap( *up_xpm
);
740 right
->setPixmap( *down_xpm
);
745 void STabBar::setFont( const QFont
&f
)
747 QWidget::setFont( f
);
751 void STabBar::setTabCaption( int id
, const QString
&caption
)
753 TabBarData
* data
= findData( id
);
755 data
->label
= caption
;
760 QString
STabBar::tabCaption( int id
)
762 TabBarData
* data
= findData( id
);
763 return data
== 0L ? QString(""):data
->label
;
766 void STabBar::tabsRecreate()
768 for ( uint k
= 0; k
< mainData
->count(); k
++ ){
769 TabBarData
* data
= mainData
->at(k
);
770 data
->width
= 4 + fontMetrics().width( data
->label
) + 14;
771 if ( iconShow
&& data
->pix
!= 0L ) data
->width
+= 16 + 4;
777 const QColor
& STabBar::textColor( int id
)
779 TabBarData
* data
= findData( id
);
781 return data
->textColor
;