]>
Commit | Line | Data |
---|---|---|
56873923 VZ |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: wx/headerctrl.h | |
3 | // Purpose: interface of wxHeaderCtrl | |
4 | // Author: Vadim Zeitlin | |
5 | // Created: 2008-12-01 | |
6 | // RCS-ID: $Id$ | |
7 | // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org> | |
8 | // Licence: wxWindows license | |
9 | ///////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | /** | |
12 | @class wxHeaderCtrl | |
13 | ||
14 | wxHeaderCtrl is the control containing the column headings which is usually | |
15 | used for display of tabular data. | |
16 | ||
17 | It is used as part of wxGrid and (will be used in the near future) in | |
18 | in wxDataViewCtrl and report view of wxListCtrl but can be also used | |
e2bfe673 VZ |
19 | independently. In general this class is meant to be used as part of another |
20 | control which already stores the column information somewhere as it can't | |
21 | be used directly: instead you need to inherit from it and implement the | |
22 | GetColumn() method to provide column information. See wxHeaderCtrlSimple | |
23 | for a concrete control class which can be used directly. | |
56873923 VZ |
24 | |
25 | In addition to labeling the columns, the control has the following | |
26 | features: | |
27 | - Column reordering support, either by explicitly configuring the | |
28 | columns order and calling SetColumnsOrder() or by dragging the | |
29 | columns interactively (if enabled). | |
30 | - Display of the icons in the header: this is often used to display a | |
31 | sort or reverse sort indicator when the column header is clicked. | |
32 | ||
33 | Notice that this control itself doesn't do anything other than displaying | |
34 | the column headers. In particular column reordering and sorting must still | |
35 | be supported by the associated control displaying the real data under the | |
f24f6579 VZ |
36 | header. Also remember to call ScrollWindow() method of the control if the |
37 | associated data display window has a horizontal scrollbar, otherwise the | |
38 | headers wouldn't align with the data when the window is scrolled. | |
56873923 VZ |
39 | |
40 | This control is implemented using the native header control under MSW | |
41 | systems and a generic implementation elsewhere. | |
42 | ||
43 | @beginStyleTable | |
44 | @style{wxHD_DRAGDROP} | |
45 | If this style is specified (it is by default), the user can reorder | |
46 | the control columns by dragging them. | |
47 | @style{wxHD_DEFAULT_STYLE} | |
48 | Symbolic name for the default control style, currently equal to @c | |
49 | wxHD_DRAGDROP. | |
50 | @endStyleTable | |
51 | ||
fa3d4aaf VZ |
52 | @beginEventTable{wxHeaderCtrlEvent} |
53 | @event{EVT_HEADER_CLICK(id, func)} | |
54 | A column heading was clicked. | |
55 | @event{EVT_HEADER_RIGHT_CLICK(id, func)} | |
56 | A column heading was right clicked. | |
57 | @event{EVT_HEADER_MIDDLE_CLICK(id, func)} | |
58 | A column heading was clicked with the middle mouse button. | |
59 | ||
60 | @event{EVT_HEADER_DCLICK(id, func)} | |
61 | A column heading was double clicked. | |
62 | @event{EVT_HEADER_RIGHT_DCLICK(id, func)} | |
63 | A column heading was right double clicked. | |
64 | @event{EVT_HEADER_MIDDLE_DCLICK(id, func)} | |
65 | A column heading was double clicked with the middle mouse button. | |
3bfaa5a7 VZ |
66 | |
67 | @event{EVT_HEADER_SEPARATOR_DCLICK(id, func)} | |
68 | Separator to the right of the specified column was double clicked | |
69 | (this action is commonly used to resize the column to fit its | |
70 | contents width and the control provides UpdateColumnWidthToFit() method | |
71 | to make implementing this easier). | |
aef252d9 | 72 | |
396825dc VZ |
73 | @event{EVT_HEADER_BEGIN_RESIZE(id, func)} |
74 | The user started to drag the separator to the right of the column | |
75 | with the specified index (this can only happen for the columns for | |
76 | which wxHeaderColumn::IsResizeable() returns true). The event can | |
77 | be vetoed to prevent the column from being resized. If it isn't, | |
565804f2 VZ |
78 | the resizing and end resize (or dragging cancelled) events will be |
79 | generated later. | |
396825dc VZ |
80 | @event{EVT_HEADER_RESIZING(id, func)} |
81 | The user is dragging the column with the specified index resizing | |
82 | it and its current width is wxHeaderCtrlEvent::GetWidth(). The | |
83 | event can be vetoed to stop the dragging operation completely at | |
84 | any time. | |
85 | @event{EVT_HEADER_END_RESIZE(id, func)} | |
565804f2 VZ |
86 | The user stopped dragging the column by releasing the mouse. The |
87 | column should normally be resized to the value of | |
88 | wxHeaderCtrlEvent::GetWidth(). | |
702f5349 VZ |
89 | |
90 | @event{EVT_HEADER_BEGIN_REORDER(id, func)} | |
91 | The user started to drag the column with the specified index (this | |
92 | can only happen for the controls with wxHD_DRAGDROP style). This | |
93 | event can be vetoed to prevent the column from being reordered, | |
94 | otherwise the end reorder message will be generated later. | |
95 | @event{EVT_HEADER_END_REORDER(id, func)} | |
565804f2 | 96 | The user dropped the column in its new location. The event can be |
702f5349 VZ |
97 | vetoed to prevent the column from being placed at the new position |
98 | or handled to update the display of the data in the associated | |
99 | control to match the new column location (available from | |
100 | wxHeaderCtrlEvent::GetNewOrder()). | |
565804f2 VZ |
101 | |
102 | @event{EVT_HEADER_DRAGGING_CANCELLED(id, func)} | |
103 | The resizing or reordering operation currently in progress was | |
104 | cancelled. This can happen if the user pressed Esc key while | |
105 | dragging the mouse or the mouse capture was lost for some other | |
106 | reason. You only need to handle this event if your application | |
107 | entered into some modal mode when resizing or reordering began, in | |
108 | which case it should handle this event in addition to the matching | |
109 | end resizing or reordering ones. | |
56873923 VZ |
110 | @endEventTable |
111 | ||
112 | @library{wxcore} | |
113 | @category{ctrl} | |
114 | ||
115 | @see wxGrid, wxListCtrl, wxDataViewCtrl | |
116 | ||
117 | ||
118 | @section headerctrl_improvements Future Improvements | |
119 | ||
120 | Some features are supported by the native MSW control and so could be | |
121 | easily implemented in this version of wxHeaderCtrl but need to be | |
122 | implemented in the generic version as well to be really useful. Please let | |
123 | us know if you need or, better, plan to work on implementing, any of them: | |
124 | - Displaying bitmaps instead of or together with the text | |
125 | - Custom drawn headers | |
126 | - Filters associated with a column. | |
127 | */ | |
128 | class wxHeaderCtrl | |
129 | { | |
130 | public: | |
131 | /** | |
132 | Default constructor not creating the underlying window. | |
133 | ||
134 | You must use Create() after creating the object using this constructor. | |
135 | */ | |
136 | wxHeaderCtrl(); | |
137 | ||
138 | /** | |
139 | Constructor creating the window. | |
140 | ||
141 | Please see Create() for the parameters documentation. | |
142 | */ | |
143 | wxHeaderCtrl(wxWindow *parent, | |
144 | wxWindowID winid = wxID_ANY, | |
145 | const wxPoint& pos = wxDefaultPosition, | |
146 | const wxSize& size = wxDefaultSize, | |
e2bfe673 | 147 | long style = wxHD_DEFAULT_STYLE, |
56873923 VZ |
148 | const wxString& name = wxHeaderCtrlNameStr); |
149 | ||
150 | /** | |
151 | Create the header control window. | |
152 | ||
153 | @param parent | |
154 | The parent window. The header control should be typically | |
155 | positioned along the top edge of this window. | |
156 | @param winid | |
157 | Id of the control or @c wxID_ANY if you don't care. | |
158 | @param pos | |
159 | The initial position of the control. | |
160 | @param size | |
161 | The initial size of the control (usually not very useful as this | |
162 | control will typically be resized to have the same width as the | |
163 | associated data display control). | |
164 | @param style | |
165 | The control style, @c wxHD_DEFAULT_STYLE by default. Notice that | |
166 | the default style allows the user to reorder the columns by | |
167 | dragging them and you need to explicitly turn this feature off by | |
168 | using @code wxHD_DEFAULT_STYLE & ~wxHD_DRAGDROP @endcode if this is | |
169 | undesirable. | |
170 | @param name | |
171 | The name of the control. | |
172 | */ | |
173 | bool Create(wxWindow *parent, | |
174 | wxWindowID winid = wxID_ANY, | |
175 | const wxPoint& pos = wxDefaultPosition, | |
176 | const wxSize& size = wxDefaultSize, | |
e2bfe673 | 177 | long style = wxHD_DEFAULT_STYLE, |
56873923 VZ |
178 | const wxString& name = wxHeaderCtrlNameStr); |
179 | ||
e2bfe673 VZ |
180 | /** |
181 | Set the number of columns in the control. | |
182 | ||
183 | The control will use GetColumn() to get information about all the | |
184 | new columns and refresh itself, i.e. this method also has the same | |
185 | effect as calling UpdateColumn() for all columns but it should only be | |
186 | used if the number of columns really changed. | |
187 | */ | |
188 | void SetColumnCount(unsigned int count); | |
189 | ||
56873923 VZ |
190 | /** |
191 | Return the number of columns in the control. | |
192 | ||
e2bfe673 VZ |
193 | @return |
194 | Number of columns as previously set by SetColumnCount(). | |
195 | ||
56873923 VZ |
196 | @see IsEmpty() |
197 | */ | |
198 | unsigned int GetColumnCount() const; | |
199 | ||
200 | /** | |
201 | Return whether the control has any columns. | |
202 | ||
203 | @see GetColumnCount() | |
204 | */ | |
205 | bool IsEmpty() const; | |
206 | ||
1efd7bc6 VZ |
207 | /** |
208 | Update the column with the given index. | |
209 | ||
210 | When the value returned by GetColumn() changes, this method must be | |
211 | called to notify the control about the change and update the visual | |
212 | display to match the new column data. | |
213 | ||
214 | @param idx | |
215 | The column index, must be less than GetColumnCount(). | |
216 | */ | |
217 | void UpdateColumn(unsigned int idx); | |
218 | ||
702f5349 VZ |
219 | /** |
220 | Change the columns display order. | |
221 | ||
222 | The display order defines the order in which the columns appear on the | |
223 | screen and does @em not affect the interpretation of indices by all the | |
224 | other class methods. | |
225 | ||
226 | The @a order array specifies the column indices corresponding to the | |
227 | display positions. | |
228 | ||
229 | @param order | |
230 | A permutation of all column indices, i.e. an array of size | |
231 | GetColumnsOrder() containing all column indices exactly once. The | |
232 | n-th element of this array defines the index of the column shown at | |
233 | the n-th position from left (for the default left-to-right writing | |
234 | direction). | |
235 | ||
236 | @see wxListCtrl::SetColumnsOrder() | |
237 | */ | |
238 | void SetColumnsOrder(const wxArrayInt& order); | |
239 | ||
240 | /** | |
241 | Return the array describing the columns display order. | |
242 | ||
243 | For the controls without wxHD_DRAGDROP style the returned array will be | |
244 | the same as was passed to SetColumnsOrder() previously or define the | |
245 | default order (with n-th element being n) if it hadn't been called. But | |
246 | for the controls with wxHD_DRAGDROP style, the columns can be also | |
247 | reordered by user. | |
248 | */ | |
249 | wxArrayInt GetColumnsOrder() const; | |
250 | ||
251 | /** | |
252 | Return the index of the column displayed at the given position. | |
253 | ||
254 | @param pos | |
255 | The display position, e.g. 0 for the left-most column, 1 for the | |
256 | next one and so on until GetColumnCount() - 1. | |
257 | ||
258 | @see GetColumnPos() | |
259 | */ | |
260 | unsigned int GetColumnAt(unsigned int pos) const; | |
261 | ||
262 | /** | |
263 | Get the position at which this column is currently displayed. | |
264 | ||
265 | Notice that a valid position is returned even for the hidden columns | |
266 | currently. | |
267 | ||
268 | @param idx | |
269 | The column index, must be less than GetColumnCount(). | |
270 | ||
271 | @see GetColumnAt() | |
272 | */ | |
273 | unsigned int GetColumnPos(unsigned int idx) const; | |
274 | ||
1bb74626 VZ |
275 | /** |
276 | Helper function to manipulate the array of column indices. | |
277 | ||
278 | This function reshuffles the array of column indices indexed by | |
279 | positions (i.e. using the same convention as for SetColumnsOrder()) so | |
280 | that the column with the given index is found at the specified | |
281 | position. | |
282 | ||
283 | @param order | |
284 | Array containing the indices of columns in order of their | |
285 | positions. | |
286 | @param idx | |
287 | The index of the column to move. | |
288 | @param pos | |
289 | The new position for the column @a idx. | |
290 | */ | |
291 | static void MoveColumnInOrderArray(wxArrayInt& order, | |
292 | unsigned int idx, | |
293 | unsigned int pos); | |
294 | ||
e2bfe673 VZ |
295 | protected: |
296 | /** | |
297 | Method to be implemented by the derived classes to return the | |
298 | information for the given column. | |
299 | ||
300 | @param idx | |
301 | The column index, between 0 and the value last passed to | |
302 | SetColumnCount(). | |
303 | */ | |
304 | virtual wxHeaderColumnBase& GetColumn(unsigned int idx) = 0; | |
3bfaa5a7 VZ |
305 | |
306 | /** | |
307 | Method which may be implemented by the derived classes to allow double | |
308 | clicking the column separator to resize the column to fit its contents. | |
309 | ||
310 | When a separator is double clicked, the default handler of | |
311 | EVT_HEADER_SEPARATOR_DCLICK event calls this function and refreshes the | |
312 | column if it returns @true so to implement the resizing of the column | |
313 | to fit its width on header double click you need to implement this | |
314 | method using logic similar to this example: | |
315 | @code | |
316 | class MyHeaderCtrl : public wxHeaderColumnBase | |
317 | { | |
318 | public: | |
319 | ... | |
320 | ||
321 | void SetWidth(int width) { m_width = width; } | |
322 | virtual int GetWidth() const { return m_width; } | |
323 | ||
324 | private: | |
325 | int m_width; | |
326 | }; | |
327 | ||
328 | class MyHeaderCtrl : public wxHeaderCtrl | |
329 | { | |
330 | public: | |
331 | protected: | |
332 | virtual wxHeaderColumnBase& GetColumn(unsigned int idx) | |
333 | { | |
334 | return m_cols[idx]; | |
335 | } | |
336 | ||
337 | virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle) | |
338 | { | |
339 | int widthContents = ... compute minimal width for column idx ... | |
340 | m_cols[idx].SetWidth(wxMax(widthContents, widthTitle)); | |
341 | return true; | |
342 | } | |
343 | ||
344 | wxVector<MyHeaderColumn> m_cols; | |
345 | }; | |
346 | @endcode | |
347 | ||
348 | Base class version simply returns @false. | |
349 | ||
350 | @param width | |
351 | Contains minimal width needed to display the column header itself | |
352 | and will usually be used as a starting point for the fitting width | |
353 | calculation. | |
354 | @return | |
355 | @true to indicate that the column was resized, i.e. GetColumn() now | |
356 | returns the new width value, and so must be refreshed or @false | |
357 | meaning that the control didn't reach to the separator double click. | |
358 | */ | |
359 | virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle); | |
4635abac VZ |
360 | |
361 | /** | |
362 | Can be overridden in the derived class to update internal data | |
363 | structures when the number of the columns in the control changes. | |
364 | ||
365 | This method is called by SetColumnCount() before effectively changing | |
366 | the number of columns. | |
367 | ||
368 | The base class version does nothing but it is good practice to still | |
369 | call it from the overridden version in the derived class. | |
370 | */ | |
371 | virtual void OnColumnCountChanging(unsigned int count); | |
e2bfe673 VZ |
372 | }; |
373 | ||
374 | ||
375 | /** | |
376 | @class wxHeaderCtrlSimple | |
377 | ||
378 | wxHeaderCtrlSimple is a concrete header control which can be used directly, | |
379 | without inheriting from it as you need to do when using wxHeaderCtrl | |
380 | itself. | |
381 | ||
382 | When using it, you need to use simple AppendColumn(), InsertColumn() and | |
383 | DeleteColumn() methods instead of setting the number of columns with | |
384 | SetColumnCount() and returning the information about them from the | |
385 | overridden GetColumn(). | |
386 | ||
387 | @library{wxcore} | |
388 | @category{ctrl} | |
389 | ||
390 | @see wxHeaderCtrl | |
391 | */ | |
392 | class wxHeaderCtrlSimple : public wxHeaderCtrl | |
393 | { | |
394 | public: | |
395 | /** | |
396 | Default constructor not creating the underlying window. | |
397 | ||
398 | You must use Create() after creating the object using this constructor. | |
399 | */ | |
400 | wxHeaderCtrlSimple(); | |
401 | ||
402 | /** | |
403 | Constructor creating the window. | |
404 | ||
405 | Please see the base class wxHeaderCtrl::Create() method for the | |
406 | parameters description. | |
407 | */ | |
408 | wxHeaderCtrlSimple(wxWindow *parent, | |
409 | wxWindowID winid = wxID_ANY, | |
410 | const wxPoint& pos = wxDefaultPosition, | |
411 | const wxSize& size = wxDefaultSize, | |
412 | long style = wxHD_DEFAULT_STYLE, | |
413 | const wxString& name = wxHeaderCtrlNameStr); | |
414 | ||
56873923 VZ |
415 | /** |
416 | Insert the column at the given position. | |
417 | ||
418 | @param col | |
419 | The column to insert. Notice that because of the existence of | |
420 | implicit conversion from wxString to wxHeaderColumn a string | |
421 | can be passed directly here. | |
422 | @param idx | |
423 | The position of the new column, from 0 to GetColumnCount(). Using | |
424 | GetColumnCount() means to append the column to the end. | |
425 | ||
426 | @see AppendColumn() | |
427 | */ | |
428 | void InsertColumn(const wxHeaderColumn& col, unsigned int idx); | |
429 | ||
430 | /** | |
431 | Append the column to the end of the control. | |
432 | ||
433 | @see InsertColumn() | |
434 | */ | |
435 | void AppendColumn(const wxHeaderColumn& col); | |
436 | ||
437 | /** | |
438 | Delete the column at the given position. | |
439 | ||
440 | @see InsertColumn(), AppendColumn() | |
441 | */ | |
442 | void DeleteColumn(unsigned int idx); | |
443 | ||
a0009205 VZ |
444 | /** |
445 | Show or hide the column. | |
446 | ||
447 | Initially the column is shown by default or hidden if it was added with | |
448 | wxCOL_HIDDEN flag set. | |
449 | ||
450 | When a column is hidden, it doesn't appear at all on the screen but its | |
451 | index is still taken into account when working with other columns. E.g. | |
452 | if there are three columns 0, 1 and 2 and the column 1 is hidden you | |
453 | still need to use index 2 to refer to the last visible column. | |
454 | ||
455 | @param idx | |
456 | The index of the column to show or hide, from 0 to GetColumnCount(). | |
457 | @param show | |
458 | Indicates whether the column should be shown (default) or hidden. | |
459 | */ | |
460 | void ShowColumn(unsigned int idx, bool show = true); | |
461 | ||
462 | /** | |
463 | Hide the column with the given index. | |
464 | ||
465 | This is the same as calling @code ShowColumn(idx, false) @endcode. | |
466 | ||
467 | @param idx | |
468 | The index of the column to show or hide, from 0 to GetColumnCount(). | |
469 | */ | |
470 | void HideColumn(unsigned int idx); | |
471 | ||
56873923 VZ |
472 | /** |
473 | Update the column sort indicator. | |
474 | ||
475 | The sort indicator, if shown, is typically an arrow pointing upwards or | |
476 | downwards depending on whether the control contents is sorted in | |
477 | ascending or descending order. | |
478 | ||
479 | @param idx | |
480 | The column to set the sort indicator for. | |
481 | @param sortOrder | |
482 | If @true or @false show the sort indicator corresponding to | |
483 | ascending or descending sort order respectively, if @c -1 remove | |
484 | the currently shown sort indicator. | |
485 | */ | |
486 | virtual void ShowSortIndicator(unsigned int idx, int sortOrder); | |
487 | ||
488 | /** | |
489 | Remove the sort indicator from the given column. | |
490 | ||
491 | This is the same as calling ShowSortIndicator() with @c -1 argument. | |
492 | ||
493 | @param idx | |
494 | The column to remove sort indicator for. | |
495 | */ | |
496 | void RemoveSortIndicator(unsigned int idx); | |
e5a16353 VZ |
497 | |
498 | protected: | |
499 | /** | |
500 | This function can be overridden in the classes deriving from this | |
501 | control instead of overriding UpdateColumnWidthToFit(). | |
502 | ||
503 | To implement automatic column resizing to fit its contents width when | |
504 | the column divider is double clicked, you need to simply return the | |
505 | fitting width for the given column @a idx from this method, the control | |
506 | will automatically use the biggest value between the one returned from | |
507 | here and the one needed for the display of the column title itself. | |
508 | ||
509 | The base class version returns -1 indicating that this function is not | |
510 | implemented. | |
511 | */ | |
512 | virtual int GetBestFittingWidth(unsigned int idx) const; | |
56873923 | 513 | }; |
fa3d4aaf VZ |
514 | |
515 | /** | |
516 | @class wxHeaderCtrlEvent | |
517 | ||
518 | Event class representing the events generated by wxHeaderCtrl. | |
519 | ||
520 | @library{wxcore} | |
521 | @category{ctrl} | |
522 | ||
523 | @see wxHeaderCtrl | |
524 | */ | |
525 | class wxHeaderCtrlEvent : public wxNotifyEvent | |
526 | { | |
527 | public: | |
528 | /** | |
529 | Return the index of the column affected by this event. | |
aef252d9 VZ |
530 | |
531 | This method can be called for all header control events. | |
fa3d4aaf VZ |
532 | */ |
533 | int GetColumn() const; | |
aef252d9 VZ |
534 | |
535 | /** | |
536 | Return the current width of the column. | |
537 | ||
538 | This method can only be called for the dragging events. | |
539 | */ | |
540 | int GetWidth() const; | |
541 | ||
702f5349 VZ |
542 | /** |
543 | Return the new order of the column. | |
544 | ||
545 | This method can only be called for end reorder event for which it | |
546 | indicates the tentative new position for the column GetColumn() | |
547 | selected by the user. If the event is not vetoed, this will become the | |
548 | new column position in wxHeaderCtrl::GetColumnsOrder(). | |
549 | */ | |
550 | unsigned int GetNewOrder() const; | |
fa3d4aaf | 551 | }; |