27#include <tqdrawutil.h>
30#include <tqstringlist.h>
33#include <tqtoolbutton.h>
34#include <tqvaluevector.h>
52 TQToolButton* scrollFirstButton;
53 TQToolButton* scrollLastButton;
54 TQToolButton* scrollBackButton;
55 TQToolButton* scrollForwardButton;
67 TQValueVector<TQRect> tabRects;
101 int tabAt(
const TQPoint& pos );
104 void drawTab( TQPainter& painter, TQRect& rect,
const TQString& text,
bool active );
107 void drawMoveMarker( TQPainter& painter,
int x,
int y );
110 void updateButtons();
115static const char * arrow_leftmost_xpm[] = {
131static const char * arrow_rightmost_xpm[] = {
147static const char * arrow_left_xpm[] = {
163static const char * arrow_right_xpm[] = {
179void KoTabBarPrivate::layoutTabs()
183 TQPainter painter( tabbar );
185 TQFont f = painter.font();
187 painter.setFont( f );
188 TQFontMetrics fm = painter.fontMetrics();
194 for(
unsigned c = 0; c < tabs.count(); c++ )
197 if( (
int)c >= firstTab-1 )
199 TQString text = tabs[ c ];
200 int tw = fm.width( text ) + 4;
201 rect = TQRect( x, 0, tw + 20, tabbar->height() );
204 tabRects.append( rect );
207 lastTab = tabRects.count();
208 for(
unsigned i = 0; i < tabRects.count(); i++ )
209 if( tabRects[i].right()-10+offset > tabbar->width() )
218 int x = tabbar->width() - offset;
219 for(
unsigned c = 0; c < tabs.count(); c++ )
222 if( (
int)c >= firstTab-1 )
224 TQString text = tabs[ c ];
225 int tw = fm.width( text ) + 4;
226 rect = TQRect( x - tw - 20, 0, tw + 20, tabbar->height() );
229 tabRects.append( rect );
232 lastTab = tabRects.count();
233 for(
unsigned i = tabRects.count()-1; i>0; i-- )
234 if( tabRects[i].left() > 0 )
242int KoTabBarPrivate::tabAt(
const TQPoint& pos )
244 for(
unsigned i = 0; i < tabRects.count(); i++ )
246 TQRect rect = tabRects[ i ];
247 if( rect.isNull() )
continue;
248 if( rect.contains( pos ) )
return i;
254void KoTabBarPrivate::drawTab( TQPainter& painter, TQRect& rect,
const TQString& text,
bool active )
256 TQPointArray polygon;
259 polygon.setPoints( 6, rect.x(), rect.y(),
260 rect.x(), rect.bottom()-3,
261 rect.x()+2, rect.bottom(),
262 rect.right()-4, rect.bottom(),
263 rect.right()-2, rect.bottom()-2,
264 rect.right()+5, rect.top() );
266 polygon.setPoints( 6, rect.right(), rect.top(),
267 rect.right(), rect.bottom()-3,
268 rect.right()-2, rect.bottom(),
269 rect.x()+4, rect.bottom(),
270 rect.x()+2, rect.bottom()-2,
271 rect.x()-5, rect.top() );
276 TQBrush bg = tabbar->colorGroup().background();
277 if( active ) bg = TQBrush(tabbar->colorGroup().base());
278 painter.setBrush( bg );
279 painter.setPen( TQPen( TQt::NoPen ) );
280 painter.drawPolygon( polygon );
283 painter.setPen( tabbar->colorGroup().dark() );
285 painter.drawLine( rect.x()-25, rect.y(), rect.right()+25, rect.top() );
286 painter.drawPolyline( polygon );
288 painter.setPen( tabbar->colorGroup().buttonText() );
289 TQFont f = painter.font();
290 if( active ) f.setBold(
true );
291 painter.setFont( f );
292 TQFontMetrics fm = painter.fontMetrics();
293 int tx = rect.x() + ( rect.width() - fm.width( text ) ) / 2;
294 int ty = rect.y() + ( rect.height() - fm.height() ) / 2 + fm.ascent();
295 painter.drawText( tx, ty, text );
300void KoTabBarPrivate::drawMoveMarker( TQPainter& painter,
int x,
int y )
302 TQPointArray movmark;
303 movmark.setPoints( 3, x, y, x + 7, y, x + 4, y + 6);
304 TQBrush oldBrush = painter.brush();
305 painter.setBrush( TQt::black );
306 painter.drawPolygon(movmark);
307 painter.setBrush( oldBrush );
310void KoTabBarPrivate::layoutButtons()
312 int bw = tabbar->height();
313 int w = tabbar->width();
318 scrollFirstButton->setGeometry( 0, 0, bw, bw );
319 scrollFirstButton->setPixmap( arrow_leftmost_xpm );
320 scrollBackButton->setGeometry( bw, 0, bw, bw );
321 scrollBackButton->setPixmap( arrow_left_xpm );
322 scrollForwardButton->setGeometry( bw*2, 0, bw, bw );
323 scrollForwardButton->setPixmap( arrow_right_xpm );
324 scrollLastButton->setGeometry( bw*3, 0, bw, bw );
325 scrollLastButton->setPixmap( arrow_rightmost_xpm );
329 scrollFirstButton->setGeometry( w-bw, 0, bw, bw );
330 scrollFirstButton->setPixmap( arrow_rightmost_xpm );
331 scrollBackButton->setGeometry( w-2*bw, 0, bw, bw );
332 scrollBackButton->setPixmap( arrow_right_xpm );
333 scrollForwardButton->setGeometry( w-3*bw, 0, bw, bw );
334 scrollForwardButton->setPixmap( arrow_left_xpm );
335 scrollLastButton->setGeometry( w-4*bw, 0, bw, bw );
336 scrollLastButton->setPixmap( arrow_leftmost_xpm );
340void KoTabBarPrivate::updateButtons()
342 scrollFirstButton->setEnabled( tabbar->canScrollBack() );
343 scrollBackButton->setEnabled( tabbar->canScrollBack() );
344 scrollForwardButton->setEnabled( tabbar->canScrollForward() );
345 scrollLastButton->setEnabled( tabbar->canScrollForward() );
350 : TQWidget( parent, name, TQt::WResizeNoErase | TQt::WRepaintNoErase )
352 d =
new KoTabBarPrivate;
355 d->reverseLayout =
false;
361 d->autoScroll =
false;
365 d->scrollFirstButton =
new TQToolButton(
this );
366 connect( d->scrollFirstButton, TQ_SIGNAL( clicked() ),
368 d->scrollLastButton =
new TQToolButton(
this );
369 connect( d->scrollLastButton, TQ_SIGNAL( clicked() ),
371 d->scrollBackButton =
new TQToolButton(
this );
372 connect( d->scrollBackButton, TQ_SIGNAL( clicked() ),
374 d->scrollForwardButton =
new TQToolButton(
this );
375 connect( d->scrollForwardButton, TQ_SIGNAL( clicked() ),
390 d->tabs.append( text );
398 int i = d->tabs.findIndex( text );
399 if ( i == -1 )
return;
401 if ( d->activeTab == i + 1 )
404 d->tabs.remove( text );
431 return d->reverseLayout;
436 if( reverse != d->reverseLayout )
438 d->reverseLayout = reverse;
448 TQString left, active;
450 if( d->activeTab > 0 )
451 active = d->tabs[ d->activeTab-1 ];
452 if( d->firstTab > 0 )
453 left = d->tabs[ d->firstTab-1 ];
459 d->firstTab = d->tabs.findIndex( left ) + 1;
460 if( d->firstTab > (
int)d->tabs.count() )
462 if( d->firstTab <= 0 )
467 if( !active.isNull() )
480 return d->tabs.count();
485 if ( d->tabs.count() == 0 )
488 return d->firstTab > 1;
493 if ( d->tabs.count() == 0 )
496 return d->lastTab < (int)d->tabs.count();
505 if( d->firstTab < 1 ) d->firstTab = 1;
518 if( d->firstTab > (
int)d->tabs.count() )
519 d->firstTab = d->tabs.count();
544 if( !d->reverseLayout )
546 int fullWidth = d->tabRects[ d->tabRects.count()-1 ].right();
547 int delta = fullWidth - width() + d->offset;
548 for(
unsigned i = 0; i < d->tabRects.count(); i++ )
549 if( d->tabRects[i].x() > delta )
558 for( ; d->firstTab <= (int)d->tabRects.count();)
560 int x = d->tabRects[ d->tabRects.count()-1 ].x();
574 int i = d->tabs.findIndex( tab );
580 if( ( i >= d->firstTab ) && ( i <= d->lastTab ) )
583 if( i < d->firstTab )
584 while( i < d->firstTab )
588 while( i > d->lastTab )
594 TQString tabName = d->tabs[ tab ];
595 TQStringList::Iterator it;
597 it = d->tabs.at( tab );
598 d->tabs.remove( it );
600 if( target > tab ) target--;
601 it = d->tabs.at( target );
602 if( target >= d->tabs.count() )
604 d->tabs.insert( it, tabName );
606 if( d->activeTab == (
int)tab+1 )
607 d->activeTab = target+1;
614 int i = d->tabs.findIndex( text );
618 if ( i + 1 == d->activeTab )
621 d->activeTab = i + 1;
628void KoTabBar::autoScrollBack()
630 if( !d->autoScroll )
return;
635 d->autoScroll =
false;
637 TQTimer::singleShot( 400,
this, TQ_SLOT( autoScrollBack() ) );
640void KoTabBar::autoScrollForward()
642 if( !d->autoScroll )
return;
647 d->autoScroll =
false;
649 TQTimer::singleShot( 400,
this, TQ_SLOT( autoScrollForward() ) );
652void KoTabBar::paintEvent( TQPaintEvent* )
654 if ( d->tabs.count() == 0 )
661 TQPixmap pm( size() );
662 pm.fill( colorGroup().background() );
663 painter.begin( &pm,
this );
665 painter.setPen( colorGroup().dark() );
666 painter.drawLine( 0, 0, width(), 0 );
668 if( !d->reverseLayout )
669 painter.translate( 5, 0 );
675 for(
int c = d->tabRects.count()-1; c>=0; c-- )
677 TQRect rect = d->tabRects[ c ];
678 if( rect.isNull() )
continue;
679 TQString text = d->tabs[ c ];
680 d->drawTab( painter, rect, text,
false );
684 if( d->activeTab > 0 )
686 TQRect rect = d->tabRects[ d->activeTab-1 ];
689 TQString text = d->tabs[ d->activeTab-1 ];
690 d->drawTab( painter, rect, text,
true );
695 if( d->targetTab > 0 )
697 int p = TQMIN( d->targetTab, (
int)d->tabRects.count() );
698 TQRect rect = d->tabRects[ p-1 ];
701 int x = !d->reverseLayout ? rect.x() : rect.right()-7;
702 if( d->targetTab > (
int)d->tabRects.count() )
703 x = !d->reverseLayout ? rect.right()-7 : rect.x()-3;
704 d->drawMoveMarker( painter, x, rect.y() );
710 if( !d->reverseLayout )
711 bitBlt(
this, d->offset, 0, &pm );
713 bitBlt(
this, 0, 0, &pm );
717void KoTabBar::resizeEvent( TQResizeEvent* )
724TQSize KoTabBar::sizeHint()
const
726 return TQSize( 40, style().pixelMetric( TQStyle::PM_ScrollBarExtent,
this ) );
731 TQStringList::Iterator it = d->tabs.find( old_name );
739 if( d->activeTab == 0 )
742 return d->tabs[ d->activeTab ];
745void KoTabBar::mousePressEvent( TQMouseEvent* ev )
747 if ( d->tabs.count() == 0 )
755 TQPoint pos = ev->pos();
756 if( !d->reverseLayout ) pos = pos - TQPoint( d->offset,0 );
758 int tab = d->tabAt( pos ) + 1;
759 if( ( tab > 0 ) && ( tab != d->activeTab ) )
767 if( d->tabRects[ tab-1 ].right() > width() - d->offset )
771 if( ev->button() == TQt::RightButton )
776void KoTabBar::mouseReleaseEvent( TQMouseEvent* ev )
778 if ( d->readOnly )
return;
780 d->autoScroll =
false;
782 if ( ev->button() == TQt::LeftButton && d->targetTab != 0 )
784 emit
tabMoved( d->activeTab-1, d->targetTab-1 );
789void KoTabBar::mouseMoveEvent( TQMouseEvent* ev )
791 if ( d->readOnly )
return;
793 TQPoint pos = ev->pos();
794 if( !d->reverseLayout) pos = pos - TQPoint( d->offset,0 );
797 int i = d->tabAt( pos ) + 1;
798 if( ( i > 0 ) && ( i != d->targetTab ) )
800 if( i == d->activeTab ) i = 0;
801 if( i == d->activeTab+1 ) i = 0;
803 if( i != d->targetTab )
806 d->autoScroll =
false;
813 TQRect r = d->tabRects[ d->tabRects.count()-1 ];
814 bool moveToLast =
false;
817 if( !d->reverseLayout )
818 if( pos.x() > r.right() )
819 if( pos.x() < width() )
821 if( d->reverseLayout )
822 if( pos.x() < r.x() )
827 if( d->targetTab != (
int)d->tabRects.count()+1 )
829 d->targetTab = d->tabRects.count()+1;
830 d->autoScroll =
false;
835 if ( pos.x() < 0 && !d->autoScroll )
837 d->autoScroll =
true;
842 int w = width() - d->offset;
843 if ( pos.x() > w && !d->autoScroll )
845 d->autoScroll =
true;
850void KoTabBar::mouseDoubleClickEvent( TQMouseEvent* ev )
852 int offset = d->reverseLayout ? 0 : d->offset;
853 if( ev->pos().x() > offset )
858void KoTabBar::wheelEvent( TQWheelEvent * e )
860 if ( d->tabs.count() == 0 )
870 const int deltaRequired = 120;
872 d->wheelDelta += e->delta();
873 int tabDelta = - (d->wheelDelta / deltaRequired);
874 d->wheelDelta = d->wheelDelta % deltaRequired;
875 int numTabs = d->tabs.size();
877 if(d->activeTab + tabDelta > numTabs)
880 d->activeTab = numTabs;
882 else if (d->activeTab + tabDelta < 1)
889 d->activeTab = d->activeTab + tabDelta;
896 int activeTabRight = d->tabRects[ d->activeTab-1 ].right();
897 int activeTabLeft = d->tabRects[ d->activeTab-1 ].left();
898 if(tabDelta > 0 && activeTabRight > width() - d->offset )
902 else if(tabDelta < 0 && activeTabLeft < width() - d->offset )
912#include "KoTabBar.moc"
void removeTab(const TQString &text)
Removes a tab from the bar.
void scrollFirst()
Scrolls to the first tab.
void tabMoved(unsigned tab, unsigned target)
This signal is emitted whenever a tab is dragged, moved and released.
void setReadOnly(bool ro)
Sets the tab bar to be read only.
KoTabBar(TQWidget *parent=0, const char *name=0)
Creates a new tabbar.
void doubleClicked()
This signal is emitted whenever the tab bar is double-clicked.
void setActiveTab(const TQString &text)
Sets active tab.
TQString activeTab() const
Returns the active tab.
TQStringList tabs() const
Returns all the tab as list of strings.
void clear()
Removes all tabs.
void setReverseLayout(bool reverse)
If reverse is true, dialogs and scroll buttonswidgets will be laid out in a mirrored as if the sheet ...
void moveTab(unsigned tab, unsigned target)
Moves a tab to another position and reorder other tabs.
void ensureVisible(const TQString &tab)
Ensures that specified tab is visible.
void addTab(const TQString &text)
Adds a tab to the tab bar.
void scrollForward()
Scrolls one tab forward.
void renameTab(const TQString &old_name, const TQString &new_name)
Renames a tab.
bool canScrollBack() const
Returns true if it is possible to scroll one tab back.
bool canScrollForward() const
Returns true if it is possible to scroll one tab forward.
void contextMenu(const TQPoint &pos)
This signal is emitted whenever the tab bar is right-clicked.
unsigned count() const
Returns number of tabs.
void setTabs(const TQStringList &list)
Replaces all tabs with the list of strings.
bool reverseLayout() const
Returns true if tabs and scroll buttons will be laid out in a mirrored (right to left) fashion.
void scrollBack()
Scrolls one tab back.
void tabChanged(const TQString &_text)
Emitted if the active tab changed.
void scrollLast()
Scrolls to the last tab.
bool readOnly() const
Returns true if the tab bar is read only.
virtual ~KoTabBar()
Destroy the tabbar.