update dev300-m58
[ooovba.git] / svtools / source / control / tabbar.cxx
blobbfa682501af409b36c9fc427c63895a280b143b4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tabbar.cxx,v $
10 * $Revision: 1.21.100.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #include "tabbar.hxx"
35 #include <tools/time.hxx>
36 #include <tools/debug.hxx>
37 #include <tools/poly.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/help.hxx>
40 #include <vcl/decoview.hxx>
41 #include <vcl/button.hxx>
42 #include <vcl/edit.hxx>
43 #include "svtaccessiblefactory.hxx"
45 // =======================================================================
47 #define TABBAR_OFFSET_X 7
48 #define TABBAR_OFFSET_X2 2
49 #define TABBAR_DRAG_SCROLLOFF 5
50 #define TABBAR_MINSIZE 5
52 const USHORT ADDNEWPAGE_AREAWIDTH = 10;
54 // =======================================================================
56 struct ImplTabBarItem
58 USHORT mnId;
59 TabBarPageBits mnBits;
60 XubString maText;
61 XubString maHelpText;
62 Rectangle maRect;
63 long mnWidth;
64 ULONG mnHelpId;
65 BOOL mbShort;
66 BOOL mbSelect;
67 BOOL mbEnable;
68 Color maTabBgColor;
69 bool IsDefaultTabBgColor() const { return maTabBgColor == Color(COL_AUTO) ? TRUE : FALSE; };
70 Color maTabTextColor;
71 bool IsDefaultTabTextColor() const { return maTabTextColor == Color(COL_AUTO) ? TRUE : FALSE; };
73 ImplTabBarItem( USHORT nItemId, const XubString& rText,
74 TabBarPageBits nPageBits ) :
75 maText( rText )
77 mnId = nItemId;
78 mnBits = nPageBits;
79 mnWidth = 0;
80 mnHelpId = 0;
81 mbShort = FALSE;
82 mbSelect = FALSE;
83 mbEnable = TRUE;
84 maTabBgColor = Color( COL_AUTO );
85 maTabTextColor = Color( COL_AUTO );
89 DECLARE_LIST( ImplTabBarList, ImplTabBarItem* )
91 // =======================================================================
93 // -----------------
94 // - ImplTabButton -
95 // -----------------
97 class ImplTabButton : public PushButton
99 public:
100 ImplTabButton( TabBar* pParent, WinBits nWinStyle = 0 ) :
101 PushButton( pParent, nWinStyle | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS ) {}
103 TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
105 virtual long PreNotify( NotifyEvent& rNEvt );
108 // =======================================================================
110 long ImplTabButton::PreNotify( NotifyEvent& rNEvt )
112 if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
114 if ( GetParent()->IsInEditMode() )
116 GetParent()->EndEditMode();
117 return TRUE;
121 return PushButton::PreNotify( rNEvt );
124 // =======================================================================
126 // ----------------
127 // - ImplTabSizer -
128 // ----------------
130 class ImplTabSizer : public Window
132 public:
133 ImplTabSizer( TabBar* pParent, WinBits nWinStyle = 0 );
135 TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
137 private:
138 void ImplTrack( const Point& rScreenPos );
140 virtual void MouseButtonDown( const MouseEvent& rMEvt );
141 virtual void Tracking( const TrackingEvent& rTEvt );
142 virtual void Paint( const Rectangle& rRect );
144 Point maStartPos;
145 long mnStartWidth;
148 // -----------------------------------------------------------------------
150 ImplTabSizer::ImplTabSizer( TabBar* pParent, WinBits nWinStyle ) :
151 Window( pParent, nWinStyle & WB_3DLOOK )
153 SetPointer( Pointer( POINTER_HSIZEBAR ) );
154 SetSizePixel( Size( 7, 0 ) );
157 // -----------------------------------------------------------------------
159 void ImplTabSizer::ImplTrack( const Point& rScreenPos )
161 TabBar* pParent = GetParent();
162 long nDiff = rScreenPos.X() - maStartPos.X();
163 pParent->mnSplitSize = mnStartWidth + (pParent->IsMirrored() ? -nDiff : nDiff);
164 if ( pParent->mnSplitSize < TABBAR_MINSIZE )
165 pParent->mnSplitSize = TABBAR_MINSIZE;
166 pParent->Split();
167 pParent->Update();
170 // -----------------------------------------------------------------------
172 void ImplTabSizer::MouseButtonDown( const MouseEvent& rMEvt )
174 if ( GetParent()->IsInEditMode() )
176 GetParent()->EndEditMode();
177 return;
180 if ( rMEvt.IsLeft() )
182 maStartPos = OutputToScreenPixel( rMEvt.GetPosPixel() );
183 mnStartWidth = GetParent()->GetSizePixel().Width();
184 StartTracking();
188 // -----------------------------------------------------------------------
190 void ImplTabSizer::Tracking( const TrackingEvent& rTEvt )
192 if ( rTEvt.IsTrackingEnded() )
194 if ( rTEvt.IsTrackingCanceled() )
195 ImplTrack( maStartPos );
196 GetParent()->mnSplitSize = 0;
198 else
199 ImplTrack( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
202 // -----------------------------------------------------------------------
204 void ImplTabSizer::Paint( const Rectangle& )
206 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
207 DecorationView aDecoView( this );
208 long nOffX = 0;
209 Size aOutputSize = GetOutputSizePixel();
211 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
213 SetLineColor( rStyleSettings.GetDarkShadowColor() );
214 DrawLine( Point( 0, 0 ), Point( 0, aOutputSize.Height()-1 ) );
215 nOffX++;
216 aOutputSize.Width()--;
218 aDecoView.DrawButton( Rectangle( Point( nOffX, 0 ), aOutputSize ), BUTTON_DRAW_NOLIGHTBORDER );
221 // =======================================================================
223 // Heisst nicht Impl, da evtl. mal von aussen benutz- und ueberladbar
225 // --------------
226 // - TabBarEdit -
227 // --------------
229 class TabBarEdit : public Edit
231 private:
232 Timer maLoseFocusTimer;
233 BOOL mbPostEvt;
235 DECL_LINK( ImplEndEditHdl, void* );
236 DECL_LINK( ImplEndTimerHdl, void* );
238 public:
239 TabBarEdit( TabBar* pParent, WinBits nWinStyle = 0 );
241 TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
243 void SetPostEvent() { mbPostEvt = TRUE; }
244 void ResetPostEvent() { mbPostEvt = FALSE; }
246 virtual long PreNotify( NotifyEvent& rNEvt );
247 virtual void LoseFocus();
250 // -----------------------------------------------------------------------
252 TabBarEdit::TabBarEdit( TabBar* pParent, WinBits nWinStyle ) :
253 Edit( pParent, nWinStyle )
255 mbPostEvt = FALSE;
258 // -----------------------------------------------------------------------
260 long TabBarEdit::PreNotify( NotifyEvent& rNEvt )
262 if ( rNEvt.GetType() == EVENT_KEYINPUT )
264 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
265 if ( !pKEvt->GetKeyCode().GetModifier() )
267 if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
269 if ( !mbPostEvt )
271 if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)FALSE ) )
272 mbPostEvt = TRUE;
274 return TRUE;
276 else if ( pKEvt->GetKeyCode().GetCode() == KEY_ESCAPE )
278 if ( !mbPostEvt )
280 if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)TRUE ) )
281 mbPostEvt = TRUE;
283 return TRUE;
288 return Edit::PreNotify( rNEvt );
291 // -----------------------------------------------------------------------
293 void TabBarEdit::LoseFocus()
295 if ( !mbPostEvt )
297 if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)FALSE ) )
298 mbPostEvt = TRUE;
301 Edit::LoseFocus();
304 // -----------------------------------------------------------------------
306 IMPL_LINK( TabBarEdit, ImplEndEditHdl, void*, pCancel )
308 ResetPostEvent();
309 maLoseFocusTimer.Stop();
311 // We need this query, because the edit get a losefous event,
312 // when it shows the context menu or the insert symbol dialog
313 if ( !HasFocus() && HasChildPathFocus( TRUE ) )
315 maLoseFocusTimer.SetTimeout( 30 );
316 maLoseFocusTimer.SetTimeoutHdl( LINK( this, TabBarEdit, ImplEndTimerHdl ) );
317 maLoseFocusTimer.Start();
319 else
320 GetParent()->EndEditMode( pCancel != 0 );
322 return 0;
325 // -----------------------------------------------------------------------
327 IMPL_LINK( TabBarEdit, ImplEndTimerHdl, void*, EMPTYARG )
329 if ( HasFocus() )
330 return 0;
332 // We need this query, because the edit get a losefous event,
333 // when it shows the context menu or the insert symbol dialog
334 if ( HasChildPathFocus( TRUE ) )
335 maLoseFocusTimer.Start();
336 else
337 GetParent()->EndEditMode( TRUE );
339 return 0;
342 // =======================================================================
343 struct TabBar_Impl
345 ImplTabSizer* mpSizer;
346 ::svt::AccessibleFactoryAccess maAccessibleFactory;
348 TabBar_Impl()
349 :mpSizer( NULL )
352 ~TabBar_Impl()
354 delete mpSizer;
358 // =======================================================================
360 void TabBar::ImplInit( WinBits nWinStyle )
362 mpItemList = new ImplTabBarList;
363 mpFirstBtn = NULL;
364 mpPrevBtn = NULL;
365 mpNextBtn = NULL;
366 mpLastBtn = NULL;
367 mpImpl = new TabBar_Impl;
368 mpEdit = NULL;
369 mnMaxPageWidth = 0;
370 mnCurMaxWidth = 0;
371 mnOffX = 0;
372 mnOffY = 0;
373 mnLastOffX = 0;
374 mnSplitSize = 0;
375 mnSwitchTime = 0;
376 mnWinStyle = nWinStyle;
377 mnCurPageId = 0;
378 mnFirstPos = 0;
379 mnDropPos = 0;
380 mnSwitchId = 0;
381 mnEditId = 0;
382 mbFormat = TRUE;
383 mbFirstFormat = TRUE;
384 mbSizeFormat = TRUE;
385 mbAutoMaxWidth = TRUE;
386 mbInSwitching = FALSE;
387 mbAutoEditMode = FALSE;
388 mbEditCanceled = FALSE;
389 mbDropPos = FALSE;
390 mbInSelect = FALSE;
391 mbSelColor = FALSE;
392 mbSelTextColor = FALSE;
393 mbMirrored = FALSE;
395 if ( nWinStyle & WB_3DTAB )
396 mnOffY++;
398 ImplInitControls();
399 SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
400 ImplInitSettings( TRUE, TRUE );
403 // -----------------------------------------------------------------------
405 TabBar::TabBar( Window* pParent, WinBits nWinStyle ) :
406 Window( pParent, (nWinStyle & WB_3DLOOK) | WB_CLIPCHILDREN )
408 ImplInit( nWinStyle );
411 // -----------------------------------------------------------------------
413 TabBar::~TabBar()
415 EndEditMode( TRUE );
417 // Controls loeschen
418 if ( mpPrevBtn )
419 delete mpPrevBtn;
420 if ( mpNextBtn )
421 delete mpNextBtn;
422 if ( mpFirstBtn )
423 delete mpFirstBtn;
424 if ( mpLastBtn )
425 delete mpLastBtn;
426 delete mpImpl;
428 // Alle Items loeschen
429 ImplTabBarItem* pItem = mpItemList->First();
430 while ( pItem )
432 delete pItem;
433 pItem = mpItemList->Next();
436 // Itemlist loeschen
437 delete mpItemList;
440 // -----------------------------------------------------------------------
442 void TabBar::ImplInitSettings( BOOL bFont, BOOL bBackground )
444 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
446 if ( bFont )
448 Font aToolFont;
449 aToolFont = rStyleSettings.GetToolFont();
450 if ( IsControlFont() )
451 aToolFont.Merge( GetControlFont() );
452 aToolFont.SetWeight( WEIGHT_BOLD );
453 SetZoomedPointFont( aToolFont );
455 // Font in der groesse Anpassen, wenn Fenster zu klein?
456 while ( GetTextHeight() > (GetOutputSizePixel().Height()-1) )
458 Font aFont = GetFont();
459 if ( aFont.GetHeight() <= 6 )
460 break;
461 aFont.SetHeight( aFont.GetHeight()-1 );
462 SetFont( aFont );
466 if ( bBackground )
468 Color aColor;
469 if ( IsControlBackground() )
470 aColor = GetControlBackground();
471 else
472 aColor = rStyleSettings.GetFaceColor();
473 SetBackground( aColor );
477 // -----------------------------------------------------------------------
479 void TabBar::ImplGetColors( Color& rFaceColor, Color& rFaceTextColor,
480 Color& rSelectColor, Color& rSelectTextColor )
482 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
484 if ( IsControlBackground() )
485 rFaceColor = GetControlBackground();
486 else
487 rFaceColor = rStyleSettings.GetInactiveTabColor();
488 if ( IsControlForeground() )
489 rFaceTextColor = GetControlForeground();
490 else
491 rFaceTextColor = rStyleSettings.GetButtonTextColor();
492 if ( mbSelColor )
493 rSelectColor = maSelColor;
494 else
495 rSelectColor = rStyleSettings.GetActiveTabColor();
496 if ( mbSelTextColor )
497 rSelectTextColor = maSelTextColor;
498 else
499 rSelectTextColor = rStyleSettings.GetWindowTextColor();
501 // Bei 3D-Tabs wird Selektions- und Face-Farbe umgedreht, da die
502 // selektierten Tabs in 3D erscheinen sollen
503 if ( mnWinStyle & WB_3DTAB )
505 Color aTempColor = rFaceColor;
506 rFaceColor = rSelectColor;
507 rSelectColor = aTempColor;
508 aTempColor = rFaceTextColor;
509 rFaceTextColor = rSelectTextColor;
510 rSelectTextColor = rFaceTextColor;
514 // -----------------------------------------------------------------------
516 BOOL TabBar::ImplCalcWidth()
518 // Groessen muessen nur ermittelt werden, wenn sich Text aendert oder
519 // wenn der Font geaendert wurde
520 if ( !mbSizeFormat )
521 return FALSE;
523 // Breiten der Tabs mit dem fetten Font ermitteln
524 Font aFont = GetFont();
525 if ( aFont.GetWeight() != WEIGHT_BOLD )
527 aFont.SetWeight( WEIGHT_BOLD );
528 SetFont( aFont );
531 if ( mnMaxPageWidth )
532 mnCurMaxWidth = mnMaxPageWidth;
533 else if ( mbAutoMaxWidth )
535 mnCurMaxWidth = mnLastOffX-mnOffX-
536 TABBAR_OFFSET_X-TABBAR_OFFSET_X-
537 TABBAR_OFFSET_X2-TABBAR_OFFSET_X2-TABBAR_OFFSET_X2;
538 if ( mnCurMaxWidth < 1 )
539 mnCurMaxWidth = 1;
541 else
542 mnCurMaxWidth = 0;
544 BOOL bChanged = FALSE;
545 ImplTabBarItem* pItem = mpItemList->First();
546 while ( pItem )
548 long nNewWidth = GetTextWidth( pItem->maText );
549 if ( mnCurMaxWidth && (nNewWidth > mnCurMaxWidth) )
551 pItem->mbShort = TRUE;
552 nNewWidth = mnCurMaxWidth;
554 else
555 pItem->mbShort = FALSE;
556 nNewWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
557 if ( pItem->mnWidth != nNewWidth )
559 pItem->mnWidth = nNewWidth;
560 if ( !pItem->maRect.IsEmpty() )
561 bChanged = TRUE;
563 pItem = mpItemList->Next();
565 mbSizeFormat = FALSE;
566 mbFormat = TRUE;
567 return bChanged;
570 // -----------------------------------------------------------------------
572 void TabBar::ImplFormat()
574 ImplCalcWidth();
576 if ( !mbFormat )
577 return;
579 USHORT n = 0;
580 long x = mnOffX;
581 ImplTabBarItem* pItem = mpItemList->First();
582 while ( pItem )
584 // Bei allen nicht sichtbaren Tabs, wird ein leeres Rechteck
585 // gesetzt
586 if ( (n+1 < mnFirstPos) || (x > mnLastOffX) )
587 pItem->maRect.SetEmpty();
588 else
590 // Etwas von der Tab vor der ersten sichtbaren Page
591 // muss auch zu sehen sein
592 if ( n+1 == mnFirstPos )
593 pItem->maRect.Left() = x-pItem->mnWidth;
594 else
596 pItem->maRect.Left() = x;
597 x += pItem->mnWidth;
599 pItem->maRect.Right() = x+TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
600 pItem->maRect.Bottom() = maWinSize.Height()-1;
602 if( mbMirrored )
604 long nTmp = mnOffX + mnLastOffX - pItem->maRect.Right();
605 pItem->maRect.Right() = mnOffX + mnLastOffX - pItem->maRect.Left();
606 pItem->maRect.Left() = nTmp;
610 n++;
611 pItem = mpItemList->Next();
614 mbFormat = FALSE;
616 // Button enablen/disablen
617 ImplEnableControls();
620 // -----------------------------------------------------------------------
622 USHORT TabBar::ImplGetLastFirstPos()
624 USHORT nCount = (USHORT)(mpItemList->Count());
625 if ( !nCount || mbSizeFormat || mbFormat )
626 return 0;
628 USHORT nLastFirstPos = nCount-1;
629 long nWinWidth = mnLastOffX-mnOffX-TABBAR_OFFSET_X-ADDNEWPAGE_AREAWIDTH;
630 long nWidth = mpItemList->GetObject( nLastFirstPos )->mnWidth;
631 while ( nLastFirstPos && (nWidth < nWinWidth) )
633 nLastFirstPos--;
634 nWidth += mpItemList->GetObject( nLastFirstPos )->mnWidth;
636 if ( (nLastFirstPos != (USHORT)(mpItemList->Count()-1)) &&
637 (nWidth > nWinWidth) )
638 nLastFirstPos++;
639 return nLastFirstPos;
642 // -----------------------------------------------------------------------
644 void TabBar::ImplInitControls()
646 if ( mnWinStyle & WB_SIZEABLE )
648 if ( !mpImpl->mpSizer )
649 mpImpl->mpSizer = new ImplTabSizer( this, mnWinStyle & (WB_DRAG | WB_3DLOOK) );
650 mpImpl->mpSizer->Show();
652 else
654 DELETEZ( mpImpl->mpSizer );
657 Link aLink = LINK( this, TabBar, ImplClickHdl );
659 if ( mnWinStyle & (WB_MINSCROLL | WB_SCROLL) )
661 if ( !mpPrevBtn )
663 mpPrevBtn = new ImplTabButton( this, WB_REPEAT );
664 mpPrevBtn->SetClickHdl( aLink );
666 mpPrevBtn->SetSymbol( mbMirrored ? SYMBOL_NEXT : SYMBOL_PREV );
667 mpPrevBtn->Show();
669 if ( !mpNextBtn )
671 mpNextBtn = new ImplTabButton( this, WB_REPEAT );
672 mpNextBtn->SetClickHdl( aLink );
674 mpNextBtn->SetSymbol( mbMirrored ? SYMBOL_PREV : SYMBOL_NEXT );
675 mpNextBtn->Show();
677 else
679 DELETEZ( mpPrevBtn );
680 DELETEZ( mpNextBtn );
683 if ( mnWinStyle & WB_SCROLL )
685 if ( !mpFirstBtn )
687 mpFirstBtn = new ImplTabButton( this );
688 mpFirstBtn->SetClickHdl( aLink );
690 mpFirstBtn->SetSymbol( mbMirrored ? SYMBOL_LAST : SYMBOL_FIRST );
691 mpFirstBtn->Show();
693 if ( !mpLastBtn )
695 mpLastBtn = new ImplTabButton( this );
696 mpLastBtn->SetClickHdl( aLink );
698 mpLastBtn->SetSymbol( mbMirrored ? SYMBOL_FIRST : SYMBOL_LAST );
699 mpLastBtn->Show();
701 else
703 DELETEZ( mpFirstBtn );
704 DELETEZ( mpLastBtn );
708 // -----------------------------------------------------------------------
710 void TabBar::ImplEnableControls()
712 if ( mbSizeFormat || mbFormat )
713 return;
715 // Buttons enablen/disblen
716 BOOL bEnableBtn = mnFirstPos > 0;
717 if ( mpFirstBtn )
718 mpFirstBtn->Enable( bEnableBtn );
719 if ( mpPrevBtn )
720 mpPrevBtn->Enable( bEnableBtn );
722 bEnableBtn = mnFirstPos < ImplGetLastFirstPos();
723 if ( mpNextBtn )
724 mpNextBtn->Enable( bEnableBtn );
725 if ( mpLastBtn )
726 mpLastBtn->Enable( bEnableBtn );
729 // -----------------------------------------------------------------------
731 void TabBar::ImplShowPage( USHORT nPos )
733 // Breite berechnen
734 long nWidth = GetOutputSizePixel().Width();
735 if ( nWidth >= TABBAR_OFFSET_X )
736 nWidth -= TABBAR_OFFSET_X;
737 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
738 if ( nPos < mnFirstPos )
739 SetFirstPageId( pItem->mnId );
740 else if ( pItem->maRect.Right() > nWidth )
742 while ( pItem->maRect.Right() > nWidth )
744 USHORT nNewPos = mnFirstPos+1;
745 SetFirstPageId( GetPageId( nNewPos ) );
746 ImplFormat();
747 if ( nNewPos != mnFirstPos )
748 break;
753 // -----------------------------------------------------------------------
755 IMPL_LINK( TabBar, ImplClickHdl, ImplTabButton*, pBtn )
757 EndEditMode();
759 USHORT nNewPos = mnFirstPos;
761 if ( pBtn == mpFirstBtn )
762 nNewPos = 0;
763 else if ( pBtn == mpPrevBtn )
765 if ( mnFirstPos )
766 nNewPos = mnFirstPos-1;
768 else if ( pBtn == mpNextBtn )
770 USHORT nCount = GetPageCount();
771 if ( mnFirstPos < nCount )
772 nNewPos = mnFirstPos+1;
774 else
776 USHORT nCount = GetPageCount();
777 if ( nCount )
778 nNewPos = nCount-1;
781 if ( nNewPos != mnFirstPos )
782 SetFirstPageId( GetPageId( nNewPos ) );
783 return 0;
786 // -----------------------------------------------------------------------
788 void TabBar::MouseMove( const MouseEvent& rMEvt )
790 if ( rMEvt.IsLeaveWindow() )
791 mbInSelect = FALSE;
793 Window::MouseMove( rMEvt );
796 // -----------------------------------------------------------------------
798 void TabBar::MouseButtonDown( const MouseEvent& rMEvt )
800 // Bei Klick in unser Fenster EditModus nur beenden und Klick nicht
801 // ausfuehren
802 if ( IsInEditMode() )
804 EndEditMode();
805 return;
808 ImplTabBarItem* pItem;
809 USHORT nSelId = GetPageId( rMEvt.GetPosPixel() );
811 if ( !rMEvt.IsLeft() )
813 Window::MouseButtonDown( rMEvt );
814 if ( (nSelId > 0) && (nSelId != mnCurPageId) )
816 USHORT nPos = GetPagePos( nSelId );
817 pItem = mpItemList->GetObject( nPos );
819 if ( pItem->mbEnable )
821 if ( ImplDeactivatePage() )
823 SetCurPageId( nSelId );
824 Update();
825 ImplActivatePage();
826 ImplSelect();
828 mbInSelect = TRUE;
831 return;
834 if ( rMEvt.IsMod2() && mbAutoEditMode && nSelId )
836 if ( StartEditMode( nSelId ) )
837 return;
840 if ( (rMEvt.GetMode() & (MOUSE_MULTISELECT | MOUSE_RANGESELECT)) && (rMEvt.GetClicks() == 1) )
842 if ( nSelId )
844 USHORT nPos = GetPagePos( nSelId );
845 BOOL bSelectTab = FALSE;
846 pItem = mpItemList->GetObject( nPos );
848 if ( pItem->mbEnable )
850 if ( (rMEvt.GetMode() & MOUSE_MULTISELECT) && (mnWinStyle & WB_MULTISELECT) )
852 if ( nSelId != mnCurPageId )
854 SelectPage( nSelId, !IsPageSelected( nSelId ) );
855 bSelectTab = TRUE;
858 else if ( mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT) )
860 bSelectTab = TRUE;
861 USHORT n;
862 BOOL bSelect;
863 USHORT nCurPos = GetPagePos( mnCurPageId );
864 if ( nPos <= nCurPos )
866 // Alle Tabs bis zur angeklickten Tab deselektieren
867 // und alle Tabs von der angeklickten Tab bis
868 // zur aktuellen Position selektieren
869 n = 0;
870 while ( n < nCurPos )
872 pItem = mpItemList->GetObject( n );
873 if ( n < nPos )
874 bSelect = FALSE;
875 else
876 bSelect = TRUE;
878 if ( pItem->mbSelect != bSelect )
880 pItem->mbSelect = bSelect;
881 if ( !pItem->maRect.IsEmpty() )
882 Invalidate( pItem->maRect );
885 n++;
889 if ( nPos >= nCurPos )
891 // Alle Tabs von der aktuellen bis zur angeklickten
892 // Tab selektieren und alle Tabs von der angeklickten
893 // Tab bis zur letzten Tab deselektieren
894 USHORT nCount = (USHORT)mpItemList->Count();
895 n = nCurPos;
896 while ( n < nCount )
898 pItem = mpItemList->GetObject( n );
900 if ( n <= nPos )
901 bSelect = TRUE;
902 else
903 bSelect = FALSE;
905 if ( pItem->mbSelect != bSelect )
907 pItem->mbSelect = bSelect;
908 if ( !pItem->maRect.IsEmpty() )
909 Invalidate( pItem->maRect );
912 n++;
917 // Gegebenenfalls muss die selektierte Tab gescrollt werden
918 if ( bSelectTab )
920 ImplShowPage( nPos );
921 Update();
922 ImplSelect();
925 else
926 ImplShowPage( nPos );
927 mbInSelect = TRUE;
929 return;
932 else if ( rMEvt.GetClicks() == 2 )
934 // Gegebenenfalls den Double-Click-Handler rufen
935 if ( !rMEvt.GetModifier() && (!nSelId || (nSelId == mnCurPageId)) )
937 USHORT nOldCurId = mnCurPageId;
938 mnCurPageId = nSelId;
939 DoubleClick();
940 // Abfrage, da im DoubleClick-Handler die aktuelle Seite
941 // umgeschaltet werden konnte
942 if ( mnCurPageId == nSelId )
943 mnCurPageId = nOldCurId;
946 return;
948 else
950 if ( nSelId )
952 // Nur Select ausfuehren, wenn noch nicht aktuelle Page
953 if ( nSelId != mnCurPageId )
955 USHORT nPos = GetPagePos( nSelId );
956 pItem = mpItemList->GetObject( nPos );
958 if ( pItem->mbEnable )
960 if ( !pItem->mbSelect )
962 // Muss invalidiert werden
963 BOOL bUpdate = FALSE;
964 if ( IsReallyVisible() && IsUpdateMode() )
965 bUpdate = TRUE;
967 // Alle selektierten Items deselektieren
968 pItem = mpItemList->First();
969 while ( pItem )
971 if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
973 pItem->mbSelect = FALSE;
974 if ( bUpdate )
975 Invalidate( pItem->maRect );
978 pItem = mpItemList->Next();
982 if ( ImplDeactivatePage() )
984 SetCurPageId( nSelId );
985 Update();
986 ImplActivatePage();
987 ImplSelect();
990 else
991 ImplShowPage( nPos );
992 mbInSelect = TRUE;
995 return;
999 Window::MouseButtonDown( rMEvt );
1002 // -----------------------------------------------------------------------
1004 void TabBar::MouseButtonUp( const MouseEvent& rMEvt )
1006 mbInSelect = FALSE;
1007 Window::MouseButtonUp( rMEvt );
1010 // -----------------------------------------------------------------------
1012 void TabBar::Paint( const Rectangle& )
1014 // Items berechnen und ausgeben
1015 USHORT nItemCount = (USHORT)mpItemList->Count();
1016 ImplTabBarItem* pItem;
1018 // kein Item, dann auch nichts zu tun
1019 if ( nItemCount )
1021 // TabBar muss formatiert sein
1022 ImplFormat();
1024 // Beim ersten Format auch dafuer sorgen, das aktuelle TabPage
1025 // sichtbar wird
1026 if ( mbFirstFormat )
1028 mbFirstFormat = FALSE;
1030 if ( mnCurPageId && (mnFirstPos == 0) && !mbDropPos )
1032 pItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) );
1033 if ( pItem->maRect.IsEmpty() )
1035 // mbDropPos setzen (bzw. misbrauchen) um Invalidate()
1036 // zu unterbinden
1037 mbDropPos = TRUE;
1038 SetFirstPageId( mnCurPageId );
1039 mbDropPos = FALSE;
1040 if ( mnFirstPos != 0 )
1041 ImplFormat();
1047 // Farben ermitteln
1048 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1049 Color aFaceColor;
1050 Color aSelectColor;
1051 Color aFaceTextColor;
1052 Color aSelectTextColor;
1053 ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
1055 // Font selektieren
1056 Font aFont = GetFont();
1057 Font aLightFont = aFont;
1058 //aLightFont.SetWeight( WEIGHT_LIGHT ); //TODO Make font weight light on custom color only?
1059 aLightFont.SetWeight( WEIGHT_NORMAL );
1061 // #i36013# exclude push buttons from painting area
1062 Rectangle aClipRect( Point( mnOffX, 0 ), Point( mnLastOffX, GetOutputHeightPixel() - 1 ) );
1063 SetClipRegion( Region( aClipRect ) );
1065 // Bei Border oben und unten einen Strich extra malen
1066 if ( (mnWinStyle & WB_BORDER) || (mnWinStyle & WB_TOPBORDER) )
1068 Size aOutputSize = GetOutputSizePixel();
1070 // Bei 3D-Tabs wird auch der Border in 3D gemalt
1071 if ( mnWinStyle & WB_3DTAB )
1073 SetLineColor( rStyleSettings.GetShadowColor() );
1074 DrawLine( Point( mnOffX, 0 ), Point( aOutputSize.Width(), 0 ) );
1077 // Border malen (Strich oben und Strich unten)
1078 SetLineColor( rStyleSettings.GetDarkShadowColor() );
1079 DrawLine( Point( mnOffX, mnOffY ), Point( aOutputSize.Width()-1, mnOffY ) );
1081 else
1082 SetLineColor( rStyleSettings.GetDarkShadowColor() );
1084 // Items ausgeben
1085 if ( nItemCount )
1087 // letzten sichtbaren Eintrag suchen
1088 USHORT n = mnFirstPos+1;
1089 if ( n >= nItemCount )
1090 n = nItemCount-1;
1091 pItem = mpItemList->Seek( n );
1092 while ( pItem )
1094 if ( !pItem->maRect.IsEmpty() )
1096 n++;
1097 pItem = mpItemList->Next();
1099 else
1100 break;
1103 // Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt)
1104 if ( pItem )
1105 n--;
1106 else if ( n >= nItemCount )
1107 n = nItemCount-1;
1108 pItem = mpItemList->Seek( n );
1109 ImplTabBarItem* pCurItem = NULL;
1110 while ( pItem )
1112 // CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt
1113 if ( !pCurItem && (pItem->mnId == mnCurPageId) )
1115 pCurItem = pItem;
1116 pItem = mpItemList->Prev();
1117 if ( !pItem )
1118 pItem = pCurItem;
1119 continue;
1122 if ( !pItem->maRect.IsEmpty() )
1124 Rectangle aRect = pItem->maRect;
1126 // Aktuelle Page wird mit einem fetten Font ausgegeben
1127 if ( pItem->mnId == mnCurPageId )
1128 SetFont( aFont );
1129 else
1130 SetFont( aLightFont );
1132 // Je nach Status die richtige FillInBrush setzen
1133 // Set the correct FillInBrush depending upon status
1134 if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
1136 // Currently selected Tab
1137 SetFillColor( aSelectColor );
1138 SetTextColor( aSelectTextColor );
1140 else
1142 if ( !pItem->IsDefaultTabBgColor() )
1144 SetFillColor( pItem->maTabBgColor );
1145 SetTextColor( pItem->maTabTextColor );
1146 } else {
1147 SetFillColor( aFaceColor );
1148 SetTextColor( aFaceTextColor );
1152 // Muss Font Kursiv geschaltet werden
1153 if ( pItem->mnBits & TPB_SPECIAL )
1155 SetTextColor( Color( COL_LIGHTBLUE ) );
1158 // Position der Page berechnen
1159 Point aPos0 = Point( aRect.Left(), mnOffY );
1160 Point aPos1 = Point( aRect.Left()+TABBAR_OFFSET_X, aRect.Bottom() );
1161 Point aPos2 = Point( aRect.Right()-TABBAR_OFFSET_X, aRect.Bottom() );
1162 Point aPos3 = Point( aRect.Right(), mnOffY );
1164 // Zuerst geben wir das Polygon gefuellt aus
1165 Polygon aPoly( 4 );
1166 aPoly[0] = aPos0;
1167 aPoly[1] = aPos1;
1168 aPoly[2] = aPos2;
1169 aPoly[3] = aPos3;
1170 DrawPolygon( aPoly );
1172 // Danach den Text zentiert ausgeben
1173 XubString aText = pItem->maText;
1174 if ( pItem->mbShort )
1175 aText = GetEllipsisString( aText, mnCurMaxWidth, TEXT_DRAW_ENDELLIPSIS );
1176 Size aRectSize = aRect.GetSize();
1177 long nTextWidth = GetTextWidth( aText );
1178 long nTextHeight = GetTextHeight();
1179 Point aTxtPos( aRect.Left()+(aRectSize.Width()-nTextWidth)/2,
1180 (aRectSize.Height()-nTextHeight)/2 );
1181 if ( pItem->IsDefaultTabBgColor() || (!pItem->mbSelect) )
1183 if ( !pItem->mbEnable )
1184 DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC) );
1185 else
1186 DrawText( aTxtPos, aText );
1188 // Jetzt im Inhalt den 3D-Effekt ausgeben
1189 aPos0.X()++;
1190 aPos1.X()++;
1191 aPos2.X()--;
1192 aPos3.X()--;
1194 // If this is the current tab, draw the left inner shadow the default color,
1195 // otherwise make it the same as the custom background color
1196 if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) {
1197 SetLineColor( rStyleSettings.GetLightColor() );
1198 } else {
1199 if ( !pItem->IsDefaultTabBgColor() )
1201 SetLineColor( pItem->maTabBgColor );
1202 } else {
1203 SetLineColor( rStyleSettings.GetLightColor() );
1206 // Draw the left side of the tab
1207 DrawLine( aPos0, aPos1 );
1209 if ( !pItem->mbSelect && (pItem->mnId != mnCurPageId) )
1211 // Draw the top inner shadow
1212 // ToDo: Change from this static color to tab custom bg color
1213 DrawLine( Point( aPos0.X(), aPos0.Y()+1 ),
1214 Point( aPos3.X(), aPos3.Y()+1 ) );
1217 SetLineColor( rStyleSettings.GetShadowColor() );
1218 DrawLine( aPos2, aPos3 );
1219 aPos1.X()--;
1220 aPos1.Y()--;
1221 aPos2.Y()--;
1222 if ( !pItem->IsDefaultTabBgColor() && ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) )
1224 SetLineColor( pItem->maTabBgColor );
1225 DrawLine( Point(aPos1.X()-1, aPos1.Y()-1), Point(aPos2.X(), aPos2.Y()-1) );
1227 DrawLine( aPos1, aPos2 );
1229 // draw a small 2px sliver of the original background color at the bottom of the selected tab
1231 if ( !pItem->IsDefaultTabBgColor() )
1233 if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) ) {
1234 SetLineColor( pItem->maTabBgColor );
1235 DrawLine( Point(aPos1.X()-1, aPos1.Y()-1), Point(aPos2.X(), aPos2.Y()-1) );
1236 if ( !pItem->mbEnable )
1237 DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC) );
1238 else
1239 DrawText( aTxtPos, aText );
1243 // Da etwas uebermalt werden konnte, muessen wir die Polygon-
1244 // umrandung nocheinmal ausgeben
1245 SetLineColor( rStyleSettings.GetDarkShadowColor() );
1246 SetFillColor();
1247 DrawPolygon( aPoly );
1249 // Beim dem aktuellen Tab die restlichten Ausgaben vornehmen und
1250 // die Schleife abbrechen, da die aktuelle Tab als letztes
1251 // ausgegeben wird
1252 if ( pItem == pCurItem )
1254 // Beim aktuellen Item muss der oberstes Strich geloescht
1255 // werden
1256 SetLineColor();
1257 SetFillColor( aSelectColor );
1258 Rectangle aDelRect( aPos0, aPos3 );
1259 DrawRect( aDelRect );
1260 if ( mnWinStyle & WB_3DTAB )
1262 aDelRect.Top()--;
1263 DrawRect( aDelRect );
1266 break;
1269 pItem = mpItemList->Prev();
1271 else
1273 if ( pItem == pCurItem )
1274 break;
1276 pItem = NULL;
1279 if ( !pItem )
1280 pItem = pCurItem;
1284 // Font wieder herstellen
1285 SetFont( aFont );
1286 // remove clip region
1287 SetClipRegion();
1290 // -----------------------------------------------------------------------
1292 void TabBar::Resize()
1294 Size aNewSize = GetOutputSizePixel();
1296 long nSizerWidth = 0;
1297 long nButtonWidth = 0;
1299 // Sizer anordnen
1300 if ( mpImpl->mpSizer )
1302 Size aSizerSize = mpImpl->mpSizer->GetSizePixel();
1303 Point aNewSizerPos( mbMirrored ? 0 : (aNewSize.Width()-aSizerSize.Width()), 0 );
1304 Size aNewSizerSize( aSizerSize.Width(), aNewSize.Height() );
1305 mpImpl->mpSizer->SetPosSizePixel( aNewSizerPos, aNewSizerSize );
1306 nSizerWidth = aSizerSize.Width();
1309 // Scroll-Buttons anordnen
1310 long nHeight = aNewSize.Height();
1311 // Font in der groesse Anpassen?
1312 ImplInitSettings( TRUE, FALSE );
1314 long nX = mbMirrored ? (aNewSize.Width()-nHeight) : 0;
1315 long nXDiff = mbMirrored ? -nHeight : nHeight;
1317 Size aBtnSize( nHeight, nHeight );
1318 if ( mpFirstBtn )
1320 mpFirstBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1321 nX += nXDiff;
1322 nButtonWidth += nHeight;
1324 if ( mpPrevBtn )
1326 mpPrevBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1327 nX += nXDiff;
1328 nButtonWidth += nHeight;
1330 if ( mpNextBtn )
1332 mpNextBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1333 nX += nXDiff;
1334 nButtonWidth += nHeight;
1336 if ( mpLastBtn )
1338 mpLastBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1339 nX += nXDiff;
1340 nButtonWidth += nHeight;
1343 // Groesse merken
1344 maWinSize = aNewSize;
1346 if( mbMirrored )
1348 mnOffX = nSizerWidth;
1349 mnLastOffX = maWinSize.Width() - nButtonWidth - 1;
1351 else
1353 mnOffX = nButtonWidth;
1354 mnLastOffX = maWinSize.Width() - nSizerWidth - 1;
1357 // Neu formatieren
1358 mbSizeFormat = TRUE;
1359 if ( IsReallyVisible() )
1361 if ( ImplCalcWidth() )
1362 Invalidate();
1363 ImplFormat();
1366 // Button enablen/disablen
1367 ImplEnableControls();
1370 // -----------------------------------------------------------------------
1372 void TabBar::RequestHelp( const HelpEvent& rHEvt )
1374 USHORT nItemId = GetPageId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
1375 if ( nItemId )
1377 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
1379 XubString aStr = GetHelpText( nItemId );
1380 if ( aStr.Len() )
1382 Rectangle aItemRect = GetPageRect( nItemId );
1383 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1384 aItemRect.Left() = aPt.X();
1385 aItemRect.Top() = aPt.Y();
1386 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1387 aItemRect.Right() = aPt.X();
1388 aItemRect.Bottom() = aPt.Y();
1389 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
1390 return;
1393 else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
1395 ULONG nHelpId = GetHelpId( nItemId );
1396 if ( nHelpId )
1398 // Wenn eine Hilfe existiert, dann ausloesen
1399 Help* pHelp = Application::GetHelp();
1400 if ( pHelp )
1401 pHelp->Start( nHelpId, this );
1402 return;
1406 // Bei Quick- oder Ballloon-Help zeigen wir den Text an,
1407 // wenn dieser abgeschnitten oder nicht voll sichtbar ist
1408 if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
1410 USHORT nPos = GetPagePos( nItemId );
1411 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1412 if ( pItem->mbShort ||
1413 (pItem->maRect.Right()-TABBAR_OFFSET_X-5 > mnLastOffX) )
1415 Rectangle aItemRect = GetPageRect( nItemId );
1416 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1417 aItemRect.Left() = aPt.X();
1418 aItemRect.Top() = aPt.Y();
1419 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1420 aItemRect.Right() = aPt.X();
1421 aItemRect.Bottom() = aPt.Y();
1422 XubString aStr = mpItemList->GetObject( nPos )->maText;
1423 if ( aStr.Len() )
1425 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
1426 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
1427 else
1428 Help::ShowQuickHelp( this, aItemRect, aStr );
1429 return;
1435 Window::RequestHelp( rHEvt );
1438 // -----------------------------------------------------------------------
1440 void TabBar::StateChanged( StateChangedType nType )
1442 Window::StateChanged( nType );
1444 if ( nType == STATE_CHANGE_INITSHOW )
1446 if ( (mbSizeFormat || mbFormat) && mpItemList->Count() )
1447 ImplFormat();
1449 else if ( (nType == STATE_CHANGE_ZOOM) ||
1450 (nType == STATE_CHANGE_CONTROLFONT) )
1452 ImplInitSettings( TRUE, FALSE );
1453 Invalidate();
1455 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1456 Invalidate();
1457 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1459 ImplInitSettings( FALSE, TRUE );
1460 Invalidate();
1462 else if ( nType == STATE_CHANGE_MIRRORING )
1464 // reacts on calls of EnableRTL, have to mirror all child controls
1465 if( mpFirstBtn ) mpFirstBtn->EnableRTL( IsRTLEnabled() );
1466 if( mpPrevBtn ) mpPrevBtn->EnableRTL( IsRTLEnabled() );
1467 if( mpNextBtn ) mpNextBtn->EnableRTL( IsRTLEnabled() );
1468 if( mpLastBtn ) mpLastBtn->EnableRTL( IsRTLEnabled() );
1469 if( mpImpl->mpSizer ) mpImpl->mpSizer->EnableRTL( IsRTLEnabled() );
1470 if( mpEdit ) mpEdit->EnableRTL( IsRTLEnabled() );
1474 // -----------------------------------------------------------------------
1476 void TabBar::DataChanged( const DataChangedEvent& rDCEvt )
1478 Window::DataChanged( rDCEvt );
1480 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1481 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1482 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1483 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1485 ImplInitSettings( TRUE, TRUE );
1486 Invalidate();
1490 // -----------------------------------------------------------------------
1492 void TabBar::ImplSelect()
1494 Select();
1496 CallEventListeners( VCLEVENT_TABBAR_PAGESELECTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1499 // -----------------------------------------------------------------------
1501 void TabBar::Select()
1503 maSelectHdl.Call( this );
1506 // -----------------------------------------------------------------------
1508 void TabBar::DoubleClick()
1510 maDoubleClickHdl.Call( this );
1513 // -----------------------------------------------------------------------
1515 void TabBar::Split()
1517 maSplitHdl.Call( this );
1520 // -----------------------------------------------------------------------
1522 void TabBar::ImplActivatePage()
1524 ActivatePage();
1526 CallEventListeners( VCLEVENT_TABBAR_PAGEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1529 // -----------------------------------------------------------------------
1531 void TabBar::ActivatePage()
1533 maActivatePageHdl.Call( this );
1536 // -----------------------------------------------------------------------
1538 long TabBar::ImplDeactivatePage()
1540 long nRet = DeactivatePage();
1542 CallEventListeners( VCLEVENT_TABBAR_PAGEDEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1544 return nRet;
1547 // -----------------------------------------------------------------------
1549 long TabBar::DeactivatePage()
1551 if ( maDeactivatePageHdl.IsSet() )
1552 return maDeactivatePageHdl.Call( this );
1553 else
1554 return TRUE;
1557 // -----------------------------------------------------------------------
1559 long TabBar::StartRenaming()
1561 if ( maStartRenamingHdl.IsSet() )
1562 return maStartRenamingHdl.Call( this );
1563 else
1564 return TRUE;
1567 // -----------------------------------------------------------------------
1569 long TabBar::AllowRenaming()
1571 if ( maAllowRenamingHdl.IsSet() )
1572 return maAllowRenamingHdl.Call( this );
1573 else
1574 return TRUE;
1577 // -----------------------------------------------------------------------
1579 void TabBar::EndRenaming()
1581 maEndRenamingHdl.Call( this );
1584 // -----------------------------------------------------------------------
1586 void TabBar::Mirror()
1591 // -----------------------------------------------------------------------
1593 void TabBar::InsertPage( USHORT nPageId, const XubString& rText,
1594 TabBarPageBits nBits, USHORT nPos )
1596 DBG_ASSERT( nPageId, "TabBar::InsertPage(): PageId == 0" );
1597 DBG_ASSERT( GetPagePos( nPageId ) == TABBAR_PAGE_NOTFOUND,
1598 "TabBar::InsertPage(): PageId already exists" );
1599 DBG_ASSERT( nBits <= TPB_SPECIAL, "TabBar::InsertPage(): nBits is wrong" );
1601 // PageItem anlegen und in die Item-Liste eintragen
1602 ImplTabBarItem* pItem = new ImplTabBarItem( nPageId, rText, nBits );
1603 mpItemList->Insert( pItem, nPos );
1604 mbSizeFormat = TRUE;
1606 // CurPageId gegebenenfalls setzen
1607 if ( !mnCurPageId )
1608 mnCurPageId = nPageId;
1610 // Leiste neu ausgeben
1611 if ( IsReallyVisible() && IsUpdateMode() )
1612 Invalidate();
1614 CallEventListeners( VCLEVENT_TABBAR_PAGEINSERTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1617 // -----------------------------------------------------------------------
1619 Color TabBar::GetTabBgColor( USHORT nPageId ) const
1621 USHORT nPos = GetPagePos( nPageId );
1623 if ( nPos != TABBAR_PAGE_NOTFOUND )
1624 return mpItemList->GetObject( nPos )->maTabBgColor;
1625 else
1626 return Color( COL_AUTO );
1629 void TabBar::SetTabBgColor( USHORT nPageId, const Color& aTabBgColor )
1631 USHORT nPos = GetPagePos( nPageId );
1632 ImplTabBarItem* pItem;
1633 if ( nPos != TABBAR_PAGE_NOTFOUND )
1635 pItem = mpItemList->GetObject( nPos );
1636 // TODO: Need to take the text color specification out of this code!
1637 if ( aTabBgColor != Color( COL_AUTO ) )
1639 pItem->maTabBgColor = aTabBgColor;
1640 if ( aTabBgColor.GetLuminance() <= 128 ) //Do not use aTabBgColor.IsDark(), because that threshold is way too low...
1641 pItem->maTabTextColor = Color( COL_WHITE );
1642 else
1643 pItem->maTabTextColor = Color( COL_BLACK );
1645 else
1647 pItem->maTabBgColor = Color( COL_AUTO );
1648 pItem->maTabTextColor = Color( COL_AUTO );
1653 // -----------------------------------------------------------------------
1655 void TabBar::RemovePage( USHORT nPageId )
1657 USHORT nPos = GetPagePos( nPageId );
1659 // Existiert Item
1660 if ( nPos != TABBAR_PAGE_NOTFOUND )
1662 if ( mnCurPageId == nPageId )
1663 mnCurPageId = 0;
1665 // Testen, ob erste sichtbare Seite verschoben werden muss
1666 if ( mnFirstPos > nPos )
1667 mnFirstPos--;
1669 // Item-Daten loeschen
1670 delete mpItemList->Remove( nPos );
1671 mbFormat = TRUE;
1673 // Leiste neu ausgeben
1674 if ( IsReallyVisible() && IsUpdateMode() )
1675 Invalidate();
1677 CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1681 // -----------------------------------------------------------------------
1683 void TabBar::MovePage( USHORT nPageId, USHORT nNewPos )
1685 USHORT nPos = GetPagePos( nPageId );
1686 Pair aPair( nPos, nNewPos );
1688 if ( nPos < nNewPos )
1689 nNewPos--;
1691 if ( nPos == nNewPos )
1692 return;
1694 // Existiert Item
1695 if ( nPos != TABBAR_PAGE_NOTFOUND )
1697 // TabBar-Item in der Liste verschieben
1698 ImplTabBarItem* pItem = mpItemList->Remove( nPos );
1699 mpItemList->Insert( pItem, nNewPos );
1700 mbFormat = TRUE;
1702 // Leiste neu ausgeben
1703 if ( IsReallyVisible() && IsUpdateMode() )
1704 Invalidate();
1706 CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED, (void*) &aPair );
1710 // -----------------------------------------------------------------------
1712 void TabBar::Clear()
1714 // Alle Items loeschen
1715 ImplTabBarItem* pItem = mpItemList->First();
1716 while ( pItem )
1718 // Item-Daten loeschen
1719 delete pItem;
1720 pItem = mpItemList->Next();
1723 // Items aus der Liste loeschen
1724 mpItemList->Clear();
1725 mbSizeFormat = TRUE;
1726 mnCurPageId = 0;
1727 mnFirstPos = 0;
1729 // Leiste neu ausgeben
1730 if ( IsReallyVisible() && IsUpdateMode() )
1731 Invalidate();
1733 CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, (void*) TABBAR_PAGE_NOTFOUND );
1736 // -----------------------------------------------------------------------
1738 void TabBar::EnablePage( USHORT nPageId, BOOL bEnable )
1740 USHORT nPos = GetPagePos( nPageId );
1742 if ( nPos != TABBAR_PAGE_NOTFOUND )
1744 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1746 if ( pItem->mbEnable != bEnable )
1748 pItem->mbEnable = bEnable;
1750 // Leiste neu ausgeben
1751 if ( IsReallyVisible() && IsUpdateMode() )
1752 Invalidate( pItem->maRect );
1754 CallEventListeners( bEnable ? VCLEVENT_TABBAR_PAGEENABLED : VCLEVENT_TABBAR_PAGEDISABLED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1759 // -----------------------------------------------------------------------
1761 BOOL TabBar::IsPageEnabled( USHORT nPageId ) const
1763 USHORT nPos = GetPagePos( nPageId );
1765 if ( nPos != TABBAR_PAGE_NOTFOUND )
1766 return mpItemList->GetObject( nPos )->mbEnable;
1767 else
1768 return FALSE;
1771 // -----------------------------------------------------------------------
1773 void TabBar::SetPageBits( USHORT nPageId, TabBarPageBits nBits )
1775 USHORT nPos = GetPagePos( nPageId );
1777 if ( nPos != TABBAR_PAGE_NOTFOUND )
1779 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1781 if ( pItem->mnBits != nBits )
1783 pItem->mnBits = nBits;
1785 // Leiste neu ausgeben
1786 if ( IsReallyVisible() && IsUpdateMode() )
1787 Invalidate( pItem->maRect );
1792 // -----------------------------------------------------------------------
1794 TabBarPageBits TabBar::GetPageBits( USHORT nPageId ) const
1796 USHORT nPos = GetPagePos( nPageId );
1798 if ( nPos != TABBAR_PAGE_NOTFOUND )
1799 return mpItemList->GetObject( nPos )->mnBits;
1800 else
1801 return FALSE;
1804 // -----------------------------------------------------------------------
1806 USHORT TabBar::GetPageCount() const
1808 return (USHORT)mpItemList->Count();
1811 // -----------------------------------------------------------------------
1813 USHORT TabBar::GetPageId( USHORT nPos ) const
1815 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1816 if ( pItem )
1817 return pItem->mnId;
1818 else
1819 return 0;
1822 // -----------------------------------------------------------------------
1824 USHORT TabBar::GetPagePos( USHORT nPageId ) const
1826 ImplTabBarItem* pItem = mpItemList->First();
1827 while ( pItem )
1829 if ( pItem->mnId == nPageId )
1830 return (USHORT)mpItemList->GetCurPos();
1832 pItem = mpItemList->Next();
1835 return TABBAR_PAGE_NOTFOUND;
1838 // -----------------------------------------------------------------------
1840 USHORT TabBar::GetPageId( const Point& rPos ) const
1842 ImplTabBarItem* pItem = mpItemList->First();
1843 while ( pItem )
1845 if ( pItem->maRect.IsInside( rPos ) )
1846 return pItem->mnId;
1848 pItem = mpItemList->Next();
1851 return 0;
1854 // -----------------------------------------------------------------------
1856 Rectangle TabBar::GetPageRect( USHORT nPageId ) const
1858 USHORT nPos = GetPagePos( nPageId );
1860 if ( nPos != TABBAR_PAGE_NOTFOUND )
1861 return mpItemList->GetObject( nPos )->maRect;
1862 else
1863 return Rectangle();
1866 // -----------------------------------------------------------------------
1868 void TabBar::SetCurPageId( USHORT nPageId )
1870 USHORT nPos = GetPagePos( nPageId );
1872 // Wenn Item nicht existiert, dann nichts machen
1873 if ( nPos != TABBAR_PAGE_NOTFOUND )
1875 // Wenn sich aktuelle Page nicht geaendert hat, dann muessen wir
1876 // jetzt nichts mehr machen
1877 if ( nPageId == mnCurPageId )
1878 return;
1880 // Muss invalidiert werden
1881 BOOL bUpdate = FALSE;
1882 if ( IsReallyVisible() && IsUpdateMode() )
1883 bUpdate = TRUE;
1885 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1886 ImplTabBarItem* pOldItem;
1888 if ( mnCurPageId )
1889 pOldItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) );
1890 else
1891 pOldItem = NULL;
1893 // Wenn Page nicht selektiert, dann vorher selektierte Seite
1894 // deselktieren, wenn dies die einzige selektierte Seite ist
1895 if ( !pItem->mbSelect && pOldItem )
1897 USHORT nSelPageCount = GetSelectPageCount();
1898 if ( nSelPageCount == 1 )
1899 pOldItem->mbSelect = FALSE;
1900 pItem->mbSelect = TRUE;
1903 mnCurPageId = nPageId;
1904 mbFormat = TRUE;
1906 // Dafuer sorgen, das aktuelle Page sichtbar wird
1907 if ( IsReallyVisible() )
1909 if ( nPos < mnFirstPos )
1910 SetFirstPageId( nPageId );
1911 else
1913 // sichtbare Breite berechnen
1914 long nWidth = mnLastOffX;
1915 if ( nWidth > TABBAR_OFFSET_X )
1916 nWidth -= TABBAR_OFFSET_X;
1917 if ( nWidth > ADDNEWPAGE_AREAWIDTH )
1918 nWidth -= ADDNEWPAGE_AREAWIDTH;
1920 if ( pItem->maRect.IsEmpty() )
1921 ImplFormat();
1923 while ( (mbMirrored ? (pItem->maRect.Left() < mnOffX) : (pItem->maRect.Right() > nWidth)) ||
1924 pItem->maRect.IsEmpty() )
1926 USHORT nNewPos = mnFirstPos+1;
1927 // Dafuer sorgen, das min. die aktuelle TabPages als
1928 // erste TabPage sichtbar ist
1929 if ( nNewPos >= nPos )
1931 SetFirstPageId( nPageId );
1932 break;
1934 else
1935 SetFirstPageId( GetPageId( nNewPos ) );
1936 ImplFormat();
1937 // Falls erste Seite nicht weitergeschaltet wird, dann
1938 // koennen wir abbrechen
1939 if ( nNewPos != mnFirstPos )
1940 break;
1945 // Leiste neu ausgeben
1946 if ( bUpdate )
1948 Invalidate( pItem->maRect );
1949 if ( pOldItem )
1950 Invalidate( pOldItem->maRect );
1955 // -----------------------------------------------------------------------
1957 void TabBar::MakeVisible( USHORT nPageId )
1959 if ( !IsReallyVisible() )
1960 return;
1962 USHORT nPos = GetPagePos( nPageId );
1964 // Wenn Item nicht existiert, dann nichts machen
1965 if ( nPos != TABBAR_PAGE_NOTFOUND )
1967 if ( nPos < mnFirstPos )
1968 SetFirstPageId( nPageId );
1969 else
1971 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1973 // sichtbare Breite berechnen
1974 long nWidth = mnLastOffX;
1975 if ( nWidth > TABBAR_OFFSET_X )
1976 nWidth -= TABBAR_OFFSET_X;
1978 if ( mbFormat || pItem->maRect.IsEmpty() )
1980 mbFormat = TRUE;
1981 ImplFormat();
1984 while ( (pItem->maRect.Right() > nWidth) ||
1985 pItem->maRect.IsEmpty() )
1987 USHORT nNewPos = mnFirstPos+1;
1988 // Dafuer sorgen, das min. die aktuelle TabPages als
1989 // erste TabPage sichtbar ist
1990 if ( nNewPos >= nPos )
1992 SetFirstPageId( nPageId );
1993 break;
1995 else
1996 SetFirstPageId( GetPageId( nNewPos ) );
1997 ImplFormat();
1998 // Falls erste Seite nicht weitergeschaltet wird, dann
1999 // koennen wir abbrechen
2000 if ( nNewPos != mnFirstPos )
2001 break;
2007 // -----------------------------------------------------------------------
2009 void TabBar::SetFirstPageId( USHORT nPageId )
2011 USHORT nPos = GetPagePos( nPageId );
2013 // Wenn Item nicht existiert, dann FALSE zurueckgeben
2014 if ( nPos != TABBAR_PAGE_NOTFOUND )
2016 if ( nPos != mnFirstPos )
2018 // Dafuer sorgen, das nach Moeglichkteit soviele Pages wie
2019 // moeglich sichtbar sind
2020 ImplFormat();
2021 USHORT nLastFirstPos = ImplGetLastFirstPos();
2022 USHORT nNewPos;
2023 if ( nPos > nLastFirstPos )
2024 nNewPos = nLastFirstPos;
2025 else
2026 nNewPos = nPos;
2028 if ( nNewPos != mnFirstPos )
2030 mnFirstPos = nNewPos;
2031 mbFormat = TRUE;
2033 // Leiste neu ausgeben (Achtung: mbDropPos beachten, da wenn
2034 // dieses Flag gesetzt ist, wird direkt gepaintet)
2035 if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos )
2036 Invalidate();
2042 // -----------------------------------------------------------------------
2044 void TabBar::SelectPage( USHORT nPageId, BOOL bSelect )
2046 USHORT nPos = GetPagePos( nPageId );
2048 if ( nPos != TABBAR_PAGE_NOTFOUND )
2050 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
2052 if ( pItem->mbSelect != bSelect )
2054 pItem->mbSelect = bSelect;
2056 // Leiste neu ausgeben
2057 if ( IsReallyVisible() && IsUpdateMode() )
2058 Invalidate( pItem->maRect );
2063 // -----------------------------------------------------------------------
2065 void TabBar::SelectPageRange( BOOL bSelect, USHORT nStartPos, USHORT nEndPos )
2067 Rectangle aPaintRect;
2068 USHORT nPos = nStartPos;
2069 ImplTabBarItem* pItem = mpItemList->Seek( nPos );
2070 while ( pItem && (nPos <= nEndPos) )
2072 if ( (pItem->mbSelect != bSelect) && (pItem->mnId != mnCurPageId) )
2074 pItem->mbSelect = bSelect;
2075 aPaintRect.Union( pItem->maRect );
2078 nPos++;
2079 pItem = mpItemList->Next();
2082 // Leiste neu ausgeben
2083 if ( IsReallyVisible() && IsUpdateMode() && !aPaintRect.IsEmpty() )
2084 Invalidate( aPaintRect );
2087 // -----------------------------------------------------------------------
2089 USHORT TabBar::GetSelectPage( USHORT nSelIndex ) const
2091 USHORT nSelected = 0;
2092 ImplTabBarItem* pItem = mpItemList->First();
2093 while ( pItem )
2095 if ( pItem->mbSelect )
2096 nSelected++;
2098 if ( nSelected == nSelIndex )
2099 return pItem->mnId;
2101 pItem = mpItemList->Next();
2104 return 0;
2107 // -----------------------------------------------------------------------
2109 USHORT TabBar::GetSelectPageCount() const
2111 USHORT nSelected = 0;
2112 ImplTabBarItem* pItem = mpItemList->First();
2113 while ( pItem )
2115 if ( pItem->mbSelect )
2116 nSelected++;
2118 pItem = mpItemList->Next();
2121 return nSelected;
2124 // -----------------------------------------------------------------------
2126 BOOL TabBar::IsPageSelected( USHORT nPageId ) const
2128 USHORT nPos = GetPagePos( nPageId );
2129 if ( nPos != TABBAR_PAGE_NOTFOUND )
2130 return mpItemList->GetObject( nPos )->mbSelect;
2131 else
2132 return FALSE;
2135 // -----------------------------------------------------------------------
2137 BOOL TabBar::StartEditMode( USHORT nPageId )
2139 USHORT nPos = GetPagePos( nPageId );
2140 if ( mpEdit || (nPos == TABBAR_PAGE_NOTFOUND) || (mnLastOffX < 8) )
2141 return FALSE;
2143 mnEditId = nPageId;
2144 if ( StartRenaming() )
2146 ImplShowPage( nPos );
2147 ImplFormat();
2148 Update();
2150 mpEdit = new TabBarEdit( this, WB_CENTER );
2151 Rectangle aRect = GetPageRect( mnEditId );
2152 long nX = aRect.Left()+TABBAR_OFFSET_X+(TABBAR_OFFSET_X2/2);
2153 long nWidth = aRect.GetWidth()-(TABBAR_OFFSET_X*2)-TABBAR_OFFSET_X2;
2154 if ( mnEditId != GetCurPageId() )
2155 nX += 1;
2156 if ( nX+nWidth > mnLastOffX )
2157 nWidth = mnLastOffX-nX;
2158 if ( nWidth < 3 )
2160 nX = aRect.Left();
2161 nWidth = aRect.GetWidth();
2163 mpEdit->SetText( GetPageText( mnEditId ) );
2164 mpEdit->SetPosSizePixel( nX, aRect.Top()+mnOffY+1, nWidth, aRect.GetHeight()-3 );
2165 Font aFont = GetPointFont();
2166 Color aForegroundColor;
2167 Color aBackgroundColor;
2168 Color aFaceColor;
2169 Color aSelectColor;
2170 Color aFaceTextColor;
2171 Color aSelectTextColor;
2172 ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
2173 if ( mnEditId != GetCurPageId() )
2174 aFont.SetWeight( WEIGHT_LIGHT );
2175 if ( IsPageSelected( mnEditId ) || (mnEditId == GetCurPageId()) )
2177 aForegroundColor = aSelectTextColor;
2178 aBackgroundColor = aSelectColor;
2180 else
2182 aForegroundColor = aFaceTextColor;
2183 aBackgroundColor = aFaceColor;
2185 if ( GetPageBits( mnEditId ) & TPB_SPECIAL )
2186 aForegroundColor = Color( COL_LIGHTBLUE );
2187 mpEdit->SetControlFont( aFont );
2188 mpEdit->SetControlForeground( aForegroundColor );
2189 mpEdit->SetControlBackground( aBackgroundColor );
2190 mpEdit->GrabFocus();
2191 mpEdit->SetSelection( Selection( 0, mpEdit->GetText().Len() ) );
2192 mpEdit->Show();
2193 return TRUE;
2195 else
2197 mnEditId = 0;
2198 return FALSE;
2202 // -----------------------------------------------------------------------
2204 void TabBar::EndEditMode( BOOL bCancel )
2206 if ( mpEdit )
2208 // call hdl
2209 BOOL bEnd = TRUE;
2210 mbEditCanceled = bCancel;
2211 maEditText = mpEdit->GetText();
2212 mpEdit->SetPostEvent();
2213 if ( !bCancel )
2215 long nAllowRenaming = AllowRenaming();
2216 if ( nAllowRenaming == TABBAR_RENAMING_YES )
2217 SetPageText( mnEditId, maEditText );
2218 else if ( nAllowRenaming == TABBAR_RENAMING_NO )
2219 bEnd = FALSE;
2220 else // nAllowRenaming == TABBAR_RENAMING_CANCEL
2221 mbEditCanceled = TRUE;
2224 // renaming not allowed, than reset edit data
2225 if ( !bEnd )
2227 mpEdit->ResetPostEvent();
2228 mpEdit->GrabFocus();
2230 else
2232 // close edit and call end hdl
2233 delete mpEdit;
2234 mpEdit = NULL;
2235 EndRenaming();
2236 mnEditId = 0;
2239 // reset
2240 maEditText.Erase();
2241 mbEditCanceled = FALSE;
2245 // -----------------------------------------------------------------------
2247 void TabBar::SetMirrored( BOOL bMirrored )
2249 if( mbMirrored != bMirrored )
2251 mbMirrored = bMirrored;
2252 mbSizeFormat = TRUE;
2253 ImplInitControls(); // for button images
2254 Resize(); // recalculates control positions
2255 Mirror();
2259 void TabBar::SetEffectiveRTL( BOOL bRTL )
2261 SetMirrored( bRTL != Application::GetSettings().GetLayoutRTL() );
2264 BOOL TabBar::IsEffectiveRTL() const
2266 return IsMirrored() != Application::GetSettings().GetLayoutRTL();
2269 // -----------------------------------------------------------------------
2271 void TabBar::SetMaxPageWidth( long nMaxWidth )
2273 if ( mnMaxPageWidth != nMaxWidth )
2275 mnMaxPageWidth = nMaxWidth;
2276 mbSizeFormat = TRUE;
2278 // Leiste neu ausgeben
2279 if ( IsReallyVisible() && IsUpdateMode() )
2280 Invalidate();
2284 // -----------------------------------------------------------------------
2286 void TabBar::SetSelectColor()
2288 if ( mbSelColor )
2290 maSelColor = Color( COL_TRANSPARENT );
2291 mbSelColor = FALSE;
2292 Invalidate();
2296 // -----------------------------------------------------------------------
2298 void TabBar::SetSelectColor( const Color& rColor )
2300 if ( rColor.GetTransparency() )
2302 if ( mbSelColor )
2304 maSelColor = Color( COL_TRANSPARENT );
2305 mbSelColor = FALSE;
2306 Invalidate();
2309 else
2311 if ( maSelColor != rColor )
2313 maSelColor = rColor;
2314 mbSelColor = TRUE;
2315 Invalidate();
2320 // -----------------------------------------------------------------------
2322 void TabBar::SetSelectTextColor()
2324 if ( mbSelTextColor )
2326 maSelTextColor = Color( COL_TRANSPARENT );
2327 mbSelTextColor = FALSE;
2328 Invalidate();
2332 // -----------------------------------------------------------------------
2334 void TabBar::SetSelectTextColor( const Color& rColor )
2336 if ( rColor.GetTransparency() )
2338 if ( mbSelTextColor )
2340 maSelTextColor = Color( COL_TRANSPARENT );
2341 mbSelTextColor = FALSE;
2342 Invalidate();
2345 else
2347 if ( maSelTextColor != rColor )
2349 maSelTextColor = rColor;
2350 mbSelTextColor = TRUE;
2351 Invalidate();
2356 // -----------------------------------------------------------------------
2358 void TabBar::SetPageText( USHORT nPageId, const XubString& rText )
2360 USHORT nPos = GetPagePos( nPageId );
2361 if ( nPos != TABBAR_PAGE_NOTFOUND )
2363 mpItemList->GetObject( nPos )->maText = rText;
2364 mbSizeFormat = TRUE;
2366 // Leiste neu ausgeben
2367 if ( IsReallyVisible() && IsUpdateMode() )
2368 Invalidate();
2370 CallEventListeners( VCLEVENT_TABBAR_PAGETEXTCHANGED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
2374 // -----------------------------------------------------------------------
2376 XubString TabBar::GetPageText( USHORT nPageId ) const
2378 USHORT nPos = GetPagePos( nPageId );
2379 if ( nPos != TABBAR_PAGE_NOTFOUND )
2380 return mpItemList->GetObject( nPos )->maText;
2381 else
2382 return XubString();
2385 // -----------------------------------------------------------------------
2387 void TabBar::SetHelpText( USHORT nPageId, const XubString& rText )
2389 USHORT nPos = GetPagePos( nPageId );
2390 if ( nPos != TABBAR_PAGE_NOTFOUND )
2391 mpItemList->GetObject( nPos )->maHelpText = rText;
2394 // -----------------------------------------------------------------------
2396 XubString TabBar::GetHelpText( USHORT nPageId ) const
2398 USHORT nPos = GetPagePos( nPageId );
2399 if ( nPos != TABBAR_PAGE_NOTFOUND )
2401 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
2402 if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
2404 Help* pHelp = Application::GetHelp();
2405 if ( pHelp )
2406 pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId, this );
2409 return pItem->maHelpText;
2411 else
2412 return XubString();
2415 // -----------------------------------------------------------------------
2417 void TabBar::SetHelpId( USHORT nPageId, ULONG nHelpId )
2419 USHORT nPos = GetPagePos( nPageId );
2420 if ( nPos != TABBAR_PAGE_NOTFOUND )
2421 mpItemList->GetObject( nPos )->mnHelpId = nHelpId;
2424 // -----------------------------------------------------------------------
2426 ULONG TabBar::GetHelpId( USHORT nPageId ) const
2428 USHORT nPos = GetPagePos( nPageId );
2429 if ( nPos != TABBAR_PAGE_NOTFOUND )
2430 return mpItemList->GetObject( nPos )->mnHelpId;
2431 else
2432 return 0;
2435 // -----------------------------------------------------------------------
2437 long TabBar::GetMinSize() const
2439 long nMinSize = TABBAR_MINSIZE + TABBAR_OFFSET_X;
2440 if ( mnWinStyle & WB_MINSCROLL )
2441 nMinSize += mpPrevBtn->GetSizePixel().Width()*2;
2442 else if ( mnWinStyle & WB_SCROLL )
2443 nMinSize += mpFirstBtn->GetSizePixel().Width()*4;
2444 return nMinSize;
2447 // -----------------------------------------------------------------------
2449 BOOL TabBar::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
2451 if ( !(mnWinStyle & WB_DRAG) || (rCEvt.GetCommand() != COMMAND_STARTDRAG) )
2452 return FALSE;
2454 // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
2455 // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
2456 // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
2457 // dies nur bei einer Mausaktion.
2458 // Ausserdem machen wir das nur, wenn kein Select() ausgeloest wurde,
2459 // da der Select schon den Bereich gescrollt haben kann
2460 if ( rCEvt.IsMouseEvent() && !mbInSelect )
2462 USHORT nSelId = GetPageId( rCEvt.GetMousePosPixel() );
2464 // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
2465 if ( !nSelId )
2466 return FALSE;
2468 // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
2469 // Seite setzen und Select rufen.
2470 if ( !IsPageSelected( nSelId ) )
2472 if ( ImplDeactivatePage() )
2474 SetCurPageId( nSelId );
2475 Update();
2476 ImplActivatePage();
2477 ImplSelect();
2479 else
2480 return FALSE;
2483 mbInSelect = FALSE;
2485 Region aRegion;
2487 // Region zuweisen
2488 rRegion = aRegion;
2490 return TRUE;
2493 // -----------------------------------------------------------------------
2495 USHORT TabBar::ShowDropPos( const Point& rPos )
2497 ImplTabBarItem* pItem;
2498 USHORT nDropId;
2499 USHORT nNewDropPos;
2500 USHORT nItemCount = (USHORT)mpItemList->Count();
2501 short nScroll = 0;
2503 if ( rPos.X() > mnLastOffX-TABBAR_DRAG_SCROLLOFF )
2505 pItem = mpItemList->GetObject( mpItemList->Count()-1 );
2506 if ( !pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()) )
2507 nNewDropPos = (USHORT)mpItemList->Count();
2508 else
2510 nNewDropPos = mnFirstPos+1;
2511 nScroll = 1;
2514 else if ( (rPos.X() <= mnOffX) ||
2515 (!mnOffX && (rPos.X() <= TABBAR_DRAG_SCROLLOFF)) )
2517 if ( mnFirstPos )
2519 nNewDropPos = mnFirstPos;
2520 nScroll = -1;
2522 else
2523 nNewDropPos = 0;
2525 else
2527 nDropId = GetPageId( rPos );
2528 if ( nDropId )
2530 nNewDropPos = GetPagePos( nDropId );
2531 if ( mnFirstPos && (nNewDropPos == mnFirstPos-1) )
2532 nScroll = -1;
2534 else
2535 nNewDropPos = nItemCount;
2538 if ( mbDropPos && (nNewDropPos == mnDropPos) && !nScroll )
2539 return mnDropPos;
2541 if ( mbDropPos )
2542 HideDropPos();
2543 mbDropPos = TRUE;
2544 mnDropPos = nNewDropPos;
2546 if ( nScroll )
2548 USHORT nOldFirstPos = mnFirstPos;
2549 SetFirstPageId( GetPageId( mnFirstPos+nScroll ) );
2551 // Direkt ausgeben, da kein Paint bei Drag and Drop moeglich
2552 if ( nOldFirstPos != mnFirstPos )
2554 Rectangle aRect( mnOffX, 0, mnLastOffX, maWinSize.Height() );
2555 SetFillColor( GetBackground().GetColor() );
2556 DrawRect( aRect );
2557 Paint( aRect );
2561 // Drop-Position-Pfeile ausgeben
2562 Color aBlackColor( COL_BLACK );
2563 long nX;
2564 long nY = (maWinSize.Height()/2)-1;
2565 USHORT nCurPos = GetPagePos( mnCurPageId );
2567 SetLineColor( aBlackColor );
2568 if ( mnDropPos < nItemCount )
2570 pItem = mpItemList->GetObject( mnDropPos );
2571 nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
2572 if ( mnDropPos == nCurPos )
2573 nX--;
2574 else
2575 nX++;
2576 if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
2577 SetLineColor( pItem->maTabTextColor );
2578 DrawLine( Point( nX, nY ), Point( nX, nY ) );
2579 DrawLine( Point( nX+1, nY-1 ), Point( nX+1, nY+1 ) );
2580 DrawLine( Point( nX+2, nY-2 ), Point( nX+2, nY+2 ) );
2581 SetLineColor( aBlackColor );
2583 if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
2585 pItem = mpItemList->GetObject( mnDropPos-1 );
2586 nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
2587 if ( mnDropPos == nCurPos )
2588 nX++;
2589 if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
2590 SetLineColor( pItem->maTabTextColor );
2591 DrawLine( Point( nX, nY ), Point( nX, nY ) );
2592 DrawLine( Point( nX-1, nY-1 ), Point( nX-1, nY+1 ) );
2593 DrawLine( Point( nX-2, nY-2 ), Point( nX-2, nY+2 ) );
2596 return mnDropPos;
2599 // -----------------------------------------------------------------------
2601 void TabBar::HideDropPos()
2603 if ( mbDropPos )
2605 ImplTabBarItem* pItem;
2606 long nX;
2607 long nY1 = (maWinSize.Height()/2)-3;
2608 long nY2 = nY1 + 5;
2609 USHORT nItemCount = (USHORT)mpItemList->Count();
2611 if ( mnDropPos < nItemCount )
2613 pItem = mpItemList->GetObject( mnDropPos );
2614 nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
2615 // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2616 // moeglich
2617 Rectangle aRect( nX-1, nY1, nX+3, nY2 );
2618 Region aRegion( aRect );
2619 SetClipRegion( aRegion );
2620 Paint( aRect );
2621 SetClipRegion();
2623 if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
2625 pItem = mpItemList->GetObject( mnDropPos-1 );
2626 nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
2627 // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2628 // moeglich
2629 Rectangle aRect( nX-2, nY1, nX+1, nY2 );
2630 Region aRegion( aRect );
2631 SetClipRegion( aRegion );
2632 Paint( aRect );
2633 SetClipRegion();
2636 mbDropPos = FALSE;
2637 mnDropPos = 0;
2641 // -----------------------------------------------------------------------
2643 BOOL TabBar::SwitchPage( const Point& rPos )
2645 BOOL bSwitch = FALSE;
2646 USHORT nSwitchId = GetPageId( rPos );
2647 if ( !nSwitchId )
2648 EndSwitchPage();
2649 else
2651 if ( nSwitchId != mnSwitchId )
2653 mnSwitchId = nSwitchId;
2654 mnSwitchTime = Time::GetSystemTicks();
2656 else
2658 // Erst nach 500 ms umschalten
2659 if ( mnSwitchId != GetCurPageId() )
2661 if ( Time::GetSystemTicks() > mnSwitchTime+500 )
2663 mbInSwitching = TRUE;
2664 if ( ImplDeactivatePage() )
2666 SetCurPageId( mnSwitchId );
2667 Update();
2668 ImplActivatePage();
2669 ImplSelect();
2670 bSwitch = TRUE;
2672 mbInSwitching = FALSE;
2678 return bSwitch;
2681 // -----------------------------------------------------------------------
2683 void TabBar::EndSwitchPage()
2685 mnSwitchTime = 0;
2686 mnSwitchId = 0;
2689 // -----------------------------------------------------------------------
2691 void TabBar::SetStyle( WinBits nStyle )
2693 mnWinStyle = nStyle;
2694 ImplInitControls();
2695 // Evt. Controls neu anordnen
2696 if ( IsReallyVisible() && IsUpdateMode() )
2697 Resize();
2700 // -----------------------------------------------------------------------
2702 Size TabBar::CalcWindowSizePixel() const
2704 long nWidth = 0;
2706 if ( mpItemList->Count() )
2708 ((TabBar*)this)->ImplCalcWidth();
2709 ImplTabBarItem* pItem = mpItemList->First();
2710 while ( pItem )
2712 nWidth += pItem->mnWidth;
2713 pItem = mpItemList->Next();
2715 nWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
2718 return Size( nWidth, GetSettings().GetStyleSettings().GetScrollBarSize() );
2720 // -----------------------------------------------------------------------
2722 Rectangle TabBar::GetPageArea() const
2724 return Rectangle( Point( mnOffX, mnOffY ), Size( mnLastOffX-mnOffX+1, GetSizePixel().Height()-mnOffY ) );
2727 // -----------------------------------------------------------------------
2729 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > TabBar::CreateAccessible()
2731 return mpImpl->maAccessibleFactory.getFactory().createAccessibleTabBar( *this );
2734 // -----------------------------------------------------------------------