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 .
20 #ifndef INCLUDED_SVTOOLS_TABBAR_HXX
21 #define INCLUDED_SVTOOLS_TABBAR_HXX
23 #include <svtools/svtdllapi.h>
24 #include <tools/link.hxx>
25 #include <vcl/window.hxx>
33 WB_SCROLL - The tabs can be scrolled via an extra field
34 WB_MINSCROLL - The tabs can be scrolled via 2 additional buttons
35 WB_RANGESELECT - Connected ranges can be selected
36 WB_MULTISELECT - single tabs can be selected
37 WB_BORDER - a border is drawn in the top and in the bottom
38 WB_TOPBORDER - a border is drawn in the top
39 WB_3DTAB - the tabs and the border are drawn in 3D
40 WB_DRAG - A StartDrag handler is called by the TabBar, if drag
41 and drop should be started. In addition, drag and drop
42 is activated in the TabBar with EnableDrop().
43 WB_SIZEABLE - a Split handler is called by the TabBar, if the user
44 wants to change the width of the TabBar
45 WB_STDTABBAR - WB_BORDER
47 If the TabBar should be used for example as Property bar, the WinBits
48 WB_TOPBORDER and WB_3DTAB should be set instead of WB_BORDER.
54 TPB_SPECIAL - Different display of the TabText, e.g. for scenario pages.
59 Select - is called when a tab is selected or unselected
60 DoubleClick - Is called when a DoubleClick has been fired in the
61 TabBar. Inside of the handler, GetCurPageId() returns
62 the clicked tab or 0, if no tab has been clicked.
63 ActivatePage - Is called, if another page is activated.
64 GetCurPageId() returns the activated page.
65 DeactivatePage - Is called, when a page is deactivated. If another page
66 may be activated, true must be returned; if another
67 page shall be excluded from the activation, false must
68 be returned. GetCurPageId() returns the page to be
76 For Drag and Drop, the WinBit WB_DRAG must be set. In addition, the
77 Command handler, the QueryDrop handler and the Drop handler must be overlaid.
78 In doing so, the following must be implemented in the handlers:
80 Command - If dragging should be started in this handler,
81 StartDrag() must be called. This method
82 then selects the respective entry or returns
83 false, if dragging cannot be carried out.
85 QueryDrop - This handler is always called by StarView, when the
86 mouse is pulled over the window while dragging
87 (s.a. SV documentation). In this handler, it must be
88 determined whether a drop is possible. The drop
89 position can be shown in TabBar using ShowDropPos().
90 When calling, the position of the Event must be passed.
91 If the position is at the left or right border,
92 scrolling automatically takes place in the TabBar.
93 This method also returns the respective drop position,
94 which is also needed for a drop. If the window is left
95 while dragging, the drop position can be taken back
96 using HideDropPos(). Thus, it is also possible to handle
97 a drag which was triggered from outside the TabBar.
99 Drop - In the Drop handler, the pages have to be moved, or
100 the new pages have to be inserted. The respective
101 drop position can be determined using ShowDropPos().
103 The following methods are needed for Drag and Drop and must be called
106 StartDrag - Must be called from the Command handler. As parameters,
107 the CommandEvent and a reference to a Region must be
108 passed. This vcl::Region then must be passed in
109 ExecuteDrag(), if the return value indicates that
110 ExecuteDrag shall be carried out. If the entry is not
111 selected, it is set as the current entry beforehand.
112 Because of this, attention must be paid that the Select
113 handler can be called from this method.
115 ShowDropPos - This method must be called by the QueryDrop handler,
116 so that the TabBar shows where the Tabs are
117 inserted. This method can also be used in the Drop
118 handler, in order to determine the position at which
119 the Tabs shall be inserted. In the method, the
120 position of the Event must be passed. This method
121 returns the position, at which the Tabs shall be inserted.
123 HideDropPos - This method takes back the DropPosition previously
124 displayed using ShowDropPos(). This method should be
125 called, when the window is left in the QueryDrop()
126 handler or the drag process has been ended.
128 The following methods can be used if the pages should be switched
129 in the Drag and Drop:
131 SwitchPage - This method must be called by the QueryDrop handler
132 if the page, over which the mouse pointer resides,
133 should be switched. This method should be called
134 each time the QueryDrop-Handler is called.
135 Switching the page happens with a delay (500 ms) and
136 is automatically managed by this method.
137 The Position of the Event must be passed in the method.
138 This method returns true if the page has been switched.
140 EndSwitchPage - This method resets the data for the switching of the
141 page. This method should be called when the window
142 is left in QueryDrop() or the drag process has been
145 IsInSwitching - With this method, it can be queried in
146 ActivatePage()/DeactivatePage() whether this has been
147 caused by SwitchPage(). Thus, for example, switching
148 can be avoided in DeactivatePage() without an error
155 If the window width can be changed by the user, the WinBit WB_SIZEABLE
156 must be set. In this case, the following handler must be overlaid:
158 Split - When this handler is called, the window should be
159 adapted to the width that is returned by GetSplitSize().
160 In doing so, no minimal or maximum width is taken into
161 account. A minimal size can be queried using
162 GetMinSize() and the maximum width must be calculated
163 by the application itself. As only Online Resize is
164 supported, the window width must be changed inside
165 this handler and possibly the width of dependent windows
166 as well. For this handler, a link can also be set using
169 The following methods deliver more information while Splitting:
171 GetSplitSize() - Returns the width of the TabBar, to which the user
172 wants to resize the window. No minimum or maximum
173 width is taken into account. However, a width < 5
174 is never returned. This method only returns valid
175 values as long as splitting is active.
177 GetMinSize() - With this method, a minimum window width can be
178 queried, so that at least something of a Tab is
179 visible. Still, the TabBar can be set more narrow
180 then the width that this method returns.
181 This method can also be called, when no splitting
188 The TabBar also offers the user the possibility to change the names
191 EnableEditMode - With this, it can be configured that on Alt+LeftClick,
192 StartEditMode() is automatically called by the TabBar.
193 In the StartRenaming() handler, the renaming can still
195 StartEditMode - With this method, the EditMode is started on a Tab.
196 false is returned, if the EditMode is already
197 active, the mode is rejected with StartRenaming()
198 or no space is available for editing.
199 EndEditMode - With this method, the EditMode is ended.
200 SetEditText - With this method, the text in the AllowRenaming()
201 handler can still be replaced by another text.
202 GetEditText - With this method, the text, which the user has typed
203 in, can be queried in the AllowRenaming() handler.
204 IsInEditMode - This method is used to query whether the EditMode
206 IsEditModeCanceled - This method can be used in the EndRenaming()
207 handler to query whether the renaming has
209 GetEditPageId - With this method, the tab that is being/has been
210 renamed is queried in the Renaming handlers.
212 StartRenaming() - This handler is called when the EditMode hast been
213 started using StartEditMode(). GetEditPageId()
214 can be used to query which Tab should be renamed.
215 false should be returned if the EditMod should
217 AllowRenaming() - This handler is called when the EditMode is ended
218 (not in case of Cancel). Within this handler, it
219 can then be tested whether the text is OK.
220 The Tab which was renamed can be queried using
222 One of the following values should be returned:
226 The Tab is not renamed, but the EditMode remains
227 active, so that the user can adapt the name
230 The EditMode was cancelled and the old text
232 EndRenaming() - This handler is called when the EditMode has been
233 ended. The tab that has been renamed can be
234 queried using GetEditPageId(). Using
235 IsEditModeCanceled(), it can be queried whether
236 the mode has been cancelled and the name has
237 thus not been changed.
243 The Page width of the tabs can be limited in order to make an easier
244 navigation by them possible. If then, the text cannot be displayed
245 completely, it is abbreviated with "..." and the whole text is
246 displayed in the Tip or in the active help (if no help text is set).
247 Using EnableAutoMaxPageWidth(), it can be configured whether the
248 maximum page width should be based on the currently visible width
249 (which is the default). Otherwise, the maximum page width can
250 also be set using SetMaxPageWidth() (in pixels) (in this case, the
251 AutoMaxPageWidth is ignored).
256 If a context-sensitive PopupMenu should be displayed, the Command
257 handler must be overlaid. Using GetPageId() and when passing the
258 mouse position, it can be determined whether the mouse click has been
259 carried out over an item resp. over which item the mouse click has
267 #define WB_RANGESELECT ((WinBits)0x00200000)
268 #define WB_MULTISELECT ((WinBits)0x00400000)
269 #define WB_TOPBORDER ((WinBits)0x04000000)
270 #define WB_3DTAB ((WinBits)0x08000000)
271 #define WB_MINSCROLL ((WinBits)0x20000000)
272 #define WB_INSERTTAB ((WinBits)0x40000000)
273 #define WB_STDTABBAR WB_BORDER
276 // - TabBarPageBits -
279 typedef sal_uInt16 TabBarPageBits
;
282 // - Bits for TabBarPages -
285 #define TPB_SPECIAL ((TabBarPageBits)0x0001)
288 // - TabBar-Types - used in TabBar::AllowRenaming
290 enum TabBarAllowRenamingReturnCode
{
293 TABBAR_RENAMING_CANCEL
301 class DataChangedEvent
;
306 struct ImplTabBarItem
;
308 typedef std::vector
<ImplTabBarItem
*> ImplTabBarList
;
310 class SVT_DLLPUBLIC TabBar
: public vcl::Window
312 friend class ImplTabButton
;
313 friend class ImplTabSizer
;
316 std::unique_ptr
<TabBar_Impl
> mpImpl
;
318 ImplTabBarList
* mpItemList
;
322 Color maSelTextColor
;
330 sal_uInt64 mnSwitchTime
;
332 sal_uInt16 mnCurPageId
;
333 sal_uInt16 mnFirstPos
;
334 sal_uInt16 mnDropPos
;
335 sal_uInt16 mnSwitchId
;
339 bool mbFirstFormat
: 1;
340 bool mbSizeFormat
: 1;
341 bool mbAutoMaxWidth
: 1;
342 bool mbInSwitching
: 1;
343 bool mbAutoEditMode
: 1;
344 bool mbEditCanceled
: 1;
348 bool mbSelTextColor
: 1;
350 bool mbScrollAlwaysEnabled
: 1;
354 Link
<> maScrollAreaContextHdl
;
355 size_t maCurrentItemList
;
357 using Window::ImplInit
;
358 SVT_DLLPRIVATE
void ImplInit( WinBits nWinStyle
);
359 SVT_DLLPRIVATE
void ImplInitSettings( bool bFont
, bool bBackground
);
360 SVT_DLLPRIVATE
void ImplGetColors(const StyleSettings
& rStyleSettings
,
361 Color
& rFaceColor
, Color
& rFaceTextColor
,
362 Color
& rSelectColor
, Color
& rSelectTextColor
);
363 SVT_DLLPRIVATE
void ImplShowPage( sal_uInt16 nPos
);
364 SVT_DLLPRIVATE
bool ImplCalcWidth();
365 SVT_DLLPRIVATE
void ImplFormat();
366 SVT_DLLPRIVATE sal_uInt16
ImplGetLastFirstPos();
367 SVT_DLLPRIVATE
void ImplInitControls();
368 SVT_DLLPRIVATE
void ImplEnableControls();
369 SVT_DLLPRIVATE
void ImplSelect();
370 SVT_DLLPRIVATE
void ImplActivatePage();
371 SVT_DLLPRIVATE
bool ImplDeactivatePage();
372 SVT_DLLPRIVATE
void ImplPrePaint(vcl::RenderContext
& rRenderContext
);
373 SVT_DLLPRIVATE ImplTabBarItem
* ImplGetLastTabBarItem( sal_uInt16 nItemCount
);
375 DECL_DLLPRIVATE_LINK(ImplClickHdl
, ImplTabButton
*);
377 DECL_DLLPRIVATE_LINK(ImplAddClickHandler
, void*);
379 ImplTabBarItem
* seek( size_t i
);
380 ImplTabBarItem
* prev();
381 ImplTabBarItem
* next();
384 virtual void AddTabClick();
387 static const sal_uInt16 APPEND
;
388 static const sal_uInt16 PAGE_NOT_FOUND
;
390 TabBar( vcl::Window
* pParent
, WinBits nWinStyle
= WB_STDTABBAR
);
392 virtual void dispose() SAL_OVERRIDE
;
394 virtual void MouseMove( const MouseEvent
& rMEvt
) SAL_OVERRIDE
;
395 virtual void MouseButtonDown( const MouseEvent
& rMEvt
) SAL_OVERRIDE
;
396 virtual void MouseButtonUp( const MouseEvent
& rMEvt
) SAL_OVERRIDE
;
397 virtual void Paint( vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
) SAL_OVERRIDE
;
398 virtual void Resize() SAL_OVERRIDE
;
399 virtual void RequestHelp( const HelpEvent
& rHEvt
) SAL_OVERRIDE
;
400 virtual void StateChanged( StateChangedType nStateChange
) SAL_OVERRIDE
;
401 virtual void DataChanged( const DataChangedEvent
& rDCEvt
) SAL_OVERRIDE
;
402 virtual bool PreNotify( NotifyEvent
& rNEvt
) SAL_OVERRIDE
;
404 virtual void Select();
405 virtual void DoubleClick();
407 virtual void ActivatePage();
408 virtual bool DeactivatePage();
409 virtual bool StartRenaming();
410 virtual TabBarAllowRenamingReturnCode
AllowRenaming();
411 virtual void EndRenaming();
412 virtual void Mirror();
414 void InsertPage( sal_uInt16 nPageId
, const OUString
& rText
,
415 TabBarPageBits nBits
= 0,
416 sal_uInt16 nPos
= TabBar::APPEND
);
417 void RemovePage( sal_uInt16 nPageId
);
418 void MovePage( sal_uInt16 nPageId
, sal_uInt16 nNewPos
);
420 Color
GetTabBgColor( sal_uInt16 nPageId
) const;
421 void SetTabBgColor( sal_uInt16 nPageId
, const Color
& aTabBgColor
);
422 bool IsDefaultTabBgColor( sal_uInt16 nPageId
);
426 bool IsPageEnabled( sal_uInt16 nPageId
) const;
428 void SetPageBits( sal_uInt16 nPageId
, TabBarPageBits nBits
= 0 );
429 TabBarPageBits
GetPageBits( sal_uInt16 nPageId
) const;
431 sal_uInt16
GetPageCount() const;
432 sal_uInt16
GetPageId( sal_uInt16 nPos
) const;
433 sal_uInt16
GetPagePos( sal_uInt16 nPageId
) const;
434 sal_uInt16
GetPageId( const Point
& rPos
) const;
435 Rectangle
GetPageRect( sal_uInt16 nPageId
) const;
436 // returns the rectangle in which page tabs are drawn
437 Rectangle
GetPageArea() const;
439 void SetCurPageId( sal_uInt16 nPageId
);
440 sal_uInt16
GetCurPageId() const { return mnCurPageId
; }
442 void SetFirstPageId( sal_uInt16 nPageId
);
443 sal_uInt16
GetFirstPageId() const { return GetPageId( mnFirstPos
); }
444 void MakeVisible( sal_uInt16 nPageId
);
446 void SelectPage( sal_uInt16 nPageId
, bool bSelect
= true );
447 sal_uInt16
GetSelectPageCount() const;
448 bool IsPageSelected( sal_uInt16 nPageId
) const;
450 void EnableAutoMaxPageWidth( bool bEnable
= true ) { mbAutoMaxWidth
= bEnable
; }
451 bool IsAutoMaxPageWidthEnabled() const { return mbAutoMaxWidth
; }
452 void SetMaxPageWidth( long nMaxWidth
);
453 long GetMaxPageWidth() const { return mnMaxPageWidth
; }
454 void ResetMaxPageWidth() { SetMaxPageWidth( 0 ); }
455 bool IsMaxPageWidth() const { return mnMaxPageWidth
!= 0; }
457 void EnableEditMode( bool bEnable
= true ) { mbAutoEditMode
= bEnable
; }
458 bool IsEditModeEnabled() const { return mbAutoEditMode
; }
459 bool StartEditMode( sal_uInt16 nPageId
);
460 void EndEditMode( bool bCancel
= false );
461 void SetEditText( const OUString
& rText
) { maEditText
= rText
; }
462 const OUString
& GetEditText() const { return maEditText
; }
463 bool IsInEditMode() const;
464 bool IsEditModeCanceled() const { return mbEditCanceled
; }
465 sal_uInt16
GetEditPageId() const { return mnEditId
; }
467 /** Mirrors the entire control including position of buttons and splitter.
468 Mirroring is done relative to the current direction of the GUI.
469 @param bMirrored sal_True = the control will draw itself RTL in LTR GUI,
470 and vice versa; sal_False = the control behaves according to the
471 current direction of the GUI. */
472 void SetMirrored(bool bMirrored
= true);
473 /** Returns true, if the control is set to mirrored mode (see SetMirrored()). */
474 bool IsMirrored() const { return mbMirrored
; }
476 /** Sets the control to LTR or RTL mode regardless of the GUI direction.
477 @param bRTL sal_False = the control will draw from left to right;
478 sal_True = the control will draw from right to left. */
479 void SetEffectiveRTL( bool bRTL
);
480 /** Returns true, if the control draws from right to left (see SetEffectiveRTL()). */
481 bool IsEffectiveRTL() const;
483 bool StartDrag( const CommandEvent
& rCEvt
, vcl::Region
& rRegion
);
484 sal_uInt16
ShowDropPos( const Point
& rPos
);
486 bool SwitchPage( const Point
& rPos
);
487 void EndSwitchPage();
488 bool IsInSwitching() { return mbInSwitching
; }
490 const Color
& GetSelectColor() const { return maSelColor
; }
491 bool IsSelectColor() const { return mbSelColor
; }
492 const Color
& GetSelectTextColor() const { return maSelTextColor
; }
493 bool IsSelectTextColor() const { return mbSelTextColor
; }
495 void SetPageText( sal_uInt16 nPageId
, const OUString
& rText
);
496 OUString
GetPageText( sal_uInt16 nPageId
) const;
497 OUString
GetHelpText( sal_uInt16 nPageId
) const;
498 OString
GetHelpId( sal_uInt16 nPageId
) const;
500 long GetSplitSize() const { return mnSplitSize
; }
502 using Window::SetHelpText
;
503 using Window::GetHelpText
;
504 using Window::SetHelpId
;
505 using Window::GetHelpId
;
507 void SetStyle( WinBits nStyle
);
508 WinBits
GetStyle() const { return mnWinStyle
; }
510 void SetScrollAlwaysEnabled(bool bScrollAlwaysEnabled
);
512 Size
CalcWindowSizePixel() const;
514 void SetSelectHdl( const Link
<>& rLink
) { maSelectHdl
= rLink
; }
515 void SetSplitHdl( const Link
<>& rLink
) { maSplitHdl
= rLink
; }
516 void SetScrollAreaContextHdl( const Link
<>& rLink
) { maScrollAreaContextHdl
= rLink
; }
519 virtual css::uno::Reference
<css::accessibility::XAccessible
> CreateAccessible() SAL_OVERRIDE
;
522 #endif // INCLUDED_SVTOOLS_TABBAR_HXX
524 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */