1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svtools/tabbar.hxx>
22 #include <tools/time.hxx>
23 #include <tools/debug.hxx>
24 #include <tools/poly.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/help.hxx>
27 #include <vcl/decoview.hxx>
28 #include <vcl/button.hxx>
29 #include <vcl/edit.hxx>
30 #include <vcl/image.hxx>
31 #include "svtaccessiblefactory.hxx"
32 #include <filectrl.hrc>
33 #include <svtools/svtresid.hxx>
34 #include <svtools/svtools.hrc>
37 // =======================================================================
39 #define TABBAR_OFFSET_X 7
40 #define TABBAR_OFFSET_X2 2
41 #define TABBAR_DRAG_SCROLLOFF 5
42 #define TABBAR_MINSIZE 5
44 const sal_uInt16 ADDNEWPAGE_AREAWIDTH
= 10;
46 // =======================================================================
51 TabBarPageBits mnBits
;
63 ImplTabBarItem( sal_uInt16 nItemId
, const OUString
& rText
,
64 TabBarPageBits nPageBits
) :
73 maTabBgColor
= Color( COL_AUTO
);
74 maTabTextColor
= Color( COL_AUTO
);
77 bool IsDefaultTabBgColor() const
79 return maTabBgColor
== Color(COL_AUTO
);
82 bool IsDefaultTabTextColor() const
84 return maTabTextColor
== Color(COL_AUTO
);
87 bool IsSelected(ImplTabBarItem
* pCurItem
) const
89 return mbSelect
|| (pCurItem
== this);
93 // =======================================================================
99 class ImplTabButton
: public PushButton
102 ImplTabButton( TabBar
* pParent
, WinBits nWinStyle
= 0 ) :
103 PushButton( pParent
, nWinStyle
| WB_RECTSTYLE
| WB_SMALLSTYLE
| WB_NOLIGHTBORDER
| WB_NOPOINTERFOCUS
) {}
105 TabBar
* GetParent() const { return (TabBar
*)Window::GetParent(); }
107 virtual long PreNotify( NotifyEvent
& rNEvt
);
110 // =======================================================================
112 long ImplTabButton::PreNotify( NotifyEvent
& rNEvt
)
114 if ( rNEvt
.GetType() == EVENT_MOUSEBUTTONDOWN
)
116 if ( GetParent()->IsInEditMode() )
118 GetParent()->EndEditMode();
123 return PushButton::PreNotify( rNEvt
);
126 // =======================================================================
132 class ImplTabSizer
: public Window
135 ImplTabSizer( TabBar
* pParent
, WinBits nWinStyle
= 0 );
137 TabBar
* GetParent() const { return (TabBar
*)Window::GetParent(); }
140 void ImplTrack( const Point
& rScreenPos
);
142 virtual void MouseButtonDown( const MouseEvent
& rMEvt
);
143 virtual void Tracking( const TrackingEvent
& rTEvt
);
144 virtual void Paint( const Rectangle
& rRect
);
150 // -----------------------------------------------------------------------
152 ImplTabSizer::ImplTabSizer( TabBar
* pParent
, WinBits nWinStyle
)
153 : Window( pParent
, nWinStyle
& WB_3DLOOK
)
156 SetPointer( Pointer( POINTER_HSIZEBAR
) );
157 SetSizePixel( Size( 7, 0 ) );
160 // -----------------------------------------------------------------------
162 void ImplTabSizer::ImplTrack( const Point
& rScreenPos
)
164 TabBar
* pParent
= GetParent();
165 long nDiff
= rScreenPos
.X() - maStartPos
.X();
166 pParent
->mnSplitSize
= mnStartWidth
+ (pParent
->IsMirrored() ? -nDiff
: nDiff
);
167 if ( pParent
->mnSplitSize
< TABBAR_MINSIZE
)
168 pParent
->mnSplitSize
= TABBAR_MINSIZE
;
173 // -----------------------------------------------------------------------
175 void ImplTabSizer::MouseButtonDown( const MouseEvent
& rMEvt
)
177 if ( GetParent()->IsInEditMode() )
179 GetParent()->EndEditMode();
183 if ( rMEvt
.IsLeft() )
185 maStartPos
= OutputToScreenPixel( rMEvt
.GetPosPixel() );
186 mnStartWidth
= GetParent()->GetSizePixel().Width();
191 // -----------------------------------------------------------------------
193 void ImplTabSizer::Tracking( const TrackingEvent
& rTEvt
)
195 if ( rTEvt
.IsTrackingEnded() )
197 if ( rTEvt
.IsTrackingCanceled() )
198 ImplTrack( maStartPos
);
199 GetParent()->mnSplitSize
= 0;
202 ImplTrack( OutputToScreenPixel( rTEvt
.GetMouseEvent().GetPosPixel() ) );
205 // -----------------------------------------------------------------------
207 void ImplTabSizer::Paint( const Rectangle
& )
209 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
210 DecorationView
aDecoView( this );
212 Size aOutputSize
= GetOutputSizePixel();
214 if ( !(rStyleSettings
.GetOptions() & STYLE_OPTION_MONO
) )
216 SetLineColor( rStyleSettings
.GetDarkShadowColor() );
217 DrawLine( Point( 0, 0 ), Point( 0, aOutputSize
.Height()-1 ) );
219 aOutputSize
.Width()--;
221 aDecoView
.DrawButton( Rectangle( Point( nOffX
, 0 ), aOutputSize
), BUTTON_DRAW_NOLIGHTBORDER
);
224 // =======================================================================
226 // Heisst nicht Impl, da evtl. mal von aussen benutz- und ueberladbar
232 class TabBarEdit
: public Edit
235 Timer maLoseFocusTimer
;
238 DECL_LINK( ImplEndEditHdl
, void* );
239 DECL_LINK( ImplEndTimerHdl
, void* );
242 TabBarEdit( TabBar
* pParent
, WinBits nWinStyle
= 0 );
244 TabBar
* GetParent() const { return (TabBar
*)Window::GetParent(); }
246 void SetPostEvent() { mbPostEvt
= sal_True
; }
247 void ResetPostEvent() { mbPostEvt
= sal_False
; }
249 virtual long PreNotify( NotifyEvent
& rNEvt
);
250 virtual void LoseFocus();
253 // -----------------------------------------------------------------------
255 TabBarEdit::TabBarEdit( TabBar
* pParent
, WinBits nWinStyle
) :
256 Edit( pParent
, nWinStyle
)
258 mbPostEvt
= sal_False
;
261 // -----------------------------------------------------------------------
263 long TabBarEdit::PreNotify( NotifyEvent
& rNEvt
)
265 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
267 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
268 if ( !pKEvt
->GetKeyCode().GetModifier() )
270 if ( pKEvt
->GetKeyCode().GetCode() == KEY_RETURN
)
274 if ( PostUserEvent( LINK( this, TabBarEdit
, ImplEndEditHdl
), (void*)sal_False
) )
275 mbPostEvt
= sal_True
;
279 else if ( pKEvt
->GetKeyCode().GetCode() == KEY_ESCAPE
)
283 if ( PostUserEvent( LINK( this, TabBarEdit
, ImplEndEditHdl
), (void*)sal_True
) )
284 mbPostEvt
= sal_True
;
291 return Edit::PreNotify( rNEvt
);
294 // -----------------------------------------------------------------------
296 void TabBarEdit::LoseFocus()
300 if ( PostUserEvent( LINK( this, TabBarEdit
, ImplEndEditHdl
), (void*)sal_False
) )
301 mbPostEvt
= sal_True
;
307 // -----------------------------------------------------------------------
309 IMPL_LINK( TabBarEdit
, ImplEndEditHdl
, void*, pCancel
)
312 maLoseFocusTimer
.Stop();
314 // We need this query, because the edit get a losefous event,
315 // when it shows the context menu or the insert symbol dialog
316 if ( !HasFocus() && HasChildPathFocus( sal_True
) )
318 maLoseFocusTimer
.SetTimeout( 30 );
319 maLoseFocusTimer
.SetTimeoutHdl( LINK( this, TabBarEdit
, ImplEndTimerHdl
) );
320 maLoseFocusTimer
.Start();
323 GetParent()->EndEditMode( pCancel
!= 0 );
328 // -----------------------------------------------------------------------
330 IMPL_LINK_NOARG(TabBarEdit
, ImplEndTimerHdl
)
335 // We need this query, because the edit get a losefous event,
336 // when it shows the context menu or the insert symbol dialog
337 if ( HasChildPathFocus( sal_True
) )
338 maLoseFocusTimer
.Start();
340 GetParent()->EndEditMode( sal_True
);
345 // =======================================================================
348 ImplTabSizer
* mpSizer
;
349 ::svt::AccessibleFactoryAccess maAccessibleFactory
;
361 // =======================================================================
363 const sal_uInt16
TabBar::APPEND
= ::std::numeric_limits
<sal_uInt16
>::max();
364 const sal_uInt16
TabBar::PAGE_NOT_FOUND
= ::std::numeric_limits
<sal_uInt16
>::max();
365 const sal_uInt16
TabBar::INSERT_TAB_POS
= ::std::numeric_limits
<sal_uInt16
>::max() - 1;
367 void TabBar::ImplInit( WinBits nWinStyle
)
369 mpItemList
= new ImplTabBarList
;
374 mpImpl
= new TabBar_Impl
;
383 mnWinStyle
= nWinStyle
;
390 mbFirstFormat
= sal_True
;
391 mbSizeFormat
= sal_True
;
392 mbAutoMaxWidth
= sal_True
;
393 mbInSwitching
= sal_False
;
394 mbAutoEditMode
= sal_False
;
395 mbEditCanceled
= sal_False
;
396 mbDropPos
= sal_False
;
397 mbInSelect
= sal_False
;
398 mbSelColor
= sal_False
;
399 mbSelTextColor
= sal_False
;
400 mbMirrored
= sal_False
;
402 if ( nWinStyle
& WB_3DTAB
)
408 mpFirstBtn
->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVET0HOME
));
410 mpPrevBtn
->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVELEFT
));
412 mpNextBtn
->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVERIGHT
));
414 mpLastBtn
->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVETOEND
));
416 SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
417 ImplInitSettings( sal_True
, sal_True
);
420 // -----------------------------------------------------------------------
422 TabBar::TabBar( Window
* pParent
, WinBits nWinStyle
) :
423 Window( pParent
, (nWinStyle
& WB_3DLOOK
) | WB_CLIPCHILDREN
)
425 ImplInit( nWinStyle
);
426 maCurrentItemList
= 0;
429 // -----------------------------------------------------------------------
433 EndEditMode( sal_True
);
446 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
) {
447 delete (*mpItemList
)[ i
];
452 // -----------------------------------------------------------------------
453 ImplTabBarItem
* TabBar::seek( size_t i
)
455 if ( i
< mpItemList
->size() )
457 maCurrentItemList
= i
;
458 return (*mpItemList
)[ maCurrentItemList
];
463 ImplTabBarItem
* TabBar::prev()
465 if ( maCurrentItemList
> 0 ) {
466 return (*mpItemList
)[ --maCurrentItemList
];
471 ImplTabBarItem
* TabBar::next()
473 if ( maCurrentItemList
+1 < mpItemList
->size() ) {
474 return (*mpItemList
)[ ++maCurrentItemList
];
479 // -----------------------------------------------------------------------
481 void TabBar::ImplInitSettings( sal_Bool bFont
, sal_Bool bBackground
)
483 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
488 aToolFont
= rStyleSettings
.GetToolFont();
489 if ( IsControlFont() )
490 aToolFont
.Merge( GetControlFont() );
491 aToolFont
.SetWeight( WEIGHT_BOLD
);
492 SetZoomedPointFont( aToolFont
);
494 // Font in der groesse Anpassen, wenn Fenster zu klein?
495 while ( GetTextHeight() > (GetOutputSizePixel().Height()-1) )
497 Font aFont
= GetFont();
498 if ( aFont
.GetHeight() <= 6 )
500 aFont
.SetHeight( aFont
.GetHeight()-1 );
508 if ( IsControlBackground() )
509 aColor
= GetControlBackground();
511 aColor
= rStyleSettings
.GetFaceColor();
512 SetBackground( aColor
);
516 // -----------------------------------------------------------------------
518 void TabBar::ImplGetColors( Color
& rFaceColor
, Color
& rFaceTextColor
,
519 Color
& rSelectColor
, Color
& rSelectTextColor
)
521 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
523 if ( IsControlBackground() )
524 rFaceColor
= GetControlBackground();
526 rFaceColor
= rStyleSettings
.GetInactiveTabColor();
527 if ( IsControlForeground() )
528 rFaceTextColor
= GetControlForeground();
530 rFaceTextColor
= rStyleSettings
.GetButtonTextColor();
532 rSelectColor
= maSelColor
;
534 rSelectColor
= rStyleSettings
.GetActiveTabColor();
535 if ( mbSelTextColor
)
536 rSelectTextColor
= maSelTextColor
;
538 rSelectTextColor
= rStyleSettings
.GetWindowTextColor();
540 // Bei 3D-Tabs wird Selektions- und Face-Farbe umgedreht, da die
541 // selektierten Tabs in 3D erscheinen sollen
542 if ( mnWinStyle
& WB_3DTAB
)
544 Color aTempColor
= rFaceColor
;
545 rFaceColor
= rSelectColor
;
546 rSelectColor
= aTempColor
;
547 aTempColor
= rFaceTextColor
;
548 rFaceTextColor
= rSelectTextColor
;
549 rSelectTextColor
= rFaceTextColor
;
553 // -----------------------------------------------------------------------
555 sal_Bool
TabBar::ImplCalcWidth()
557 // Groessen muessen nur ermittelt werden, wenn sich Text aendert oder
558 // wenn der Font geaendert wurde
562 // Breiten der Tabs mit dem fetten Font ermitteln
563 Font aFont
= GetFont();
564 if ( aFont
.GetWeight() != WEIGHT_BOLD
)
566 aFont
.SetWeight( WEIGHT_BOLD
);
570 if ( mnMaxPageWidth
)
571 mnCurMaxWidth
= mnMaxPageWidth
;
572 else if ( mbAutoMaxWidth
)
574 mnCurMaxWidth
= mnLastOffX
-mnOffX
-
575 TABBAR_OFFSET_X
-TABBAR_OFFSET_X
-
576 TABBAR_OFFSET_X2
-TABBAR_OFFSET_X2
-TABBAR_OFFSET_X2
;
577 if ( mnCurMaxWidth
< 1 )
583 sal_Bool bChanged
= sal_False
;
584 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
586 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
587 long nNewWidth
= GetTextWidth( pItem
->maText
);
588 if ( mnCurMaxWidth
&& (nNewWidth
> mnCurMaxWidth
) )
590 pItem
->mbShort
= sal_True
;
591 nNewWidth
= mnCurMaxWidth
;
594 pItem
->mbShort
= sal_False
;
595 nNewWidth
+= TABBAR_OFFSET_X
+TABBAR_OFFSET_X2
;
596 if ( pItem
->mnWidth
!= nNewWidth
)
598 pItem
->mnWidth
= nNewWidth
;
599 if ( !pItem
->maRect
.IsEmpty() )
603 mbSizeFormat
= sal_False
;
608 // -----------------------------------------------------------------------
610 void TabBar::ImplFormat()
619 for ( size_t i
= 0, nL
= mpItemList
->size(); i
< nL
; ++i
)
621 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
622 // Bei allen nicht sichtbaren Tabs, wird ein leeres Rechteck
624 if ( (n
+1 < mnFirstPos
) || (x
> mnLastOffX
) )
625 pItem
->maRect
.SetEmpty();
628 // Etwas von der Tab vor der ersten sichtbaren Page
629 // muss auch zu sehen sein
630 if ( n
+1 == mnFirstPos
)
631 pItem
->maRect
.Left() = x
-pItem
->mnWidth
;
634 pItem
->maRect
.Left() = x
;
637 pItem
->maRect
.Right() = x
+TABBAR_OFFSET_X
+TABBAR_OFFSET_X2
;
638 pItem
->maRect
.Bottom() = maWinSize
.Height()-1;
642 long nTmp
= mnOffX
+ mnLastOffX
- pItem
->maRect
.Right();
643 pItem
->maRect
.Right() = mnOffX
+ mnLastOffX
- pItem
->maRect
.Left();
644 pItem
->maRect
.Left() = nTmp
;
651 mbFormat
= sal_False
;
653 // Button enablen/disablen
654 ImplEnableControls();
657 // -----------------------------------------------------------------------
659 sal_uInt16
TabBar::ImplGetLastFirstPos()
661 sal_uInt16 nCount
= (sal_uInt16
)(mpItemList
->size());
662 if ( !nCount
|| mbSizeFormat
|| mbFormat
)
665 sal_uInt16 nLastFirstPos
= nCount
-1;
666 long nWinWidth
= mnLastOffX
-mnOffX
-TABBAR_OFFSET_X
-ADDNEWPAGE_AREAWIDTH
;
667 long nWidth
= (*mpItemList
)[ nLastFirstPos
]->mnWidth
;
668 while ( nLastFirstPos
&& (nWidth
< nWinWidth
) )
671 nWidth
+= (*mpItemList
)[ nLastFirstPos
]->mnWidth
;
673 if ( (nLastFirstPos
!= (sal_uInt16
)(mpItemList
->size()-1)) &&
674 (nWidth
> nWinWidth
) )
676 return nLastFirstPos
;
679 // -----------------------------------------------------------------------
681 void TabBar::ImplInitControls()
683 if ( mnWinStyle
& WB_SIZEABLE
)
685 if ( !mpImpl
->mpSizer
)
686 mpImpl
->mpSizer
= new ImplTabSizer( this, mnWinStyle
& (WB_DRAG
| WB_3DLOOK
) );
687 mpImpl
->mpSizer
->Show();
691 DELETEZ( mpImpl
->mpSizer
);
694 Link aLink
= LINK( this, TabBar
, ImplClickHdl
);
696 if ( mnWinStyle
& (WB_MINSCROLL
| WB_SCROLL
) )
700 mpPrevBtn
= new ImplTabButton( this, WB_REPEAT
);
701 mpPrevBtn
->SetClickHdl( aLink
);
703 mpPrevBtn
->SetSymbol( mbMirrored
? SYMBOL_NEXT
: SYMBOL_PREV
);
708 mpNextBtn
= new ImplTabButton( this, WB_REPEAT
);
709 mpNextBtn
->SetClickHdl( aLink
);
711 mpNextBtn
->SetSymbol( mbMirrored
? SYMBOL_PREV
: SYMBOL_NEXT
);
716 DELETEZ( mpPrevBtn
);
717 DELETEZ( mpNextBtn
);
720 if ( mnWinStyle
& WB_SCROLL
)
724 mpFirstBtn
= new ImplTabButton( this );
725 mpFirstBtn
->SetClickHdl( aLink
);
727 mpFirstBtn
->SetSymbol( mbMirrored
? SYMBOL_LAST
: SYMBOL_FIRST
);
732 mpLastBtn
= new ImplTabButton( this );
733 mpLastBtn
->SetClickHdl( aLink
);
735 mpLastBtn
->SetSymbol( mbMirrored
? SYMBOL_FIRST
: SYMBOL_LAST
);
740 DELETEZ( mpFirstBtn
);
741 DELETEZ( mpLastBtn
);
744 mbHasInsertTab
= (mnWinStyle
& WB_INSERTTAB
);
747 // -----------------------------------------------------------------------
749 void TabBar::ImplEnableControls()
751 if ( mbSizeFormat
|| mbFormat
)
754 // Buttons enablen/disblen
755 sal_Bool bEnableBtn
= mnFirstPos
> 0;
757 mpFirstBtn
->Enable( bEnableBtn
);
759 mpPrevBtn
->Enable( bEnableBtn
);
761 bEnableBtn
= mnFirstPos
< ImplGetLastFirstPos();
763 mpNextBtn
->Enable( bEnableBtn
);
765 mpLastBtn
->Enable( bEnableBtn
);
768 // -----------------------------------------------------------------------
770 void TabBar::ImplShowPage( sal_uInt16 nPos
)
773 long nWidth
= GetOutputSizePixel().Width();
774 if ( nWidth
>= TABBAR_OFFSET_X
)
775 nWidth
-= TABBAR_OFFSET_X
;
776 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
777 if ( nPos
< mnFirstPos
)
778 SetFirstPageId( pItem
->mnId
);
779 else if ( pItem
->maRect
.Right() > nWidth
)
781 while ( pItem
->maRect
.Right() > nWidth
)
783 sal_uInt16 nNewPos
= mnFirstPos
+1;
784 SetFirstPageId( GetPageId( nNewPos
) );
786 if ( nNewPos
!= mnFirstPos
)
792 // -----------------------------------------------------------------------
794 IMPL_LINK( TabBar
, ImplClickHdl
, ImplTabButton
*, pBtn
)
798 sal_uInt16 nNewPos
= mnFirstPos
;
800 if ( pBtn
== mpFirstBtn
)
802 else if ( pBtn
== mpPrevBtn
)
805 nNewPos
= mnFirstPos
-1;
807 else if ( pBtn
== mpNextBtn
)
809 sal_uInt16 nCount
= GetPageCount();
810 if ( mnFirstPos
< nCount
)
811 nNewPos
= mnFirstPos
+1;
815 sal_uInt16 nCount
= GetPageCount();
820 if ( nNewPos
!= mnFirstPos
)
821 SetFirstPageId( GetPageId( nNewPos
) );
825 // -----------------------------------------------------------------------
827 void TabBar::MouseMove( const MouseEvent
& rMEvt
)
829 if ( rMEvt
.IsLeaveWindow() )
830 mbInSelect
= sal_False
;
832 Window::MouseMove( rMEvt
);
835 // -----------------------------------------------------------------------
837 void TabBar::MouseButtonDown( const MouseEvent
& rMEvt
)
839 // Bei Klick in unser Fenster EditModus nur beenden und Klick nicht
841 if ( IsInEditMode() )
847 ImplTabBarItem
* pItem
;
848 sal_uInt16 nSelId
= GetPageId( rMEvt
.GetPosPixel() );
850 if ( !rMEvt
.IsLeft() )
852 Window::MouseButtonDown( rMEvt
);
853 if ( (nSelId
> 0) && (nSelId
!= mnCurPageId
) )
855 sal_uInt16 nPos
= GetPagePos( nSelId
);
856 pItem
= (*mpItemList
)[ nPos
];
858 if ( pItem
->mbEnable
)
860 if ( ImplDeactivatePage() )
862 SetCurPageId( nSelId
);
867 mbInSelect
= sal_True
;
873 if ( rMEvt
.IsMod2() && mbAutoEditMode
&& nSelId
)
875 if ( StartEditMode( nSelId
) )
879 if ( (rMEvt
.GetMode() & (MOUSE_MULTISELECT
| MOUSE_RANGESELECT
)) && (rMEvt
.GetClicks() == 1) )
883 sal_uInt16 nPos
= GetPagePos( nSelId
);
884 sal_Bool bSelectTab
= sal_False
;
885 pItem
= (*mpItemList
)[ nPos
];
887 if ( pItem
->mbEnable
)
889 if ( (rMEvt
.GetMode() & MOUSE_MULTISELECT
) && (mnWinStyle
& WB_MULTISELECT
) )
891 if ( nSelId
!= mnCurPageId
)
893 SelectPage( nSelId
, !IsPageSelected( nSelId
) );
894 bSelectTab
= sal_True
;
897 else if ( mnWinStyle
& (WB_MULTISELECT
| WB_RANGESELECT
) )
899 bSelectTab
= sal_True
;
902 sal_uInt16 nCurPos
= GetPagePos( mnCurPageId
);
903 if ( nPos
<= nCurPos
)
905 // Alle Tabs bis zur angeklickten Tab deselektieren
906 // und alle Tabs von der angeklickten Tab bis
907 // zur aktuellen Position selektieren
909 while ( n
< nCurPos
)
911 pItem
= (*mpItemList
)[ n
];
917 if ( pItem
->mbSelect
!= bSelect
)
919 pItem
->mbSelect
= bSelect
;
920 if ( !pItem
->maRect
.IsEmpty() )
921 Invalidate( pItem
->maRect
);
928 if ( nPos
>= nCurPos
)
930 // Alle Tabs von der aktuellen bis zur angeklickten
931 // Tab selektieren und alle Tabs von der angeklickten
932 // Tab bis zur letzten Tab deselektieren
933 sal_uInt16 nCount
= (sal_uInt16
)mpItemList
->size();
937 pItem
= (*mpItemList
)[ n
];
944 if ( pItem
->mbSelect
!= bSelect
)
946 pItem
->mbSelect
= bSelect
;
947 if ( !pItem
->maRect
.IsEmpty() )
948 Invalidate( pItem
->maRect
);
956 // Gegebenenfalls muss die selektierte Tab gescrollt werden
959 ImplShowPage( nPos
);
965 ImplShowPage( nPos
);
966 mbInSelect
= sal_True
;
971 else if ( rMEvt
.GetClicks() == 2 )
973 // Gegebenenfalls den Double-Click-Handler rufen
974 if ( !rMEvt
.GetModifier() && (!nSelId
|| (nSelId
== mnCurPageId
)) )
976 sal_uInt16 nOldCurId
= mnCurPageId
;
977 mnCurPageId
= nSelId
;
979 // Abfrage, da im DoubleClick-Handler die aktuelle Seite
980 // umgeschaltet werden konnte
981 if ( mnCurPageId
== nSelId
)
982 mnCurPageId
= nOldCurId
;
991 // Nur Select ausfuehren, wenn noch nicht aktuelle Page
992 if ( nSelId
!= mnCurPageId
)
994 sal_uInt16 nPos
= GetPagePos( nSelId
);
995 pItem
= (*mpItemList
)[ nPos
];
997 if ( pItem
->mbEnable
)
999 if ( !pItem
->mbSelect
)
1001 // Muss invalidiert werden
1002 sal_Bool bUpdate
= sal_False
;
1003 if ( IsReallyVisible() && IsUpdateMode() )
1006 // Alle selektierten Items deselektieren
1007 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
1009 pItem
= (*mpItemList
)[ i
];
1010 if ( pItem
->mbSelect
|| (pItem
->mnId
== mnCurPageId
) )
1012 pItem
->mbSelect
= sal_False
;
1014 Invalidate( pItem
->maRect
);
1019 if ( ImplDeactivatePage() )
1021 SetCurPageId( nSelId
);
1028 ImplShowPage( nPos
);
1029 mbInSelect
= sal_True
;
1036 Window::MouseButtonDown( rMEvt
);
1039 // -----------------------------------------------------------------------
1041 void TabBar::MouseButtonUp( const MouseEvent
& rMEvt
)
1043 mbInSelect
= sal_False
;
1044 Window::MouseButtonUp( rMEvt
);
1048 // -----------------------------------------------------------------------
1052 class TabBarPaintGuard
1055 explicit TabBarPaintGuard(TabBar
& rParent
) :
1057 maFont(rParent
.GetFont())
1059 // #i36013# exclude push buttons from painting area
1060 mrParent
.SetClipRegion( Region(mrParent
.GetPageArea()) );
1065 // Restore original font.
1066 mrParent
.SetFont(maFont
);
1067 // remove clip region
1068 mrParent
.SetClipRegion();
1079 explicit TabDrawer(TabBar
& rParent
) :
1081 mpStyleSettings(&mrParent
.GetSettings().GetStyleSettings()),
1084 mbCustomColored(false),
1085 mbSpecialTab(false),
1090 void drawOutputAreaBorder()
1092 WinBits nWinStyle
= mrParent
.GetStyle();
1094 // Bei Border oben und unten einen Strich extra malen
1095 if ( (nWinStyle
& WB_BORDER
) || (nWinStyle
& WB_TOPBORDER
) )
1097 Size aOutputSize
= mrParent
.GetOutputSizePixel();
1098 Rectangle aOutRect
= mrParent
.GetPageArea();
1100 // Bei 3D-Tabs wird auch der Border in 3D gemalt
1101 if ( nWinStyle
& WB_3DTAB
)
1103 mrParent
.SetLineColor( mpStyleSettings
->GetShadowColor() );
1104 mrParent
.DrawLine( Point( aOutRect
.Left(), 0 ), Point( aOutputSize
.Width(), 0 ) );
1107 // Border malen (Strich oben und Strich unten)
1108 mrParent
.SetLineColor( mpStyleSettings
->GetDarkShadowColor() );
1109 mrParent
.DrawLine( aOutRect
.TopLeft(), Point( aOutputSize
.Width()-1, aOutRect
.Top() ) );
1113 void drawOuterFrame()
1115 mrParent
.DrawPolygon(maPoly
);
1118 void drawLeftShadow()
1120 Point p1
= maPoly
[0], p2
= maPoly
[1];
1124 mrParent
.DrawLine(p1
, p2
);
1127 void drawRightShadow()
1129 Point p1
= maPoly
[2];
1130 Point p2
= maPoly
[3];
1133 mrParent
.DrawLine(p1
, p2
);
1136 void drawTopInnerShadow()
1138 Point p1
= maPoly
[0], p2
= maPoly
[3];
1141 mrParent
.DrawLine(p1
, p2
);
1144 void drawBottomShadow(bool bColored
)
1146 Point p1
= maPoly
[1], p2
= maPoly
[2];
1151 mrParent
.DrawLine(p1
, p2
);
1154 p1
+= Point(-1, -1);
1156 mrParent
.DrawLine(p1
, p2
);
1160 void drawText(const String
& aText
)
1162 Rectangle aRect
= maRect
;
1163 long nTextWidth
= mrParent
.GetTextWidth(aText
);
1164 long nTextHeight
= mrParent
.GetTextHeight();
1165 Point aPos
= aRect
.TopLeft();
1166 aPos
.X() += (aRect
.getWidth() - nTextWidth
) / 2;
1167 aPos
.Y() += (aRect
.getHeight() - nTextHeight
) / 2;
1170 mrParent
.DrawText(aPos
, aText
);
1172 mrParent
.DrawCtrlText(
1173 aPos
, aText
, 0, STRING_LEN
, (TEXT_DRAW_DISABLE
| TEXT_DRAW_MNEMONIC
));
1176 void drawOverTopBorder(bool b3DTab
)
1178 Point p1
= maPoly
[0], p2
= maPoly
[3];
1181 Rectangle
aDelRect(p1
, p2
);
1182 mrParent
.DrawRect(aDelRect
);
1186 mrParent
.DrawRect(aDelRect
);
1192 mrParent
.SetLineColor(mpStyleSettings
->GetDarkShadowColor());
1194 // Je nach Status die richtige FillInBrush setzen
1195 // Set the correct FillInBrush depending upon status
1198 // Currently selected Tab
1199 mrParent
.SetFillColor( maSelectedColor
);
1201 else if ( mbCustomColored
)
1203 mrParent
.SetFillColor( maCustomColor
);
1207 mrParent
.SetFillColor( maUnselectedColor
);
1212 // If this is the current tab, draw the left inner shadow the default color,
1213 // otherwise make it the same as the custom background color
1214 Color aColor
= mpStyleSettings
->GetLightColor();
1215 if (mbCustomColored
&& !mbSelected
)
1216 aColor
= maCustomColor
;
1218 mrParent
.SetLineColor(aColor
);
1222 drawTopInnerShadow();
1224 mrParent
.SetLineColor( mpStyleSettings
->GetShadowColor() );
1226 if ( mbCustomColored
&& mbSelected
)
1228 mrParent
.SetLineColor(maCustomColor
);
1229 drawBottomShadow(true);
1232 drawBottomShadow(false);
1234 // Draw the outer frame once more. In some environments, the outer frame
1235 // gets overpainted.
1236 mrParent
.SetLineColor( mpStyleSettings
->GetDarkShadowColor() );
1237 mrParent
.SetFillColor();
1241 void drawPlusImage()
1243 SvtResId
id( BMP_LIST_ADD
);
1244 Image
aPlusImg( id
);
1245 // Center the image within the bounding rectangle.
1246 Size aSize
= aPlusImg
.GetSizePixel();
1247 Point pt
= maRect
.TopLeft();
1248 long nXOffSet
= (maRect
.GetWidth() - aSize
.Width()) / 2;
1249 long nYOffset
= (maRect
.GetHeight() - aSize
.Height()) / 2;
1250 pt
+= Point(nXOffSet
, nYOffset
);
1252 mrParent
.DrawImage(pt
, aPlusImg
);
1255 void setRect(const Rectangle
& rRect
)
1259 long nOffY
= mrParent
.GetPageArea().getY();
1261 // Zuerst geben wir das Polygon gefuellt aus
1262 maPoly
[0] = Point( rRect
.Left(), nOffY
);
1263 maPoly
[1] = Point( rRect
.Left()+TABBAR_OFFSET_X
, rRect
.Bottom() );
1264 maPoly
[2] = Point( rRect
.Right()-TABBAR_OFFSET_X
, rRect
.Bottom() );
1265 maPoly
[3] = Point( rRect
.Right(), nOffY
);
1268 void setSelected(bool b
)
1273 void setCustomColored(bool b
)
1275 mbCustomColored
= b
;
1278 void setSpecialTab(bool b
)
1283 void setEnabled(bool b
)
1288 void setSelectedFillColor(const Color
& rColor
)
1290 maSelectedColor
= rColor
;
1293 void setUnselectedFillColor(const Color
& rColor
)
1295 maUnselectedColor
= rColor
;
1298 void setCustomColor(const Color
& rColor
)
1300 maCustomColor
= rColor
;
1305 const StyleSettings
* mpStyleSettings
;
1310 Color maSelectedColor
;
1311 Color maCustomColor
;
1312 Color maUnselectedColor
;
1315 bool mbCustomColored
:1;
1316 bool mbSpecialTab
:1;
1322 void TabBar::Paint( const Rectangle
& rect
)
1324 if(IsNativeControlSupported(CTRL_WINDOW_BACKGROUND
,PART_ENTIRE_CONTROL
))
1325 DrawNativeControl(CTRL_WINDOW_BACKGROUND
,PART_ENTIRE_CONTROL
,rect
,
1326 CTRL_STATE_ENABLED
,ImplControlValue(0),OUString());
1328 // Items berechnen und ausgeben
1329 sal_uInt16 nItemCount
= (sal_uInt16
)mpItemList
->size();
1335 Color aFaceColor
, aSelectColor
, aFaceTextColor
, aSelectTextColor
;
1336 ImplGetColors( aFaceColor
, aFaceTextColor
, aSelectColor
, aSelectTextColor
);
1339 Font aFont
= GetFont();
1340 Font aLightFont
= aFont
;
1341 aLightFont
.SetWeight( WEIGHT_NORMAL
);
1343 TabBarPaintGuard
aGuard(*this);
1344 TabDrawer
aDrawer(*this);
1345 aDrawer
.setSelectedFillColor(aSelectColor
);
1346 aDrawer
.setUnselectedFillColor(aFaceColor
);
1347 aDrawer
.drawOutputAreaBorder();
1349 // Now, start drawing the tabs.
1351 ImplTabBarItem
* pItem
= ImplGetLastTabBarItem(nItemCount
);
1353 if (pItem
&& mbHasInsertTab
)
1355 // Draw the insert tab at the right end.
1356 Rectangle aRect
= ImplGetInsertTabRect(pItem
);
1357 aDrawer
.setRect(aRect
);
1359 aDrawer
.drawPlusImage();
1362 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1363 ImplTabBarItem
* pCurItem
= NULL
;
1366 // CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt
1367 if ( !pCurItem
&& (pItem
->mnId
== mnCurPageId
) )
1376 bool bCurrent
= pItem
== pCurItem
;
1378 if ( !pItem
->maRect
.IsEmpty() )
1380 Rectangle aRect
= pItem
->maRect
;
1381 bool bSelected
= pItem
->IsSelected(pCurItem
);
1382 // We disable custom background color in high contrast mode.
1383 bool bCustomBgColor
= !pItem
->IsDefaultTabBgColor() && !rStyleSettings
.GetHighContrastMode();
1384 bool bSpecialTab
= (pItem
->mnBits
& TPB_SPECIAL
);
1385 bool bEnabled
= pItem
->mbEnable
;
1386 OUString aText
= pItem
->mbShort
?
1387 GetEllipsisString(pItem
->maText
, mnCurMaxWidth
, TEXT_DRAW_ENDELLIPSIS
) : pItem
->maText
;
1389 aDrawer
.setRect(aRect
);
1390 aDrawer
.setSelected(bSelected
);
1391 aDrawer
.setCustomColored(bCustomBgColor
);
1392 aDrawer
.setSpecialTab(bSpecialTab
);
1393 aDrawer
.setEnabled(bEnabled
);
1394 aDrawer
.setCustomColor(pItem
->maTabBgColor
);
1397 // Aktuelle Page wird mit einem fetten Font ausgegeben
1401 SetFont( aLightFont
);
1403 // Je nach Status die richtige FillInBrush setzen
1404 // Set the correct FillInBrush depending upon status
1406 SetTextColor( aSelectTextColor
);
1407 else if ( bCustomBgColor
)
1408 SetTextColor( pItem
->maTabTextColor
);
1410 SetTextColor( aFaceTextColor
);
1412 // This tab is "special", and a special tab needs a blue text.
1414 SetTextColor(Color(COL_LIGHTBLUE
));
1416 aDrawer
.drawText(aText
);
1421 SetFillColor(aSelectColor
);
1422 aDrawer
.drawOverTopBorder(mnWinStyle
& WB_3DTAB
);
1441 // -----------------------------------------------------------------------
1442 void TabBar::Resize()
1444 Size aNewSize
= GetOutputSizePixel();
1446 long nSizerWidth
= 0;
1447 long nButtonWidth
= 0;
1450 if ( mpImpl
->mpSizer
)
1452 Size aSizerSize
= mpImpl
->mpSizer
->GetSizePixel();
1453 Point
aNewSizerPos( mbMirrored
? 0 : (aNewSize
.Width()-aSizerSize
.Width()), 0 );
1454 Size
aNewSizerSize( aSizerSize
.Width(), aNewSize
.Height() );
1455 mpImpl
->mpSizer
->SetPosSizePixel( aNewSizerPos
, aNewSizerSize
);
1456 nSizerWidth
= aSizerSize
.Width();
1459 // Scroll-Buttons anordnen
1460 long nHeight
= aNewSize
.Height();
1461 // Font in der groesse Anpassen?
1462 ImplInitSettings( sal_True
, sal_False
);
1464 long nX
= mbMirrored
? (aNewSize
.Width()-nHeight
) : 0;
1465 long nXDiff
= mbMirrored
? -nHeight
: nHeight
;
1467 Size
aBtnSize( nHeight
, nHeight
);
1470 mpFirstBtn
->SetPosSizePixel( Point( nX
, 0 ), aBtnSize
);
1472 nButtonWidth
+= nHeight
;
1476 mpPrevBtn
->SetPosSizePixel( Point( nX
, 0 ), aBtnSize
);
1478 nButtonWidth
+= nHeight
;
1482 mpNextBtn
->SetPosSizePixel( Point( nX
, 0 ), aBtnSize
);
1484 nButtonWidth
+= nHeight
;
1488 mpLastBtn
->SetPosSizePixel( Point( nX
, 0 ), aBtnSize
);
1490 nButtonWidth
+= nHeight
;
1494 maWinSize
= aNewSize
;
1498 mnOffX
= nSizerWidth
;
1499 mnLastOffX
= maWinSize
.Width() - nButtonWidth
- 1;
1503 mnOffX
= nButtonWidth
;
1504 mnLastOffX
= maWinSize
.Width() - nSizerWidth
- 1;
1508 mbSizeFormat
= sal_True
;
1509 if ( IsReallyVisible() )
1511 if ( ImplCalcWidth() )
1516 // Button enablen/disablen
1517 ImplEnableControls();
1520 // -----------------------------------------------------------------------
1522 void TabBar::RequestHelp( const HelpEvent
& rHEvt
)
1524 sal_uInt16 nItemId
= GetPageId( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ) );
1527 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
1529 OUString aStr
= GetHelpText( nItemId
);
1530 if (!aStr
.isEmpty())
1532 Rectangle aItemRect
= GetPageRect( nItemId
);
1533 Point aPt
= OutputToScreenPixel( aItemRect
.TopLeft() );
1534 aItemRect
.Left() = aPt
.X();
1535 aItemRect
.Top() = aPt
.Y();
1536 aPt
= OutputToScreenPixel( aItemRect
.BottomRight() );
1537 aItemRect
.Right() = aPt
.X();
1538 aItemRect
.Bottom() = aPt
.Y();
1539 Help::ShowBalloon( this, aItemRect
.Center(), aItemRect
, aStr
);
1543 else if ( rHEvt
.GetMode() & HELPMODE_EXTENDED
)
1545 OUString
aHelpId( OStringToOUString( GetHelpId( nItemId
), RTL_TEXTENCODING_UTF8
) );
1546 if ( !aHelpId
.isEmpty() )
1548 // Wenn eine Hilfe existiert, dann ausloesen
1549 Help
* pHelp
= Application::GetHelp();
1551 pHelp
->Start( aHelpId
, this );
1556 // Bei Quick- oder Ballloon-Help zeigen wir den Text an,
1557 // wenn dieser abgeschnitten oder nicht voll sichtbar ist
1558 if ( rHEvt
.GetMode() & (HELPMODE_QUICK
| HELPMODE_BALLOON
) )
1560 sal_uInt16 nPos
= GetPagePos( nItemId
);
1561 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
1562 if ( pItem
->mbShort
||
1563 (pItem
->maRect
.Right()-TABBAR_OFFSET_X
-5 > mnLastOffX
) )
1565 Rectangle aItemRect
= GetPageRect( nItemId
);
1566 Point aPt
= OutputToScreenPixel( aItemRect
.TopLeft() );
1567 aItemRect
.Left() = aPt
.X();
1568 aItemRect
.Top() = aPt
.Y();
1569 aPt
= OutputToScreenPixel( aItemRect
.BottomRight() );
1570 aItemRect
.Right() = aPt
.X();
1571 aItemRect
.Bottom() = aPt
.Y();
1572 OUString aStr
= (*mpItemList
)[ nPos
]->maText
;
1573 if (!aStr
.isEmpty())
1575 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
1576 Help::ShowBalloon( this, aItemRect
.Center(), aItemRect
, aStr
);
1578 Help::ShowQuickHelp( this, aItemRect
, aStr
);
1585 Window::RequestHelp( rHEvt
);
1588 // -----------------------------------------------------------------------
1590 void TabBar::StateChanged( StateChangedType nType
)
1592 Window::StateChanged( nType
);
1594 if ( nType
== STATE_CHANGE_INITSHOW
)
1596 if ( (mbSizeFormat
|| mbFormat
) && !mpItemList
->empty() )
1599 else if ( (nType
== STATE_CHANGE_ZOOM
) ||
1600 (nType
== STATE_CHANGE_CONTROLFONT
) )
1602 ImplInitSettings( sal_True
, sal_False
);
1605 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
1607 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
1609 ImplInitSettings( sal_False
, sal_True
);
1612 else if ( nType
== STATE_CHANGE_MIRRORING
)
1614 // reacts on calls of EnableRTL, have to mirror all child controls
1615 if( mpFirstBtn
) mpFirstBtn
->EnableRTL( IsRTLEnabled() );
1616 if( mpPrevBtn
) mpPrevBtn
->EnableRTL( IsRTLEnabled() );
1617 if( mpNextBtn
) mpNextBtn
->EnableRTL( IsRTLEnabled() );
1618 if( mpLastBtn
) mpLastBtn
->EnableRTL( IsRTLEnabled() );
1619 if( mpImpl
->mpSizer
) mpImpl
->mpSizer
->EnableRTL( IsRTLEnabled() );
1620 if( mpEdit
) mpEdit
->EnableRTL( IsRTLEnabled() );
1624 // -----------------------------------------------------------------------
1626 void TabBar::DataChanged( const DataChangedEvent
& rDCEvt
)
1628 Window::DataChanged( rDCEvt
);
1630 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
1631 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
1632 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1633 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
1635 ImplInitSettings( sal_True
, sal_True
);
1640 // -----------------------------------------------------------------------
1642 void TabBar::ImplSelect()
1646 CallEventListeners( VCLEVENT_TABBAR_PAGESELECTED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(mnCurPageId
)) );
1649 // -----------------------------------------------------------------------
1651 void TabBar::Select()
1653 maSelectHdl
.Call( this );
1656 // -----------------------------------------------------------------------
1658 void TabBar::DoubleClick()
1660 maDoubleClickHdl
.Call( this );
1663 // -----------------------------------------------------------------------
1665 void TabBar::Split()
1667 maSplitHdl
.Call( this );
1670 // -----------------------------------------------------------------------
1672 void TabBar::ImplActivatePage()
1676 CallEventListeners( VCLEVENT_TABBAR_PAGEACTIVATED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(mnCurPageId
)) );
1679 // -----------------------------------------------------------------------
1681 void TabBar::ActivatePage()
1683 maActivatePageHdl
.Call( this );
1686 // -----------------------------------------------------------------------
1688 long TabBar::ImplDeactivatePage()
1690 long nRet
= DeactivatePage();
1692 CallEventListeners( VCLEVENT_TABBAR_PAGEDEACTIVATED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(mnCurPageId
)) );
1697 void TabBar::ImplPrePaint()
1699 sal_uInt16 nItemCount
= (sal_uInt16
)mpItemList
->size();
1703 ImplTabBarItem
* pItem
;
1705 // TabBar muss formatiert sein
1708 // Beim ersten Format auch dafuer sorgen, das aktuelle TabPage
1710 if ( mbFirstFormat
)
1712 mbFirstFormat
= sal_False
;
1714 if ( mnCurPageId
&& (mnFirstPos
== 0) && !mbDropPos
)
1716 pItem
= (*mpItemList
)[ GetPagePos( mnCurPageId
) ];
1717 if ( pItem
->maRect
.IsEmpty() )
1719 // mbDropPos setzen (bzw. misbrauchen) um Invalidate()
1721 mbDropPos
= sal_True
;
1722 SetFirstPageId( mnCurPageId
);
1723 mbDropPos
= sal_False
;
1724 if ( mnFirstPos
!= 0 )
1731 ImplTabBarItem
* TabBar::ImplGetLastTabBarItem( sal_uInt16 nItemCount
)
1733 // letzten sichtbaren Eintrag suchen
1734 sal_uInt16 n
= mnFirstPos
+1;
1735 if ( n
>= nItemCount
)
1737 ImplTabBarItem
* pItem
= seek( n
);
1740 if ( !pItem
->maRect
.IsEmpty() )
1749 // Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt)
1752 else if ( n
>= nItemCount
)
1758 Rectangle
TabBar::ImplGetInsertTabRect(ImplTabBarItem
* pItem
) const
1760 if (mbHasInsertTab
&& pItem
)
1762 Rectangle aInsTabRect
= pItem
->maRect
;
1765 aInsTabRect
.getX() + aInsTabRect
.getWidth() - TABBAR_OFFSET_X
- TABBAR_OFFSET_X2
);
1768 aInsTabRect
.getX() - 3*TABBAR_OFFSET_X
- TABBAR_OFFSET_X2
);
1769 aInsTabRect
.setWidth(32);
1775 // -----------------------------------------------------------------------
1777 long TabBar::DeactivatePage()
1779 if ( maDeactivatePageHdl
.IsSet() )
1780 return maDeactivatePageHdl
.Call( this );
1785 // -----------------------------------------------------------------------
1787 long TabBar::StartRenaming()
1789 if ( maStartRenamingHdl
.IsSet() )
1790 return maStartRenamingHdl
.Call( this );
1795 // -----------------------------------------------------------------------
1797 long TabBar::AllowRenaming()
1799 if ( maAllowRenamingHdl
.IsSet() )
1800 return maAllowRenamingHdl
.Call( this );
1805 // -----------------------------------------------------------------------
1807 void TabBar::EndRenaming()
1809 maEndRenamingHdl
.Call( this );
1812 // -----------------------------------------------------------------------
1814 void TabBar::Mirror()
1819 // -----------------------------------------------------------------------
1821 void TabBar::InsertPage( sal_uInt16 nPageId
, const OUString
& rText
,
1822 TabBarPageBits nBits
, sal_uInt16 nPos
)
1824 DBG_ASSERT( nPageId
, "TabBar::InsertPage(): PageId == 0" );
1825 DBG_ASSERT( GetPagePos( nPageId
) == PAGE_NOT_FOUND
,
1826 "TabBar::InsertPage(): PageId already exists" );
1827 DBG_ASSERT( nBits
<= TPB_SPECIAL
, "TabBar::InsertPage(): nBits is wrong" );
1829 // PageItem anlegen und in die Item-Liste eintragen
1830 ImplTabBarItem
* pItem
= new ImplTabBarItem( nPageId
, rText
, nBits
);
1831 if ( nPos
< mpItemList
->size() ) {
1832 ImplTabBarList::iterator it
= mpItemList
->begin();
1833 ::std::advance( it
, nPos
);
1834 mpItemList
->insert( it
, pItem
);
1836 mpItemList
->push_back( pItem
);
1838 mbSizeFormat
= sal_True
;
1840 // CurPageId gegebenenfalls setzen
1842 mnCurPageId
= nPageId
;
1844 // Leiste neu ausgeben
1845 if ( IsReallyVisible() && IsUpdateMode() )
1848 CallEventListeners( VCLEVENT_TABBAR_PAGEINSERTED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(nPageId
)) );
1851 // -----------------------------------------------------------------------
1853 Color
TabBar::GetTabBgColor( sal_uInt16 nPageId
) const
1855 sal_uInt16 nPos
= GetPagePos( nPageId
);
1857 if ( nPos
!= PAGE_NOT_FOUND
)
1858 return (*mpItemList
)[ nPos
]->maTabBgColor
;
1860 return Color( COL_AUTO
);
1863 void TabBar::SetTabBgColor( sal_uInt16 nPageId
, const Color
& aTabBgColor
)
1865 sal_uInt16 nPos
= GetPagePos( nPageId
);
1866 ImplTabBarItem
* pItem
;
1867 if ( nPos
!= PAGE_NOT_FOUND
)
1869 pItem
= (*mpItemList
)[ nPos
];
1870 if ( aTabBgColor
!= Color( COL_AUTO
) )
1872 pItem
->maTabBgColor
= aTabBgColor
;
1873 if ( aTabBgColor
.GetLuminance() <= 128 ) //Do not use aTabBgColor.IsDark(), because that threshold is way too low...
1874 pItem
->maTabTextColor
= Color( COL_WHITE
);
1876 pItem
->maTabTextColor
= Color( COL_BLACK
);
1880 pItem
->maTabBgColor
= Color( COL_AUTO
);
1881 pItem
->maTabTextColor
= Color( COL_AUTO
);
1886 // -----------------------------------------------------------------------
1888 void TabBar::RemovePage( sal_uInt16 nPageId
)
1890 sal_uInt16 nPos
= GetPagePos( nPageId
);
1893 if ( nPos
!= PAGE_NOT_FOUND
)
1895 if ( mnCurPageId
== nPageId
)
1898 // Testen, ob erste sichtbare Seite verschoben werden muss
1899 if ( mnFirstPos
> nPos
)
1902 // Item-Daten loeschen
1903 ImplTabBarList::iterator it
= mpItemList
->begin();
1904 ::std::advance( it
, nPos
);
1906 mpItemList
->erase( it
);
1908 // Leiste neu ausgeben
1909 if ( IsReallyVisible() && IsUpdateMode() )
1912 CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(nPageId
)) );
1916 // -----------------------------------------------------------------------
1918 void TabBar::MovePage( sal_uInt16 nPageId
, sal_uInt16 nNewPos
)
1920 sal_uInt16 nPos
= GetPagePos( nPageId
);
1921 Pair
aPair( nPos
, nNewPos
);
1923 if ( nPos
< nNewPos
)
1926 if ( nPos
== nNewPos
)
1930 if ( nPos
!= PAGE_NOT_FOUND
)
1932 // TabBar-Item in der Liste verschieben
1933 ImplTabBarList::iterator it
= mpItemList
->begin();
1934 ::std::advance( it
, nPos
);
1935 ImplTabBarItem
* pItem
= *it
;
1936 mpItemList
->erase( it
);
1937 if ( nNewPos
< mpItemList
->size() ) {
1938 it
= mpItemList
->begin();
1939 ::std::advance( it
, nNewPos
);
1940 mpItemList
->insert( it
, pItem
);
1942 mpItemList
->push_back( pItem
);
1945 // Leiste neu ausgeben
1946 if ( IsReallyVisible() && IsUpdateMode() )
1949 CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED
, (void*) &aPair
);
1953 // -----------------------------------------------------------------------
1955 void TabBar::Clear()
1957 // Alle Items loeschen
1958 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
) {
1959 delete (*mpItemList
)[ i
];
1961 mpItemList
->clear();
1963 // Items aus der Liste loeschen
1964 mbSizeFormat
= sal_True
;
1967 maCurrentItemList
= 0;
1969 // Leiste neu ausgeben
1970 if ( IsReallyVisible() && IsUpdateMode() )
1973 CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(PAGE_NOT_FOUND
)) );
1976 // -----------------------------------------------------------------------
1978 sal_Bool
TabBar::IsPageEnabled( sal_uInt16 nPageId
) const
1980 sal_uInt16 nPos
= GetPagePos( nPageId
);
1982 if ( nPos
!= PAGE_NOT_FOUND
)
1983 return (*mpItemList
)[ nPos
]->mbEnable
;
1988 // -----------------------------------------------------------------------
1990 void TabBar::SetPageBits( sal_uInt16 nPageId
, TabBarPageBits nBits
)
1992 sal_uInt16 nPos
= GetPagePos( nPageId
);
1994 if ( nPos
!= PAGE_NOT_FOUND
)
1996 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
1998 if ( pItem
->mnBits
!= nBits
)
2000 pItem
->mnBits
= nBits
;
2002 // Leiste neu ausgeben
2003 if ( IsReallyVisible() && IsUpdateMode() )
2004 Invalidate( pItem
->maRect
);
2009 // -----------------------------------------------------------------------
2011 TabBarPageBits
TabBar::GetPageBits( sal_uInt16 nPageId
) const
2013 sal_uInt16 nPos
= GetPagePos( nPageId
);
2015 if ( nPos
!= PAGE_NOT_FOUND
)
2016 return (*mpItemList
)[ nPos
]->mnBits
;
2021 // -----------------------------------------------------------------------
2023 sal_uInt16
TabBar::GetPageCount() const
2025 return (sal_uInt16
)mpItemList
->size();
2028 // -----------------------------------------------------------------------
2030 sal_uInt16
TabBar::GetPageId( sal_uInt16 nPos
) const
2032 return ( nPos
< mpItemList
->size() ) ? (*mpItemList
)[ nPos
]->mnId
: 0;
2035 // -----------------------------------------------------------------------
2037 sal_uInt16
TabBar::GetPagePos( sal_uInt16 nPageId
) const
2039 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
) {
2040 if ( (*mpItemList
)[ i
]->mnId
== nPageId
) {
2041 return sal_uInt16( i
);
2044 return PAGE_NOT_FOUND
;
2047 // -----------------------------------------------------------------------
2049 sal_uInt16
TabBar::GetPageId( const Point
& rPos
, bool bCheckInsTab
) const
2051 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
2053 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
2054 if ( pItem
->maRect
.IsInside( rPos
) )
2058 if (bCheckInsTab
&& mbHasInsertTab
&& !mpItemList
->empty())
2060 ImplTabBarItem
* pItem
= mpItemList
->back();
2061 if (ImplGetInsertTabRect(pItem
).IsInside(rPos
))
2062 return INSERT_TAB_POS
;
2068 // -----------------------------------------------------------------------
2070 Rectangle
TabBar::GetPageRect( sal_uInt16 nPageId
) const
2072 sal_uInt16 nPos
= GetPagePos( nPageId
);
2074 if ( nPos
!= PAGE_NOT_FOUND
)
2075 return (*mpItemList
)[ nPos
]->maRect
;
2080 // -----------------------------------------------------------------------
2082 void TabBar::SetCurPageId( sal_uInt16 nPageId
)
2084 sal_uInt16 nPos
= GetPagePos( nPageId
);
2086 // Wenn Item nicht existiert, dann nichts machen
2087 if ( nPos
!= PAGE_NOT_FOUND
)
2089 // Wenn sich aktuelle Page nicht geaendert hat, dann muessen wir
2090 // jetzt nichts mehr machen
2091 if ( nPageId
== mnCurPageId
)
2094 // Muss invalidiert werden
2095 sal_Bool bUpdate
= sal_False
;
2096 if ( IsReallyVisible() && IsUpdateMode() )
2099 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2100 ImplTabBarItem
* pOldItem
;
2103 pOldItem
= (*mpItemList
)[ GetPagePos( mnCurPageId
) ];
2107 // Wenn Page nicht selektiert, dann vorher selektierte Seite
2108 // deselktieren, wenn dies die einzige selektierte Seite ist
2109 if ( !pItem
->mbSelect
&& pOldItem
)
2111 sal_uInt16 nSelPageCount
= GetSelectPageCount();
2112 if ( nSelPageCount
== 1 )
2113 pOldItem
->mbSelect
= sal_False
;
2114 pItem
->mbSelect
= sal_True
;
2117 mnCurPageId
= nPageId
;
2118 mbFormat
= sal_True
;
2120 // Dafuer sorgen, das aktuelle Page sichtbar wird
2121 if ( IsReallyVisible() )
2123 if ( nPos
< mnFirstPos
)
2124 SetFirstPageId( nPageId
);
2127 // sichtbare Breite berechnen
2128 long nWidth
= mnLastOffX
;
2129 if ( nWidth
> TABBAR_OFFSET_X
)
2130 nWidth
-= TABBAR_OFFSET_X
;
2131 if ( nWidth
> ADDNEWPAGE_AREAWIDTH
)
2132 nWidth
-= ADDNEWPAGE_AREAWIDTH
;
2134 if ( pItem
->maRect
.IsEmpty() )
2137 while ( (mbMirrored
? (pItem
->maRect
.Left() < mnOffX
) : (pItem
->maRect
.Right() > nWidth
)) ||
2138 pItem
->maRect
.IsEmpty() )
2140 sal_uInt16 nNewPos
= mnFirstPos
+1;
2141 // Dafuer sorgen, das min. die aktuelle TabPages als
2142 // erste TabPage sichtbar ist
2143 if ( nNewPos
>= nPos
)
2145 SetFirstPageId( nPageId
);
2149 SetFirstPageId( GetPageId( nNewPos
) );
2151 // Falls erste Seite nicht weitergeschaltet wird, dann
2152 // koennen wir abbrechen
2153 if ( nNewPos
!= mnFirstPos
)
2159 // Leiste neu ausgeben
2162 Invalidate( pItem
->maRect
);
2164 Invalidate( pOldItem
->maRect
);
2169 // -----------------------------------------------------------------------
2171 void TabBar::MakeVisible( sal_uInt16 nPageId
)
2173 if ( !IsReallyVisible() )
2176 sal_uInt16 nPos
= GetPagePos( nPageId
);
2178 // Wenn Item nicht existiert, dann nichts machen
2179 if ( nPos
!= PAGE_NOT_FOUND
)
2181 if ( nPos
< mnFirstPos
)
2182 SetFirstPageId( nPageId
);
2185 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2187 // sichtbare Breite berechnen
2188 long nWidth
= mnLastOffX
;
2189 if ( nWidth
> TABBAR_OFFSET_X
)
2190 nWidth
-= TABBAR_OFFSET_X
;
2192 if ( mbFormat
|| pItem
->maRect
.IsEmpty() )
2194 mbFormat
= sal_True
;
2198 while ( (pItem
->maRect
.Right() > nWidth
) ||
2199 pItem
->maRect
.IsEmpty() )
2201 sal_uInt16 nNewPos
= mnFirstPos
+1;
2202 // Dafuer sorgen, das min. die aktuelle TabPages als
2203 // erste TabPage sichtbar ist
2204 if ( nNewPos
>= nPos
)
2206 SetFirstPageId( nPageId
);
2210 SetFirstPageId( GetPageId( nNewPos
) );
2212 // Falls erste Seite nicht weitergeschaltet wird, dann
2213 // koennen wir abbrechen
2214 if ( nNewPos
!= mnFirstPos
)
2221 // -----------------------------------------------------------------------
2223 void TabBar::SetFirstPageId( sal_uInt16 nPageId
)
2225 sal_uInt16 nPos
= GetPagePos( nPageId
);
2227 // Wenn Item nicht existiert, dann sal_False zurueckgeben
2228 if ( nPos
!= PAGE_NOT_FOUND
)
2230 if ( nPos
!= mnFirstPos
)
2232 // Dafuer sorgen, das nach Moeglichkteit soviele Pages wie
2233 // moeglich sichtbar sind
2235 sal_uInt16 nLastFirstPos
= ImplGetLastFirstPos();
2237 if ( nPos
> nLastFirstPos
)
2238 nNewPos
= nLastFirstPos
;
2242 if ( nNewPos
!= mnFirstPos
)
2244 mnFirstPos
= nNewPos
;
2245 mbFormat
= sal_True
;
2247 // Leiste neu ausgeben (Achtung: mbDropPos beachten, da wenn
2248 // dieses Flag gesetzt ist, wird direkt gepaintet)
2249 if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos
)
2256 // -----------------------------------------------------------------------
2258 void TabBar::SelectPage( sal_uInt16 nPageId
, sal_Bool bSelect
)
2260 sal_uInt16 nPos
= GetPagePos( nPageId
);
2262 if ( nPos
!= PAGE_NOT_FOUND
)
2264 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2266 if ( pItem
->mbSelect
!= bSelect
)
2268 pItem
->mbSelect
= bSelect
;
2270 // Leiste neu ausgeben
2271 if ( IsReallyVisible() && IsUpdateMode() )
2272 Invalidate( pItem
->maRect
);
2277 // -----------------------------------------------------------------------
2279 sal_uInt16
TabBar::GetSelectPageCount() const
2281 sal_uInt16 nSelected
= 0;
2282 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
2284 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
2285 if ( pItem
->mbSelect
)
2292 // -----------------------------------------------------------------------
2294 sal_Bool
TabBar::IsPageSelected( sal_uInt16 nPageId
) const
2296 sal_uInt16 nPos
= GetPagePos( nPageId
);
2297 if ( nPos
!= PAGE_NOT_FOUND
)
2298 return (*mpItemList
)[ nPos
]->mbSelect
;
2303 // -----------------------------------------------------------------------
2305 sal_Bool
TabBar::StartEditMode( sal_uInt16 nPageId
)
2307 sal_uInt16 nPos
= GetPagePos( nPageId
);
2308 if ( mpEdit
|| (nPos
== PAGE_NOT_FOUND
) || (mnLastOffX
< 8) )
2312 if ( StartRenaming() )
2314 ImplShowPage( nPos
);
2318 mpEdit
= new TabBarEdit( this, WB_CENTER
);
2319 Rectangle aRect
= GetPageRect( mnEditId
);
2320 long nX
= aRect
.Left()+TABBAR_OFFSET_X
+(TABBAR_OFFSET_X2
/2);
2321 long nWidth
= aRect
.GetWidth()-(TABBAR_OFFSET_X
*2)-TABBAR_OFFSET_X2
;
2322 if ( mnEditId
!= GetCurPageId() )
2324 if ( nX
+nWidth
> mnLastOffX
)
2325 nWidth
= mnLastOffX
-nX
;
2329 nWidth
= aRect
.GetWidth();
2331 mpEdit
->SetText( GetPageText( mnEditId
) );
2332 mpEdit
->setPosSizePixel( nX
, aRect
.Top()+mnOffY
+1, nWidth
, aRect
.GetHeight()-3 );
2333 Font aFont
= GetPointFont();
2334 Color aForegroundColor
;
2335 Color aBackgroundColor
;
2338 Color aFaceTextColor
;
2339 Color aSelectTextColor
;
2340 ImplGetColors( aFaceColor
, aFaceTextColor
, aSelectColor
, aSelectTextColor
);
2341 if ( mnEditId
!= GetCurPageId() )
2342 aFont
.SetWeight( WEIGHT_LIGHT
);
2343 if ( IsPageSelected( mnEditId
) || (mnEditId
== GetCurPageId()) )
2345 aForegroundColor
= aSelectTextColor
;
2346 aBackgroundColor
= aSelectColor
;
2350 aForegroundColor
= aFaceTextColor
;
2351 aBackgroundColor
= aFaceColor
;
2353 if ( GetPageBits( mnEditId
) & TPB_SPECIAL
)
2354 aForegroundColor
= Color( COL_LIGHTBLUE
);
2355 mpEdit
->SetControlFont( aFont
);
2356 mpEdit
->SetControlForeground( aForegroundColor
);
2357 mpEdit
->SetControlBackground( aBackgroundColor
);
2358 mpEdit
->GrabFocus();
2359 mpEdit
->SetSelection( Selection( 0, mpEdit
->GetText().getLength() ) );
2370 // -----------------------------------------------------------------------
2372 void TabBar::EndEditMode( sal_Bool bCancel
)
2377 sal_Bool bEnd
= sal_True
;
2378 mbEditCanceled
= bCancel
;
2379 maEditText
= mpEdit
->GetText();
2380 mpEdit
->SetPostEvent();
2383 long nAllowRenaming
= AllowRenaming();
2384 if ( nAllowRenaming
== TABBAR_RENAMING_YES
)
2385 SetPageText( mnEditId
, maEditText
);
2386 else if ( nAllowRenaming
== TABBAR_RENAMING_NO
)
2388 else // nAllowRenaming == TABBAR_RENAMING_CANCEL
2389 mbEditCanceled
= sal_True
;
2392 // renaming not allowed, than reset edit data
2395 mpEdit
->ResetPostEvent();
2396 mpEdit
->GrabFocus();
2400 // close edit and call end hdl
2408 maEditText
= OUString();
2409 mbEditCanceled
= false;
2413 // -----------------------------------------------------------------------
2415 void TabBar::SetMirrored(bool bMirrored
)
2417 if( mbMirrored
!= bMirrored
)
2419 mbMirrored
= bMirrored
;
2420 mbSizeFormat
= true;
2421 ImplInitControls(); // for button images
2422 Resize(); // recalculates control positions
2427 void TabBar::SetEffectiveRTL( bool bRTL
)
2429 SetMirrored( bRTL
!= Application::GetSettings().GetLayoutRTL() );
2432 bool TabBar::IsEffectiveRTL() const
2434 return IsMirrored() != Application::GetSettings().GetLayoutRTL();
2437 // -----------------------------------------------------------------------
2439 void TabBar::SetMaxPageWidth( long nMaxWidth
)
2441 if ( mnMaxPageWidth
!= nMaxWidth
)
2443 mnMaxPageWidth
= nMaxWidth
;
2444 mbSizeFormat
= sal_True
;
2446 // Leiste neu ausgeben
2447 if ( IsReallyVisible() && IsUpdateMode() )
2452 // -----------------------------------------------------------------------
2454 void TabBar::SetPageText( sal_uInt16 nPageId
, const OUString
& rText
)
2456 sal_uInt16 nPos
= GetPagePos( nPageId
);
2457 if ( nPos
!= PAGE_NOT_FOUND
)
2459 (*mpItemList
)[ nPos
]->maText
= rText
;
2460 mbSizeFormat
= sal_True
;
2462 // Leiste neu ausgeben
2463 if ( IsReallyVisible() && IsUpdateMode() )
2466 CallEventListeners( VCLEVENT_TABBAR_PAGETEXTCHANGED
, reinterpret_cast<void*>(sal::static_int_cast
<sal_IntPtr
>(nPageId
)) );
2470 // -----------------------------------------------------------------------
2472 OUString
TabBar::GetPageText( sal_uInt16 nPageId
) const
2474 sal_uInt16 nPos
= GetPagePos( nPageId
);
2475 if ( nPos
!= PAGE_NOT_FOUND
)
2476 return (*mpItemList
)[ nPos
]->maText
;
2480 // -----------------------------------------------------------------------
2482 XubString
TabBar::GetHelpText( sal_uInt16 nPageId
) const
2484 sal_uInt16 nPos
= GetPagePos( nPageId
);
2485 if ( nPos
!= PAGE_NOT_FOUND
)
2487 ImplTabBarItem
* pItem
= (*mpItemList
)[ nPos
];
2488 if (pItem
->maHelpText
.isEmpty() && !pItem
->maHelpId
.isEmpty())
2490 Help
* pHelp
= Application::GetHelp();
2492 pItem
->maHelpText
= pHelp
->GetHelpText( OStringToOUString( pItem
->maHelpId
, RTL_TEXTENCODING_UTF8
), this );
2495 return pItem
->maHelpText
;
2500 // -----------------------------------------------------------------------
2502 OString
TabBar::GetHelpId( sal_uInt16 nPageId
) const
2504 sal_uInt16 nPos
= GetPagePos( nPageId
);
2506 if ( nPos
!= PAGE_NOT_FOUND
)
2507 return (*mpItemList
)[ nPos
]->maHelpId
;
2511 // -----------------------------------------------------------------------
2513 sal_Bool
TabBar::StartDrag( const CommandEvent
& rCEvt
, Region
& rRegion
)
2515 if ( !(mnWinStyle
& WB_DRAG
) || (rCEvt
.GetCommand() != COMMAND_STARTDRAG
) )
2518 // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
2519 // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
2520 // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
2521 // dies nur bei einer Mausaktion.
2522 // Ausserdem machen wir das nur, wenn kein Select() ausgeloest wurde,
2523 // da der Select schon den Bereich gescrollt haben kann
2524 if ( rCEvt
.IsMouseEvent() && !mbInSelect
)
2526 sal_uInt16 nSelId
= GetPageId( rCEvt
.GetMousePosPixel() );
2528 // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
2532 // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
2533 // Seite setzen und Select rufen.
2534 if ( !IsPageSelected( nSelId
) )
2536 if ( ImplDeactivatePage() )
2538 SetCurPageId( nSelId
);
2547 mbInSelect
= sal_False
;
2557 // -----------------------------------------------------------------------
2559 sal_uInt16
TabBar::ShowDropPos( const Point
& rPos
)
2561 ImplTabBarItem
* pItem
;
2563 sal_uInt16 nNewDropPos
;
2564 sal_uInt16 nItemCount
= (sal_uInt16
)mpItemList
->size();
2567 if ( rPos
.X() > mnLastOffX
-TABBAR_DRAG_SCROLLOFF
)
2569 pItem
= (*mpItemList
)[ mpItemList
->size()-1 ];
2570 if ( !pItem
->maRect
.IsEmpty() && (rPos
.X() > pItem
->maRect
.Right()) )
2571 nNewDropPos
= (sal_uInt16
)mpItemList
->size();
2574 nNewDropPos
= mnFirstPos
+1;
2578 else if ( (rPos
.X() <= mnOffX
) ||
2579 (!mnOffX
&& (rPos
.X() <= TABBAR_DRAG_SCROLLOFF
)) )
2583 nNewDropPos
= mnFirstPos
;
2591 nDropId
= GetPageId( rPos
);
2594 nNewDropPos
= GetPagePos( nDropId
);
2595 if ( mnFirstPos
&& (nNewDropPos
== mnFirstPos
-1) )
2599 nNewDropPos
= nItemCount
;
2602 if ( mbDropPos
&& (nNewDropPos
== mnDropPos
) && !nScroll
)
2607 mbDropPos
= sal_True
;
2608 mnDropPos
= nNewDropPos
;
2612 sal_uInt16 nOldFirstPos
= mnFirstPos
;
2613 SetFirstPageId( GetPageId( mnFirstPos
+nScroll
) );
2615 // Direkt ausgeben, da kein Paint bei Drag and Drop moeglich
2616 if ( nOldFirstPos
!= mnFirstPos
)
2618 Rectangle
aRect( mnOffX
, 0, mnLastOffX
, maWinSize
.Height() );
2619 SetFillColor( GetBackground().GetColor() );
2625 // Drop-Position-Pfeile ausgeben
2626 Color
aBlackColor( COL_BLACK
);
2628 long nY
= (maWinSize
.Height()/2)-1;
2629 sal_uInt16 nCurPos
= GetPagePos( mnCurPageId
);
2631 SetLineColor( aBlackColor
);
2632 if ( mnDropPos
< nItemCount
)
2634 pItem
= (*mpItemList
)[ mnDropPos
];
2635 nX
= pItem
->maRect
.Left()+TABBAR_OFFSET_X
;
2636 if ( mnDropPos
== nCurPos
)
2640 if ( !pItem
->IsDefaultTabBgColor() && !pItem
->mbSelect
)
2641 SetLineColor( pItem
->maTabTextColor
);
2642 DrawLine( Point( nX
, nY
), Point( nX
, nY
) );
2643 DrawLine( Point( nX
+1, nY
-1 ), Point( nX
+1, nY
+1 ) );
2644 DrawLine( Point( nX
+2, nY
-2 ), Point( nX
+2, nY
+2 ) );
2645 SetLineColor( aBlackColor
);
2647 if ( (mnDropPos
> 0) && (mnDropPos
< nItemCount
+1) )
2649 pItem
= (*mpItemList
)[ mnDropPos
-1 ];
2650 nX
= pItem
->maRect
.Right()-TABBAR_OFFSET_X
;
2651 if ( mnDropPos
== nCurPos
)
2653 if ( !pItem
->IsDefaultTabBgColor() && !pItem
->mbSelect
)
2654 SetLineColor( pItem
->maTabTextColor
);
2655 DrawLine( Point( nX
, nY
), Point( nX
, nY
) );
2656 DrawLine( Point( nX
-1, nY
-1 ), Point( nX
-1, nY
+1 ) );
2657 DrawLine( Point( nX
-2, nY
-2 ), Point( nX
-2, nY
+2 ) );
2663 // -----------------------------------------------------------------------
2665 void TabBar::HideDropPos()
2669 ImplTabBarItem
* pItem
;
2671 long nY1
= (maWinSize
.Height()/2)-3;
2673 sal_uInt16 nItemCount
= (sal_uInt16
)mpItemList
->size();
2675 if ( mnDropPos
< nItemCount
)
2677 pItem
= (*mpItemList
)[ mnDropPos
];
2678 nX
= pItem
->maRect
.Left()+TABBAR_OFFSET_X
;
2679 // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2681 Rectangle
aRect( nX
-1, nY1
, nX
+3, nY2
);
2682 Region
aRegion( aRect
);
2683 SetClipRegion( aRegion
);
2687 if ( (mnDropPos
> 0) && (mnDropPos
< nItemCount
+1) )
2689 pItem
= (*mpItemList
)[ mnDropPos
-1 ];
2690 nX
= pItem
->maRect
.Right()-TABBAR_OFFSET_X
;
2691 // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2693 Rectangle
aRect( nX
-2, nY1
, nX
+1, nY2
);
2694 Region
aRegion( aRect
);
2695 SetClipRegion( aRegion
);
2700 mbDropPos
= sal_False
;
2705 // -----------------------------------------------------------------------
2707 sal_Bool
TabBar::SwitchPage( const Point
& rPos
)
2709 sal_Bool bSwitch
= sal_False
;
2710 sal_uInt16 nSwitchId
= GetPageId( rPos
);
2715 if ( nSwitchId
!= mnSwitchId
)
2717 mnSwitchId
= nSwitchId
;
2718 mnSwitchTime
= Time::GetSystemTicks();
2722 // Erst nach 500 ms umschalten
2723 if ( mnSwitchId
!= GetCurPageId() )
2725 if ( Time::GetSystemTicks() > mnSwitchTime
+500 )
2727 mbInSwitching
= sal_True
;
2728 if ( ImplDeactivatePage() )
2730 SetCurPageId( mnSwitchId
);
2736 mbInSwitching
= sal_False
;
2745 // -----------------------------------------------------------------------
2747 void TabBar::EndSwitchPage()
2753 // -----------------------------------------------------------------------
2755 void TabBar::SetStyle( WinBits nStyle
)
2757 mnWinStyle
= nStyle
;
2759 // Evt. Controls neu anordnen
2760 if ( IsReallyVisible() && IsUpdateMode() )
2764 // -----------------------------------------------------------------------
2766 Size
TabBar::CalcWindowSizePixel() const
2770 if ( mpItemList
->size() )
2772 ((TabBar
*)this)->ImplCalcWidth();
2773 for ( size_t i
= 0, n
= mpItemList
->size(); i
< n
; ++i
)
2775 ImplTabBarItem
* pItem
= (*mpItemList
)[ i
];
2776 nWidth
+= pItem
->mnWidth
;
2778 nWidth
+= TABBAR_OFFSET_X
+TABBAR_OFFSET_X2
;
2781 return Size( nWidth
, GetSettings().GetStyleSettings().GetScrollBarSize() );
2783 // -----------------------------------------------------------------------
2785 Rectangle
TabBar::GetPageArea() const
2787 return Rectangle( Point( mnOffX
, mnOffY
), Size( mnLastOffX
-mnOffX
+1, GetSizePixel().Height()-mnOffY
) );
2790 // -----------------------------------------------------------------------
2792 ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> TabBar::CreateAccessible()
2794 return mpImpl
->maAccessibleFactory
.getFactory().createAccessibleTabBar( *this );
2797 // -----------------------------------------------------------------------
2799 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */