Line data Source code
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_SVTOOLS_VALUESET_HXX
21 : #define INCLUDED_SVTOOLS_VALUESET_HXX
22 :
23 : #include <svtools/svtdllapi.h>
24 :
25 : #include <vcl/ctrl.hxx>
26 : #include <vcl/virdev.hxx>
27 : #include <vcl/timer.hxx>
28 : #include <memory>
29 : #include <vector>
30 :
31 : class MouseEvent;
32 : class TrackingEvent;
33 : class HelpEvent;
34 : class KeyEvent;
35 : class DataChangedEvent;
36 : class ScrollBar;
37 :
38 : struct ValueSetItem;
39 :
40 : class ValueSetAcc;
41 : class ValueItemAcc;
42 : enum class DrawFrameStyle;
43 :
44 : /*************************************************************************
45 :
46 : Description
47 : ============
48 :
49 : class ValueSet
50 :
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.
61 :
62 : Cross references
63 :
64 : class ListBox
65 :
66 : --------------------------------------------------------------------------
67 :
68 : WinBits
69 :
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 scroolbar 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 : --------------------------------------------------------------------------
104 :
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.
111 :
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.
124 :
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.
128 :
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).
137 :
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.
141 :
142 : --------------------------------------------------------------------------
143 :
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().
149 :
150 : In case of a visible Control the creation of the new output area could be
151 : activated before Paint by calling Format().
152 :
153 : --------------------------------------------------------------------------
154 :
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.
161 :
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.
171 :
172 : --------------------------------------------------------------------------
173 :
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().
177 :
178 : *************************************************************************/
179 :
180 : typedef std::vector<ValueSetItem*> ValueItemList;
181 : typedef std::unique_ptr<ValueSetItem> ValueSetItemPtr;
182 :
183 : // - ValueSet types -
184 : #define WB_RADIOSEL ((WinBits)0x00008000)
185 : #define WB_ITEMBORDER ((WinBits)0x00010000)
186 : #define WB_DOUBLEBORDER ((WinBits)0x00020000)
187 : #define WB_NAMEFIELD ((WinBits)0x00040000)
188 : #define WB_NONEFIELD ((WinBits)0x00080000)
189 : #define WB_FLATVALUESET ((WinBits)0x02000000)
190 : #define WB_NO_DIRECTSELECT ((WinBits)0x04000000)
191 : #define WB_MENUSTYLEVALUESET ((WinBits)0x08000000)
192 :
193 :
194 : #define VALUESET_APPEND ((size_t)-1)
195 : #define VALUESET_ITEM_NOTFOUND ((size_t)-1)
196 :
197 : class SVT_DLLPUBLIC ValueSet : public Control
198 : {
199 : private:
200 :
201 : ScopedVclPtr<VirtualDevice> maVirDev;
202 : Timer maTimer;
203 : ValueItemList mItemList;
204 : ValueSetItemPtr mpNoneItem;
205 : VclPtr<ScrollBar> mxScrollBar;
206 : Rectangle maNoneItemRect;
207 : Rectangle maItemListRect;
208 : long mnItemWidth;
209 : long mnItemHeight;
210 : long mnTextOffset;
211 : long mnVisLines;
212 : long mnLines;
213 : long mnUserItemWidth;
214 : long mnUserItemHeight;
215 : sal_uInt16 mnSelItemId;
216 : sal_uInt16 mnHighItemId;
217 : sal_uInt16 mnCols;
218 : sal_uInt16 mnCurCol;
219 : sal_uInt16 mnUserCols;
220 : sal_uInt16 mnUserVisLines;
221 : sal_uInt16 mnFirstLine;
222 : sal_uInt16 mnSpacing;
223 : DrawFrameStyle mnFrameStyle;
224 : Color maColor;
225 : Link<> maDoubleClickHdl;
226 : Link<> maSelectHdl;
227 : Link<> maHighlightHdl;
228 :
229 : // bitfield
230 : bool mbFormat : 1;
231 : bool mbHighlight : 1;
232 : bool mbSelection : 1;
233 : bool mbNoSelection : 1;
234 : bool mbDrawSelection : 1;
235 : bool mbBlackSel : 1;
236 : bool mbDoubleSel : 1;
237 : bool mbScroll : 1;
238 : bool mbFullMode : 1;
239 : bool mbEdgeBlending : 1;
240 : bool mbIsTransientChildrenDisabled : 1;
241 : bool mbHasVisibleItems : 1;
242 :
243 : friend class ValueSetAcc;
244 : friend class ValueItemAcc;
245 :
246 : using Control::ImplInitSettings;
247 : using Window::ImplInit;
248 : SVT_DLLPRIVATE void ImplInit();
249 : SVT_DLLPRIVATE void ImplInitSettings( bool bFont, bool bForeground, bool bBackground );
250 :
251 : virtual void ApplySettings(vcl::RenderContext& rRenderContext) SAL_OVERRIDE;
252 :
253 : SVT_DLLPRIVATE void ImplInitScrollBar();
254 : SVT_DLLPRIVATE void ImplDeleteItems();
255 : SVT_DLLPRIVATE void ImplFormatItem(vcl::RenderContext& rRenderContext, ValueSetItem* pItem, Rectangle aRect);
256 : SVT_DLLPRIVATE void ImplDrawItemText(vcl::RenderContext& rRenderContext, const OUString& rStr);
257 : SVT_DLLPRIVATE void ImplDrawSelect(vcl::RenderContext& rRenderContext, sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel);
258 : SVT_DLLPRIVATE void ImplDrawSelect(vcl::RenderContext& rRenderContext);
259 : SVT_DLLPRIVATE void ImplHideSelect(sal_uInt16 nItemId);
260 : SVT_DLLPRIVATE void ImplHighlightItem(sal_uInt16 nItemId, bool bIsSelection = true);
261 : SVT_DLLPRIVATE void ImplDraw(vcl::RenderContext& rRenderContext);
262 : using Window::ImplScroll;
263 : SVT_DLLPRIVATE bool ImplScroll( const Point& rPos );
264 : SVT_DLLPRIVATE size_t ImplGetItem( const Point& rPoint, bool bMove = false ) const;
265 : SVT_DLLPRIVATE ValueSetItem* ImplGetItem( size_t nPos );
266 : SVT_DLLPRIVATE ValueSetItem* ImplGetFirstItem();
267 : SVT_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const;
268 : SVT_DLLPRIVATE void ImplInsertItem( ValueSetItem *const pItem, const size_t nPos );
269 : SVT_DLLPRIVATE Rectangle ImplGetItemRect( size_t nPos ) const;
270 : SVT_DLLPRIVATE void ImplFireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
271 : SVT_DLLPRIVATE bool ImplHasAccessibleListeners();
272 : SVT_DLLPRIVATE void ImplTracking( const Point& rPos, bool bRepeat );
273 : SVT_DLLPRIVATE void ImplEndTracking( const Point& rPos, bool bCancel );
274 : DECL_DLLPRIVATE_LINK( ImplScrollHdl, ScrollBar* );
275 : DECL_DLLPRIVATE_LINK_TYPED( ImplTimerHdl, Timer*, void );
276 :
277 : ValueSet (const ValueSet &) SAL_DELETED_FUNCTION;
278 : ValueSet & operator= (const ValueSet &) SAL_DELETED_FUNCTION;
279 :
280 : protected:
281 : bool StartDrag( const CommandEvent& rCEvt, vcl::Region& rRegion );
282 :
283 : virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() SAL_OVERRIDE;
284 :
285 : public:
286 : ValueSet( vcl::Window* pParent, WinBits nWinStyle, bool bDisableTransientChildren = false );
287 : ValueSet( vcl::Window* pParent, const ResId& rResId, bool bDisableTransientChildren = false );
288 : virtual ~ValueSet();
289 : virtual void dispose() SAL_OVERRIDE;
290 :
291 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
292 : virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
293 : virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
294 : virtual void Tracking( const TrackingEvent& rMEvt ) SAL_OVERRIDE;
295 : virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
296 : virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE;
297 : virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE;
298 : virtual void GetFocus() SAL_OVERRIDE;
299 : virtual void LoseFocus() SAL_OVERRIDE;
300 : virtual void Resize() SAL_OVERRIDE;
301 : virtual Size GetOptimalSize() const SAL_OVERRIDE;
302 : virtual void RequestHelp( const HelpEvent& rHEvt ) SAL_OVERRIDE;
303 : virtual void StateChanged( StateChangedType nStateChange ) SAL_OVERRIDE;
304 : virtual void DataChanged( const DataChangedEvent& rDCEvt ) SAL_OVERRIDE;
305 :
306 : virtual void Select();
307 : void DoubleClick();
308 : virtual void UserDraw( const UserDrawEvent& rUDEvt );
309 :
310 : void InsertItem(sal_uInt16 nItemId, const Image& rImage, size_t nPos = VALUESET_APPEND);
311 : void InsertItem(sal_uInt16 nItemId, const Image& rImage,
312 : const OUString& rStr, size_t nPos = VALUESET_APPEND);
313 : void InsertItem(sal_uInt16 nItemId, const Color& rColor,
314 : const OUString& rStr, size_t nPos = VALUESET_APPEND);
315 : void InsertItem(sal_uInt16 nItemId, size_t nPos = VALUESET_APPEND);
316 : void InsertItem(sal_uInt16 nItemId, const OUString& rStr, size_t nPos = VALUESET_APPEND);
317 : void RemoveItem(sal_uInt16 nItemId);
318 :
319 : void Clear();
320 :
321 : size_t GetItemCount() const;
322 : size_t GetItemPos( sal_uInt16 nItemId ) const;
323 : sal_uInt16 GetItemId( size_t nPos ) const;
324 : sal_uInt16 GetItemId( const Point& rPos ) const;
325 : Rectangle GetItemRect( sal_uInt16 nItemId ) const;
326 :
327 : void EnableFullItemMode( bool bFullMode = true );
328 : bool IsFullItemModeEnabled() const
329 : {
330 : return mbFullMode;
331 : }
332 : void SetColCount( sal_uInt16 nNewCols = 1 );
333 0 : sal_uInt16 GetColCount() const
334 : {
335 0 : return mnUserCols;
336 : }
337 : void SetLineCount( sal_uInt16 nNewLines = 0 );
338 0 : sal_uInt16 GetLineCount() const
339 : {
340 0 : return mnUserVisLines;
341 : }
342 : void SetItemWidth( long nItemWidth = 0 );
343 : long GetItemWidth() const
344 : {
345 : return mnUserItemWidth;
346 : }
347 : void SetItemHeight( long nLineHeight = 0 );
348 : long GetItemHeight() const
349 : {
350 : return mnUserItemHeight;
351 : }
352 : sal_uInt16 GetFirstLine() const
353 : {
354 : return mnFirstLine;
355 : }
356 :
357 : void SelectItem( sal_uInt16 nItemId );
358 0 : sal_uInt16 GetSelectItemId() const
359 : {
360 0 : return mnSelItemId;
361 : }
362 0 : bool IsItemSelected( sal_uInt16 nItemId ) const
363 : {
364 0 : return !mbNoSelection && (nItemId == mnSelItemId);
365 : }
366 : void SetNoSelection();
367 0 : bool IsNoSelection() const
368 : {
369 0 : return mbNoSelection;
370 : }
371 :
372 : void SetItemImage( sal_uInt16 nItemId, const Image& rImage );
373 : Image GetItemImage( sal_uInt16 nItemId ) const;
374 : void SetItemColor( sal_uInt16 nItemId, const Color& rColor );
375 : Color GetItemColor( sal_uInt16 nItemId ) const;
376 : void SetItemData( sal_uInt16 nItemId, void* pData );
377 : void* GetItemData( sal_uInt16 nItemId ) const;
378 : void SetItemText( sal_uInt16 nItemId, const OUString& rStr );
379 : OUString GetItemText( sal_uInt16 nItemId ) const;
380 : void SetColor( const Color& rColor );
381 0 : void SetColor()
382 : {
383 0 : SetColor(Color(COL_TRANSPARENT));
384 0 : }
385 : Color GetColor() const
386 : {
387 : return maColor;
388 : }
389 192 : bool IsColor() const
390 : {
391 192 : return maColor.GetTransparency() == 0;
392 : }
393 :
394 : void SetExtraSpacing( sal_uInt16 nNewSpacing );
395 : sal_uInt16 GetExtraSpacing()
396 : {
397 : return mnSpacing;
398 : }
399 :
400 : void Format(vcl::RenderContext& rRenderContext);
401 : void SetFormat(bool bFormat = true);
402 :
403 : void StartSelection();
404 : void EndSelection();
405 :
406 : Size CalcWindowSizePixel(const Size& rItemSize,
407 : sal_uInt16 nCalcCols = 0,
408 : sal_uInt16 nCalcLines = 0) const;
409 : Size CalcItemSizePixel(const Size& rSize, bool bOut = true) const;
410 : long GetScrollWidth() const;
411 :
412 10 : void SetSelectHdl(const Link<>& rLink)
413 : {
414 10 : maSelectHdl = rLink;
415 10 : }
416 : const Link<>& GetSelectHdl() const
417 : {
418 : return maSelectHdl;
419 : }
420 0 : void SetDoubleClickHdl(const Link<>& rLink)
421 : {
422 0 : maDoubleClickHdl = rLink;
423 0 : }
424 : const Link<>& GetDoubleClickHdl() const
425 : {
426 : return maDoubleClickHdl;
427 : }
428 :
429 : void SetHighlightHdl(const Link<>& rLink);
430 :
431 192 : bool GetEdgeBlending() const
432 : {
433 192 : return mbEdgeBlending;
434 : }
435 : void SetEdgeBlending(bool bNew);
436 : };
437 :
438 : #endif // INCLUDED_SVTOOLS_VALUESET_HXX
439 :
440 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|