added support for drop down toolbar buttons (patch 1713470)
[wxWidgets.git] / include / wx / tbarbase.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/tbarbase.h
3 // Purpose: Base class for toolbar classes
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_TBARBASE_H_
13 #define _WX_TBARBASE_H_
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 #include "wx/defs.h"
20
21 #if wxUSE_TOOLBAR
22
23 #include "wx/bitmap.h"
24 #include "wx/list.h"
25 #include "wx/control.h"
26
27 class WXDLLEXPORT wxToolBarBase;
28 class WXDLLEXPORT wxToolBarToolBase;
29 class WXDLLEXPORT wxImage;
30
31 // ----------------------------------------------------------------------------
32 // constants
33 // ----------------------------------------------------------------------------
34
35 extern WXDLLEXPORT_DATA(const wxChar) wxToolBarNameStr[];
36 extern WXDLLEXPORT_DATA(const wxSize) wxDefaultSize;
37 extern WXDLLEXPORT_DATA(const wxPoint) wxDefaultPosition;
38
39 enum wxToolBarToolStyle
40 {
41 wxTOOL_STYLE_BUTTON = 1,
42 wxTOOL_STYLE_SEPARATOR = 2,
43 wxTOOL_STYLE_CONTROL
44 };
45
46 // ----------------------------------------------------------------------------
47 // wxToolBarTool is a toolbar element.
48 //
49 // It has a unique id (except for the separators which always have id wxID_ANY), the
50 // style (telling whether it is a normal button, separator or a control), the
51 // state (toggled or not, enabled or not) and short and long help strings. The
52 // default implementations use the short help string for the tooltip text which
53 // is popped up when the mouse pointer enters the tool and the long help string
54 // for the applications status bar.
55 // ----------------------------------------------------------------------------
56
57 class WXDLLEXPORT wxToolBarToolBase : public wxObject
58 {
59 public:
60 // ctors & dtor
61 // ------------
62
63 wxToolBarToolBase(wxToolBarBase *tbar = (wxToolBarBase *)NULL,
64 int toolid = wxID_SEPARATOR,
65 const wxString& label = wxEmptyString,
66 const wxBitmap& bmpNormal = wxNullBitmap,
67 const wxBitmap& bmpDisabled = wxNullBitmap,
68 wxItemKind kind = wxITEM_NORMAL,
69 wxObject *clientData = (wxObject *) NULL,
70 const wxString& shortHelpString = wxEmptyString,
71 const wxString& longHelpString = wxEmptyString)
72 : m_label(label),
73 m_shortHelpString(shortHelpString),
74 m_longHelpString(longHelpString),
75 m_dropdownMenu(NULL)
76 {
77 m_tbar = tbar;
78 m_id = toolid;
79 if (m_id == wxID_ANY)
80 m_id = wxNewId();
81 m_clientData = clientData;
82
83 m_bmpNormal = bmpNormal;
84 m_bmpDisabled = bmpDisabled;
85
86 m_kind = kind;
87
88 m_enabled = true;
89 m_toggled = false;
90
91 m_toolStyle = toolid == wxID_SEPARATOR ? wxTOOL_STYLE_SEPARATOR
92 : wxTOOL_STYLE_BUTTON;
93 }
94
95 wxToolBarToolBase(wxToolBarBase *tbar,
96 wxControl *control,
97 const wxString& label)
98 : m_label(label)
99 {
100 m_tbar = tbar;
101 m_control = control;
102 m_id = control->GetId();
103
104 m_kind = wxITEM_MAX; // invalid value
105
106 m_enabled = true;
107 m_toggled = false;
108
109 m_toolStyle = wxTOOL_STYLE_CONTROL;
110
111 m_dropdownMenu = 0;
112 }
113
114 virtual ~wxToolBarToolBase();
115
116 // accessors
117 // ---------
118
119 // general
120 int GetId() const { return m_id; }
121
122 wxControl *GetControl() const
123 {
124 wxASSERT_MSG( IsControl(), _T("this toolbar tool is not a control") );
125
126 return m_control;
127 }
128
129 wxToolBarBase *GetToolBar() const { return m_tbar; }
130
131 // style
132 bool IsButton() const { return m_toolStyle == wxTOOL_STYLE_BUTTON; }
133 bool IsControl() const { return m_toolStyle == wxTOOL_STYLE_CONTROL; }
134 bool IsSeparator() const { return m_toolStyle == wxTOOL_STYLE_SEPARATOR; }
135 int GetStyle() const { return m_toolStyle; }
136 wxItemKind GetKind() const
137 {
138 wxASSERT_MSG( IsButton(), _T("only makes sense for buttons") );
139
140 return m_kind;
141 }
142
143 // state
144 bool IsEnabled() const { return m_enabled; }
145 bool IsToggled() const { return m_toggled; }
146 bool CanBeToggled() const
147 { return m_kind == wxITEM_CHECK || m_kind == wxITEM_RADIO; }
148
149 // attributes
150 const wxBitmap& GetNormalBitmap() const { return m_bmpNormal; }
151 const wxBitmap& GetDisabledBitmap() const { return m_bmpDisabled; }
152
153 const wxBitmap& GetBitmap() const
154 { return IsEnabled() ? GetNormalBitmap() : GetDisabledBitmap(); }
155
156 const wxString& GetLabel() const { return m_label; }
157
158 const wxString& GetShortHelp() const { return m_shortHelpString; }
159 const wxString& GetLongHelp() const { return m_longHelpString; }
160
161 wxObject *GetClientData() const
162 {
163 if ( m_toolStyle == wxTOOL_STYLE_CONTROL )
164 {
165 return (wxObject*)m_control->GetClientData();
166 }
167 else
168 {
169 return m_clientData;
170 }
171 }
172
173 // modifiers: return true if the state really changed
174 bool Enable(bool enable);
175 bool Toggle(bool toggle);
176 bool SetToggle(bool toggle);
177 bool SetShortHelp(const wxString& help);
178 bool SetLongHelp(const wxString& help);
179
180 void Toggle() { Toggle(!IsToggled()); }
181
182 void SetNormalBitmap(const wxBitmap& bmp) { m_bmpNormal = bmp; }
183 void SetDisabledBitmap(const wxBitmap& bmp) { m_bmpDisabled = bmp; }
184
185 virtual void SetLabel(const wxString& label) { m_label = label; }
186
187 void SetClientData(wxObject *clientData)
188 {
189 if ( m_toolStyle == wxTOOL_STYLE_CONTROL )
190 {
191 m_control->SetClientData(clientData);
192 }
193 else
194 {
195 m_clientData = clientData;
196 }
197 }
198
199 // add tool to/remove it from a toolbar
200 virtual void Detach() { m_tbar = (wxToolBarBase *)NULL; }
201 virtual void Attach(wxToolBarBase *tbar) { m_tbar = tbar; }
202
203 // these methods are only for tools of wxITEM_DROPDOWN kind (but even such
204 // tools can have a NULL associated menu)
205 void SetDropdownMenu(wxMenu *menu);
206 wxMenu *GetDropdownMenu() const { return m_dropdownMenu; }
207
208 protected:
209 wxToolBarBase *m_tbar; // the toolbar to which we belong (may be NULL)
210
211 // tool parameters
212 int m_toolStyle; // see enum wxToolBarToolStyle
213 int m_id; // the tool id, wxID_SEPARATOR for separator
214 wxItemKind m_kind; // for normal buttons may be wxITEM_NORMAL/CHECK/RADIO
215
216 // as controls have their own client data, no need to waste memory
217 union
218 {
219 wxObject *m_clientData;
220 wxControl *m_control;
221 };
222
223 // tool state
224 bool m_toggled;
225 bool m_enabled;
226
227 // normal and disabled bitmaps for the tool, both can be invalid
228 wxBitmap m_bmpNormal;
229 wxBitmap m_bmpDisabled;
230
231 // the button label
232 wxString m_label;
233
234 // short and long help strings
235 wxString m_shortHelpString;
236 wxString m_longHelpString;
237
238 wxMenu *m_dropdownMenu;
239
240 DECLARE_DYNAMIC_CLASS_NO_COPY(wxToolBarToolBase)
241 };
242
243 // a list of toolbar tools
244 WX_DECLARE_EXPORTED_LIST(wxToolBarToolBase, wxToolBarToolsList);
245
246 // ----------------------------------------------------------------------------
247 // the base class for all toolbars
248 // ----------------------------------------------------------------------------
249
250 class WXDLLEXPORT wxToolBarBase : public wxControl
251 {
252 public:
253 wxToolBarBase();
254 virtual ~wxToolBarBase();
255
256 // toolbar construction
257 // --------------------
258
259 // the full AddTool() function
260 //
261 // If bmpDisabled is wxNullBitmap, a shadowed version of the normal bitmap
262 // is created and used as the disabled image.
263 wxToolBarToolBase *AddTool(int toolid,
264 const wxString& label,
265 const wxBitmap& bitmap,
266 const wxBitmap& bmpDisabled,
267 wxItemKind kind = wxITEM_NORMAL,
268 const wxString& shortHelp = wxEmptyString,
269 const wxString& longHelp = wxEmptyString,
270 wxObject *data = NULL)
271 {
272 return DoAddTool(toolid, label, bitmap, bmpDisabled, kind,
273 shortHelp, longHelp, data);
274 }
275
276 // the most common AddTool() version
277 wxToolBarToolBase *AddTool(int toolid,
278 const wxString& label,
279 const wxBitmap& bitmap,
280 const wxString& shortHelp = wxEmptyString,
281 wxItemKind kind = wxITEM_NORMAL)
282 {
283 return AddTool(toolid, label, bitmap, wxNullBitmap, kind, shortHelp);
284 }
285
286 // add a check tool, i.e. a tool which can be toggled
287 wxToolBarToolBase *AddCheckTool(int toolid,
288 const wxString& label,
289 const wxBitmap& bitmap,
290 const wxBitmap& bmpDisabled = wxNullBitmap,
291 const wxString& shortHelp = wxEmptyString,
292 const wxString& longHelp = wxEmptyString,
293 wxObject *data = NULL)
294 {
295 return AddTool(toolid, label, bitmap, bmpDisabled, wxITEM_CHECK,
296 shortHelp, longHelp, data);
297 }
298
299 // add a radio tool, i.e. a tool which can be toggled and releases any
300 // other toggled radio tools in the same group when it happens
301 wxToolBarToolBase *AddRadioTool(int toolid,
302 const wxString& label,
303 const wxBitmap& bitmap,
304 const wxBitmap& bmpDisabled = wxNullBitmap,
305 const wxString& shortHelp = wxEmptyString,
306 const wxString& longHelp = wxEmptyString,
307 wxObject *data = NULL)
308 {
309 return AddTool(toolid, label, bitmap, bmpDisabled, wxITEM_RADIO,
310 shortHelp, longHelp, data);
311 }
312
313
314 // insert the new tool at the given position, if pos == GetToolsCount(), it
315 // is equivalent to AddTool()
316 virtual wxToolBarToolBase *InsertTool
317 (
318 size_t pos,
319 int toolid,
320 const wxString& label,
321 const wxBitmap& bitmap,
322 const wxBitmap& bmpDisabled = wxNullBitmap,
323 wxItemKind kind = wxITEM_NORMAL,
324 const wxString& shortHelp = wxEmptyString,
325 const wxString& longHelp = wxEmptyString,
326 wxObject *clientData = NULL
327 );
328
329 virtual wxToolBarToolBase *AddTool (wxToolBarToolBase *tool);
330 virtual wxToolBarToolBase *InsertTool (size_t pos, wxToolBarToolBase *tool);
331
332 // add an arbitrary control to the toolbar (notice that the control will be
333 // deleted by the toolbar and that it will also adjust its position/size)
334 //
335 // the label is optional and, if specified, will be shown near the control
336 // NB: the control should have toolbar as its parent
337 virtual wxToolBarToolBase *
338 AddControl(wxControl *control, const wxString& label = wxEmptyString);
339
340 virtual wxToolBarToolBase *
341 InsertControl(size_t pos, wxControl *control,
342 const wxString& label = wxEmptyString);
343
344 // get the control with the given id or return NULL
345 virtual wxControl *FindControl( int toolid );
346
347 // add a separator to the toolbar
348 virtual wxToolBarToolBase *AddSeparator();
349 virtual wxToolBarToolBase *InsertSeparator(size_t pos);
350
351 // remove the tool from the toolbar: the caller is responsible for actually
352 // deleting the pointer
353 virtual wxToolBarToolBase *RemoveTool(int toolid);
354
355 // delete tool either by index or by position
356 virtual bool DeleteToolByPos(size_t pos);
357 virtual bool DeleteTool(int toolid);
358
359 // delete all tools
360 virtual void ClearTools();
361
362 // must be called after all buttons have been created to finish toolbar
363 // initialisation
364 virtual bool Realize();
365
366 // tools state
367 // -----------
368
369 virtual void EnableTool(int toolid, bool enable);
370 virtual void ToggleTool(int toolid, bool toggle);
371
372 // Set this to be togglable (or not)
373 virtual void SetToggle(int toolid, bool toggle);
374
375 // set/get tools client data (not for controls)
376 virtual wxObject *GetToolClientData(int toolid) const;
377 virtual void SetToolClientData(int toolid, wxObject *clientData);
378
379 // returns tool pos, or wxNOT_FOUND if tool isn't found
380 virtual int GetToolPos(int id) const;
381
382 // return true if the tool is toggled
383 virtual bool GetToolState(int toolid) const;
384
385 virtual bool GetToolEnabled(int toolid) const;
386
387 virtual void SetToolShortHelp(int toolid, const wxString& helpString);
388 virtual wxString GetToolShortHelp(int toolid) const;
389 virtual void SetToolLongHelp(int toolid, const wxString& helpString);
390 virtual wxString GetToolLongHelp(int toolid) const;
391
392 virtual void SetToolNormalBitmap(int WXUNUSED(id),
393 const wxBitmap& WXUNUSED(bitmap)) {}
394 virtual void SetToolDisabledBitmap(int WXUNUSED(id),
395 const wxBitmap& WXUNUSED(bitmap)) {}
396
397
398 // margins/packing/separation
399 // --------------------------
400
401 virtual void SetMargins(int x, int y);
402 void SetMargins(const wxSize& size)
403 { SetMargins((int) size.x, (int) size.y); }
404 virtual void SetToolPacking(int packing)
405 { m_toolPacking = packing; }
406 virtual void SetToolSeparation(int separation)
407 { m_toolSeparation = separation; }
408
409 virtual wxSize GetToolMargins() const { return wxSize(m_xMargin, m_yMargin); }
410 virtual int GetToolPacking() const { return m_toolPacking; }
411 virtual int GetToolSeparation() const { return m_toolSeparation; }
412
413 // toolbar geometry
414 // ----------------
415
416 // set the number of toolbar rows
417 virtual void SetRows(int nRows);
418
419 // the toolbar can wrap - limit the number of columns or rows it may take
420 void SetMaxRowsCols(int rows, int cols)
421 { m_maxRows = rows; m_maxCols = cols; }
422 int GetMaxRows() const { return m_maxRows; }
423 int GetMaxCols() const { return m_maxCols; }
424
425 // get/set the size of the bitmaps used by the toolbar: should be called
426 // before adding any tools to the toolbar
427 virtual void SetToolBitmapSize(const wxSize& size)
428 { m_defaultWidth = size.x; m_defaultHeight = size.y; }
429 virtual wxSize GetToolBitmapSize() const
430 { return wxSize(m_defaultWidth, m_defaultHeight); }
431
432 // the button size in some implementations is bigger than the bitmap size:
433 // get the total button size (by default the same as bitmap size)
434 virtual wxSize GetToolSize() const
435 { return GetToolBitmapSize(); }
436
437 // returns a (non separator) tool containing the point (x, y) or NULL if
438 // there is no tool at this point (corrdinates are client)
439 virtual wxToolBarToolBase *FindToolForPosition(wxCoord x,
440 wxCoord y) const = 0;
441
442 // find the tool by id
443 wxToolBarToolBase *FindById(int toolid) const;
444
445 // return true if this is a vertical toolbar, otherwise false
446 bool IsVertical() const { return HasFlag(wxTB_LEFT | wxTB_RIGHT); }
447
448
449 // the old versions of the various methods kept for compatibility
450 // don't use in the new code!
451 // --------------------------------------------------------------
452
453 wxToolBarToolBase *AddTool(int toolid,
454 const wxBitmap& bitmap,
455 const wxBitmap& bmpDisabled,
456 bool toggle = false,
457 wxObject *clientData = NULL,
458 const wxString& shortHelpString = wxEmptyString,
459 const wxString& longHelpString = wxEmptyString)
460 {
461 return AddTool(toolid, wxEmptyString,
462 bitmap, bmpDisabled,
463 toggle ? wxITEM_CHECK : wxITEM_NORMAL,
464 shortHelpString, longHelpString, clientData);
465 }
466
467 wxToolBarToolBase *AddTool(int toolid,
468 const wxBitmap& bitmap,
469 const wxString& shortHelpString = wxEmptyString,
470 const wxString& longHelpString = wxEmptyString)
471 {
472 return AddTool(toolid, wxEmptyString,
473 bitmap, wxNullBitmap, wxITEM_NORMAL,
474 shortHelpString, longHelpString, NULL);
475 }
476
477 wxToolBarToolBase *AddTool(int toolid,
478 const wxBitmap& bitmap,
479 const wxBitmap& bmpDisabled,
480 bool toggle,
481 wxCoord xPos,
482 wxCoord yPos = wxDefaultCoord,
483 wxObject *clientData = NULL,
484 const wxString& shortHelp = wxEmptyString,
485 const wxString& longHelp = wxEmptyString)
486 {
487 return DoAddTool(toolid, wxEmptyString, bitmap, bmpDisabled,
488 toggle ? wxITEM_CHECK : wxITEM_NORMAL,
489 shortHelp, longHelp, clientData, xPos, yPos);
490 }
491
492 wxToolBarToolBase *InsertTool(size_t pos,
493 int toolid,
494 const wxBitmap& bitmap,
495 const wxBitmap& bmpDisabled = wxNullBitmap,
496 bool toggle = false,
497 wxObject *clientData = NULL,
498 const wxString& shortHelp = wxEmptyString,
499 const wxString& longHelp = wxEmptyString)
500 {
501 return InsertTool(pos, toolid, wxEmptyString, bitmap, bmpDisabled,
502 toggle ? wxITEM_CHECK : wxITEM_NORMAL,
503 shortHelp, longHelp, clientData);
504 }
505
506 // event handlers
507 // --------------
508
509 // NB: these functions are deprecated, use EVT_TOOL_XXX() instead!
510
511 // Only allow toggle if returns true. Call when left button up.
512 virtual bool OnLeftClick(int toolid, bool toggleDown);
513
514 // Call when right button down.
515 virtual void OnRightClick(int toolid, long x, long y);
516
517 // Called when the mouse cursor enters a tool bitmap.
518 // Argument is wxID_ANY if mouse is exiting the toolbar.
519 virtual void OnMouseEnter(int toolid);
520
521 // more deprecated functions
522 // -------------------------
523
524 // use GetToolMargins() instead
525 wxSize GetMargins() const { return GetToolMargins(); }
526
527 // implementation only from now on
528 // -------------------------------
529
530 size_t GetToolsCount() const { return m_tools.GetCount(); }
531
532 // Do the toolbar button updates (check for EVT_UPDATE_UI handlers)
533 virtual void UpdateWindowUI(long flags = wxUPDATE_UI_NONE) ;
534
535 // don't want toolbars to accept the focus
536 virtual bool AcceptsFocus() const { return false; }
537
538 // Set dropdown menu
539 bool SetDropdownMenu(int toolid, wxMenu *menu);
540
541 protected:
542 // to implement in derived classes
543 // -------------------------------
544
545 // create a new toolbar tool and add it to the toolbar, this is typically
546 // implemented by just calling InsertTool()
547 virtual wxToolBarToolBase *DoAddTool
548 (
549 int toolid,
550 const wxString& label,
551 const wxBitmap& bitmap,
552 const wxBitmap& bmpDisabled,
553 wxItemKind kind,
554 const wxString& shortHelp = wxEmptyString,
555 const wxString& longHelp = wxEmptyString,
556 wxObject *clientData = NULL,
557 wxCoord xPos = wxDefaultCoord,
558 wxCoord yPos = wxDefaultCoord
559 );
560
561 // the tool is not yet inserted into m_tools list when this function is
562 // called and will only be added to it if this function succeeds
563 virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool) = 0;
564
565 // the tool is still in m_tools list when this function is called, it will
566 // only be deleted from it if it succeeds
567 virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool) = 0;
568
569 // called when the tools enabled flag changes
570 virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable) = 0;
571
572 // called when the tool is toggled
573 virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle) = 0;
574
575 // called when the tools "can be toggled" flag changes
576 virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle) = 0;
577
578 // the functions to create toolbar tools
579 virtual wxToolBarToolBase *CreateTool(int toolid,
580 const wxString& label,
581 const wxBitmap& bmpNormal,
582 const wxBitmap& bmpDisabled,
583 wxItemKind kind,
584 wxObject *clientData,
585 const wxString& shortHelp,
586 const wxString& longHelp) = 0;
587
588 virtual wxToolBarToolBase *CreateTool(wxControl *control,
589 const wxString& label) = 0;
590
591 // helper functions
592 // ----------------
593
594 // call this from derived class ctor/Create() to ensure that we have either
595 // wxTB_HORIZONTAL or wxTB_VERTICAL style, there is a lot of existing code
596 // which randomly checks either one or the other of them and gets confused
597 // if neither is set (and making one of them 0 is not an option neither as
598 // then the existing tests would break down)
599 void FixupStyle();
600
601 // un-toggle all buttons in the same radio group
602 void UnToggleRadioGroup(wxToolBarToolBase *tool);
603
604 // the list of all our tools
605 wxToolBarToolsList m_tools;
606
607 // the offset of the first tool
608 int m_xMargin;
609 int m_yMargin;
610
611 // the maximum number of toolbar rows/columns
612 int m_maxRows;
613 int m_maxCols;
614
615 // the tool packing and separation
616 int m_toolPacking,
617 m_toolSeparation;
618
619 // the size of the toolbar bitmaps
620 wxCoord m_defaultWidth, m_defaultHeight;
621
622 private:
623 DECLARE_EVENT_TABLE()
624 DECLARE_NO_COPY_CLASS(wxToolBarBase)
625 };
626
627 // deprecated function for creating the image for disabled buttons, use
628 // wxImage::ConvertToGreyscale() instead
629 #if WXWIN_COMPATIBILITY_2_8
630
631 wxDEPRECATED( bool wxCreateGreyedImage(const wxImage& in, wxImage& out) );
632
633 #endif // WXWIN_COMPATIBILITY_2_8
634
635
636 #endif // wxUSE_TOOLBAR
637
638 #endif
639 // _WX_TBARBASE_H_
640