Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / include / svtools / valueset.hxx
blobe470be598bfd42bd39cd66e4681d5be20bd93150
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_VALUESET_HXX
21 #define INCLUDED_SVTOOLS_VALUESET_HXX
23 #include <svtools/svtdllapi.h>
25 #include <vcl/ctrl.hxx>
26 #include <vcl/virdev.hxx>
27 #include <vcl/timer.hxx>
28 #include <memory>
29 #include <vector>
31 class MouseEvent;
32 class TrackingEvent;
33 class HelpEvent;
34 class KeyEvent;
35 class DataChangedEvent;
36 class ScrollBar;
38 struct ValueSetItem;
40 class ValueSetAcc;
41 class ValueItemAcc;
42 enum class DrawFrameStyle;
44 /*************************************************************************
46 Description
47 ============
49 class ValueSet
51 This class allows the selection of an item. In the process items are
52 drawn side by side. The selection of items can be more clear than in a
53 ListBox shape for example in case of colors or samples.
54 The amount of columns drawn by the control and whether the items
55 should be encircled can be specified. Optional a NoSelection or name
56 field could be shown. By default image and color items are supported.
57 Items could be drawn by oneself if InsertItem() is only called with
58 an ID. To achieve this the UserDraw handler needs to be overridden. The
59 description text could be specified afterwards in case of UserDraw
60 and any other items.
62 Cross references
64 class ListBox
66 --------------------------------------------------------------------------
68 WinBits
70 WB_RADIOSEL If set the selection will be drawn like an
71 ImageRadioButton. This does only make sense if the image
72 is at least 8 pixel smaller on each side than the item
73 and also WB_DOUBLEBORDER is set and as color
74 COL_WINDOWWORKSPACE is specified.
75 WB_FLATVALUESET Flat Look (if you set WB_ITEMBORDER or WB_DOUBLEBORDER,
76 then you get extra border space, but the Borders
77 aren't painted),
78 WB_ITEMBORDER Items will be bordered
79 WB_DOUBLEBORDER Items will be bordered twice. Additionally WB_ITEMBORDER
80 has to be set, as otherwise this WinBit wouldn't have any
81 effect. It is needed if there are items with a white
82 background, since otherwise the 3D effect wouldn't be
83 recognizable.
84 WB_NAMEFIELD There is a namefield, where the name of an item will be
85 shown.
86 WB_NONEFIELD There is a NoSelection field which can be selected if
87 0 is passed along with SelectItem. Respectively
88 GetSelectItemId() returns 0 if this field or nothing
89 is selected. This field shows the text which is specified
90 by SetText() respectively no one, if no text was set. With
91 SetNoSelection() the selection can be disabled.
92 WB_VSCROLL A scrollbar will be always shown. The visible number of
93 lines have to be specified with SetLineCount() if this
94 flag is set.
95 WB_BORDER A border will be drawn around the window.
96 WB_NOPOINTERFOCUS The focus won't be gathered, if the control was pressed by
97 the mouse.
98 WB_TABSTOP It is possible to jump into the ValueSet with the tab key.
99 WB_NOTABSTOP It is not possible to jump into the ValueSet with the
100 tab key.
101 WB_NO_DIRECTSELECT Cursor travelling doesn't call select immediately. To
102 execute the selection <RETURN> has to be pressed.
103 --------------------------------------------------------------------------
105 The number of columns must be either set with SetColCount() or
106 SetItemWidth(). If the number of columns is specified by SetColCount()
107 the width of the items will be calculated by the visible range.
108 If the items should have a static width, it has to be specified
109 with SetItemWidth(). In this case the number of columns will be calculated
110 by the visible range.
112 The number of rows is given by the number of items / number of columns. The
113 number of visible rows must either specified by SetLineCount() or
114 SetItemWidth(). If the number of visible rows is specified by SetLineCount(),
115 the height of the items will be calculated from the visible height. If the
116 items should have a fixed height it has to be specified with SetItemHeight().
117 In this case the number of visible rows is then calculated from the visible
118 height. If the number of visible rows is neither specified by SetLineCount()
119 nor by SetItemHeight() all rows will be shown. The height of the items will
120 be calculated by the visible height. If the number of visible rows is
121 specified by SetLineCount() or SetItemHeight() ValueSet does scroll
122 automatically when more lines are available, as are visible. If scrolling
123 should be also possible with a ScrollBar WB_VSCROLL needs to be set.
125 The distance between the items can be increased by SetExtraSpacing(). The
126 distance, which will be shown between two items (both in x and in y), is
127 measured in pixels.
129 The exact window size for a specific item size can be calculated by
130 CalcWindowSizePixel(). To do this all relevant data (number of columns/...)
131 have to be specified and if no number of rows was set, all items need to
132 be inserted. If the window was created with WB_BORDER/Border=sal_True the
133 size has to be specified with SetOutputSizePixel(). In other cases different
134 size-methods can be used. With CalcItemSize() the inner and outer size of
135 an item could be calculated (for this the free space defined by
136 SetExtraSpacing() will not be included).
138 The background color could be specified by SetColor(), with which the image
139 or UserDraw items will be underlayed. If no color is specified the color
140 of other windows (WindowColor) will be used for the background.
142 --------------------------------------------------------------------------
144 At first all items should be inserted and only then Show() should be called
145 since the output area will be precomputed. If this is not done the first
146 Paint will appear a little bit slower. Therefore the Control, if it is loaded
147 from the resource and only supplied with items during runtime, should be
148 loaded with Hide = sal_True and then displayed with Show().
150 In case of a visible Control the creation of the new output area could be
151 activated before Paint by calling Format().
153 --------------------------------------------------------------------------
155 If Drag and Drop will be called from the ValueSet the Command-Handler has to
156 be overridden. From this StartDrag needs to be called. If this method returns
157 sal_True the drag-process could be initiated by ExecuteDrag(), otherwise no
158 processing will take place. This method makes sure that ValueSet stops its
159 processing and as appropriate selects the entry. Therefore the calling of
160 Select-Handler within this function must be expected.
162 For dropping QueryDrop() and Drop() need to be overridden and ShowDropPos()
163 and HideDropPos() should be called within these methods.
164 To show the insertion point ShowDropPos() has to be called within the
165 QueryDrop-Handler. ShowDropPos() also scrolls the ValueSet if the passed
166 position is located at the window border. Furthermore ShowDropPos() returns
167 the position, at which the item should be inserted respectively which
168 insertion point was shown. If no insertion point was determined
169 VALUESET_ITEM_NOTFOUND will be returned. If the window was left during dragging
170 or the drag process is terminated HideDropPos() should be called in any case.
172 --------------------------------------------------------------------------
174 This class is currently still in the SV-Tools. That's why the ValueSet needs
175 to be loaded as a Control out of the resource and the desired WinBits have
176 to be set (before Show) with SetStyle().
178 *************************************************************************/
180 typedef std::vector<ValueSetItem*> ValueItemList;
182 #define WB_RADIOSEL ((WinBits)0x00008000)
183 #define WB_ITEMBORDER ((WinBits)0x00010000)
184 #define WB_DOUBLEBORDER ((WinBits)0x00020000)
185 #define WB_NAMEFIELD ((WinBits)0x00040000)
186 #define WB_NONEFIELD ((WinBits)0x00080000)
187 #define WB_FLATVALUESET ((WinBits)0x02000000)
188 #define WB_NO_DIRECTSELECT ((WinBits)0x04000000)
189 #define WB_MENUSTYLEVALUESET ((WinBits)0x08000000)
191 #define VALUESET_APPEND ((size_t)-1)
192 #define VALUESET_ITEM_NOTFOUND ((size_t)-1)
195 class SVT_DLLPUBLIC ValueSet : public Control
197 private:
199 ScopedVclPtr<VirtualDevice> maVirDev;
200 Timer maTimer;
201 ValueItemList mItemList;
202 std::unique_ptr<ValueSetItem> mpNoneItem;
203 VclPtr<ScrollBar> mxScrollBar;
204 tools::Rectangle maNoneItemRect;
205 tools::Rectangle maItemListRect;
206 long mnItemWidth;
207 long mnItemHeight;
208 long mnTextOffset;
209 long mnVisLines;
210 long mnLines;
211 long mnUserItemWidth;
212 long mnUserItemHeight;
213 sal_uInt16 mnSelItemId;
214 sal_uInt16 mnSavedItemId;
215 sal_uInt16 mnHighItemId;
216 sal_uInt16 mnCols;
217 sal_uInt16 mnCurCol;
218 sal_uInt16 mnUserCols;
219 sal_uInt16 mnUserVisLines;
220 sal_uInt16 mnFirstLine;
221 sal_uInt16 mnSpacing;
222 DrawFrameStyle mnFrameStyle;
223 Color maColor;
224 Link<ValueSet*,void> maDoubleClickHdl;
225 Link<ValueSet*,void> maSelectHdl;
226 Link<ValueSet*,void> maHighlightHdl;
228 bool mbFormat : 1;
229 bool mbHighlight : 1;
230 bool mbSelection : 1;
231 bool mbNoSelection : 1;
232 bool mbDrawSelection : 1;
233 bool mbBlackSel : 1;
234 bool mbDoubleSel : 1;
235 bool mbScroll : 1;
236 bool mbFullMode : 1;
237 bool mbEdgeBlending : 1;
238 bool mbHasVisibleItems : 1;
240 friend class ValueSetAcc;
241 friend class ValueItemAcc;
243 using Control::ImplInitSettings;
244 SVT_DLLPRIVATE void ImplInitSettings( bool bFont, bool bForeground, bool bBackground );
246 virtual void ApplySettings(vcl::RenderContext& rRenderContext) override;
248 SVT_DLLPRIVATE void ImplInitScrollBar();
249 SVT_DLLPRIVATE void ImplDeleteItems();
250 SVT_DLLPRIVATE void ImplFormatItem(vcl::RenderContext& rRenderContext, ValueSetItem* pItem, tools::Rectangle aRect);
251 SVT_DLLPRIVATE void ImplDrawItemText(vcl::RenderContext& rRenderContext, const OUString& rStr);
252 SVT_DLLPRIVATE void ImplDrawSelect(vcl::RenderContext& rRenderContext, sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel);
253 SVT_DLLPRIVATE void ImplDrawSelect(vcl::RenderContext& rRenderContext);
254 SVT_DLLPRIVATE void ImplHideSelect(sal_uInt16 nItemId);
255 SVT_DLLPRIVATE void ImplHighlightItem(sal_uInt16 nItemId, bool bIsSelection = true);
256 SVT_DLLPRIVATE void ImplDraw(vcl::RenderContext& rRenderContext);
257 using Window::ImplScroll;
258 SVT_DLLPRIVATE bool ImplScroll( const Point& rPos );
259 SVT_DLLPRIVATE size_t ImplGetItem( const Point& rPoint ) const;
260 SVT_DLLPRIVATE ValueSetItem* ImplGetItem( size_t nPos );
261 SVT_DLLPRIVATE ValueSetItem* ImplGetFirstItem();
262 SVT_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const;
263 SVT_DLLPRIVATE void ImplInsertItem( ValueSetItem *const pItem, const size_t nPos );
264 SVT_DLLPRIVATE tools::Rectangle ImplGetItemRect( size_t nPos ) const;
265 SVT_DLLPRIVATE void ImplFireAccessibleEvent( short nEventId, const css::uno::Any& rOldValue, const css::uno::Any& rNewValue );
266 SVT_DLLPRIVATE bool ImplHasAccessibleListeners();
267 SVT_DLLPRIVATE void ImplTracking( const Point& rPos, bool bRepeat );
268 SVT_DLLPRIVATE void ImplEndTracking( const Point& rPos, bool bCancel );
269 DECL_DLLPRIVATE_LINK( ImplScrollHdl, ScrollBar*, void );
270 DECL_DLLPRIVATE_LINK( ImplTimerHdl, Timer*, void );
272 ValueSet (const ValueSet &) = delete;
273 ValueSet & operator= (const ValueSet &) = delete;
275 protected:
276 void StartDrag( const CommandEvent& rCEvt, vcl::Region& rRegion );
278 virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
280 public:
281 ValueSet( vcl::Window* pParent, WinBits nWinStyle );
282 virtual ~ValueSet() override;
283 virtual void dispose() override;
285 virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
286 virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
287 virtual void MouseMove( const MouseEvent& rMEvt ) override;
288 virtual void Tracking( const TrackingEvent& rMEvt ) override;
289 virtual void KeyInput( const KeyEvent& rKEvt ) override;
290 virtual void Command( const CommandEvent& rCEvt ) override;
291 virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
292 virtual void GetFocus() override;
293 virtual void LoseFocus() override;
294 virtual void Resize() override;
295 virtual Size GetOptimalSize() const override;
296 virtual void RequestHelp( const HelpEvent& rHEvt ) override;
297 virtual void StateChanged( StateChangedType nStateChange ) override;
298 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
300 virtual void Select();
301 virtual void UserDraw( const UserDrawEvent& rUDEvt );
303 /// Insert @rImage item.
304 void InsertItem(sal_uInt16 nItemId, const Image& rImage);
305 /// Insert @rImage item with @rStr as either a legend or tooltip depending on @bShowLegend.
306 void InsertItem(sal_uInt16 nItemId, const Image& rImage,
307 const OUString& rStr, size_t nPos = VALUESET_APPEND, bool bShowLegend = false);
308 /// Insert an @rColor item with @rStr tooltip.
309 void InsertItem(sal_uInt16 nItemId, const Color& rColor,
310 const OUString& rStr);
311 /// Insert an User Drawn item.
312 void InsertItem(sal_uInt16 nItemId, size_t nPos = VALUESET_APPEND);
313 /// Insert an User Drawn item with @rStr tooltip.
314 void InsertItem(sal_uInt16 nItemId, const OUString& rStr, size_t nPos);
315 void RemoveItem(sal_uInt16 nItemId);
317 void Clear();
319 size_t GetItemCount() const;
320 size_t GetItemPos( sal_uInt16 nItemId ) const;
321 sal_uInt16 GetItemId( size_t nPos ) const;
322 sal_uInt16 GetItemId( const Point& rPos ) const;
323 tools::Rectangle GetItemRect( sal_uInt16 nItemId ) const;
324 void EnableFullItemMode( bool bFullMode );
326 void SetColCount( sal_uInt16 nNewCols = 1 );
327 sal_uInt16 GetColCount() const
329 return mnUserCols;
331 void SetLineCount( sal_uInt16 nNewLines = 0 );
332 sal_uInt16 GetLineCount() const
334 return mnUserVisLines;
336 void SetItemWidth( long nItemWidth );
337 void SetItemHeight( long nLineHeight );
338 Size GetLargestItemSize();
339 void RecalculateItemSizes();
341 void SelectItem( sal_uInt16 nItemId );
342 sal_uInt16 GetSelectItemId() const
344 return mnSelItemId;
346 size_t GetSelectItemPos() const
348 return GetItemPos( mnSelItemId );
350 void SaveValue() { mnSavedItemId = GetSelectItemId(); }
351 bool IsItemSelected( sal_uInt16 nItemId ) const
353 return !mbNoSelection && (nItemId == mnSelItemId);
355 void SetNoSelection();
356 bool IsNoSelection() const
358 return mbNoSelection;
361 void SetItemImage( sal_uInt16 nItemId, const Image& rImage );
362 Image GetItemImage( sal_uInt16 nItemId ) const;
363 void SetItemColor( sal_uInt16 nItemId, const Color& rColor );
364 Color GetItemColor( sal_uInt16 nItemId ) const;
365 void SetItemData( sal_uInt16 nItemId, void* pData );
366 void* GetItemData( sal_uInt16 nItemId ) const;
367 void SetItemText( sal_uInt16 nItemId, const OUString& rStr );
368 OUString GetItemText( sal_uInt16 nItemId ) const;
369 void SetColor( const Color& rColor );
370 void SetColor()
372 SetColor(Color(COL_TRANSPARENT));
374 bool IsColor() const
376 return maColor.GetTransparency() == 0;
379 void SetExtraSpacing( sal_uInt16 nNewSpacing );
381 void Format(vcl::RenderContext& rRenderContext);
382 void SetFormat();
384 void StartSelection();
385 void EndSelection();
387 Size CalcWindowSizePixel(const Size& rItemSize,
388 sal_uInt16 nCalcCols = 0,
389 sal_uInt16 nCalcLines = 0) const;
390 Size CalcItemSizePixel(const Size& rSize) const;
391 long GetScrollWidth() const;
393 void SetSelectHdl(const Link<ValueSet*,void>& rLink)
395 maSelectHdl = rLink;
397 void SetDoubleClickHdl(const Link<ValueSet*,void>& rLink)
399 maDoubleClickHdl = rLink;
402 void SetHighlightHdl(const Link<ValueSet*,void>& rLink);
404 bool GetEdgeBlending() const
406 return mbEdgeBlending;
408 void SetEdgeBlending(bool bNew);
411 #endif // INCLUDED_SVTOOLS_VALUESET_HXX
413 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */