Coverage Report

Created: 2026-04-09 11:41

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