Coverage Report

Created: 2025-12-31 10:39

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 <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: */