]> git.saurik.com Git - wxWidgets.git/blob - include/wx/propgrid/editors.h
hook the docview-specific customization of event handling logic at TryValidator(...
[wxWidgets.git] / include / wx / propgrid / editors.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/propgrid/editors.h
3 // Purpose: wxPropertyGrid editors
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 2007-04-14
7 // RCS-ID: $Id:
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_PROPGRID_EDITORS_H_
13 #define _WX_PROPGRID_EDITORS_H_
14
15 #if wxUSE_PROPGRID
16
17 // -----------------------------------------------------------------------
18 // wxPGWindowList contains list of editor windows returned by CreateControls.
19
20 class wxPGWindowList
21 {
22 public:
23 wxPGWindowList()
24 {
25 m_primary = m_secondary = NULL;
26 }
27
28 void SetSecondary( wxWindow* secondary ) { m_secondary = secondary; }
29
30 wxWindow* m_primary;
31 wxWindow* m_secondary;
32
33 #ifndef SWIG
34 wxPGWindowList( wxWindow* a )
35 {
36 m_primary = a;
37 m_secondary = NULL;
38 };
39 wxPGWindowList( wxWindow* a, wxWindow* b )
40 {
41 m_primary = a;
42 m_secondary = b;
43 };
44 #endif
45 };
46
47 // -----------------------------------------------------------------------
48
49 /** @class wxPGEditor
50
51 Base class for custom wxPropertyGrid editors.
52
53 @remarks
54 - Names of builtin property editors are: TextCtrl, Choice,
55 ComboBox, CheckBox, TextCtrlAndButton, and ChoiceAndButton. Additional
56 editors include SpinCtrl and DatePickerCtrl, but using them requires
57 calling wxPropertyGrid::RegisterAdditionalEditors() prior use.
58
59 - Pointer to builtin editor is available as wxPGEditor_EditorName
60 (eg. wxPGEditor_TextCtrl).
61
62 - To add new editor you need to register it first using static function
63 wxPropertyGrid::RegisterEditorClass(), with code like this:
64 @code
65 wxPGEditor *editorPointer = wxPropertyGrid::RegisterEditorClass(
66 new MyEditorClass(), "MyEditor");
67 @endcode
68 After that, wxPropertyGrid will take ownership of the given object, but
69 you should still store editorPointer somewhere, so you can pass it to
70 wxPGProperty::SetEditor(), or return it from
71 wxPGEditor::DoGetEditorClass().
72
73 @library{wxpropgrid}
74 @category{propgrid}
75 */
76 class WXDLLIMPEXP_PROPGRID wxPGEditor : public wxObject
77 {
78 #ifndef SWIG
79 DECLARE_ABSTRACT_CLASS(wxPGEditor)
80 #endif
81 public:
82
83 /** Constructor. */
84 wxPGEditor()
85 : wxObject()
86 {
87 m_clientData = NULL;
88 }
89
90 /** Destructor. */
91 virtual ~wxPGEditor();
92
93 /**
94 Returns pointer to the name of the editor. For example,
95 wxPG_EDITOR(TextCtrl) has name "TextCtrl". This method is autogenerated
96 for custom editors.
97 */
98 virtual wxString GetName() const = 0;
99
100 /**
101 Instantiates editor controls.
102
103 @param propgrid
104 wxPropertyGrid to which the property belongs (use as parent for
105 control).
106 @param property
107 Property for which this method is called.
108 @param pos
109 Position, inside wxPropertyGrid, to create control(s) to.
110 @param size
111 Initial size for control(s).
112
113 @remarks
114 - Primary control shall use id wxPG_SUBID1, and secondary (button)
115 control shall use wxPG_SUBID2.
116 - Implementation shoud use connect all necessary events to the
117 wxPropertyGrid::OnCustomEditorEvent. For Example:
118 @code
119 // Relays wxEVT_COMMAND_TEXT_UPDATED events of primary editor
120 // control to the OnEvent.
121 // NOTE: This event in particular is actually automatically
122 // conveyed, but it is just used as an example.
123 propgrid->Connect(wxPG_SUBID1, wxEVT_COMMAND_TEXT_UPDATED,
124 wxCommandEventHandler(
125 wxPropertyGrid::OnCustomEditorEvent));
126 @endcode
127 OnCustomEditorEvent will then forward events, first to
128 wxPGEditor::OnEvent and then to wxPGProperty::OnEvent.
129
130 */
131 virtual wxPGWindowList CreateControls(wxPropertyGrid* propgrid,
132 wxPGProperty* property,
133 const wxPoint& pos,
134 const wxSize& size) const = 0;
135 #define wxPG_DECLARE_CREATECONTROLS \
136 virtual wxPGWindowList \
137 CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property, \
138 const wxPoint& pos, const wxSize& sz ) const;
139
140 /** Loads value from property to the control. */
141 virtual void UpdateControl( wxPGProperty* property,
142 wxWindow* ctrl ) const = 0;
143
144 /**
145 Used to get the renderer to draw the value with when the control is
146 hidden.
147
148 Default implementation returns g_wxPGDefaultRenderer.
149 */
150 //virtual wxPGCellRenderer* GetCellRenderer() const;
151
152 /** Draws value for given property.
153 */
154 virtual void DrawValue( wxDC& dc,
155 const wxRect& rect,
156 wxPGProperty* property,
157 const wxString& text ) const;
158
159 /** Handles events. Returns true if value in control was modified
160 (see wxPGProperty::OnEvent for more information).
161 */
162 virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
163 wxWindow* wnd_primary, wxEvent& event ) const = 0;
164
165 #if !defined(SWIG) || defined(CREATE_VCW)
166 /** Returns value from control, via parameter 'variant'.
167 Usually ends up calling property's StringToValue or IntToValue.
168 Returns true if value was different.
169 */
170 virtual bool GetValueFromControl( wxVariant& variant,
171 wxPGProperty* property,
172 wxWindow* ctrl ) const;
173 #endif
174
175 /** Sets value in control to unspecified. */
176 virtual void SetValueToUnspecified( wxPGProperty* property,
177 wxWindow* ctrl ) const = 0;
178
179 /** Sets control's value specifically from string. */
180 virtual void SetControlStringValue( wxPGProperty* property,
181 wxWindow* ctrl,
182 const wxString& txt ) const;
183
184 /** Sets control's value specifically from int (applies to choice etc.). */
185 virtual void SetControlIntValue( wxPGProperty* property,
186 wxWindow* ctrl,
187 int value ) const;
188
189 /** Inserts item to existing control. Index -1 means appending.
190 Default implementation does nothing. Returns index of item added.
191 */
192 virtual int InsertItem( wxWindow* ctrl,
193 const wxString& label,
194 int index ) const;
195
196 /** Deletes item from existing control.
197 Default implementation does nothing.
198 */
199 virtual void DeleteItem( wxWindow* ctrl, int index ) const;
200
201 /** Extra processing when control gains focus. For example, wxTextCtrl
202 based controls should select all text.
203 */
204 virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const;
205
206 /** Returns true if control itself can contain the custom image. Default is
207 to return false.
208 */
209 virtual bool CanContainCustomImage() const;
210
211 //
212 // This member is public so scripting language bindings
213 // wrapper code can access it freely.
214 void* m_clientData;
215 };
216
217
218 //
219 // Note that we don't use this macro in this file because
220 // otherwise doxygen gets confused.
221 //
222 #define WX_PG_DECLARE_EDITOR_CLASS(CLASSNAME) \
223 DECLARE_DYNAMIC_CLASS(CLASSNAME) \
224 public: \
225 virtual wxString GetName() const; \
226 private:
227
228
229 #define WX_PG_IMPLEMENT_EDITOR_CLASS(EDITOR,CLASSNAME,BASECLASS) \
230 IMPLEMENT_DYNAMIC_CLASS(CLASSNAME, BASECLASS) \
231 wxString CLASSNAME::GetName() const \
232 { \
233 return wxS(#EDITOR); \
234 } \
235 wxPGEditor* wxPGEditor_##EDITOR = (wxPGEditor*) NULL; \
236 wxPGEditor* wxPGConstruct##EDITOR##EditorClass() \
237 { \
238 wxASSERT( !wxPGEditor_##EDITOR ); \
239 return new CLASSNAME(); \
240 }
241
242
243 #define WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS() \
244 wxPG_DECLARE_CREATECONTROLS \
245 virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const; \
246 virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property, \
247 wxWindow* primary, wxEvent& event ) const; \
248 virtual bool GetValueFromControl( wxVariant& variant, \
249 wxPGProperty* property, \
250 wxWindow* ctrl ) const; \
251 virtual void SetValueToUnspecified( wxPGProperty* property, \
252 wxWindow* ctrl ) const;
253
254
255 //
256 // Following are the built-in editor classes.
257 //
258
259 class WXDLLIMPEXP_PROPGRID wxPGTextCtrlEditor : public wxPGEditor
260 {
261 #ifndef SWIG
262 DECLARE_DYNAMIC_CLASS(wxPGTextCtrlEditor)
263 #endif
264 public:
265 wxPGTextCtrlEditor() {}
266 virtual ~wxPGTextCtrlEditor();
267
268 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
269 virtual wxString GetName() const;
270
271 //virtual wxPGCellRenderer* GetCellRenderer() const;
272 virtual void SetControlStringValue( wxPGProperty* property,
273 wxWindow* ctrl,
274 const wxString& txt ) const;
275 virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const;
276
277 // Provided so that, for example, ComboBox editor can use the same code
278 // (multiple inheritance would get way too messy).
279 static bool OnTextCtrlEvent( wxPropertyGrid* propgrid,
280 wxPGProperty* property,
281 wxWindow* ctrl,
282 wxEvent& event );
283
284 static bool GetTextCtrlValueFromControl( wxVariant& variant,
285 wxPGProperty* property,
286 wxWindow* ctrl );
287
288 };
289
290
291 class WXDLLIMPEXP_PROPGRID wxPGChoiceEditor : public wxPGEditor
292 {
293 #ifndef SWIG
294 DECLARE_DYNAMIC_CLASS(wxPGChoiceEditor)
295 #endif
296 public:
297 wxPGChoiceEditor() {}
298 virtual ~wxPGChoiceEditor();
299
300 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
301 virtual wxString GetName() const;
302
303 virtual void SetControlIntValue( wxPGProperty* property,
304 wxWindow* ctrl,
305 int value ) const;
306 virtual void SetControlStringValue( wxPGProperty* property,
307 wxWindow* ctrl,
308 const wxString& txt ) const;
309
310 virtual int InsertItem( wxWindow* ctrl,
311 const wxString& label,
312 int index ) const;
313 virtual void DeleteItem( wxWindow* ctrl, int index ) const;
314 virtual bool CanContainCustomImage() const;
315
316 // CreateControls calls this with CB_READONLY in extraStyle
317 wxWindow* CreateControlsBase( wxPropertyGrid* propgrid,
318 wxPGProperty* property,
319 const wxPoint& pos,
320 const wxSize& sz,
321 long extraStyle ) const;
322
323 };
324
325
326 class WXDLLIMPEXP_PROPGRID wxPGComboBoxEditor : public wxPGChoiceEditor
327 {
328 #ifndef SWIG
329 DECLARE_DYNAMIC_CLASS(wxPGComboBoxEditor)
330 #endif
331 public:
332 wxPGComboBoxEditor() {}
333 virtual ~wxPGComboBoxEditor();
334
335 // Macro is used for convenience due to different signature with wxPython
336 wxPG_DECLARE_CREATECONTROLS
337
338 virtual wxString GetName() const;
339
340 virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const;
341
342 virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
343 wxWindow* ctrl, wxEvent& event ) const;
344
345 virtual bool GetValueFromControl( wxVariant& variant,
346 wxPGProperty* property,
347 wxWindow* ctrl ) const;
348
349 virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const;
350
351 };
352
353
354 // Exclude classes from being able to be derived from in wxPython bindings
355 #ifndef SWIG
356
357 class WXDLLIMPEXP_PROPGRID wxPGChoiceAndButtonEditor : public wxPGChoiceEditor
358 {
359 public:
360 wxPGChoiceAndButtonEditor() {}
361 virtual ~wxPGChoiceAndButtonEditor();
362 virtual wxString GetName() const;
363
364 // Macro is used for convenience due to different signature with wxPython
365 wxPG_DECLARE_CREATECONTROLS
366
367 DECLARE_DYNAMIC_CLASS(wxPGChoiceAndButtonEditor)
368 };
369
370 class WXDLLIMPEXP_PROPGRID
371 wxPGTextCtrlAndButtonEditor : public wxPGTextCtrlEditor
372 {
373 public:
374 wxPGTextCtrlAndButtonEditor() {}
375 virtual ~wxPGTextCtrlAndButtonEditor();
376 virtual wxString GetName() const;
377 wxPG_DECLARE_CREATECONTROLS
378
379 DECLARE_DYNAMIC_CLASS(wxPGTextCtrlAndButtonEditor)
380 };
381
382 #endif // !SWIG
383
384
385 #if wxPG_INCLUDE_CHECKBOX || defined(DOXYGEN)
386
387 //
388 // Use custom check box code instead of native control
389 // for cleaner (ie. more integrated) look.
390 //
391 class WXDLLIMPEXP_PROPGRID wxPGCheckBoxEditor : public wxPGEditor
392 {
393 #ifndef SWIG
394 DECLARE_DYNAMIC_CLASS(wxPGCheckBoxEditor)
395 #endif
396 public:
397 wxPGCheckBoxEditor() {}
398 virtual ~wxPGCheckBoxEditor();
399
400 virtual wxString GetName() const;
401 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
402
403 virtual void DrawValue( wxDC& dc,
404 const wxRect& rect,
405 wxPGProperty* property,
406 const wxString& text ) const;
407 //virtual wxPGCellRenderer* GetCellRenderer() const;
408
409 virtual void SetControlIntValue( wxPGProperty* property,
410 wxWindow* ctrl,
411 int value ) const;
412 };
413
414 #endif
415
416
417 // -----------------------------------------------------------------------
418 // Editor class registeration macros
419
420 #define wxPGRegisterEditorClass(EDITOR) \
421 if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
422 { \
423 wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
424 wxPGConstruct##EDITOR##EditorClass(), wxS(#EDITOR) ); \
425 }
426
427 // Use this in RegisterDefaultEditors.
428 #define wxPGRegisterDefaultEditorClass(EDITOR) \
429 if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
430 { \
431 wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
432 wxPGConstruct##EDITOR##EditorClass(), wxS(#EDITOR), true ); \
433 }
434
435 #define wxPG_INIT_REQUIRED_EDITOR(T) \
436 wxPGRegisterEditorClass(T)
437
438
439 // -----------------------------------------------------------------------
440
441 /** @class wxPGEditorDialogAdapter
442
443 Derive a class from this to adapt an existing editor dialog or function to
444 be used when editor button of a property is pushed.
445
446 You only need to derive class and implement DoShowDialog() to create and
447 show the dialog, and finally submit the value returned by the dialog
448 via SetValue().
449
450 @library{wxpropgrid}
451 @category{propgrid}
452 */
453 class WXDLLIMPEXP_PROPGRID wxPGEditorDialogAdapter : public wxObject
454 {
455 #ifndef SWIG
456 DECLARE_ABSTRACT_CLASS(wxPGEditorDialogAdapter)
457 #endif
458 public:
459 wxPGEditorDialogAdapter()
460 : wxObject()
461 {
462 m_clientData = NULL;
463 }
464
465 virtual ~wxPGEditorDialogAdapter() { }
466
467 bool ShowDialog( wxPropertyGrid* propGrid, wxPGProperty* property );
468
469 virtual bool DoShowDialog( wxPropertyGrid* propGrid,
470 wxPGProperty* property ) = 0;
471
472 void SetValue( wxVariant value )
473 {
474 m_value = value;
475 }
476
477 /**
478 This method is typically only used if deriving class from existing
479 adapter with value conversion purposes.
480 */
481 wxVariant& GetValue() { return m_value; }
482
483 //
484 // This member is public so scripting language bindings
485 // wrapper code can access it freely.
486 void* m_clientData;
487
488 private:
489 wxVariant m_value;
490 };
491
492 // -----------------------------------------------------------------------
493
494
495 /** @class wxPGMultiButton
496
497 This class can be used to have multiple buttons in a property editor.
498 You will need to create a new property editor class, override
499 CreateControls, and have it return wxPGMultiButton instance in
500 wxPGWindowList::SetSecondary(). For instance, here we add three buttons to
501 a textctrl editor:
502
503 @code
504
505 #include <wx/propgrid/editors.h>
506
507 class wxMultiButtonTextCtrlEditor : public wxPGTextCtrlEditor
508 {
509 WX_PG_DECLARE_EDITOR_CLASS(wxMultiButtonTextCtrlEditor)
510 public:
511 wxMultiButtonTextCtrlEditor() {}
512 virtual ~wxMultiButtonTextCtrlEditor() {}
513
514 wxPG_DECLARE_CREATECONTROLS
515 virtual bool OnEvent( wxPropertyGrid* propGrid,
516 wxPGProperty* property,
517 wxWindow* ctrl,
518 wxEvent& event ) const;
519
520 };
521
522 WX_PG_IMPLEMENT_EDITOR_CLASS(MultiButtonTextCtrlEditor,
523 wxMultiButtonTextCtrlEditor,
524 wxPGTextCtrlEditor)
525
526 wxPGWindowList
527 wxMultiButtonTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid,
528 wxPGProperty* property,
529 const wxPoint& pos,
530 const wxSize& sz ) const
531 {
532 // Create and populate buttons-subwindow
533 wxPGMultiButton* buttons = new wxPGMultiButton( propGrid, sz );
534
535 // Add two regular buttons
536 buttons->Add( "..." );
537 buttons->Add( "A" );
538 // Add a bitmap button
539 buttons->Add( wxArtProvider::GetBitmap(wxART_FOLDER) );
540
541 // Create the 'primary' editor control (textctrl in this case)
542 wxPGWindowList wndList = wxPGTextCtrlEditor::CreateControls(
543 propGrid,
544 property,
545 pos,
546 buttons->GetPrimarySize()
547 );
548
549 // Finally, move buttons-subwindow to correct position and make sure
550 // returned wxPGWindowList contains our custom button list.
551 buttons->FinalizePosition(pos);
552
553 wndList.SetSecondary( buttons );
554 return wndList;
555 }
556
557 bool wxMultiButtonTextCtrlEditor::OnEvent( wxPropertyGrid* propGrid,
558 wxPGProperty* property,
559 wxWindow* ctrl,
560 wxEvent& event ) const
561 {
562 if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
563 {
564 wxPGMultiButton* buttons = (wxPGMultiButton*)
565 propGrid->GetEditorControlSecondary();
566
567 if ( event.GetId() == buttons->GetButtonId(0) )
568 {
569 // Do something when first button is pressed
570 return true;
571 }
572 if ( event.GetId() == buttons->GetButtonId(1) )
573 {
574 // Do something when first button is pressed
575 return true;
576 }
577 if ( event.GetId() == buttons->GetButtonId(2) )
578 {
579 // Do something when second button is pressed
580 return true;
581 }
582 }
583 return wxPGTextCtrlEditor::OnEvent(propGrid, property, ctrl, event);
584 }
585
586 @endcode
587
588 Further to use this editor, code like this can be used:
589
590 @code
591
592 // Register editor class - needs only to be called once
593 wxPGRegisterEditorClass( MultiButtonTextCtrlEditor );
594
595 // Insert the property that will have multiple buttons
596 propGrid->Append( new wxLongStringProperty("MultipleButtons",
597 wxPG_LABEL) );
598
599 // Change property to use editor created in the previous code segment
600 propGrid->SetPropertyEditor( "MultipleButtons",
601 wxPG_EDITOR(MultiButtonTextCtrlEditor) );
602
603 @endcode
604
605 @library{wxpropgrid}
606 @category{propgrid}
607 */
608 class WXDLLIMPEXP_PROPGRID wxPGMultiButton : public wxWindow
609 {
610 public:
611 wxPGMultiButton( wxPropertyGrid* pg, const wxSize& sz );
612
613 wxWindow* GetButton( unsigned int i ) { return (wxWindow*) m_buttons[i]; }
614 const wxWindow* GetButton( unsigned int i ) const
615 { return (const wxWindow*) m_buttons[i]; }
616
617 /** Utility function to be used in event handlers.
618 */
619 int GetButtonId( unsigned int i ) const { return GetButton(i)->GetId(); }
620
621 /** Returns number of buttons.
622 */
623 int GetCount() const { return m_buttons.Count(); }
624
625 void Add( const wxString& label, int id = -2 );
626 #if wxUSE_BMPBUTTON
627 void Add( const wxBitmap& bitmap, int id = -2 );
628 #endif
629
630 wxSize GetPrimarySize() const
631 {
632 return wxSize(m_fullEditorSize.x - m_buttonsWidth, m_fullEditorSize.y);
633 }
634
635 void FinalizePosition( const wxPoint& pos )
636 {
637 Move( pos.x + m_fullEditorSize.x - m_buttonsWidth, pos.y );
638 }
639
640 #ifndef DOXYGEN
641 protected:
642
643 int GenId( int id ) const;
644
645 wxArrayPtrVoid m_buttons;
646 wxSize m_fullEditorSize;
647 int m_buttonsWidth;
648 #endif // !DOXYGEN
649 };
650
651 // -----------------------------------------------------------------------
652
653 #endif // wxUSE_PROPGRID
654
655 #endif // _WX_PROPGRID_EDITORS_H_