update dev300-m57
[ooovba.git] / svtools / source / control / tabbar.cxx
blobed1abbe53a2a8e40aae6f7e7467b0e3071d0af70
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;
69 ImplTabBarItem( USHORT nItemId, const XubString& rText,
70 TabBarPageBits nPageBits ) :
71 maText( rText )
73 mnId = nItemId;
74 mnBits = nPageBits;
75 mnWidth = 0;
76 mnHelpId = 0;
77 mbShort = FALSE;
78 mbSelect = FALSE;
79 mbEnable = TRUE;
83 DECLARE_LIST( ImplTabBarList, ImplTabBarItem* )
85 // =======================================================================
87 // -----------------
88 // - ImplTabButton -
89 // -----------------
91 class ImplTabButton : public PushButton
93 public:
94 ImplTabButton( TabBar* pParent, WinBits nWinStyle = 0 ) :
95 PushButton( pParent, nWinStyle | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS ) {}
97 TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
99 virtual long PreNotify( NotifyEvent& rNEvt );
102 // =======================================================================
104 long ImplTabButton::PreNotify( NotifyEvent& rNEvt )
106 if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
108 if ( GetParent()->IsInEditMode() )
110 GetParent()->EndEditMode();
111 return TRUE;
115 return PushButton::PreNotify( rNEvt );
118 // =======================================================================
120 // ----------------
121 // - ImplTabSizer -
122 // ----------------
124 class ImplTabSizer : public Window
126 public:
127 ImplTabSizer( TabBar* pParent, WinBits nWinStyle = 0 );
129 TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
131 private:
132 void ImplTrack( const Point& rScreenPos );
134 virtual void MouseButtonDown( const MouseEvent& rMEvt );
135 virtual void Tracking( const TrackingEvent& rTEvt );
136 virtual void Paint( const Rectangle& rRect );
138 Point maStartPos;
139 long mnStartWidth;
142 // -----------------------------------------------------------------------
144 ImplTabSizer::ImplTabSizer( TabBar* pParent, WinBits nWinStyle ) :
145 Window( pParent, nWinStyle & WB_3DLOOK )
147 SetPointer( Pointer( POINTER_HSIZEBAR ) );
148 SetSizePixel( Size( 7, 0 ) );
151 // -----------------------------------------------------------------------
153 void ImplTabSizer::ImplTrack( const Point& rScreenPos )
155 TabBar* pParent = GetParent();
156 long nDiff = rScreenPos.X() - maStartPos.X();
157 pParent->mnSplitSize = mnStartWidth + (pParent->IsMirrored() ? -nDiff : nDiff);
158 if ( pParent->mnSplitSize < TABBAR_MINSIZE )
159 pParent->mnSplitSize = TABBAR_MINSIZE;
160 pParent->Split();
161 pParent->Update();
164 // -----------------------------------------------------------------------
166 void ImplTabSizer::MouseButtonDown( const MouseEvent& rMEvt )
168 if ( GetParent()->IsInEditMode() )
170 GetParent()->EndEditMode();
171 return;
174 if ( rMEvt.IsLeft() )
176 maStartPos = OutputToScreenPixel( rMEvt.GetPosPixel() );
177 mnStartWidth = GetParent()->GetSizePixel().Width();
178 StartTracking();
182 // -----------------------------------------------------------------------
184 void ImplTabSizer::Tracking( const TrackingEvent& rTEvt )
186 if ( rTEvt.IsTrackingEnded() )
188 if ( rTEvt.IsTrackingCanceled() )
189 ImplTrack( maStartPos );
190 GetParent()->mnSplitSize = 0;
192 else
193 ImplTrack( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
196 // -----------------------------------------------------------------------
198 void ImplTabSizer::Paint( const Rectangle& )
200 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
201 DecorationView aDecoView( this );
202 long nOffX = 0;
203 Size aOutputSize = GetOutputSizePixel();
205 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
207 SetLineColor( rStyleSettings.GetDarkShadowColor() );
208 DrawLine( Point( 0, 0 ), Point( 0, aOutputSize.Height()-1 ) );
209 nOffX++;
210 aOutputSize.Width()--;
212 aDecoView.DrawButton( Rectangle( Point( nOffX, 0 ), aOutputSize ), BUTTON_DRAW_NOLIGHTBORDER );
215 // =======================================================================
217 // Heisst nicht Impl, da evtl. mal von aussen benutz- und ueberladbar
219 // --------------
220 // - TabBarEdit -
221 // --------------
223 class TabBarEdit : public Edit
225 private:
226 Timer maLoseFocusTimer;
227 BOOL mbPostEvt;
229 DECL_LINK( ImplEndEditHdl, void* );
230 DECL_LINK( ImplEndTimerHdl, void* );
232 public:
233 TabBarEdit( TabBar* pParent, WinBits nWinStyle = 0 );
235 TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
237 void SetPostEvent() { mbPostEvt = TRUE; }
238 void ResetPostEvent() { mbPostEvt = FALSE; }
240 virtual long PreNotify( NotifyEvent& rNEvt );
241 virtual void LoseFocus();
244 // -----------------------------------------------------------------------
246 TabBarEdit::TabBarEdit( TabBar* pParent, WinBits nWinStyle ) :
247 Edit( pParent, nWinStyle )
249 mbPostEvt = FALSE;
252 // -----------------------------------------------------------------------
254 long TabBarEdit::PreNotify( NotifyEvent& rNEvt )
256 if ( rNEvt.GetType() == EVENT_KEYINPUT )
258 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
259 if ( !pKEvt->GetKeyCode().GetModifier() )
261 if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
263 if ( !mbPostEvt )
265 if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)FALSE ) )
266 mbPostEvt = TRUE;
268 return TRUE;
270 else if ( pKEvt->GetKeyCode().GetCode() == KEY_ESCAPE )
272 if ( !mbPostEvt )
274 if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)TRUE ) )
275 mbPostEvt = TRUE;
277 return TRUE;
282 return Edit::PreNotify( rNEvt );
285 // -----------------------------------------------------------------------
287 void TabBarEdit::LoseFocus()
289 if ( !mbPostEvt )
291 if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)FALSE ) )
292 mbPostEvt = TRUE;
295 Edit::LoseFocus();
298 // -----------------------------------------------------------------------
300 IMPL_LINK( TabBarEdit, ImplEndEditHdl, void*, pCancel )
302 ResetPostEvent();
303 maLoseFocusTimer.Stop();
305 // We need this query, because the edit get a losefous event,
306 // when it shows the context menu or the insert symbol dialog
307 if ( !HasFocus() && HasChildPathFocus( TRUE ) )
309 maLoseFocusTimer.SetTimeout( 30 );
310 maLoseFocusTimer.SetTimeoutHdl( LINK( this, TabBarEdit, ImplEndTimerHdl ) );
311 maLoseFocusTimer.Start();
313 else
314 GetParent()->EndEditMode( pCancel != 0 );
316 return 0;
319 // -----------------------------------------------------------------------
321 IMPL_LINK( TabBarEdit, ImplEndTimerHdl, void*, EMPTYARG )
323 if ( HasFocus() )
324 return 0;
326 // We need this query, because the edit get a losefous event,
327 // when it shows the context menu or the insert symbol dialog
328 if ( HasChildPathFocus( TRUE ) )
329 maLoseFocusTimer.Start();
330 else
331 GetParent()->EndEditMode( TRUE );
333 return 0;
336 // =======================================================================
337 struct TabBar_Impl
339 ImplTabSizer* mpSizer;
340 ::svt::AccessibleFactoryAccess maAccessibleFactory;
342 TabBar_Impl()
343 :mpSizer( NULL )
346 ~TabBar_Impl()
348 delete mpSizer;
352 // =======================================================================
354 void TabBar::ImplInit( WinBits nWinStyle )
356 mpItemList = new ImplTabBarList;
357 mpFirstBtn = NULL;
358 mpPrevBtn = NULL;
359 mpNextBtn = NULL;
360 mpLastBtn = NULL;
361 mpImpl = new TabBar_Impl;
362 mpEdit = NULL;
363 mnMaxPageWidth = 0;
364 mnCurMaxWidth = 0;
365 mnOffX = 0;
366 mnOffY = 0;
367 mnLastOffX = 0;
368 mnSplitSize = 0;
369 mnSwitchTime = 0;
370 mnWinStyle = nWinStyle;
371 mnCurPageId = 0;
372 mnFirstPos = 0;
373 mnDropPos = 0;
374 mnSwitchId = 0;
375 mnEditId = 0;
376 mbFormat = TRUE;
377 mbFirstFormat = TRUE;
378 mbSizeFormat = TRUE;
379 mbAutoMaxWidth = TRUE;
380 mbInSwitching = FALSE;
381 mbAutoEditMode = FALSE;
382 mbEditCanceled = FALSE;
383 mbDropPos = FALSE;
384 mbInSelect = FALSE;
385 mbSelColor = FALSE;
386 mbSelTextColor = FALSE;
387 mbMirrored = FALSE;
389 if ( nWinStyle & WB_3DTAB )
390 mnOffY++;
392 ImplInitControls();
393 SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
394 ImplInitSettings( TRUE, TRUE );
397 // -----------------------------------------------------------------------
399 TabBar::TabBar( Window* pParent, WinBits nWinStyle ) :
400 Window( pParent, (nWinStyle & WB_3DLOOK) | WB_CLIPCHILDREN )
402 ImplInit( nWinStyle );
405 // -----------------------------------------------------------------------
407 TabBar::~TabBar()
409 EndEditMode( TRUE );
411 // Controls loeschen
412 if ( mpPrevBtn )
413 delete mpPrevBtn;
414 if ( mpNextBtn )
415 delete mpNextBtn;
416 if ( mpFirstBtn )
417 delete mpFirstBtn;
418 if ( mpLastBtn )
419 delete mpLastBtn;
420 delete mpImpl;
422 // Alle Items loeschen
423 ImplTabBarItem* pItem = mpItemList->First();
424 while ( pItem )
426 delete pItem;
427 pItem = mpItemList->Next();
430 // Itemlist loeschen
431 delete mpItemList;
434 // -----------------------------------------------------------------------
436 void TabBar::ImplInitSettings( BOOL bFont, BOOL bBackground )
438 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
440 if ( bFont )
442 Font aToolFont;
443 aToolFont = rStyleSettings.GetToolFont();
444 if ( IsControlFont() )
445 aToolFont.Merge( GetControlFont() );
446 aToolFont.SetWeight( WEIGHT_BOLD );
447 SetZoomedPointFont( aToolFont );
449 // Font in der groesse Anpassen, wenn Fenster zu klein?
450 while ( GetTextHeight() > (GetOutputSizePixel().Height()-1) )
452 Font aFont = GetFont();
453 if ( aFont.GetHeight() <= 6 )
454 break;
455 aFont.SetHeight( aFont.GetHeight()-1 );
456 SetFont( aFont );
460 if ( bBackground )
462 Color aColor;
463 if ( IsControlBackground() )
464 aColor = GetControlBackground();
465 else
466 aColor = rStyleSettings.GetFaceColor();
467 SetBackground( aColor );
471 // -----------------------------------------------------------------------
473 void TabBar::ImplGetColors( Color& rFaceColor, Color& rFaceTextColor,
474 Color& rSelectColor, Color& rSelectTextColor )
476 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
478 if ( IsControlBackground() )
479 rFaceColor = GetControlBackground();
480 else
481 rFaceColor = rStyleSettings.GetInactiveTabColor();
482 if ( IsControlForeground() )
483 rFaceTextColor = GetControlForeground();
484 else
485 rFaceTextColor = rStyleSettings.GetButtonTextColor();
486 if ( mbSelColor )
487 rSelectColor = maSelColor;
488 else
489 rSelectColor = rStyleSettings.GetActiveTabColor();
490 if ( mbSelTextColor )
491 rSelectTextColor = maSelTextColor;
492 else
493 rSelectTextColor = rStyleSettings.GetWindowTextColor();
495 // Bei 3D-Tabs wird Selektions- und Face-Farbe umgedreht, da die
496 // selektierten Tabs in 3D erscheinen sollen
497 if ( mnWinStyle & WB_3DTAB )
499 Color aTempColor = rFaceColor;
500 rFaceColor = rSelectColor;
501 rSelectColor = aTempColor;
502 aTempColor = rFaceTextColor;
503 rFaceTextColor = rSelectTextColor;
504 rSelectTextColor = rFaceTextColor;
508 // -----------------------------------------------------------------------
510 BOOL TabBar::ImplCalcWidth()
512 // Groessen muessen nur ermittelt werden, wenn sich Text aendert oder
513 // wenn der Font geaendert wurde
514 if ( !mbSizeFormat )
515 return FALSE;
517 // Breiten der Tabs mit dem fetten Font ermitteln
518 Font aFont = GetFont();
519 if ( aFont.GetWeight() != WEIGHT_BOLD )
521 aFont.SetWeight( WEIGHT_BOLD );
522 SetFont( aFont );
525 if ( mnMaxPageWidth )
526 mnCurMaxWidth = mnMaxPageWidth;
527 else if ( mbAutoMaxWidth )
529 mnCurMaxWidth = mnLastOffX-mnOffX-
530 TABBAR_OFFSET_X-TABBAR_OFFSET_X-
531 TABBAR_OFFSET_X2-TABBAR_OFFSET_X2-TABBAR_OFFSET_X2;
532 if ( mnCurMaxWidth < 1 )
533 mnCurMaxWidth = 1;
535 else
536 mnCurMaxWidth = 0;
538 BOOL bChanged = FALSE;
539 ImplTabBarItem* pItem = mpItemList->First();
540 while ( pItem )
542 long nNewWidth = GetTextWidth( pItem->maText );
543 if ( mnCurMaxWidth && (nNewWidth > mnCurMaxWidth) )
545 pItem->mbShort = TRUE;
546 nNewWidth = mnCurMaxWidth;
548 else
549 pItem->mbShort = FALSE;
550 nNewWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
551 if ( pItem->mnWidth != nNewWidth )
553 pItem->mnWidth = nNewWidth;
554 if ( !pItem->maRect.IsEmpty() )
555 bChanged = TRUE;
557 pItem = mpItemList->Next();
559 mbSizeFormat = FALSE;
560 mbFormat = TRUE;
561 return bChanged;
564 // -----------------------------------------------------------------------
566 void TabBar::ImplFormat()
568 ImplCalcWidth();
570 if ( !mbFormat )
571 return;
573 USHORT n = 0;
574 long x = mnOffX;
575 ImplTabBarItem* pItem = mpItemList->First();
576 while ( pItem )
578 // Bei allen nicht sichtbaren Tabs, wird ein leeres Rechteck
579 // gesetzt
580 if ( (n+1 < mnFirstPos) || (x > mnLastOffX) )
581 pItem->maRect.SetEmpty();
582 else
584 // Etwas von der Tab vor der ersten sichtbaren Page
585 // muss auch zu sehen sein
586 if ( n+1 == mnFirstPos )
587 pItem->maRect.Left() = x-pItem->mnWidth;
588 else
590 pItem->maRect.Left() = x;
591 x += pItem->mnWidth;
593 pItem->maRect.Right() = x+TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
594 pItem->maRect.Bottom() = maWinSize.Height()-1;
596 if( mbMirrored )
598 long nTmp = mnOffX + mnLastOffX - pItem->maRect.Right();
599 pItem->maRect.Right() = mnOffX + mnLastOffX - pItem->maRect.Left();
600 pItem->maRect.Left() = nTmp;
604 n++;
605 pItem = mpItemList->Next();
608 mbFormat = FALSE;
610 // Button enablen/disablen
611 ImplEnableControls();
614 // -----------------------------------------------------------------------
616 USHORT TabBar::ImplGetLastFirstPos()
618 USHORT nCount = (USHORT)(mpItemList->Count());
619 if ( !nCount || mbSizeFormat || mbFormat )
620 return 0;
622 USHORT nLastFirstPos = nCount-1;
623 long nWinWidth = mnLastOffX-mnOffX-TABBAR_OFFSET_X-ADDNEWPAGE_AREAWIDTH;
624 long nWidth = mpItemList->GetObject( nLastFirstPos )->mnWidth;
625 while ( nLastFirstPos && (nWidth < nWinWidth) )
627 nLastFirstPos--;
628 nWidth += mpItemList->GetObject( nLastFirstPos )->mnWidth;
630 if ( (nLastFirstPos != (USHORT)(mpItemList->Count()-1)) &&
631 (nWidth > nWinWidth) )
632 nLastFirstPos++;
633 return nLastFirstPos;
636 // -----------------------------------------------------------------------
638 void TabBar::ImplInitControls()
640 if ( mnWinStyle & WB_SIZEABLE )
642 if ( !mpImpl->mpSizer )
643 mpImpl->mpSizer = new ImplTabSizer( this, mnWinStyle & (WB_DRAG | WB_3DLOOK) );
644 mpImpl->mpSizer->Show();
646 else
648 DELETEZ( mpImpl->mpSizer );
651 Link aLink = LINK( this, TabBar, ImplClickHdl );
653 if ( mnWinStyle & (WB_MINSCROLL | WB_SCROLL) )
655 if ( !mpPrevBtn )
657 mpPrevBtn = new ImplTabButton( this, WB_REPEAT );
658 mpPrevBtn->SetClickHdl( aLink );
660 mpPrevBtn->SetSymbol( mbMirrored ? SYMBOL_NEXT : SYMBOL_PREV );
661 mpPrevBtn->Show();
663 if ( !mpNextBtn )
665 mpNextBtn = new ImplTabButton( this, WB_REPEAT );
666 mpNextBtn->SetClickHdl( aLink );
668 mpNextBtn->SetSymbol( mbMirrored ? SYMBOL_PREV : SYMBOL_NEXT );
669 mpNextBtn->Show();
671 else
673 DELETEZ( mpPrevBtn );
674 DELETEZ( mpNextBtn );
677 if ( mnWinStyle & WB_SCROLL )
679 if ( !mpFirstBtn )
681 mpFirstBtn = new ImplTabButton( this );
682 mpFirstBtn->SetClickHdl( aLink );
684 mpFirstBtn->SetSymbol( mbMirrored ? SYMBOL_LAST : SYMBOL_FIRST );
685 mpFirstBtn->Show();
687 if ( !mpLastBtn )
689 mpLastBtn = new ImplTabButton( this );
690 mpLastBtn->SetClickHdl( aLink );
692 mpLastBtn->SetSymbol( mbMirrored ? SYMBOL_FIRST : SYMBOL_LAST );
693 mpLastBtn->Show();
695 else
697 DELETEZ( mpFirstBtn );
698 DELETEZ( mpLastBtn );
702 // -----------------------------------------------------------------------
704 void TabBar::ImplEnableControls()
706 if ( mbSizeFormat || mbFormat )
707 return;
709 // Buttons enablen/disblen
710 BOOL bEnableBtn = mnFirstPos > 0;
711 if ( mpFirstBtn )
712 mpFirstBtn->Enable( bEnableBtn );
713 if ( mpPrevBtn )
714 mpPrevBtn->Enable( bEnableBtn );
716 bEnableBtn = mnFirstPos < ImplGetLastFirstPos();
717 if ( mpNextBtn )
718 mpNextBtn->Enable( bEnableBtn );
719 if ( mpLastBtn )
720 mpLastBtn->Enable( bEnableBtn );
723 // -----------------------------------------------------------------------
725 void TabBar::ImplShowPage( USHORT nPos )
727 // Breite berechnen
728 long nWidth = GetOutputSizePixel().Width();
729 if ( nWidth >= TABBAR_OFFSET_X )
730 nWidth -= TABBAR_OFFSET_X;
731 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
732 if ( nPos < mnFirstPos )
733 SetFirstPageId( pItem->mnId );
734 else if ( pItem->maRect.Right() > nWidth )
736 while ( pItem->maRect.Right() > nWidth )
738 USHORT nNewPos = mnFirstPos+1;
739 SetFirstPageId( GetPageId( nNewPos ) );
740 ImplFormat();
741 if ( nNewPos != mnFirstPos )
742 break;
747 // -----------------------------------------------------------------------
749 IMPL_LINK( TabBar, ImplClickHdl, ImplTabButton*, pBtn )
751 EndEditMode();
753 USHORT nNewPos = mnFirstPos;
755 if ( pBtn == mpFirstBtn )
756 nNewPos = 0;
757 else if ( pBtn == mpPrevBtn )
759 if ( mnFirstPos )
760 nNewPos = mnFirstPos-1;
762 else if ( pBtn == mpNextBtn )
764 USHORT nCount = GetPageCount();
765 if ( mnFirstPos < nCount )
766 nNewPos = mnFirstPos+1;
768 else
770 USHORT nCount = GetPageCount();
771 if ( nCount )
772 nNewPos = nCount-1;
775 if ( nNewPos != mnFirstPos )
776 SetFirstPageId( GetPageId( nNewPos ) );
777 return 0;
780 // -----------------------------------------------------------------------
782 void TabBar::MouseMove( const MouseEvent& rMEvt )
784 if ( rMEvt.IsLeaveWindow() )
785 mbInSelect = FALSE;
787 Window::MouseMove( rMEvt );
790 // -----------------------------------------------------------------------
792 void TabBar::MouseButtonDown( const MouseEvent& rMEvt )
794 // Bei Klick in unser Fenster EditModus nur beenden und Klick nicht
795 // ausfuehren
796 if ( IsInEditMode() )
798 EndEditMode();
799 return;
802 ImplTabBarItem* pItem;
803 USHORT nSelId = GetPageId( rMEvt.GetPosPixel() );
805 if ( !rMEvt.IsLeft() )
807 Window::MouseButtonDown( rMEvt );
808 if ( (nSelId > 0) && (nSelId != mnCurPageId) )
810 USHORT nPos = GetPagePos( nSelId );
811 pItem = mpItemList->GetObject( nPos );
813 if ( pItem->mbEnable )
815 if ( ImplDeactivatePage() )
817 SetCurPageId( nSelId );
818 Update();
819 ImplActivatePage();
820 ImplSelect();
822 mbInSelect = TRUE;
825 return;
828 if ( rMEvt.IsMod2() && mbAutoEditMode && nSelId )
830 if ( StartEditMode( nSelId ) )
831 return;
834 if ( (rMEvt.GetMode() & (MOUSE_MULTISELECT | MOUSE_RANGESELECT)) && (rMEvt.GetClicks() == 1) )
836 if ( nSelId )
838 USHORT nPos = GetPagePos( nSelId );
839 BOOL bSelectTab = FALSE;
840 pItem = mpItemList->GetObject( nPos );
842 if ( pItem->mbEnable )
844 if ( (rMEvt.GetMode() & MOUSE_MULTISELECT) && (mnWinStyle & WB_MULTISELECT) )
846 if ( nSelId != mnCurPageId )
848 SelectPage( nSelId, !IsPageSelected( nSelId ) );
849 bSelectTab = TRUE;
852 else if ( mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT) )
854 bSelectTab = TRUE;
855 USHORT n;
856 BOOL bSelect;
857 USHORT nCurPos = GetPagePos( mnCurPageId );
858 if ( nPos <= nCurPos )
860 // Alle Tabs bis zur angeklickten Tab deselektieren
861 // und alle Tabs von der angeklickten Tab bis
862 // zur aktuellen Position selektieren
863 n = 0;
864 while ( n < nCurPos )
866 pItem = mpItemList->GetObject( n );
867 if ( n < nPos )
868 bSelect = FALSE;
869 else
870 bSelect = TRUE;
872 if ( pItem->mbSelect != bSelect )
874 pItem->mbSelect = bSelect;
875 if ( !pItem->maRect.IsEmpty() )
876 Invalidate( pItem->maRect );
879 n++;
883 if ( nPos >= nCurPos )
885 // Alle Tabs von der aktuellen bis zur angeklickten
886 // Tab selektieren und alle Tabs von der angeklickten
887 // Tab bis zur letzten Tab deselektieren
888 USHORT nCount = (USHORT)mpItemList->Count();
889 n = nCurPos;
890 while ( n < nCount )
892 pItem = mpItemList->GetObject( n );
894 if ( n <= nPos )
895 bSelect = TRUE;
896 else
897 bSelect = FALSE;
899 if ( pItem->mbSelect != bSelect )
901 pItem->mbSelect = bSelect;
902 if ( !pItem->maRect.IsEmpty() )
903 Invalidate( pItem->maRect );
906 n++;
911 // Gegebenenfalls muss die selektierte Tab gescrollt werden
912 if ( bSelectTab )
914 ImplShowPage( nPos );
915 Update();
916 ImplSelect();
919 else
920 ImplShowPage( nPos );
921 mbInSelect = TRUE;
923 return;
926 else if ( rMEvt.GetClicks() == 2 )
928 // Gegebenenfalls den Double-Click-Handler rufen
929 if ( !rMEvt.GetModifier() && (!nSelId || (nSelId == mnCurPageId)) )
931 USHORT nOldCurId = mnCurPageId;
932 mnCurPageId = nSelId;
933 DoubleClick();
934 // Abfrage, da im DoubleClick-Handler die aktuelle Seite
935 // umgeschaltet werden konnte
936 if ( mnCurPageId == nSelId )
937 mnCurPageId = nOldCurId;
940 return;
942 else
944 if ( nSelId )
946 // Nur Select ausfuehren, wenn noch nicht aktuelle Page
947 if ( nSelId != mnCurPageId )
949 USHORT nPos = GetPagePos( nSelId );
950 pItem = mpItemList->GetObject( nPos );
952 if ( pItem->mbEnable )
954 if ( !pItem->mbSelect )
956 // Muss invalidiert werden
957 BOOL bUpdate = FALSE;
958 if ( IsReallyVisible() && IsUpdateMode() )
959 bUpdate = TRUE;
961 // Alle selektierten Items deselektieren
962 pItem = mpItemList->First();
963 while ( pItem )
965 if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
967 pItem->mbSelect = FALSE;
968 if ( bUpdate )
969 Invalidate( pItem->maRect );
972 pItem = mpItemList->Next();
976 if ( ImplDeactivatePage() )
978 SetCurPageId( nSelId );
979 Update();
980 ImplActivatePage();
981 ImplSelect();
984 else
985 ImplShowPage( nPos );
986 mbInSelect = TRUE;
989 return;
993 Window::MouseButtonDown( rMEvt );
996 // -----------------------------------------------------------------------
998 void TabBar::MouseButtonUp( const MouseEvent& rMEvt )
1000 mbInSelect = FALSE;
1001 Window::MouseButtonUp( rMEvt );
1004 // -----------------------------------------------------------------------
1006 void TabBar::Paint( const Rectangle& )
1008 // Items berechnen und ausgeben
1009 USHORT nItemCount = (USHORT)mpItemList->Count();
1010 ImplTabBarItem* pItem;
1012 // kein Item, dann auch nichts zu tun
1013 if ( nItemCount )
1015 // TabBar muss formatiert sein
1016 ImplFormat();
1018 // Beim ersten Format auch dafuer sorgen, das aktuelle TabPage
1019 // sichtbar wird
1020 if ( mbFirstFormat )
1022 mbFirstFormat = FALSE;
1024 if ( mnCurPageId && (mnFirstPos == 0) && !mbDropPos )
1026 pItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) );
1027 if ( pItem->maRect.IsEmpty() )
1029 // mbDropPos setzen (bzw. misbrauchen) um Invalidate()
1030 // zu unterbinden
1031 mbDropPos = TRUE;
1032 SetFirstPageId( mnCurPageId );
1033 mbDropPos = FALSE;
1034 if ( mnFirstPos != 0 )
1035 ImplFormat();
1041 // Farben ermitteln
1042 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1043 Color aFaceColor;
1044 Color aSelectColor;
1045 Color aFaceTextColor;
1046 Color aSelectTextColor;
1047 ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
1049 // Font selektieren
1050 Font aFont = GetFont();
1051 Font aLightFont = aFont;
1052 aLightFont.SetWeight( WEIGHT_LIGHT );
1054 // #i36013# exclude push buttons from painting area
1055 Rectangle aClipRect( Point( mnOffX, 0 ), Point( mnLastOffX, GetOutputHeightPixel() - 1 ) );
1056 SetClipRegion( Region( aClipRect ) );
1058 // Bei Border oben und unten einen Strich extra malen
1059 if ( (mnWinStyle & WB_BORDER) || (mnWinStyle & WB_TOPBORDER) )
1061 Size aOutputSize = GetOutputSizePixel();
1063 // Bei 3D-Tabs wird auch der Border in 3D gemalt
1064 if ( mnWinStyle & WB_3DTAB )
1066 SetLineColor( rStyleSettings.GetShadowColor() );
1067 DrawLine( Point( mnOffX, 0 ), Point( aOutputSize.Width(), 0 ) );
1070 // Border malen (Strich oben und Strich unten)
1071 SetLineColor( rStyleSettings.GetDarkShadowColor() );
1072 DrawLine( Point( mnOffX, mnOffY ), Point( aOutputSize.Width()-1, mnOffY ) );
1074 else
1075 SetLineColor( rStyleSettings.GetDarkShadowColor() );
1077 // Items ausgeben
1078 if ( nItemCount )
1080 // letzten sichtbaren Eintrag suchen
1081 USHORT n = mnFirstPos+1;
1082 if ( n >= nItemCount )
1083 n = nItemCount-1;
1084 pItem = mpItemList->Seek( n );
1085 while ( pItem )
1087 if ( !pItem->maRect.IsEmpty() )
1089 n++;
1090 pItem = mpItemList->Next();
1092 else
1093 break;
1096 // Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt)
1097 if ( pItem )
1098 n--;
1099 else if ( n >= nItemCount )
1100 n = nItemCount-1;
1101 pItem = mpItemList->Seek( n );
1102 ImplTabBarItem* pCurItem = NULL;
1103 while ( pItem )
1105 // CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt
1106 if ( !pCurItem && (pItem->mnId == mnCurPageId) )
1108 pCurItem = pItem;
1109 pItem = mpItemList->Prev();
1110 if ( !pItem )
1111 pItem = pCurItem;
1112 continue;
1115 if ( !pItem->maRect.IsEmpty() )
1117 Rectangle aRect = pItem->maRect;
1119 // Aktuelle Page wird mit einem fetten Font ausgegeben
1120 if ( pItem->mnId == mnCurPageId )
1121 SetFont( aFont );
1122 else
1123 SetFont( aLightFont );
1125 // Je nach Status die richtige FillInBrush setzen
1126 if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
1128 SetFillColor( aSelectColor );
1129 SetTextColor( aSelectTextColor );
1131 else
1133 SetFillColor( aFaceColor );
1134 SetTextColor( aFaceTextColor );
1137 // Muss Font Kursiv geschaltet werden
1138 if ( pItem->mnBits & TPB_SPECIAL )
1140 SetTextColor( Color( COL_LIGHTBLUE ) );
1143 // Position der Page berechnen
1144 Point aPos0 = Point( aRect.Left(), mnOffY );
1145 Point aPos1 = Point( aRect.Left()+TABBAR_OFFSET_X, aRect.Bottom() );
1146 Point aPos2 = Point( aRect.Right()-TABBAR_OFFSET_X, aRect.Bottom() );
1147 Point aPos3 = Point( aRect.Right(), mnOffY );
1149 // Zuerst geben wir das Polygon gefuellt aus
1150 Polygon aPoly( 4 );
1151 aPoly[0] = aPos0;
1152 aPoly[1] = aPos1;
1153 aPoly[2] = aPos2;
1154 aPoly[3] = aPos3;
1155 DrawPolygon( aPoly );
1157 // Danach den Text zentiert ausgeben
1158 XubString aText = pItem->maText;
1159 if ( pItem->mbShort )
1160 aText = GetEllipsisString( aText, mnCurMaxWidth, TEXT_DRAW_ENDELLIPSIS );
1161 Size aRectSize = aRect.GetSize();
1162 long nTextWidth = GetTextWidth( aText );
1163 long nTextHeight = GetTextHeight();
1164 Point aTxtPos( aRect.Left()+(aRectSize.Width()-nTextWidth)/2,
1165 (aRectSize.Height()-nTextHeight)/2 );
1166 if ( !pItem->mbEnable )
1167 DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC) );
1168 else
1169 DrawText( aTxtPos, aText );
1171 // Jetzt im Inhalt den 3D-Effekt ausgeben
1172 aPos0.X()++;
1173 aPos1.X()++;
1174 aPos2.X()--;
1175 aPos3.X()--;
1176 SetLineColor( rStyleSettings.GetLightColor() );
1177 DrawLine( aPos0, aPos1 );
1179 if ( !pItem->mbSelect && (pItem->mnId != mnCurPageId) )
1181 DrawLine( Point( aPos0.X(), aPos0.Y()+1 ),
1182 Point( aPos3.X(), aPos3.Y()+1 ) );
1185 SetLineColor( rStyleSettings.GetShadowColor() );
1186 DrawLine( aPos2, aPos3 );
1187 aPos1.X()--;
1188 aPos1.Y()--;
1189 aPos2.Y()--;
1190 DrawLine( aPos1, aPos2 );
1192 // Da etwas uebermalt werden konnte, muessen wir die Polygon-
1193 // umrandung nocheinmal ausgeben
1194 SetLineColor( rStyleSettings.GetDarkShadowColor() );
1195 SetFillColor();
1196 DrawPolygon( aPoly );
1198 // Beim dem aktuellen Tab die restlichten Ausgaben vornehmen und
1199 // die Schleife abbrechen, da die aktuelle Tab als letztes
1200 // ausgegeben wird
1201 if ( pItem == pCurItem )
1203 // Beim aktuellen Item muss der oberstes Strich geloescht
1204 // werden
1205 SetLineColor();
1206 SetFillColor( aSelectColor );
1207 Rectangle aDelRect( aPos0, aPos3 );
1208 DrawRect( aDelRect );
1209 if ( mnWinStyle & WB_3DTAB )
1211 aDelRect.Top()--;
1212 DrawRect( aDelRect );
1215 break;
1218 pItem = mpItemList->Prev();
1220 else
1222 if ( pItem == pCurItem )
1223 break;
1225 pItem = NULL;
1228 if ( !pItem )
1229 pItem = pCurItem;
1233 // Font wieder herstellen
1234 SetFont( aFont );
1235 // remove clip region
1236 SetClipRegion();
1239 // -----------------------------------------------------------------------
1241 void TabBar::Resize()
1243 Size aNewSize = GetOutputSizePixel();
1245 long nSizerWidth = 0;
1246 long nButtonWidth = 0;
1248 // Sizer anordnen
1249 if ( mpImpl->mpSizer )
1251 Size aSizerSize = mpImpl->mpSizer->GetSizePixel();
1252 Point aNewSizerPos( mbMirrored ? 0 : (aNewSize.Width()-aSizerSize.Width()), 0 );
1253 Size aNewSizerSize( aSizerSize.Width(), aNewSize.Height() );
1254 mpImpl->mpSizer->SetPosSizePixel( aNewSizerPos, aNewSizerSize );
1255 nSizerWidth = aSizerSize.Width();
1258 // Scroll-Buttons anordnen
1259 long nHeight = aNewSize.Height();
1260 // Font in der groesse Anpassen?
1261 ImplInitSettings( TRUE, FALSE );
1263 long nX = mbMirrored ? (aNewSize.Width()-nHeight) : 0;
1264 long nXDiff = mbMirrored ? -nHeight : nHeight;
1266 Size aBtnSize( nHeight, nHeight );
1267 if ( mpFirstBtn )
1269 mpFirstBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1270 nX += nXDiff;
1271 nButtonWidth += nHeight;
1273 if ( mpPrevBtn )
1275 mpPrevBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1276 nX += nXDiff;
1277 nButtonWidth += nHeight;
1279 if ( mpNextBtn )
1281 mpNextBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1282 nX += nXDiff;
1283 nButtonWidth += nHeight;
1285 if ( mpLastBtn )
1287 mpLastBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1288 nX += nXDiff;
1289 nButtonWidth += nHeight;
1292 // Groesse merken
1293 maWinSize = aNewSize;
1295 if( mbMirrored )
1297 mnOffX = nSizerWidth;
1298 mnLastOffX = maWinSize.Width() - nButtonWidth - 1;
1300 else
1302 mnOffX = nButtonWidth;
1303 mnLastOffX = maWinSize.Width() - nSizerWidth - 1;
1306 // Neu formatieren
1307 mbSizeFormat = TRUE;
1308 if ( IsReallyVisible() )
1310 if ( ImplCalcWidth() )
1311 Invalidate();
1312 ImplFormat();
1315 // Button enablen/disablen
1316 ImplEnableControls();
1319 // -----------------------------------------------------------------------
1321 void TabBar::RequestHelp( const HelpEvent& rHEvt )
1323 USHORT nItemId = GetPageId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
1324 if ( nItemId )
1326 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
1328 XubString aStr = GetHelpText( nItemId );
1329 if ( aStr.Len() )
1331 Rectangle aItemRect = GetPageRect( nItemId );
1332 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1333 aItemRect.Left() = aPt.X();
1334 aItemRect.Top() = aPt.Y();
1335 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1336 aItemRect.Right() = aPt.X();
1337 aItemRect.Bottom() = aPt.Y();
1338 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
1339 return;
1342 else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
1344 ULONG nHelpId = GetHelpId( nItemId );
1345 if ( nHelpId )
1347 // Wenn eine Hilfe existiert, dann ausloesen
1348 Help* pHelp = Application::GetHelp();
1349 if ( pHelp )
1350 pHelp->Start( nHelpId, this );
1351 return;
1355 // Bei Quick- oder Ballloon-Help zeigen wir den Text an,
1356 // wenn dieser abgeschnitten oder nicht voll sichtbar ist
1357 if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
1359 USHORT nPos = GetPagePos( nItemId );
1360 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1361 if ( pItem->mbShort ||
1362 (pItem->maRect.Right()-TABBAR_OFFSET_X-5 > mnLastOffX) )
1364 Rectangle aItemRect = GetPageRect( nItemId );
1365 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1366 aItemRect.Left() = aPt.X();
1367 aItemRect.Top() = aPt.Y();
1368 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1369 aItemRect.Right() = aPt.X();
1370 aItemRect.Bottom() = aPt.Y();
1371 XubString aStr = mpItemList->GetObject( nPos )->maText;
1372 if ( aStr.Len() )
1374 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
1375 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
1376 else
1377 Help::ShowQuickHelp( this, aItemRect, aStr );
1378 return;
1384 Window::RequestHelp( rHEvt );
1387 // -----------------------------------------------------------------------
1389 void TabBar::StateChanged( StateChangedType nType )
1391 Window::StateChanged( nType );
1393 if ( nType == STATE_CHANGE_INITSHOW )
1395 if ( (mbSizeFormat || mbFormat) && mpItemList->Count() )
1396 ImplFormat();
1398 else if ( (nType == STATE_CHANGE_ZOOM) ||
1399 (nType == STATE_CHANGE_CONTROLFONT) )
1401 ImplInitSettings( TRUE, FALSE );
1402 Invalidate();
1404 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1405 Invalidate();
1406 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1408 ImplInitSettings( FALSE, TRUE );
1409 Invalidate();
1411 else if ( nType == STATE_CHANGE_MIRRORING )
1413 // reacts on calls of EnableRTL, have to mirror all child controls
1414 if( mpFirstBtn ) mpFirstBtn->EnableRTL( IsRTLEnabled() );
1415 if( mpPrevBtn ) mpPrevBtn->EnableRTL( IsRTLEnabled() );
1416 if( mpNextBtn ) mpNextBtn->EnableRTL( IsRTLEnabled() );
1417 if( mpLastBtn ) mpLastBtn->EnableRTL( IsRTLEnabled() );
1418 if( mpImpl->mpSizer ) mpImpl->mpSizer->EnableRTL( IsRTLEnabled() );
1419 if( mpEdit ) mpEdit->EnableRTL( IsRTLEnabled() );
1423 // -----------------------------------------------------------------------
1425 void TabBar::DataChanged( const DataChangedEvent& rDCEvt )
1427 Window::DataChanged( rDCEvt );
1429 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1430 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1431 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1432 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1434 ImplInitSettings( TRUE, TRUE );
1435 Invalidate();
1439 // -----------------------------------------------------------------------
1441 void TabBar::ImplSelect()
1443 Select();
1445 CallEventListeners( VCLEVENT_TABBAR_PAGESELECTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1448 // -----------------------------------------------------------------------
1450 void TabBar::Select()
1452 maSelectHdl.Call( this );
1455 // -----------------------------------------------------------------------
1457 void TabBar::DoubleClick()
1459 maDoubleClickHdl.Call( this );
1462 // -----------------------------------------------------------------------
1464 void TabBar::Split()
1466 maSplitHdl.Call( this );
1469 // -----------------------------------------------------------------------
1471 void TabBar::ImplActivatePage()
1473 ActivatePage();
1475 CallEventListeners( VCLEVENT_TABBAR_PAGEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1478 // -----------------------------------------------------------------------
1480 void TabBar::ActivatePage()
1482 maActivatePageHdl.Call( this );
1485 // -----------------------------------------------------------------------
1487 long TabBar::ImplDeactivatePage()
1489 long nRet = DeactivatePage();
1491 CallEventListeners( VCLEVENT_TABBAR_PAGEDEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1493 return nRet;
1496 // -----------------------------------------------------------------------
1498 long TabBar::DeactivatePage()
1500 if ( maDeactivatePageHdl.IsSet() )
1501 return maDeactivatePageHdl.Call( this );
1502 else
1503 return TRUE;
1506 // -----------------------------------------------------------------------
1508 long TabBar::StartRenaming()
1510 if ( maStartRenamingHdl.IsSet() )
1511 return maStartRenamingHdl.Call( this );
1512 else
1513 return TRUE;
1516 // -----------------------------------------------------------------------
1518 long TabBar::AllowRenaming()
1520 if ( maAllowRenamingHdl.IsSet() )
1521 return maAllowRenamingHdl.Call( this );
1522 else
1523 return TRUE;
1526 // -----------------------------------------------------------------------
1528 void TabBar::EndRenaming()
1530 maEndRenamingHdl.Call( this );
1533 // -----------------------------------------------------------------------
1535 void TabBar::Mirror()
1540 // -----------------------------------------------------------------------
1542 void TabBar::InsertPage( USHORT nPageId, const XubString& rText,
1543 TabBarPageBits nBits, USHORT nPos )
1545 DBG_ASSERT( nPageId, "TabBar::InsertPage(): PageId == 0" );
1546 DBG_ASSERT( GetPagePos( nPageId ) == TABBAR_PAGE_NOTFOUND,
1547 "TabBar::InsertPage(): PageId already exists" );
1548 DBG_ASSERT( nBits <= TPB_SPECIAL, "TabBar::InsertPage(): nBits is wrong" );
1550 // PageItem anlegen und in die Item-Liste eintragen
1551 ImplTabBarItem* pItem = new ImplTabBarItem( nPageId, rText, nBits );
1552 mpItemList->Insert( pItem, nPos );
1553 mbSizeFormat = TRUE;
1555 // CurPageId gegebenenfalls setzen
1556 if ( !mnCurPageId )
1557 mnCurPageId = nPageId;
1559 // Leiste neu ausgeben
1560 if ( IsReallyVisible() && IsUpdateMode() )
1561 Invalidate();
1563 CallEventListeners( VCLEVENT_TABBAR_PAGEINSERTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1566 // -----------------------------------------------------------------------
1568 void TabBar::RemovePage( USHORT nPageId )
1570 USHORT nPos = GetPagePos( nPageId );
1572 // Existiert Item
1573 if ( nPos != TABBAR_PAGE_NOTFOUND )
1575 if ( mnCurPageId == nPageId )
1576 mnCurPageId = 0;
1578 // Testen, ob erste sichtbare Seite verschoben werden muss
1579 if ( mnFirstPos > nPos )
1580 mnFirstPos--;
1582 // Item-Daten loeschen
1583 delete mpItemList->Remove( nPos );
1584 mbFormat = TRUE;
1586 // Leiste neu ausgeben
1587 if ( IsReallyVisible() && IsUpdateMode() )
1588 Invalidate();
1590 CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1594 // -----------------------------------------------------------------------
1596 void TabBar::MovePage( USHORT nPageId, USHORT nNewPos )
1598 USHORT nPos = GetPagePos( nPageId );
1599 Pair aPair( nPos, nNewPos );
1601 if ( nPos < nNewPos )
1602 nNewPos--;
1604 if ( nPos == nNewPos )
1605 return;
1607 // Existiert Item
1608 if ( nPos != TABBAR_PAGE_NOTFOUND )
1610 // TabBar-Item in der Liste verschieben
1611 ImplTabBarItem* pItem = mpItemList->Remove( nPos );
1612 mpItemList->Insert( pItem, nNewPos );
1613 mbFormat = TRUE;
1615 // Leiste neu ausgeben
1616 if ( IsReallyVisible() && IsUpdateMode() )
1617 Invalidate();
1619 CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED, (void*) &aPair );
1623 // -----------------------------------------------------------------------
1625 void TabBar::Clear()
1627 // Alle Items loeschen
1628 ImplTabBarItem* pItem = mpItemList->First();
1629 while ( pItem )
1631 // Item-Daten loeschen
1632 delete pItem;
1633 pItem = mpItemList->Next();
1636 // Items aus der Liste loeschen
1637 mpItemList->Clear();
1638 mbSizeFormat = TRUE;
1639 mnCurPageId = 0;
1640 mnFirstPos = 0;
1642 // Leiste neu ausgeben
1643 if ( IsReallyVisible() && IsUpdateMode() )
1644 Invalidate();
1646 CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, (void*) TABBAR_PAGE_NOTFOUND );
1649 // -----------------------------------------------------------------------
1651 void TabBar::EnablePage( USHORT nPageId, BOOL bEnable )
1653 USHORT nPos = GetPagePos( nPageId );
1655 if ( nPos != TABBAR_PAGE_NOTFOUND )
1657 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1659 if ( pItem->mbEnable != bEnable )
1661 pItem->mbEnable = bEnable;
1663 // Leiste neu ausgeben
1664 if ( IsReallyVisible() && IsUpdateMode() )
1665 Invalidate( pItem->maRect );
1667 CallEventListeners( bEnable ? VCLEVENT_TABBAR_PAGEENABLED : VCLEVENT_TABBAR_PAGEDISABLED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1672 // -----------------------------------------------------------------------
1674 BOOL TabBar::IsPageEnabled( USHORT nPageId ) const
1676 USHORT nPos = GetPagePos( nPageId );
1678 if ( nPos != TABBAR_PAGE_NOTFOUND )
1679 return mpItemList->GetObject( nPos )->mbEnable;
1680 else
1681 return FALSE;
1684 // -----------------------------------------------------------------------
1686 void TabBar::SetPageBits( USHORT nPageId, TabBarPageBits nBits )
1688 USHORT nPos = GetPagePos( nPageId );
1690 if ( nPos != TABBAR_PAGE_NOTFOUND )
1692 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1694 if ( pItem->mnBits != nBits )
1696 pItem->mnBits = nBits;
1698 // Leiste neu ausgeben
1699 if ( IsReallyVisible() && IsUpdateMode() )
1700 Invalidate( pItem->maRect );
1705 // -----------------------------------------------------------------------
1707 TabBarPageBits TabBar::GetPageBits( USHORT nPageId ) const
1709 USHORT nPos = GetPagePos( nPageId );
1711 if ( nPos != TABBAR_PAGE_NOTFOUND )
1712 return mpItemList->GetObject( nPos )->mnBits;
1713 else
1714 return FALSE;
1717 // -----------------------------------------------------------------------
1719 USHORT TabBar::GetPageCount() const
1721 return (USHORT)mpItemList->Count();
1724 // -----------------------------------------------------------------------
1726 USHORT TabBar::GetPageId( USHORT nPos ) const
1728 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1729 if ( pItem )
1730 return pItem->mnId;
1731 else
1732 return 0;
1735 // -----------------------------------------------------------------------
1737 USHORT TabBar::GetPagePos( USHORT nPageId ) const
1739 ImplTabBarItem* pItem = mpItemList->First();
1740 while ( pItem )
1742 if ( pItem->mnId == nPageId )
1743 return (USHORT)mpItemList->GetCurPos();
1745 pItem = mpItemList->Next();
1748 return TABBAR_PAGE_NOTFOUND;
1751 // -----------------------------------------------------------------------
1753 USHORT TabBar::GetPageId( const Point& rPos ) const
1755 ImplTabBarItem* pItem = mpItemList->First();
1756 while ( pItem )
1758 if ( pItem->maRect.IsInside( rPos ) )
1759 return pItem->mnId;
1761 pItem = mpItemList->Next();
1764 return 0;
1767 // -----------------------------------------------------------------------
1769 Rectangle TabBar::GetPageRect( USHORT nPageId ) const
1771 USHORT nPos = GetPagePos( nPageId );
1773 if ( nPos != TABBAR_PAGE_NOTFOUND )
1774 return mpItemList->GetObject( nPos )->maRect;
1775 else
1776 return Rectangle();
1779 // -----------------------------------------------------------------------
1781 void TabBar::SetCurPageId( USHORT nPageId )
1783 USHORT nPos = GetPagePos( nPageId );
1785 // Wenn Item nicht existiert, dann nichts machen
1786 if ( nPos != TABBAR_PAGE_NOTFOUND )
1788 // Wenn sich aktuelle Page nicht geaendert hat, dann muessen wir
1789 // jetzt nichts mehr machen
1790 if ( nPageId == mnCurPageId )
1791 return;
1793 // Muss invalidiert werden
1794 BOOL bUpdate = FALSE;
1795 if ( IsReallyVisible() && IsUpdateMode() )
1796 bUpdate = TRUE;
1798 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1799 ImplTabBarItem* pOldItem;
1801 if ( mnCurPageId )
1802 pOldItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) );
1803 else
1804 pOldItem = NULL;
1806 // Wenn Page nicht selektiert, dann vorher selektierte Seite
1807 // deselktieren, wenn dies die einzige selektierte Seite ist
1808 if ( !pItem->mbSelect && pOldItem )
1810 USHORT nSelPageCount = GetSelectPageCount();
1811 if ( nSelPageCount == 1 )
1812 pOldItem->mbSelect = FALSE;
1813 pItem->mbSelect = TRUE;
1816 mnCurPageId = nPageId;
1817 mbFormat = TRUE;
1819 // Dafuer sorgen, das aktuelle Page sichtbar wird
1820 if ( IsReallyVisible() )
1822 if ( nPos < mnFirstPos )
1823 SetFirstPageId( nPageId );
1824 else
1826 // sichtbare Breite berechnen
1827 long nWidth = mnLastOffX;
1828 if ( nWidth > TABBAR_OFFSET_X )
1829 nWidth -= TABBAR_OFFSET_X;
1830 if ( nWidth > ADDNEWPAGE_AREAWIDTH )
1831 nWidth -= ADDNEWPAGE_AREAWIDTH;
1833 if ( pItem->maRect.IsEmpty() )
1834 ImplFormat();
1836 while ( (mbMirrored ? (pItem->maRect.Left() < mnOffX) : (pItem->maRect.Right() > nWidth)) ||
1837 pItem->maRect.IsEmpty() )
1839 USHORT nNewPos = mnFirstPos+1;
1840 // Dafuer sorgen, das min. die aktuelle TabPages als
1841 // erste TabPage sichtbar ist
1842 if ( nNewPos >= nPos )
1844 SetFirstPageId( nPageId );
1845 break;
1847 else
1848 SetFirstPageId( GetPageId( nNewPos ) );
1849 ImplFormat();
1850 // Falls erste Seite nicht weitergeschaltet wird, dann
1851 // koennen wir abbrechen
1852 if ( nNewPos != mnFirstPos )
1853 break;
1858 // Leiste neu ausgeben
1859 if ( bUpdate )
1861 Invalidate( pItem->maRect );
1862 if ( pOldItem )
1863 Invalidate( pOldItem->maRect );
1868 // -----------------------------------------------------------------------
1870 void TabBar::MakeVisible( USHORT nPageId )
1872 if ( !IsReallyVisible() )
1873 return;
1875 USHORT nPos = GetPagePos( nPageId );
1877 // Wenn Item nicht existiert, dann nichts machen
1878 if ( nPos != TABBAR_PAGE_NOTFOUND )
1880 if ( nPos < mnFirstPos )
1881 SetFirstPageId( nPageId );
1882 else
1884 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1886 // sichtbare Breite berechnen
1887 long nWidth = mnLastOffX;
1888 if ( nWidth > TABBAR_OFFSET_X )
1889 nWidth -= TABBAR_OFFSET_X;
1891 if ( mbFormat || pItem->maRect.IsEmpty() )
1893 mbFormat = TRUE;
1894 ImplFormat();
1897 while ( (pItem->maRect.Right() > nWidth) ||
1898 pItem->maRect.IsEmpty() )
1900 USHORT nNewPos = mnFirstPos+1;
1901 // Dafuer sorgen, das min. die aktuelle TabPages als
1902 // erste TabPage sichtbar ist
1903 if ( nNewPos >= nPos )
1905 SetFirstPageId( nPageId );
1906 break;
1908 else
1909 SetFirstPageId( GetPageId( nNewPos ) );
1910 ImplFormat();
1911 // Falls erste Seite nicht weitergeschaltet wird, dann
1912 // koennen wir abbrechen
1913 if ( nNewPos != mnFirstPos )
1914 break;
1920 // -----------------------------------------------------------------------
1922 void TabBar::SetFirstPageId( USHORT nPageId )
1924 USHORT nPos = GetPagePos( nPageId );
1926 // Wenn Item nicht existiert, dann FALSE zurueckgeben
1927 if ( nPos != TABBAR_PAGE_NOTFOUND )
1929 if ( nPos != mnFirstPos )
1931 // Dafuer sorgen, das nach Moeglichkteit soviele Pages wie
1932 // moeglich sichtbar sind
1933 ImplFormat();
1934 USHORT nLastFirstPos = ImplGetLastFirstPos();
1935 USHORT nNewPos;
1936 if ( nPos > nLastFirstPos )
1937 nNewPos = nLastFirstPos;
1938 else
1939 nNewPos = nPos;
1941 if ( nNewPos != mnFirstPos )
1943 mnFirstPos = nNewPos;
1944 mbFormat = TRUE;
1946 // Leiste neu ausgeben (Achtung: mbDropPos beachten, da wenn
1947 // dieses Flag gesetzt ist, wird direkt gepaintet)
1948 if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos )
1949 Invalidate();
1955 // -----------------------------------------------------------------------
1957 void TabBar::SelectPage( USHORT nPageId, BOOL bSelect )
1959 USHORT nPos = GetPagePos( nPageId );
1961 if ( nPos != TABBAR_PAGE_NOTFOUND )
1963 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
1965 if ( pItem->mbSelect != bSelect )
1967 pItem->mbSelect = bSelect;
1969 // Leiste neu ausgeben
1970 if ( IsReallyVisible() && IsUpdateMode() )
1971 Invalidate( pItem->maRect );
1976 // -----------------------------------------------------------------------
1978 void TabBar::SelectPageRange( BOOL bSelect, USHORT nStartPos, USHORT nEndPos )
1980 Rectangle aPaintRect;
1981 USHORT nPos = nStartPos;
1982 ImplTabBarItem* pItem = mpItemList->Seek( nPos );
1983 while ( pItem && (nPos <= nEndPos) )
1985 if ( (pItem->mbSelect != bSelect) && (pItem->mnId != mnCurPageId) )
1987 pItem->mbSelect = bSelect;
1988 aPaintRect.Union( pItem->maRect );
1991 nPos++;
1992 pItem = mpItemList->Next();
1995 // Leiste neu ausgeben
1996 if ( IsReallyVisible() && IsUpdateMode() && !aPaintRect.IsEmpty() )
1997 Invalidate( aPaintRect );
2000 // -----------------------------------------------------------------------
2002 USHORT TabBar::GetSelectPage( USHORT nSelIndex ) const
2004 USHORT nSelected = 0;
2005 ImplTabBarItem* pItem = mpItemList->First();
2006 while ( pItem )
2008 if ( pItem->mbSelect )
2009 nSelected++;
2011 if ( nSelected == nSelIndex )
2012 return pItem->mnId;
2014 pItem = mpItemList->Next();
2017 return 0;
2020 // -----------------------------------------------------------------------
2022 USHORT TabBar::GetSelectPageCount() const
2024 USHORT nSelected = 0;
2025 ImplTabBarItem* pItem = mpItemList->First();
2026 while ( pItem )
2028 if ( pItem->mbSelect )
2029 nSelected++;
2031 pItem = mpItemList->Next();
2034 return nSelected;
2037 // -----------------------------------------------------------------------
2039 BOOL TabBar::IsPageSelected( USHORT nPageId ) const
2041 USHORT nPos = GetPagePos( nPageId );
2042 if ( nPos != TABBAR_PAGE_NOTFOUND )
2043 return mpItemList->GetObject( nPos )->mbSelect;
2044 else
2045 return FALSE;
2048 // -----------------------------------------------------------------------
2050 BOOL TabBar::StartEditMode( USHORT nPageId )
2052 USHORT nPos = GetPagePos( nPageId );
2053 if ( mpEdit || (nPos == TABBAR_PAGE_NOTFOUND) || (mnLastOffX < 8) )
2054 return FALSE;
2056 mnEditId = nPageId;
2057 if ( StartRenaming() )
2059 ImplShowPage( nPos );
2060 ImplFormat();
2061 Update();
2063 mpEdit = new TabBarEdit( this, WB_CENTER );
2064 Rectangle aRect = GetPageRect( mnEditId );
2065 long nX = aRect.Left()+TABBAR_OFFSET_X+(TABBAR_OFFSET_X2/2);
2066 long nWidth = aRect.GetWidth()-(TABBAR_OFFSET_X*2)-TABBAR_OFFSET_X2;
2067 if ( mnEditId != GetCurPageId() )
2068 nX += 1;
2069 if ( nX+nWidth > mnLastOffX )
2070 nWidth = mnLastOffX-nX;
2071 if ( nWidth < 3 )
2073 nX = aRect.Left();
2074 nWidth = aRect.GetWidth();
2076 mpEdit->SetText( GetPageText( mnEditId ) );
2077 mpEdit->SetPosSizePixel( nX, aRect.Top()+mnOffY+1, nWidth, aRect.GetHeight()-3 );
2078 Font aFont = GetPointFont();
2079 Color aForegroundColor;
2080 Color aBackgroundColor;
2081 Color aFaceColor;
2082 Color aSelectColor;
2083 Color aFaceTextColor;
2084 Color aSelectTextColor;
2085 ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
2086 if ( mnEditId != GetCurPageId() )
2087 aFont.SetWeight( WEIGHT_LIGHT );
2088 if ( IsPageSelected( mnEditId ) || (mnEditId == GetCurPageId()) )
2090 aForegroundColor = aSelectTextColor;
2091 aBackgroundColor = aSelectColor;
2093 else
2095 aForegroundColor = aFaceTextColor;
2096 aBackgroundColor = aFaceColor;
2098 if ( GetPageBits( mnEditId ) & TPB_SPECIAL )
2099 aForegroundColor = Color( COL_LIGHTBLUE );
2100 mpEdit->SetControlFont( aFont );
2101 mpEdit->SetControlForeground( aForegroundColor );
2102 mpEdit->SetControlBackground( aBackgroundColor );
2103 mpEdit->GrabFocus();
2104 mpEdit->SetSelection( Selection( 0, mpEdit->GetText().Len() ) );
2105 mpEdit->Show();
2106 return TRUE;
2108 else
2110 mnEditId = 0;
2111 return FALSE;
2115 // -----------------------------------------------------------------------
2117 void TabBar::EndEditMode( BOOL bCancel )
2119 if ( mpEdit )
2121 // call hdl
2122 BOOL bEnd = TRUE;
2123 mbEditCanceled = bCancel;
2124 maEditText = mpEdit->GetText();
2125 mpEdit->SetPostEvent();
2126 if ( !bCancel )
2128 long nAllowRenaming = AllowRenaming();
2129 if ( nAllowRenaming == TABBAR_RENAMING_YES )
2130 SetPageText( mnEditId, maEditText );
2131 else if ( nAllowRenaming == TABBAR_RENAMING_NO )
2132 bEnd = FALSE;
2133 else // nAllowRenaming == TABBAR_RENAMING_CANCEL
2134 mbEditCanceled = TRUE;
2137 // renaming not allowed, than reset edit data
2138 if ( !bEnd )
2140 mpEdit->ResetPostEvent();
2141 mpEdit->GrabFocus();
2143 else
2145 // close edit and call end hdl
2146 delete mpEdit;
2147 mpEdit = NULL;
2148 EndRenaming();
2149 mnEditId = 0;
2152 // reset
2153 maEditText.Erase();
2154 mbEditCanceled = FALSE;
2158 // -----------------------------------------------------------------------
2160 void TabBar::SetMirrored( BOOL bMirrored )
2162 if( mbMirrored != bMirrored )
2164 mbMirrored = bMirrored;
2165 mbSizeFormat = TRUE;
2166 ImplInitControls(); // for button images
2167 Resize(); // recalculates control positions
2168 Mirror();
2172 void TabBar::SetEffectiveRTL( BOOL bRTL )
2174 SetMirrored( bRTL != Application::GetSettings().GetLayoutRTL() );
2177 BOOL TabBar::IsEffectiveRTL() const
2179 return IsMirrored() != Application::GetSettings().GetLayoutRTL();
2182 // -----------------------------------------------------------------------
2184 void TabBar::SetMaxPageWidth( long nMaxWidth )
2186 if ( mnMaxPageWidth != nMaxWidth )
2188 mnMaxPageWidth = nMaxWidth;
2189 mbSizeFormat = TRUE;
2191 // Leiste neu ausgeben
2192 if ( IsReallyVisible() && IsUpdateMode() )
2193 Invalidate();
2197 // -----------------------------------------------------------------------
2199 void TabBar::SetSelectColor()
2201 if ( mbSelColor )
2203 maSelColor = Color( COL_TRANSPARENT );
2204 mbSelColor = FALSE;
2205 Invalidate();
2209 // -----------------------------------------------------------------------
2211 void TabBar::SetSelectColor( const Color& rColor )
2213 if ( rColor.GetTransparency() )
2215 if ( mbSelColor )
2217 maSelColor = Color( COL_TRANSPARENT );
2218 mbSelColor = FALSE;
2219 Invalidate();
2222 else
2224 if ( maSelColor != rColor )
2226 maSelColor = rColor;
2227 mbSelColor = TRUE;
2228 Invalidate();
2233 // -----------------------------------------------------------------------
2235 void TabBar::SetSelectTextColor()
2237 if ( mbSelTextColor )
2239 maSelTextColor = Color( COL_TRANSPARENT );
2240 mbSelTextColor = FALSE;
2241 Invalidate();
2245 // -----------------------------------------------------------------------
2247 void TabBar::SetSelectTextColor( const Color& rColor )
2249 if ( rColor.GetTransparency() )
2251 if ( mbSelTextColor )
2253 maSelTextColor = Color( COL_TRANSPARENT );
2254 mbSelTextColor = FALSE;
2255 Invalidate();
2258 else
2260 if ( maSelTextColor != rColor )
2262 maSelTextColor = rColor;
2263 mbSelTextColor = TRUE;
2264 Invalidate();
2269 // -----------------------------------------------------------------------
2271 void TabBar::SetPageText( USHORT nPageId, const XubString& rText )
2273 USHORT nPos = GetPagePos( nPageId );
2274 if ( nPos != TABBAR_PAGE_NOTFOUND )
2276 mpItemList->GetObject( nPos )->maText = rText;
2277 mbSizeFormat = TRUE;
2279 // Leiste neu ausgeben
2280 if ( IsReallyVisible() && IsUpdateMode() )
2281 Invalidate();
2283 CallEventListeners( VCLEVENT_TABBAR_PAGETEXTCHANGED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
2287 // -----------------------------------------------------------------------
2289 XubString TabBar::GetPageText( USHORT nPageId ) const
2291 USHORT nPos = GetPagePos( nPageId );
2292 if ( nPos != TABBAR_PAGE_NOTFOUND )
2293 return mpItemList->GetObject( nPos )->maText;
2294 else
2295 return XubString();
2298 // -----------------------------------------------------------------------
2300 void TabBar::SetHelpText( USHORT nPageId, const XubString& rText )
2302 USHORT nPos = GetPagePos( nPageId );
2303 if ( nPos != TABBAR_PAGE_NOTFOUND )
2304 mpItemList->GetObject( nPos )->maHelpText = rText;
2307 // -----------------------------------------------------------------------
2309 XubString TabBar::GetHelpText( USHORT nPageId ) const
2311 USHORT nPos = GetPagePos( nPageId );
2312 if ( nPos != TABBAR_PAGE_NOTFOUND )
2314 ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
2315 if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
2317 Help* pHelp = Application::GetHelp();
2318 if ( pHelp )
2319 pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId, this );
2322 return pItem->maHelpText;
2324 else
2325 return XubString();
2328 // -----------------------------------------------------------------------
2330 void TabBar::SetHelpId( USHORT nPageId, ULONG nHelpId )
2332 USHORT nPos = GetPagePos( nPageId );
2333 if ( nPos != TABBAR_PAGE_NOTFOUND )
2334 mpItemList->GetObject( nPos )->mnHelpId = nHelpId;
2337 // -----------------------------------------------------------------------
2339 ULONG TabBar::GetHelpId( USHORT nPageId ) const
2341 USHORT nPos = GetPagePos( nPageId );
2342 if ( nPos != TABBAR_PAGE_NOTFOUND )
2343 return mpItemList->GetObject( nPos )->mnHelpId;
2344 else
2345 return 0;
2348 // -----------------------------------------------------------------------
2350 long TabBar::GetMinSize() const
2352 long nMinSize = TABBAR_MINSIZE + TABBAR_OFFSET_X;
2353 if ( mnWinStyle & WB_MINSCROLL )
2354 nMinSize += mpPrevBtn->GetSizePixel().Width()*2;
2355 else if ( mnWinStyle & WB_SCROLL )
2356 nMinSize += mpFirstBtn->GetSizePixel().Width()*4;
2357 return nMinSize;
2360 // -----------------------------------------------------------------------
2362 BOOL TabBar::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
2364 if ( !(mnWinStyle & WB_DRAG) || (rCEvt.GetCommand() != COMMAND_STARTDRAG) )
2365 return FALSE;
2367 // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
2368 // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
2369 // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
2370 // dies nur bei einer Mausaktion.
2371 // Ausserdem machen wir das nur, wenn kein Select() ausgeloest wurde,
2372 // da der Select schon den Bereich gescrollt haben kann
2373 if ( rCEvt.IsMouseEvent() && !mbInSelect )
2375 USHORT nSelId = GetPageId( rCEvt.GetMousePosPixel() );
2377 // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
2378 if ( !nSelId )
2379 return FALSE;
2381 // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
2382 // Seite setzen und Select rufen.
2383 if ( !IsPageSelected( nSelId ) )
2385 if ( ImplDeactivatePage() )
2387 SetCurPageId( nSelId );
2388 Update();
2389 ImplActivatePage();
2390 ImplSelect();
2392 else
2393 return FALSE;
2396 mbInSelect = FALSE;
2398 Region aRegion;
2400 // Region zuweisen
2401 rRegion = aRegion;
2403 return TRUE;
2406 // -----------------------------------------------------------------------
2408 USHORT TabBar::ShowDropPos( const Point& rPos )
2410 ImplTabBarItem* pItem;
2411 USHORT nDropId;
2412 USHORT nNewDropPos;
2413 USHORT nItemCount = (USHORT)mpItemList->Count();
2414 short nScroll = 0;
2416 if ( rPos.X() > mnLastOffX-TABBAR_DRAG_SCROLLOFF )
2418 pItem = mpItemList->GetObject( mpItemList->Count()-1 );
2419 if ( !pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()) )
2420 nNewDropPos = (USHORT)mpItemList->Count();
2421 else
2423 nNewDropPos = mnFirstPos+1;
2424 nScroll = 1;
2427 else if ( (rPos.X() <= mnOffX) ||
2428 (!mnOffX && (rPos.X() <= TABBAR_DRAG_SCROLLOFF)) )
2430 if ( mnFirstPos )
2432 nNewDropPos = mnFirstPos;
2433 nScroll = -1;
2435 else
2436 nNewDropPos = 0;
2438 else
2440 nDropId = GetPageId( rPos );
2441 if ( nDropId )
2443 nNewDropPos = GetPagePos( nDropId );
2444 if ( mnFirstPos && (nNewDropPos == mnFirstPos-1) )
2445 nScroll = -1;
2447 else
2448 nNewDropPos = nItemCount;
2451 if ( mbDropPos && (nNewDropPos == mnDropPos) && !nScroll )
2452 return mnDropPos;
2454 if ( mbDropPos )
2455 HideDropPos();
2456 mbDropPos = TRUE;
2457 mnDropPos = nNewDropPos;
2459 if ( nScroll )
2461 USHORT nOldFirstPos = mnFirstPos;
2462 SetFirstPageId( GetPageId( mnFirstPos+nScroll ) );
2464 // Direkt ausgeben, da kein Paint bei Drag and Drop moeglich
2465 if ( nOldFirstPos != mnFirstPos )
2467 Rectangle aRect( mnOffX, 0, mnLastOffX, maWinSize.Height() );
2468 SetFillColor( GetBackground().GetColor() );
2469 DrawRect( aRect );
2470 Paint( aRect );
2474 // Drop-Position-Pfeile ausgeben
2475 Color aBlackColor( COL_BLACK );
2476 long nX;
2477 long nY = (maWinSize.Height()/2)-1;
2478 USHORT nCurPos = GetPagePos( mnCurPageId );
2480 SetLineColor( aBlackColor );
2481 if ( mnDropPos < nItemCount )
2483 pItem = mpItemList->GetObject( mnDropPos );
2484 nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
2485 if ( mnDropPos == nCurPos )
2486 nX--;
2487 else
2488 nX++;
2489 DrawLine( Point( nX, nY ), Point( nX, nY ) );
2490 DrawLine( Point( nX+1, nY-1 ), Point( nX+1, nY+1 ) );
2491 DrawLine( Point( nX+2, nY-2 ), Point( nX+2, nY+2 ) );
2493 if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
2495 pItem = mpItemList->GetObject( mnDropPos-1 );
2496 nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
2497 if ( mnDropPos == nCurPos )
2498 nX++;
2499 DrawLine( Point( nX, nY ), Point( nX, nY ) );
2500 DrawLine( Point( nX-1, nY-1 ), Point( nX-1, nY+1 ) );
2501 DrawLine( Point( nX-2, nY-2 ), Point( nX-2, nY+2 ) );
2504 return mnDropPos;
2507 // -----------------------------------------------------------------------
2509 void TabBar::HideDropPos()
2511 if ( mbDropPos )
2513 ImplTabBarItem* pItem;
2514 long nX;
2515 long nY1 = (maWinSize.Height()/2)-3;
2516 long nY2 = nY1 + 5;
2517 USHORT nItemCount = (USHORT)mpItemList->Count();
2519 if ( mnDropPos < nItemCount )
2521 pItem = mpItemList->GetObject( mnDropPos );
2522 nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
2523 // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2524 // moeglich
2525 Rectangle aRect( nX-1, nY1, nX+3, nY2 );
2526 Region aRegion( aRect );
2527 SetClipRegion( aRegion );
2528 Paint( aRect );
2529 SetClipRegion();
2531 if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
2533 pItem = mpItemList->GetObject( mnDropPos-1 );
2534 nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
2535 // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2536 // moeglich
2537 Rectangle aRect( nX-2, nY1, nX+1, nY2 );
2538 Region aRegion( aRect );
2539 SetClipRegion( aRegion );
2540 Paint( aRect );
2541 SetClipRegion();
2544 mbDropPos = FALSE;
2545 mnDropPos = 0;
2549 // -----------------------------------------------------------------------
2551 BOOL TabBar::SwitchPage( const Point& rPos )
2553 BOOL bSwitch = FALSE;
2554 USHORT nSwitchId = GetPageId( rPos );
2555 if ( !nSwitchId )
2556 EndSwitchPage();
2557 else
2559 if ( nSwitchId != mnSwitchId )
2561 mnSwitchId = nSwitchId;
2562 mnSwitchTime = Time::GetSystemTicks();
2564 else
2566 // Erst nach 500 ms umschalten
2567 if ( mnSwitchId != GetCurPageId() )
2569 if ( Time::GetSystemTicks() > mnSwitchTime+500 )
2571 mbInSwitching = TRUE;
2572 if ( ImplDeactivatePage() )
2574 SetCurPageId( mnSwitchId );
2575 Update();
2576 ImplActivatePage();
2577 ImplSelect();
2578 bSwitch = TRUE;
2580 mbInSwitching = FALSE;
2586 return bSwitch;
2589 // -----------------------------------------------------------------------
2591 void TabBar::EndSwitchPage()
2593 mnSwitchTime = 0;
2594 mnSwitchId = 0;
2597 // -----------------------------------------------------------------------
2599 void TabBar::SetStyle( WinBits nStyle )
2601 mnWinStyle = nStyle;
2602 ImplInitControls();
2603 // Evt. Controls neu anordnen
2604 if ( IsReallyVisible() && IsUpdateMode() )
2605 Resize();
2608 // -----------------------------------------------------------------------
2610 Size TabBar::CalcWindowSizePixel() const
2612 long nWidth = 0;
2614 if ( mpItemList->Count() )
2616 ((TabBar*)this)->ImplCalcWidth();
2617 ImplTabBarItem* pItem = mpItemList->First();
2618 while ( pItem )
2620 nWidth += pItem->mnWidth;
2621 pItem = mpItemList->Next();
2623 nWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
2626 return Size( nWidth, GetSettings().GetStyleSettings().GetScrollBarSize() );
2628 // -----------------------------------------------------------------------
2630 Rectangle TabBar::GetPageArea() const
2632 return Rectangle( Point( mnOffX, mnOffY ), Size( mnLastOffX-mnOffX+1, GetSizePixel().Height()-mnOffY ) );
2635 // -----------------------------------------------------------------------
2637 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > TabBar::CreateAccessible()
2639 return mpImpl->maAccessibleFactory.getFactory().createAccessibleTabBar( *this );
2642 // -----------------------------------------------------------------------