/src/libreoffice/include/vcl/headbar.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #ifndef INCLUDED_VCL_HEADBAR_HXX |
21 | | #define INCLUDED_VCL_HEADBAR_HXX |
22 | | |
23 | | #include <comphelper/OAccessible.hxx> |
24 | | #include <vcl/dllapi.h> |
25 | | #include <tools/link.hxx> |
26 | | #include <vcl/window.hxx> |
27 | | #include <o3tl/typed_flags_set.hxx> |
28 | | #include <memory> |
29 | | |
30 | | /************************************************************************* |
31 | | |
32 | | Description |
33 | | ============ |
34 | | |
35 | | class HeaderBar |
36 | | |
37 | | This class serves for displaying a header bar. A header bar can display |
38 | | texts, images or both of them. The items can be changed in size, dragged or |
39 | | clicked at. In many cases, it makes, for example, sense to use this control |
40 | | in combination with a SvTabListBox. |
41 | | |
42 | | -------------------------------------------------------------------------- |
43 | | |
44 | | WinBits |
45 | | |
46 | | WB_BORDER a border is drawn in the top and in the bottom |
47 | | WB_BOTTOMBORDER a border is drawn in the bottom |
48 | | WB_BUTTONSTYLE The items look like buttons, otherwise they are flat. |
49 | | WB_3DLOOK 3D look |
50 | | WB_DRAG items can be dragged |
51 | | WB_STDHEADERBAR WB_BUTTONSTYLE | WB_BOTTOMBORDER |
52 | | |
53 | | -------------------------------------------------------------------------- |
54 | | |
55 | | ItemBits |
56 | | |
57 | | HeaderBarItemBits::LEFT content is displayed in the item left-justified |
58 | | HeaderBarItemBits::CENTER content is displayed in the item centred |
59 | | HeaderBarItemBits::RIGHT content is displayed in the item right-justified |
60 | | HeaderBarItemBits::TOP content is displayed in the item at the upper border |
61 | | HeaderBarItemBits::VCENTER content is displayed in the item vertically centred |
62 | | HeaderBarItemBits::BOTTOM content is displayed in the item at the bottom border |
63 | | HeaderBarItemBits::LEFTIMAGE in case of text and image, the image is displayed left of the text |
64 | | HeaderBarItemBits::RIGHTIMAGE in case of text and image, the image is displayed right of the text |
65 | | HeaderBarItemBits::FIXED item cannot be changed in size |
66 | | HeaderBarItemBits::FIXEDPOS item cannot be moved |
67 | | HeaderBarItemBits::CLICKABLE item is clickable |
68 | | (select handler is only called on MouseButtonUp) |
69 | | HeaderBarItemBits::FLAT item is displayed in a flat way, even if WB_BUTTONSTYLE is set |
70 | | HeaderBarItemBits::DOWNARROW An arrow pointing downwards is displayed behind the text, |
71 | | which should, for example, be shown, when after this item, |
72 | | a corresponding list is sorted in descending order. |
73 | | The status of the arrow can be set/reset with SetItemBits(). |
74 | | HeaderBarItemBits::UPARROW An arrow pointing upwards is displayed behind the text, |
75 | | which should, for example, be shown, when after this item, |
76 | | a corresponding list is sorted in ascending order. |
77 | | The status of the arrow can be set/reset with SetItemBits(). |
78 | | HeaderBarItemBits::USERDRAW For this item, the UserDraw handler is called as well. |
79 | | HeaderBarItemBits::STDSTYLE (HeaderBarItemBits::LEFT | HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::CLICKABLE) |
80 | | |
81 | | -------------------------------------------------------------------------- |
82 | | |
83 | | Handler |
84 | | |
85 | | Select() Is called, when the item is clicked. If HeaderBarItemBits::CLICKABLE |
86 | | is set in the item and not HeaderBarItemBits::FLAT, the handler is only |
87 | | called in the MouseButtonUp handler, when the mouse has been |
88 | | released over the item. In this case, the Select handler |
89 | | behaves like it does with a ToolBox button. |
90 | | DoubleClick() This handler is called, when an item is double-clicked. |
91 | | Whether the item or the separator has been clicked, can |
92 | | be determined by IsItemMode(). Normally, when a separator |
93 | | is double-clicked, the optimal column width should be |
94 | | calculated and should be set. |
95 | | StartDrag() This handler is called, when dragging is started resp. |
96 | | an item has been clicked. At the latest in this handler, |
97 | | the size of the size-line should be set with |
98 | | SetDragSize(), if IsItemMode() returns false. |
99 | | Drag() This handler is called, when dragging is taking place. |
100 | | If no size is set with SetDragSize(), this handler can |
101 | | be used to draw the line in the neighbouring window by |
102 | | oneself. The current dragging position can be requested |
103 | | with GetDragPos(). In every case, IsItemMode() |
104 | | should be checked to find out whether a separator is |
105 | | dragged as well. |
106 | | EndDrag() This handler is called, when a dragging process has been |
107 | | stopped. If GetCurItemId() returns 0 in the EndDrag handler, |
108 | | the drag process was aborted. If this is not the case and |
109 | | IsItemMode() returns false, the new size of the dragged |
110 | | item should be requested using GetItemSize() and it |
111 | | should be taken over in the corresponding control. |
112 | | If IsItemMode() returns true, GetCurItemId() |
113 | | returns an Id and IsItemDrag() returns true, this |
114 | | item has been dragged. In this case, the new position |
115 | | should be requested using GetItemPos() and the data |
116 | | in the corresponding control should be adapted. |
117 | | Otherwise, the position to which the item has been dragged |
118 | | could also be requested with GetItemDragPos(). |
119 | | |
120 | | Further methods that are important for the handler. |
121 | | |
122 | | GetCurItemId() Returns the id of the item, for which the handler has |
123 | | currently been called. Only returns a valid id in the |
124 | | handlers Select(), DoubleClick(), StartDrag(), |
125 | | Drag() and EndDrag(). In the EndDrag handler, |
126 | | this method returns the id of the dragged item or 0, |
127 | | if the drag process has been aborted. |
128 | | GetItemDragPos() Returns the position, at which an item has been moved. |
129 | | HEADERBAR_ITEM_NOTFOUND is returned, if the process |
130 | | has been aborted or no ItemDrag is active. |
131 | | IsItemMode() This method can be used to determine whether the |
132 | | handler has been called for an item or a separator. |
133 | | true - handler was called for the item |
134 | | false - handler was called for the separator |
135 | | IsItemDrag() This method can be used to determine whether an item |
136 | | has been dragged or selected. |
137 | | true - item is dragged |
138 | | false - item is selected |
139 | | SetDragSize() This method is used to set the size of the separating |
140 | | line that is drawn by the control. It should be |
141 | | equivalent to the height of the neighbouring window. |
142 | | The height of the HeaderBar is added automatically. |
143 | | |
144 | | -------------------------------------------------------------------------- |
145 | | |
146 | | Further methods |
147 | | |
148 | | SetOffset() This method sets the offset, from which on the |
149 | | items are shown. This is needed when the |
150 | | corresponding window is scrolled. |
151 | | CalcWindowSizePixel() This method can be used to calculate the height |
152 | | of the window, so that the content of the item |
153 | | can be displayed. |
154 | | |
155 | | -------------------------------------------------------------------------- |
156 | | |
157 | | Tips and tricks: |
158 | | |
159 | | 1) ContextMenu |
160 | | If a context sensitive PopupMenu should be shown, the command |
161 | | handler must be overlaid. Using GetItemId() and when passing the |
162 | | mouse position, it can be determined whether the mouse click has been |
163 | | carried out over an item resp. over which item the mouse click has been |
164 | | carried out. |
165 | | |
166 | | 2) last item |
167 | | If ButtonStyle has been set, it looks better, if an empty item is |
168 | | set at the end which takes up the remaining space. |
169 | | In order to do that, you can insert an item with an empty string and |
170 | | pass HEADERBAR_FULLSIZE as size. For such an item, you should not set |
171 | | HeaderBarItemBits::CLICKABLE, but HeaderBarItemBits::FIXEDPOS. |
172 | | |
173 | | *************************************************************************/ |
174 | | |
175 | | class ImplHeadItem; |
176 | | |
177 | 0 | #define WB_BOTTOMBORDER (WinBits(0x0400)) |
178 | 0 | #define WB_BUTTONSTYLE (WinBits(0x0800)) |
179 | | #define WB_STDHEADERBAR (WB_BUTTONSTYLE | WB_BOTTOMBORDER) |
180 | | |
181 | | enum class HeaderBarItemBits |
182 | | { |
183 | | NONE = 0x0000, |
184 | | LEFT = 0x0001, |
185 | | CENTER = 0x0002, |
186 | | RIGHT = 0x0004, |
187 | | LEFTIMAGE = 0x0010, |
188 | | RIGHTIMAGE = 0x0020, |
189 | | CLICKABLE = 0x0400, |
190 | | FLAT = 0x0800, |
191 | | DOWNARROW = 0x1000, |
192 | | UPARROW = 0x2000, |
193 | | STDSTYLE = LEFT | LEFTIMAGE | CLICKABLE, |
194 | | }; |
195 | | |
196 | | namespace o3tl |
197 | | { |
198 | | template<> struct typed_flags<HeaderBarItemBits> : is_typed_flags<HeaderBarItemBits, 0x3c37> {}; |
199 | | } |
200 | | |
201 | 0 | #define HEADERBAR_APPEND (sal_uInt16(0xFFFF)) |
202 | 0 | #define HEADERBAR_ITEM_NOTFOUND (sal_uInt16(0xFFFF)) |
203 | 0 | #define HEADERBAR_FULLSIZE (tools::Long(1000000000)) |
204 | | |
205 | | class VCL_DLLPUBLIC HeaderBar : public vcl::Window |
206 | | { |
207 | | private: |
208 | | std::vector<std::unique_ptr<ImplHeadItem>> mvItemList; |
209 | | tools::Long mnBorderOff1; |
210 | | tools::Long mnBorderOff2; |
211 | | tools::Long mnOffset; |
212 | | tools::Long mnDX; |
213 | | tools::Long mnDY; |
214 | | tools::Long mnDragSize; |
215 | | tools::Long mnStartPos; |
216 | | tools::Long mnDragPos; |
217 | | tools::Long mnMouseOff; |
218 | | sal_uInt16 mnCurItemId; |
219 | | sal_uInt16 mnItemDragPos; |
220 | | bool mbDragable; |
221 | | bool mbDrag; |
222 | | bool mbItemDrag; |
223 | | bool mbOutDrag; |
224 | | bool mbButtonStyle; |
225 | | bool mbItemMode; |
226 | | Link<HeaderBar*,void> maStartDragHdl; |
227 | | Link<HeaderBar*,void> maEndDragHdl; |
228 | | Link<HeaderBar*,void> maSelectHdl; |
229 | | Link<HeaderBar*,void> maCreateAccessibleHdl; |
230 | | |
231 | | rtl::Reference<comphelper::OAccessible> mpAccessible; |
232 | | |
233 | | using Window::ImplInit; |
234 | | SAL_DLLPRIVATE void ImplInit( WinBits nWinStyle ); |
235 | | SAL_DLLPRIVATE void ImplInitSettings( bool bFont, bool bForeground, bool bBackground ); |
236 | | SAL_DLLPRIVATE tools::Long ImplGetItemPos( sal_uInt16 nPos ) const; |
237 | | SAL_DLLPRIVATE tools::Rectangle ImplGetItemRect( sal_uInt16 nPos ) const; |
238 | | SAL_DLLPRIVATE sal_uInt16 ImplDoHitTest( const Point& rPos, tools::Long& nMouseOff, sal_uInt16& nPos ) const; |
239 | | SAL_DLLPRIVATE void ImplInvertDrag( sal_uInt16 nStartPos, sal_uInt16 nEndPos ); |
240 | | SAL_DLLPRIVATE void ImplDrawItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHigh, |
241 | | const tools::Rectangle& rItemRect, const tools::Rectangle* pRect); |
242 | | SAL_DLLPRIVATE void ImplDrawItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHigh, |
243 | | const tools::Rectangle* pRect); |
244 | | SAL_DLLPRIVATE void ImplUpdate( sal_uInt16 nPos, |
245 | | bool bEnd = false ); |
246 | | SAL_DLLPRIVATE void ImplStartDrag( const Point& rPos, bool bCommand ); |
247 | | SAL_DLLPRIVATE void ImplDrag( const Point& rPos ); |
248 | | SAL_DLLPRIVATE void ImplEndDrag( bool bCancel ); |
249 | | |
250 | | virtual void ApplySettings(vcl::RenderContext& rRenderContext) override; |
251 | | |
252 | | public: |
253 | | HeaderBar( vcl::Window* pParent, WinBits nWinBits ); |
254 | | virtual ~HeaderBar() override; |
255 | | |
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; |
266 | | |
267 | | virtual Size GetOptimalSize() const override; |
268 | | |
269 | | virtual void EndDrag(); |
270 | | virtual void Select(); |
271 | | virtual void DoubleClick(); |
272 | | |
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(); |
279 | | |
280 | | void SetOffset( tools::Long nNewOffset ); |
281 | 0 | void SetDragSize( tools::Long nNewSize ) { mnDragSize = nNewSize; } |
282 | | |
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 | 0 | sal_uInt16 GetCurItemId() const { return mnCurItemId; } |
289 | 0 | bool IsItemMode() const { return mbItemMode; } |
290 | | |
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; |
295 | | |
296 | | void SetItemText( sal_uInt16 nItemId, const OUString& rText ); |
297 | | const OUString & GetItemText( sal_uInt16 nItemId ) const; |
298 | | |
299 | | OUString GetHelpText( sal_uInt16 nItemId ) const; |
300 | | |
301 | | Size CalcWindowSizePixel() const; |
302 | | |
303 | | using Window::SetHelpId; |
304 | | |
305 | 0 | void SetStartDragHdl( const Link<HeaderBar*,void>& rLink ) { maStartDragHdl = rLink; } |
306 | 0 | void SetEndDragHdl( const Link<HeaderBar*,void>& rLink ) { maEndDragHdl = rLink; } |
307 | 0 | void SetSelectHdl( const Link<HeaderBar*,void>& rLink ) { maSelectHdl = rLink; } |
308 | 0 | void SetCreateAccessibleHdl( const Link<HeaderBar*,void>& rLink ) { maCreateAccessibleHdl = rLink; } |
309 | | |
310 | 0 | bool IsDragable() const { return mbDragable; } |
311 | | |
312 | | /** Creates and returns the accessible object of the header bar. */ |
313 | | virtual rtl::Reference<comphelper::OAccessible> CreateAccessible() override; |
314 | | void SetAccessible(rtl::Reference<comphelper::OAccessible>& rAccessible); |
315 | | }; |
316 | | |
317 | | #endif // INCLUDED_VCL_HEADBAR_HXX |
318 | | |
319 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |