Branch libreoffice-5-0-4
[LibreOffice.git] / include / svtools / tabbar.hxx
blob9d0ee92437c4ed26c518960d1dc0f9fa680467a5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
26 #include <vector>
30 Allowed StylbeBits
31 ------------------
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.
51 Allowed PageBits
52 -----------------
54 TPB_SPECIAL - Different display of the TabText, e.g. for scenario pages.
56 Handlers
57 -------
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
69 deactivated.
73 Drag and Drop
74 -------------
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
104 by the handlers:
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
143 ended.
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
149 box.
152 Window Resize
153 --------------
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
167 SetSplitHdl().
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
182 is active.
185 Edit Mode
186 ----------
188 The TabBar also offers the user the possibility to change the names
189 in the Tabs.
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
194 be rejected.
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
205 is active.
206 IsEditModeCanceled - This method can be used in the EndRenaming()
207 handler to query whether the renaming has
208 been canceled.
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
216 not be started.
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
221 GetEditPageId().
222 One of the following values should be returned:
223 TAB_RENAMING_YES
224 The Tab is renamed.
225 TAB_RENAMING_NO
226 The Tab is not renamed, but the EditMode remains
227 active, so that the user can adapt the name
228 accordingly.
229 TAB_RENAMING_CANCEL
230 The EditMode was cancelled and the old text
231 is restored.
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.
240 Maximum Page width
241 -------------------
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).
253 ContextMenu
254 -----------
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
260 been carried out.
264 // - WinBits -
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 {
291 TABBAR_RENAMING_NO,
292 TABBAR_RENAMING_YES,
293 TABBAR_RENAMING_CANCEL
297 // - TabBar -
299 class MouseEvent;
300 class TrackingEvent;
301 class DataChangedEvent;
302 class ImplTabButton;
303 class ImplTabSizer;
304 class TabBarEdit;
306 struct ImplTabBarItem;
307 struct TabBar_Impl;
308 typedef std::vector<ImplTabBarItem*> ImplTabBarList;
310 class SVT_DLLPUBLIC TabBar : public vcl::Window
312 friend class ImplTabButton;
313 friend class ImplTabSizer;
315 private:
316 std::unique_ptr<TabBar_Impl> mpImpl;
318 ImplTabBarList* mpItemList;
320 OUString maEditText;
321 Color maSelColor;
322 Color maSelTextColor;
323 Size maWinSize;
324 long mnMaxPageWidth;
325 long mnCurMaxWidth;
326 long mnOffX;
327 long mnOffY;
328 long mnLastOffX;
329 long mnSplitSize;
330 sal_uInt64 mnSwitchTime;
331 WinBits mnWinStyle;
332 sal_uInt16 mnCurPageId;
333 sal_uInt16 mnFirstPos;
334 sal_uInt16 mnDropPos;
335 sal_uInt16 mnSwitchId;
336 sal_uInt16 mnEditId;
338 bool mbFormat : 1;
339 bool mbFirstFormat : 1;
340 bool mbSizeFormat : 1;
341 bool mbAutoMaxWidth : 1;
342 bool mbInSwitching : 1;
343 bool mbAutoEditMode : 1;
344 bool mbEditCanceled : 1;
345 bool mbDropPos : 1;
346 bool mbInSelect : 1;
347 bool mbSelColor : 1;
348 bool mbSelTextColor : 1;
349 bool mbMirrored : 1;
350 bool mbScrollAlwaysEnabled : 1;
352 Link<> maSelectHdl;
353 Link<> maSplitHdl;
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();
383 protected:
384 virtual void AddTabClick();
386 public:
387 static const sal_uInt16 APPEND;
388 static const sal_uInt16 PAGE_NOT_FOUND;
390 TabBar( vcl::Window* pParent, WinBits nWinStyle = WB_STDTABBAR );
391 virtual ~TabBar();
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();
406 void Split();
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 );
424 void Clear();
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 );
485 void HideDropPos();
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; }
518 // accessibility
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: */