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