bump product version to 6.3.0.0.beta1
[LibreOffice.git] / include / svtools / tabbar.hxx
blobbccdbb55d3ed806ff8b93ddd1f24b0049e57cec4
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 <o3tl/typed_flags_set.hxx>
27 #include <memory>
29 class StyleSettings;
33 Allowed StylbeBits
34 ------------------
36 WB_SCROLL - The tabs can be scrolled via an extra field
37 WB_MINSCROLL - The tabs can be scrolled via 2 additional buttons
38 WB_RANGESELECT - Connected ranges can be selected
39 WB_MULTISELECT - single tabs can be selected
40 WB_BORDER - a border is drawn in the top and in the bottom
41 WB_DRAG - A StartDrag handler is called by the TabBar, if drag
42 and drop should be started. In addition, drag and drop
43 is activated in the TabBar with EnableDrop().
44 WB_SIZEABLE - a Split handler is called by the TabBar, if the user
45 wants to change the width of the TabBar
46 WB_STDTABBAR - WB_BORDER
49 Allowed PageBits
50 -----------------
52 Setting page bits modify the display attributes of the tab name
54 TabBarPageBits::Blue
55 - Display tab name in light blue, used in draw for
56 invisible layers and in calc for scenario pages
57 TabBarPageBits::Italic
58 - Display tab name italic, used in draw for
59 locked layers
60 TabBarPageBits::Underline
61 - Display tab name underlined, used in draw for
62 non-printable layers
65 Handlers
66 -------
68 Select - is called when a tab is selected or unselected
69 DoubleClick - Is called when a DoubleClick has been fired in the
70 TabBar. Inside of the handler, GetCurPageId() returns
71 the clicked tab or 0, if no tab has been clicked.
72 ActivatePage - Is called, if another page is activated.
73 GetCurPageId() returns the activated page.
74 DeactivatePage - Is called, when a page is deactivated. If another page
75 may be activated, true must be returned; if another
76 page shall be excluded from the activation, false must
77 be returned. GetCurPageId() returns the page to be
78 deactivated.
81 Drag and Drop
82 -------------
84 For Drag and Drop, the WinBit WB_DRAG must be set. In addition, the
85 Command handler, the QueryDrop handler and the Drop handler must be overlaid.
86 In doing so, the following must be implemented in the handlers:
88 Command - If dragging should be started in this handler,
89 StartDrag() must be called. This method
90 then selects the respective entry or returns
91 false, if dragging cannot be carried out.
93 QueryDrop - This handler is always called by StarView, when the
94 mouse is pulled over the window while dragging
95 (s.a. SV documentation). In this handler, it must be
96 determined whether a drop is possible. The drop
97 position can be shown in TabBar using ShowDropPos().
98 When calling, the position of the Event must be passed.
99 If the position is at the left or right border,
100 scrolling automatically takes place in the TabBar.
101 This method also returns the respective drop position,
102 which is also needed for a drop. If the window is left
103 while dragging, the drop position can be taken back
104 using HideDropPos(). Thus, it is also possible to handle
105 a drag which was triggered from outside the TabBar.
107 Drop - In the Drop handler, the pages have to be moved, or
108 the new pages have to be inserted. The respective
109 drop position can be determined using ShowDropPos().
111 The following methods are needed for Drag and Drop and must be called
112 by the handlers:
114 StartDrag - Must be called from the Command handler. As parameters,
115 the CommandEvent and a reference to a Region must be
116 passed. This vcl::Region then must be passed in
117 ExecuteDrag(), if the return value indicates that
118 ExecuteDrag shall be carried out. If the entry is not
119 selected, it is set as the current entry beforehand.
120 Because of this, attention must be paid that the Select
121 handler can be called from this method.
123 ShowDropPos - This method must be called by the QueryDrop handler,
124 so that the TabBar shows where the Tabs are
125 inserted. This method can also be used in the Drop
126 handler, in order to determine the position at which
127 the Tabs shall be inserted. In the method, the
128 position of the Event must be passed. This method
129 returns the position, at which the Tabs shall be inserted.
131 HideDropPos - This method takes back the DropPosition previously
132 displayed using ShowDropPos(). This method should be
133 called, when the window is left in the QueryDrop()
134 handler or the drag process has been ended.
136 The following methods can be used if the pages should be switched
137 in the Drag and Drop:
139 SwitchPage - This method must be called by the QueryDrop handler
140 if the page, over which the mouse pointer resides,
141 should be switched. This method should be called
142 each time the QueryDrop-Handler is called.
143 Switching the page happens with a delay (500 ms) and
144 is automatically managed by this method.
145 The Position of the Event must be passed in the method.
146 This method returns true if the page has been switched.
148 EndSwitchPage - This method resets the data for the switching of the
149 page. This method should be called when the window
150 is left in QueryDrop() or the drag process has been
151 ended.
153 IsInSwitching - With this method, it can be queried in
154 ActivatePage()/DeactivatePage() whether this has been
155 caused by SwitchPage(). Thus, for example, switching
156 can be avoided in DeactivatePage() without an error
157 box.
160 Window Resize
161 --------------
163 If the window width can be changed by the user, the WinBit WB_SIZEABLE
164 must be set. In this case, the following handler must be overlaid:
166 Split - When this handler is called, the window should be
167 adapted to the width that is returned by GetSplitSize().
168 In doing so, no minimal or maximum width is taken into
169 account. A minimal size can be queried using
170 GetMinSize() and the maximum width must be calculated
171 by the application itself. As only Online Resize is
172 supported, the window width must be changed inside
173 this handler and possibly the width of dependent windows
174 as well. For this handler, a link can also be set using
175 SetSplitHdl().
177 The following methods deliver more information while Splitting:
179 GetSplitSize() - Returns the width of the TabBar, to which the user
180 wants to resize the window. No minimum or maximum
181 width is taken into account. However, a width < 5
182 is never returned. This method only returns valid
183 values as long as splitting is active.
185 GetMinSize() - With this method, a minimum window width can be
186 queried, so that at least something of a Tab is
187 visible. Still, the TabBar can be set more narrow
188 then the width that this method returns.
189 This method can also be called, when no splitting
190 is active.
193 Edit Mode
194 ----------
196 The TabBar also offers the user the possibility to change the names
197 in the Tabs.
199 EnableEditMode - With this, it can be configured that on Alt+LeftClick,
200 StartEditMode() is automatically called by the TabBar.
201 In the StartRenaming() handler, the renaming can still
202 be rejected.
203 StartEditMode - With this method, the EditMode is started on a Tab.
204 false is returned, if the EditMode is already
205 active, the mode is rejected with StartRenaming()
206 or no space is available for editing.
207 EndEditMode - With this method, the EditMode is ended.
208 SetEditText - With this method, the text in the AllowRenaming()
209 handler can still be replaced by another text.
210 GetEditText - With this method, the text, which the user has typed
211 in, can be queried in the AllowRenaming() handler.
212 IsInEditMode - This method is used to query whether the EditMode
213 is active.
214 IsEditModeCanceled - This method can be used in the EndRenaming()
215 handler to query whether the renaming has
216 been canceled.
217 GetEditPageId - With this method, the tab that is being/has been
218 renamed is queried in the Renaming handlers.
220 StartRenaming() - This handler is called when the EditMode hast been
221 started using StartEditMode(). GetEditPageId()
222 can be used to query which Tab should be renamed.
223 false should be returned if the EditMod should
224 not be started.
225 AllowRenaming() - This handler is called when the EditMode is ended
226 (not in case of Cancel). Within this handler, it
227 can then be tested whether the text is OK.
228 The Tab which was renamed can be queried using
229 GetEditPageId().
230 One of the following values should be returned:
231 TAB_RENAMING_YES
232 The Tab is renamed.
233 TAB_RENAMING_NO
234 The Tab is not renamed, but the EditMode remains
235 active, so that the user can adapt the name
236 accordingly.
237 TAB_RENAMING_CANCEL
238 The EditMode was cancelled and the old text
239 is restored.
240 EndRenaming() - This handler is called when the EditMode has been
241 ended. The tab that has been renamed can be
242 queried using GetEditPageId(). Using
243 IsEditModeCanceled(), it can be queried whether
244 the mode has been cancelled and the name has
245 thus not been changed.
248 Maximum Page width
249 -------------------
251 The Page width of the tabs can be limited in order to make an easier
252 navigation by them possible. If then, the text cannot be displayed
253 completely, it is abbreviated with "..." and the whole text is
254 displayed in the Tip or in the active help (if no help text is set).
255 Using EnableAutoMaxPageWidth(), it can be configured whether the
256 maximum page width should be based on the currently visible width
257 (which is the default). Otherwise, the maximum page width can
258 also be set using SetMaxPageWidth() (in pixels) (in this case, the
259 AutoMaxPageWidth is ignored).
261 ContextMenu
262 -----------
264 If a context-sensitive PopupMenu should be displayed, the Command
265 handler must be overlaid. Using GetPageId() and when passing the
266 mouse position, it can be determined whether the mouse click has been
267 carried out over an item resp. over which item the mouse click has
268 been carried out.
271 class Button;
273 #define WB_RANGESELECT (WinBits(0x00200000))
274 #define WB_MULTISELECT (WinBits(0x00400000))
275 #define WB_MINSCROLL (WinBits(0x20000000))
276 #define WB_INSERTTAB (WinBits(0x40000000))
277 #define WB_STDTABBAR WB_BORDER
279 // Page bits
281 enum class TabBarPageBits {
282 NONE = 0x00,
283 Blue = 0x01,
284 Italic = 0x02,
285 Underline = 0x04,
287 namespace o3tl {
288 template<> struct typed_flags<TabBarPageBits> : is_typed_flags<TabBarPageBits, 0x07> {};
291 // interface checks only, do not use in regular control flow
293 #define TPB_DISPLAY_NAME_ALLFLAGS (TabBarPageBits::Blue | TabBarPageBits::Italic | TabBarPageBits::Underline)
295 // - TabBar-Types - used in TabBar::AllowRenaming
297 enum TabBarAllowRenamingReturnCode {
298 TABBAR_RENAMING_NO,
299 TABBAR_RENAMING_YES,
300 TABBAR_RENAMING_CANCEL
303 class MouseEvent;
304 class DataChangedEvent;
306 struct ImplTabBarItem;
307 struct TabBar_Impl;
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 OUString maEditText;
319 Size maWinSize;
320 long mnMaxPageWidth;
321 long mnCurMaxWidth;
322 long mnOffX;
323 long mnOffY;
324 long mnLastOffX;
325 long mnSplitSize;
326 sal_uInt64 mnSwitchTime;
327 WinBits mnWinStyle;
328 sal_uInt16 mnCurPageId;
329 sal_uInt16 mnFirstPos;
330 sal_uInt16 mnDropPos;
331 sal_uInt16 mnSwitchId;
332 sal_uInt16 mnEditId;
334 bool mbFormat : 1;
335 bool mbFirstFormat : 1;
336 bool mbSizeFormat : 1;
337 bool mbAutoEditMode : 1;
338 bool mbEditCanceled : 1;
339 bool mbDropPos : 1;
340 bool mbInSelect : 1;
341 bool mbMirrored : 1;
342 bool mbScrollAlwaysEnabled : 1;
344 Link<TabBar*,void> maSelectHdl;
345 Link<TabBar*,void> maSplitHdl;
346 Link<const CommandEvent&, void> maScrollAreaContextHdl;
347 size_t maCurrentItemList;
349 using Window::ImplInit;
350 SVT_DLLPRIVATE void ImplInit( WinBits nWinStyle );
351 SVT_DLLPRIVATE void ImplInitSettings( bool bFont, bool bBackground );
352 SVT_DLLPRIVATE void ImplGetColors(const StyleSettings& rStyleSettings,
353 Color& rFaceColor, Color& rFaceTextColor,
354 Color& rSelectColor, Color& rSelectTextColor);
355 SVT_DLLPRIVATE void ImplShowPage( sal_uInt16 nPos );
356 SVT_DLLPRIVATE bool ImplCalcWidth();
357 SVT_DLLPRIVATE void ImplFormat();
358 SVT_DLLPRIVATE sal_uInt16 ImplGetLastFirstPos();
359 SVT_DLLPRIVATE void ImplInitControls();
360 SVT_DLLPRIVATE void ImplEnableControls();
361 SVT_DLLPRIVATE void ImplSelect();
362 SVT_DLLPRIVATE void ImplActivatePage();
363 SVT_DLLPRIVATE bool ImplDeactivatePage();
364 SVT_DLLPRIVATE void ImplPrePaint();
365 SVT_DLLPRIVATE ImplTabBarItem* ImplGetLastTabBarItem( sal_uInt16 nItemCount );
367 DECL_DLLPRIVATE_LINK(ImplClickHdl, Button*, void);
369 DECL_DLLPRIVATE_LINK(ImplAddClickHandler, Button*, void);
371 ImplTabBarItem* seek( size_t i );
372 ImplTabBarItem* prev();
373 ImplTabBarItem* next();
375 protected:
376 virtual void AddTabClick();
377 OUString GetAuxiliaryText(sal_uInt16 nPageId) const; // needed in derived class LayerTabBar
378 void SetAuxiliaryText(sal_uInt16 nPageId, const OUString& rText );
380 public:
381 static const sal_uInt16 APPEND;
382 static const sal_uInt16 PAGE_NOT_FOUND;
384 TabBar( vcl::Window* pParent, WinBits nWinStyle );
385 virtual ~TabBar() override;
386 virtual void dispose() override;
388 virtual void MouseMove( const MouseEvent& rMEvt ) override;
389 virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
390 virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
391 virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
392 virtual void Resize() override;
393 virtual void RequestHelp( const HelpEvent& rHEvt ) override;
394 virtual void StateChanged( StateChangedType nStateChange ) override;
395 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
396 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
398 virtual void Select();
399 virtual void DoubleClick();
400 void Split();
401 virtual void ActivatePage();
402 virtual bool DeactivatePage();
403 virtual bool StartRenaming();
404 virtual TabBarAllowRenamingReturnCode AllowRenaming();
405 virtual void EndRenaming();
406 virtual void Mirror();
408 virtual void InsertPage( sal_uInt16 nPageId, const OUString& rText,
409 TabBarPageBits nBits = TabBarPageBits::NONE,
410 sal_uInt16 nPos = TabBar::APPEND );
411 void RemovePage( sal_uInt16 nPageId );
412 void MovePage( sal_uInt16 nPageId, sal_uInt16 nNewPos );
414 Color GetTabBgColor( sal_uInt16 nPageId ) const;
415 void SetTabBgColor( sal_uInt16 nPageId, const Color& aTabBgColor );
417 void Clear();
419 bool IsPageEnabled( sal_uInt16 nPageId ) const;
421 void SetPageBits( sal_uInt16 nPageId, TabBarPageBits nBits );
422 TabBarPageBits GetPageBits( sal_uInt16 nPageId ) const;
424 sal_uInt16 GetPageCount() const;
425 sal_uInt16 GetPageId( sal_uInt16 nPos ) const;
426 sal_uInt16 GetPagePos( sal_uInt16 nPageId ) const;
427 sal_uInt16 GetCurPagePos() const { return GetPagePos(GetCurPageId()); }
428 sal_uInt16 GetPageId( const Point& rPos ) const;
429 tools::Rectangle GetPageRect( sal_uInt16 nPageId ) const;
430 // returns the rectangle in which page tabs are drawn
431 tools::Rectangle GetPageArea() const;
433 void SetCurPageId( sal_uInt16 nPageId );
434 sal_uInt16 GetCurPageId() const { return mnCurPageId; }
436 void SetFirstPageId( sal_uInt16 nPageId );
437 void MakeVisible( sal_uInt16 nPageId );
439 void SelectPage( sal_uInt16 nPageId, bool bSelect );
440 sal_uInt16 GetSelectPageCount() const;
441 bool IsPageSelected( sal_uInt16 nPageId ) const;
442 void SetProtectionSymbol( sal_uInt16 nPageId, bool bProtection );
444 void SetMaxPageWidth( long nMaxWidth );
446 void EnableEditMode() { mbAutoEditMode = true; }
447 bool StartEditMode( sal_uInt16 nPageId );
448 void EndEditMode( bool bCancel = false );
449 void SetEditText( const OUString& rText ) { maEditText = rText; }
450 const OUString& GetEditText() const { return maEditText; }
451 bool IsInEditMode() const;
452 bool IsEditModeCanceled() const { return mbEditCanceled; }
453 sal_uInt16 GetEditPageId() const { return mnEditId; }
455 /** Mirrors the entire control including position of buttons and splitter.
456 Mirroring is done relative to the current direction of the GUI.
457 @param bMirrored sal_True = the control will draw itself RTL in LTR GUI,
458 and vice versa; sal_False = the control behaves according to the
459 current direction of the GUI. */
460 void SetMirrored(bool bMirrored);
461 /** Returns true, if the control is set to mirrored mode (see SetMirrored()). */
462 bool IsMirrored() const { return mbMirrored; }
464 /** Sets the control to LTR or RTL mode regardless of the GUI direction.
465 @param bRTL sal_False = the control will draw from left to right;
466 sal_True = the control will draw from right to left. */
467 void SetEffectiveRTL( bool bRTL );
468 /** Returns true, if the control draws from right to left (see SetEffectiveRTL()). */
469 bool IsEffectiveRTL() const;
471 bool StartDrag( const CommandEvent& rCEvt, vcl::Region& rRegion );
472 sal_uInt16 ShowDropPos( const Point& rPos );
473 void HideDropPos();
474 void SwitchPage( const Point& rPos );
475 void EndSwitchPage();
477 virtual void SetPageText( sal_uInt16 nPageId, const OUString& rText );
478 OUString GetPageText( sal_uInt16 nPageId ) const;
479 OUString GetHelpText( sal_uInt16 nPageId ) const;
481 long GetSplitSize() const { return mnSplitSize; }
483 using Window::SetHelpText;
484 using Window::GetHelpText;
485 using Window::SetHelpId;
486 using Window::GetHelpId;
488 void SetStyle( WinBits nStyle );
489 WinBits GetStyle() const { return mnWinStyle; }
491 void SetScrollAlwaysEnabled(bool bScrollAlwaysEnabled);
493 Size CalcWindowSizePixel() const;
495 void SetSelectHdl( const Link<TabBar*,void>& rLink ) { maSelectHdl = rLink; }
496 void SetSplitHdl( const Link<TabBar*,void>& rLink ) { maSplitHdl = rLink; }
497 void SetScrollAreaContextHdl( const Link<const CommandEvent&,void>& rLink ) { maScrollAreaContextHdl = rLink; }
499 // accessibility
500 virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
503 #endif // INCLUDED_SVTOOLS_TABBAR_HXX
505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */