tdf#149529 crash on deref deleted ScDocument*
[LibreOffice.git] / include / vcl / headbar.hxx
blob1f9fc429ae94b2716d9c7b8989522a02c7804eab
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_VCL_HEADBAR_HXX
21 #define INCLUDED_VCL_HEADBAR_HXX
23 #include <vcl/dllapi.h>
24 #include <tools/link.hxx>
25 #include <vcl/window.hxx>
26 #include <o3tl/typed_flags_set.hxx>
27 #include <memory>
29 /*************************************************************************
31 Description
32 ============
34 class HeaderBar
36 This class serves for displaying a header bar. A header bar can display
37 texts, images or both of them. The items can be changed in size, dragged or
38 clicked at. In many cases, it makes, for example, sense to use this control
39 in combination with a SvTabListBox.
41 --------------------------------------------------------------------------
43 WinBits
45 WB_BORDER a border is drawn in the top and in the bottom
46 WB_BOTTOMBORDER a border is drawn in the bottom
47 WB_BUTTONSTYLE The items look like buttons, otherwise they are flat.
48 WB_3DLOOK 3D look
49 WB_DRAG items can be dragged
50 WB_STDHEADERBAR WB_BUTTONSTYLE | WB_BOTTOMBORDER
52 --------------------------------------------------------------------------
54 ItemBits
56 HeaderBarItemBits::LEFT content is displayed in the item left-justified
57 HeaderBarItemBits::CENTER content is displayed in the item centred
58 HeaderBarItemBits::RIGHT content is displayed in the item right-justified
59 HeaderBarItemBits::TOP content is displayed in the item at the upper border
60 HeaderBarItemBits::VCENTER content is displayed in the item vertically centred
61 HeaderBarItemBits::BOTTOM content is displayed in the item at the bottom border
62 HeaderBarItemBits::LEFTIMAGE in case of text and image, the image is displayed left of the text
63 HeaderBarItemBits::RIGHTIMAGE in case of text and image, the image is displayed right of the text
64 HeaderBarItemBits::FIXED item cannot be changed in size
65 HeaderBarItemBits::FIXEDPOS item cannot be moved
66 HeaderBarItemBits::CLICKABLE item is clickable
67 (select handler is only called on MouseButtonUp)
68 HeaderBarItemBits::FLAT item is displayed in a flat way, even if WB_BUTTONSTYLE is set
69 HeaderBarItemBits::DOWNARROW An arrow pointing downwards is displayed behind the text,
70 which should, for example, be shown, when after this item,
71 a corresponding list is sorted in descending order.
72 The status of the arrow can be set/reset with SetItemBits().
73 HeaderBarItemBits::UPARROW An arrow pointing upwards is displayed behind the text,
74 which should, for example, be shown, when after this item,
75 a corresponding list is sorted in ascending order.
76 The status of the arrow can be set/reset with SetItemBits().
77 HeaderBarItemBits::USERDRAW For this item, the UserDraw handler is called as well.
78 HeaderBarItemBits::STDSTYLE (HeaderBarItemBits::LEFT | HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::CLICKABLE)
80 --------------------------------------------------------------------------
82 Handler
84 Select() Is called, when the item is clicked. If HeaderBarItemBits::CLICKABLE
85 is set in the item and not HeaderBarItemBits::FLAT, the handler is only
86 called in the MouseButtonUp handler, when the mouse has been
87 released over the item. In this case, the Select handler
88 behaves like it does with a ToolBox button.
89 DoubleClick() This handler is called, when an item is double-clicked.
90 Whether the item or the separator has been clicked, can
91 be determined by IsItemMode(). Normally, when a separator
92 is double-clicked, the optimal column width should be
93 calculated and should be set.
94 StartDrag() This handler is called, when dragging is started resp.
95 an item has been clicked. At the latest in this handler,
96 the size of the size-line should be set with
97 SetDragSize(), if IsItemMode() returns false.
98 Drag() This handler is called, when dragging is taking place.
99 If no size is set with SetDragSize(), this handler can
100 be used to draw the line in the neighbouring window by
101 oneself. The current dragging position can be requested
102 with GetDragPos(). In every case, IsItemMode()
103 should be checked to find out whether a separator is
104 dragged as well.
105 EndDrag() This handler is called, when a dragging process has been
106 stopped. If GetCurItemId() returns 0 in the EndDrag handler,
107 the drag process was aborted. If this is not the case and
108 IsItemMode() returns false, the new size of the dragged
109 item should be requested using GetItemSize() and it
110 should be taken over in the corresponding control.
111 If IsItemMode() returns true, GetCurItemId()
112 returns an Id and IsItemDrag() returns true, this
113 item has been dragged. In this case, the new position
114 should be requested using GetItemPos() and the data
115 in the corresponding control should be adapted.
116 Otherwise, the position to which the item has been dragged
117 could also be requested with GetItemDragPos().
119 Further methods that are important for the handler.
121 GetCurItemId() Returns the id of the item, for which the handler has
122 currently been called. Only returns a valid id in the
123 handlers Select(), DoubleClick(), StartDrag(),
124 Drag() and EndDrag(). In the EndDrag handler,
125 this method returns the id of the dragged item or 0,
126 if the drag process has been aborted.
127 GetItemDragPos() Returns the position, at which an item has been moved.
128 HEADERBAR_ITEM_NOTFOUND is returned, if the process
129 has been aborted or no ItemDrag is active.
130 IsItemMode() This method can be used to determine whether the
131 handler has been called for an item or a separator.
132 true - handler was called for the item
133 false - handler was called for the separator
134 IsItemDrag() This method can be used to determine whether an item
135 has been dragged or selected.
136 true - item is dragged
137 false - item is selected
138 SetDragSize() This method is used to set the size of the separating
139 line that is drawn by the control. It should be
140 equivalent to the height of the neighbouring window.
141 The height of the HeaderBar is added automatically.
143 --------------------------------------------------------------------------
145 Further methods
147 SetOffset() This method sets the offset, from which on the
148 items are shown. This is needed when the
149 corresponding window is scrolled.
150 CalcWindowSizePixel() This method can be used to calculate the height
151 of the window, so that the content of the item
152 can be displayed.
154 --------------------------------------------------------------------------
156 Tips and tricks:
158 1) ContextMenu
159 If a context sensitive PopupMenu should be shown, the command
160 handler must be overlaid. Using GetItemId() and when passing the
161 mouse position, it can be determined whether the mouse click has been
162 carried out over an item resp. over which item the mouse click has been
163 carried out.
165 2) last item
166 If ButtonStyle has been set, it looks better, if an empty item is
167 set at the end which takes up the remaining space.
168 In order to do that, you can insert an item with an empty string and
169 pass HEADERBAR_FULLSIZE as size. For such an item, you should not set
170 HeaderBarItemBits::CLICKABLE, but HeaderBarItemBits::FIXEDPOS.
172 *************************************************************************/
174 class ImplHeadItem;
176 #define WB_BOTTOMBORDER (WinBits(0x0400))
177 #define WB_BUTTONSTYLE (WinBits(0x0800))
178 #define WB_STDHEADERBAR (WB_BUTTONSTYLE | WB_BOTTOMBORDER)
180 enum class HeaderBarItemBits
182 NONE = 0x0000,
183 LEFT = 0x0001,
184 CENTER = 0x0002,
185 RIGHT = 0x0004,
186 LEFTIMAGE = 0x0010,
187 RIGHTIMAGE = 0x0020,
188 CLICKABLE = 0x0400,
189 FLAT = 0x0800,
190 DOWNARROW = 0x1000,
191 UPARROW = 0x2000,
192 STDSTYLE = LEFT | LEFTIMAGE | CLICKABLE,
195 namespace o3tl
197 template<> struct typed_flags<HeaderBarItemBits> : is_typed_flags<HeaderBarItemBits, 0x3c37> {};
200 #define HEADERBAR_APPEND (sal_uInt16(0xFFFF))
201 #define HEADERBAR_ITEM_NOTFOUND (sal_uInt16(0xFFFF))
202 #define HEADERBAR_FULLSIZE (tools::Long(1000000000))
204 class VCL_DLLPUBLIC HeaderBar : public vcl::Window
206 private:
207 std::vector<std::unique_ptr<ImplHeadItem>> mvItemList;
208 tools::Long mnBorderOff1;
209 tools::Long mnBorderOff2;
210 tools::Long mnOffset;
211 tools::Long mnDX;
212 tools::Long mnDY;
213 tools::Long mnDragSize;
214 tools::Long mnStartPos;
215 tools::Long mnDragPos;
216 tools::Long mnMouseOff;
217 sal_uInt16 mnCurItemId;
218 sal_uInt16 mnItemDragPos;
219 bool mbDragable;
220 bool mbDrag;
221 bool mbItemDrag;
222 bool mbOutDrag;
223 bool mbButtonStyle;
224 bool mbItemMode;
225 Link<HeaderBar*,void> maStartDragHdl;
226 Link<HeaderBar*,void> maEndDragHdl;
227 Link<HeaderBar*,void> maSelectHdl;
228 Link<HeaderBar*,void> maCreateAccessibleHdl;
230 css::uno::Reference< css::accessibility::XAccessible >
231 mxAccessible;
233 using Window::ImplInit;
234 VCL_DLLPRIVATE void ImplInit( WinBits nWinStyle );
235 VCL_DLLPRIVATE void ImplInitSettings( bool bFont, bool bForeground, bool bBackground );
236 VCL_DLLPRIVATE tools::Long ImplGetItemPos( sal_uInt16 nPos ) const;
237 VCL_DLLPRIVATE tools::Rectangle ImplGetItemRect( sal_uInt16 nPos ) const;
238 VCL_DLLPRIVATE sal_uInt16 ImplDoHitTest( const Point& rPos, tools::Long& nMouseOff, sal_uInt16& nPos ) const;
239 VCL_DLLPRIVATE void ImplInvertDrag( sal_uInt16 nStartPos, sal_uInt16 nEndPos );
240 VCL_DLLPRIVATE void ImplDrawItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHigh,
241 const tools::Rectangle& rItemRect, const tools::Rectangle* pRect);
242 VCL_DLLPRIVATE void ImplDrawItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHigh,
243 const tools::Rectangle* pRect);
244 VCL_DLLPRIVATE void ImplUpdate( sal_uInt16 nPos,
245 bool bEnd = false );
246 VCL_DLLPRIVATE void ImplStartDrag( const Point& rPos, bool bCommand );
247 VCL_DLLPRIVATE void ImplDrag( const Point& rPos );
248 VCL_DLLPRIVATE void ImplEndDrag( bool bCancel );
250 virtual void ApplySettings(vcl::RenderContext& rRenderContext) override;
252 public:
253 HeaderBar( vcl::Window* pParent, WinBits nWinBits );
254 virtual ~HeaderBar() override;
256 virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
257 virtual void MouseMove( const MouseEvent& rMEvt ) override;
258 virtual void Tracking( const TrackingEvent& rTEvt ) override;
259 virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
260 virtual void Draw( OutputDevice* pDev, const Point& rPos,SystemTextColorFlags nFlags ) override;
261 virtual void Resize() override;
262 virtual void Command( const CommandEvent& rCEvt ) override;
263 virtual void RequestHelp( const HelpEvent& rHEvt ) override;
264 virtual void StateChanged( StateChangedType nStateChange ) override;
265 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
267 virtual Size GetOptimalSize() const override;
269 virtual void EndDrag();
270 virtual void Select();
271 virtual void DoubleClick();
273 void InsertItem( sal_uInt16 nItemId, const OUString& rText,
274 tools::Long nSize, HeaderBarItemBits nBits = HeaderBarItemBits::STDSTYLE,
275 sal_uInt16 nPos = HEADERBAR_APPEND );
276 void RemoveItem( sal_uInt16 nItemId );
277 void MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos );
278 void Clear();
280 void SetOffset( tools::Long nNewOffset );
281 void SetDragSize( tools::Long nNewSize ) { mnDragSize = nNewSize; }
283 sal_uInt16 GetItemCount() const;
284 sal_uInt16 GetItemPos( sal_uInt16 nItemId ) const;
285 sal_uInt16 GetItemId( sal_uInt16 nPos ) const;
286 sal_uInt16 GetItemId( const Point& rPos ) const;
287 tools::Rectangle GetItemRect( sal_uInt16 nItemId ) const;
288 sal_uInt16 GetCurItemId() const { return mnCurItemId; }
289 bool IsItemMode() const { return mbItemMode; }
291 void SetItemSize( sal_uInt16 nItemId, tools::Long nNewSize );
292 tools::Long GetItemSize( sal_uInt16 nItemId ) const;
293 void SetItemBits( sal_uInt16 nItemId, HeaderBarItemBits nNewBits );
294 HeaderBarItemBits GetItemBits( sal_uInt16 nItemId ) const;
296 void SetItemText( sal_uInt16 nItemId, const OUString& rText );
297 OUString GetItemText( sal_uInt16 nItemId ) const;
299 OUString GetHelpText( sal_uInt16 nItemId ) const;
301 Size CalcWindowSizePixel() const;
303 using Window::SetHelpId;
305 void SetStartDragHdl( const Link<HeaderBar*,void>& rLink ) { maStartDragHdl = rLink; }
306 void SetEndDragHdl( const Link<HeaderBar*,void>& rLink ) { maEndDragHdl = rLink; }
307 void SetSelectHdl( const Link<HeaderBar*,void>& rLink ) { maSelectHdl = rLink; }
308 void SetCreateAccessibleHdl( const Link<HeaderBar*,void>& rLink ) { maCreateAccessibleHdl = rLink; }
310 bool IsDragable() const { return mbDragable; }
312 /** Creates and returns the accessible object of the header bar. */
313 virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override;
314 void SetAccessible( const css::uno::Reference< css::accessibility::XAccessible >& );
317 #endif // INCLUDED_VCL_HEADBAR_HXX
319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */