1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/propgrid/editors.h
3 // Purpose: wxPropertyGrid editors
4 // Author: Jaakko Salli
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_PROPGRID_EDITORS_H_
13 #define _WX_PROPGRID_EDITORS_H_
17 // -----------------------------------------------------------------------
18 // wxPGWindowList contains list of editor windows returned by CreateControls.
25 m_primary
= m_secondary
= NULL
;
28 void SetSecondary( wxWindow
* secondary
) { m_secondary
= secondary
; }
31 wxWindow
* m_secondary
;
34 wxPGWindowList( wxWindow
* a
)
39 wxPGWindowList( wxWindow
* a
, wxWindow
* b
)
47 // -----------------------------------------------------------------------
51 Base class for custom wxPropertyGrid editors.
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.
59 - Pointer to builtin editor is available as wxPGEditor_EditorName
60 (eg. wxPGEditor_TextCtrl).
62 - To add new editor you need to register it first using static function
63 wxPropertyGrid::RegisterEditorClass(), with code like this:
65 wxPGEditor *editorPointer = wxPropertyGrid::RegisterEditorClass(
66 new MyEditorClass(), "MyEditor");
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().
76 class WXDLLIMPEXP_PROPGRID wxPGEditor
: public wxObject
79 DECLARE_ABSTRACT_CLASS(wxPGEditor
)
91 virtual ~wxPGEditor();
94 Returns pointer to the name of the editor. For example,
95 wxPG_EDITOR(TextCtrl) has name "TextCtrl". This method is autogenerated
98 virtual wxString
GetName() const = 0;
101 Instantiates editor controls.
104 wxPropertyGrid to which the property belongs (use as parent for
107 Property for which this method is called.
109 Position, inside wxPropertyGrid, to create control(s) to.
111 Initial size for control(s).
114 - Primary control shall use id wxPG_SUBID1, and secondary (button)
115 control shall use wxPG_SUBID2.
116 - Implementation shoud connect all necessary events to the
117 wxPropertyGrid::OnCustomEditorEvent. For Example:
119 // Relays wxEVT_COMMAND_TEXT_UPDATED events of primary editor
120 // control to the OnEvent.
121 propgrid->Connect(control->GetId(), wxEVT_COMMAND_TEXT_UPDATED,
122 wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent));
124 OnCustomEditorEvent will then forward events, first to
125 wxPGEditor::OnEvent() and then to wxPGProperty::OnEvent().
127 virtual wxPGWindowList
CreateControls(wxPropertyGrid
* propgrid
,
128 wxPGProperty
* property
,
130 const wxSize
& size
) const = 0;
131 #define wxPG_DECLARE_CREATECONTROLS \
132 virtual wxPGWindowList \
133 CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property, \
134 const wxPoint& pos, const wxSize& sz ) const;
136 /** Loads value from property to the control. */
137 virtual void UpdateControl( wxPGProperty
* property
,
138 wxWindow
* ctrl
) const = 0;
141 Used to get the renderer to draw the value with when the control is
144 Default implementation returns g_wxPGDefaultRenderer.
146 //virtual wxPGCellRenderer* GetCellRenderer() const;
148 /** Draws value for given property.
150 virtual void DrawValue( wxDC
& dc
,
152 wxPGProperty
* property
,
153 const wxString
& text
) const;
155 /** Handles events. Returns true if value in control was modified
156 (see wxPGProperty::OnEvent for more information).
158 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
159 wxWindow
* wnd_primary
, wxEvent
& event
) const = 0;
161 #if !defined(SWIG) || defined(CREATE_VCW)
162 /** Returns value from control, via parameter 'variant'.
163 Usually ends up calling property's StringToValue or IntToValue.
164 Returns true if value was different.
166 virtual bool GetValueFromControl( wxVariant
& variant
,
167 wxPGProperty
* property
,
168 wxWindow
* ctrl
) const;
171 /** Sets value in control to unspecified. */
172 virtual void SetValueToUnspecified( wxPGProperty
* property
,
173 wxWindow
* ctrl
) const = 0;
175 /** Sets control's value specifically from string. */
176 virtual void SetControlStringValue( wxPGProperty
* property
,
178 const wxString
& txt
) const;
180 /** Sets control's value specifically from int (applies to choice etc.). */
181 virtual void SetControlIntValue( wxPGProperty
* property
,
185 /** Inserts item to existing control. Index -1 means appending.
186 Default implementation does nothing. Returns index of item added.
188 virtual int InsertItem( wxWindow
* ctrl
,
189 const wxString
& label
,
192 /** Deletes item from existing control.
193 Default implementation does nothing.
195 virtual void DeleteItem( wxWindow
* ctrl
, int index
) const;
197 /** Extra processing when control gains focus. For example, wxTextCtrl
198 based controls should select all text.
200 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
202 /** Returns true if control itself can contain the custom image. Default is
205 virtual bool CanContainCustomImage() const;
208 // This member is public so scripting language bindings
209 // wrapper code can access it freely.
215 // Note that we don't use this macro in this file because
216 // otherwise doxygen gets confused.
218 #define WX_PG_DECLARE_EDITOR_CLASS(CLASSNAME) \
219 DECLARE_DYNAMIC_CLASS(CLASSNAME) \
221 virtual wxString GetName() const; \
225 #define WX_PG_IMPLEMENT_EDITOR_CLASS(EDITOR,CLASSNAME,BASECLASS) \
226 IMPLEMENT_DYNAMIC_CLASS(CLASSNAME, BASECLASS) \
227 wxString CLASSNAME::GetName() const \
229 return wxS(#EDITOR); \
231 wxPGEditor* wxPGEditor_##EDITOR = (wxPGEditor*) NULL; \
232 wxPGEditor* wxPGConstruct##EDITOR##EditorClass() \
234 wxASSERT( !wxPGEditor_##EDITOR ); \
235 return new CLASSNAME(); \
239 #define WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS() \
240 wxPG_DECLARE_CREATECONTROLS \
241 virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const; \
242 virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property, \
243 wxWindow* primary, wxEvent& event ) const; \
244 virtual bool GetValueFromControl( wxVariant& variant, \
245 wxPGProperty* property, \
246 wxWindow* ctrl ) const; \
247 virtual void SetValueToUnspecified( wxPGProperty* property, \
248 wxWindow* ctrl ) const;
252 // Following are the built-in editor classes.
255 class WXDLLIMPEXP_PROPGRID wxPGTextCtrlEditor
: public wxPGEditor
258 DECLARE_DYNAMIC_CLASS(wxPGTextCtrlEditor
)
261 wxPGTextCtrlEditor() {}
262 virtual ~wxPGTextCtrlEditor();
264 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
265 virtual wxString
GetName() const;
267 //virtual wxPGCellRenderer* GetCellRenderer() const;
268 virtual void SetControlStringValue( wxPGProperty
* property
,
270 const wxString
& txt
) const;
271 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
273 // Provided so that, for example, ComboBox editor can use the same code
274 // (multiple inheritance would get way too messy).
275 static bool OnTextCtrlEvent( wxPropertyGrid
* propgrid
,
276 wxPGProperty
* property
,
280 static bool GetTextCtrlValueFromControl( wxVariant
& variant
,
281 wxPGProperty
* property
,
287 class WXDLLIMPEXP_PROPGRID wxPGChoiceEditor
: public wxPGEditor
290 DECLARE_DYNAMIC_CLASS(wxPGChoiceEditor
)
293 wxPGChoiceEditor() {}
294 virtual ~wxPGChoiceEditor();
296 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
297 virtual wxString
GetName() const;
299 virtual void SetControlIntValue( wxPGProperty
* property
,
302 virtual void SetControlStringValue( wxPGProperty
* property
,
304 const wxString
& txt
) const;
306 virtual int InsertItem( wxWindow
* ctrl
,
307 const wxString
& label
,
309 virtual void DeleteItem( wxWindow
* ctrl
, int index
) const;
310 virtual bool CanContainCustomImage() const;
312 // CreateControls calls this with CB_READONLY in extraStyle
313 wxWindow
* CreateControlsBase( wxPropertyGrid
* propgrid
,
314 wxPGProperty
* property
,
317 long extraStyle
) const;
322 class WXDLLIMPEXP_PROPGRID wxPGComboBoxEditor
: public wxPGChoiceEditor
325 DECLARE_DYNAMIC_CLASS(wxPGComboBoxEditor
)
328 wxPGComboBoxEditor() {}
329 virtual ~wxPGComboBoxEditor();
331 // Macro is used for convenience due to different signature with wxPython
332 wxPG_DECLARE_CREATECONTROLS
334 virtual wxString
GetName() const;
336 virtual void UpdateControl( wxPGProperty
* property
, wxWindow
* ctrl
) const;
338 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
339 wxWindow
* ctrl
, wxEvent
& event
) const;
341 virtual bool GetValueFromControl( wxVariant
& variant
,
342 wxPGProperty
* property
,
343 wxWindow
* ctrl
) const;
345 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
350 // Exclude classes from being able to be derived from in wxPython bindings
353 class WXDLLIMPEXP_PROPGRID wxPGChoiceAndButtonEditor
: public wxPGChoiceEditor
356 wxPGChoiceAndButtonEditor() {}
357 virtual ~wxPGChoiceAndButtonEditor();
358 virtual wxString
GetName() const;
360 // Macro is used for convenience due to different signature with wxPython
361 wxPG_DECLARE_CREATECONTROLS
363 DECLARE_DYNAMIC_CLASS(wxPGChoiceAndButtonEditor
)
366 class WXDLLIMPEXP_PROPGRID
367 wxPGTextCtrlAndButtonEditor
: public wxPGTextCtrlEditor
370 wxPGTextCtrlAndButtonEditor() {}
371 virtual ~wxPGTextCtrlAndButtonEditor();
372 virtual wxString
GetName() const;
373 wxPG_DECLARE_CREATECONTROLS
375 DECLARE_DYNAMIC_CLASS(wxPGTextCtrlAndButtonEditor
)
381 #if wxPG_INCLUDE_CHECKBOX || defined(DOXYGEN)
384 // Use custom check box code instead of native control
385 // for cleaner (ie. more integrated) look.
387 class WXDLLIMPEXP_PROPGRID wxPGCheckBoxEditor
: public wxPGEditor
390 DECLARE_DYNAMIC_CLASS(wxPGCheckBoxEditor
)
393 wxPGCheckBoxEditor() {}
394 virtual ~wxPGCheckBoxEditor();
396 virtual wxString
GetName() const;
397 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
399 virtual void DrawValue( wxDC
& dc
,
401 wxPGProperty
* property
,
402 const wxString
& text
) const;
403 //virtual wxPGCellRenderer* GetCellRenderer() const;
405 virtual void SetControlIntValue( wxPGProperty
* property
,
413 // -----------------------------------------------------------------------
414 // Editor class registeration macros
416 #define wxPGRegisterEditorClass(EDITOR) \
417 if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
419 wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
420 wxPGConstruct##EDITOR##EditorClass(), wxS(#EDITOR) ); \
423 // Use this in RegisterDefaultEditors.
424 #define wxPGRegisterDefaultEditorClass(EDITOR) \
425 if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
427 wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
428 wxPGConstruct##EDITOR##EditorClass(), wxS(#EDITOR), true ); \
431 #define wxPG_INIT_REQUIRED_EDITOR(T) \
432 wxPGRegisterEditorClass(T)
435 // -----------------------------------------------------------------------
437 /** @class wxPGEditorDialogAdapter
439 Derive a class from this to adapt an existing editor dialog or function to
440 be used when editor button of a property is pushed.
442 You only need to derive class and implement DoShowDialog() to create and
443 show the dialog, and finally submit the value returned by the dialog
449 class WXDLLIMPEXP_PROPGRID wxPGEditorDialogAdapter
: public wxObject
452 DECLARE_ABSTRACT_CLASS(wxPGEditorDialogAdapter
)
455 wxPGEditorDialogAdapter()
461 virtual ~wxPGEditorDialogAdapter() { }
463 bool ShowDialog( wxPropertyGrid
* propGrid
, wxPGProperty
* property
);
465 virtual bool DoShowDialog( wxPropertyGrid
* propGrid
,
466 wxPGProperty
* property
) = 0;
468 void SetValue( wxVariant value
)
474 This method is typically only used if deriving class from existing
475 adapter with value conversion purposes.
477 wxVariant
& GetValue() { return m_value
; }
480 // This member is public so scripting language bindings
481 // wrapper code can access it freely.
488 // -----------------------------------------------------------------------
491 /** @class wxPGMultiButton
493 This class can be used to have multiple buttons in a property editor.
494 You will need to create a new property editor class, override
495 CreateControls, and have it return wxPGMultiButton instance in
496 wxPGWindowList::SetSecondary(). For instance, here we add three buttons to
501 #include <wx/propgrid/editors.h>
503 class wxMultiButtonTextCtrlEditor : public wxPGTextCtrlEditor
505 WX_PG_DECLARE_EDITOR_CLASS(wxMultiButtonTextCtrlEditor)
507 wxMultiButtonTextCtrlEditor() {}
508 virtual ~wxMultiButtonTextCtrlEditor() {}
510 wxPG_DECLARE_CREATECONTROLS
511 virtual bool OnEvent( wxPropertyGrid* propGrid,
512 wxPGProperty* property,
514 wxEvent& event ) const;
518 WX_PG_IMPLEMENT_EDITOR_CLASS(MultiButtonTextCtrlEditor,
519 wxMultiButtonTextCtrlEditor,
523 wxMultiButtonTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid,
524 wxPGProperty* property,
526 const wxSize& sz ) const
528 // Create and populate buttons-subwindow
529 wxPGMultiButton* buttons = new wxPGMultiButton( propGrid, sz );
531 // Add two regular buttons
532 buttons->Add( "..." );
534 // Add a bitmap button
535 buttons->Add( wxArtProvider::GetBitmap(wxART_FOLDER) );
537 // Create the 'primary' editor control (textctrl in this case)
538 wxPGWindowList wndList = wxPGTextCtrlEditor::CreateControls(
542 buttons->GetPrimarySize()
545 // Finally, move buttons-subwindow to correct position and make sure
546 // returned wxPGWindowList contains our custom button list.
547 buttons->FinalizePosition(pos);
549 wndList.SetSecondary( buttons );
553 bool wxMultiButtonTextCtrlEditor::OnEvent( wxPropertyGrid* propGrid,
554 wxPGProperty* property,
556 wxEvent& event ) const
558 if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
560 wxPGMultiButton* buttons = (wxPGMultiButton*)
561 propGrid->GetEditorControlSecondary();
563 if ( event.GetId() == buttons->GetButtonId(0) )
565 // Do something when first button is pressed
568 if ( event.GetId() == buttons->GetButtonId(1) )
570 // Do something when first button is pressed
573 if ( event.GetId() == buttons->GetButtonId(2) )
575 // Do something when second button is pressed
579 return wxPGTextCtrlEditor::OnEvent(propGrid, property, ctrl, event);
584 Further to use this editor, code like this can be used:
588 // Register editor class - needs only to be called once
589 wxPGRegisterEditorClass( MultiButtonTextCtrlEditor );
591 // Insert the property that will have multiple buttons
592 propGrid->Append( new wxLongStringProperty("MultipleButtons",
595 // Change property to use editor created in the previous code segment
596 propGrid->SetPropertyEditor( "MultipleButtons",
597 wxPG_EDITOR(MultiButtonTextCtrlEditor) );
604 class WXDLLIMPEXP_PROPGRID wxPGMultiButton
: public wxWindow
607 wxPGMultiButton( wxPropertyGrid
* pg
, const wxSize
& sz
);
609 wxWindow
* GetButton( unsigned int i
) { return (wxWindow
*) m_buttons
[i
]; }
610 const wxWindow
* GetButton( unsigned int i
) const
611 { return (const wxWindow
*) m_buttons
[i
]; }
613 /** Utility function to be used in event handlers.
615 int GetButtonId( unsigned int i
) const { return GetButton(i
)->GetId(); }
617 /** Returns number of buttons.
619 int GetCount() const { return m_buttons
.Count(); }
621 void Add( const wxString
& label
, int id
= -2 );
623 void Add( const wxBitmap
& bitmap
, int id
= -2 );
626 wxSize
GetPrimarySize() const
628 return wxSize(m_fullEditorSize
.x
- m_buttonsWidth
, m_fullEditorSize
.y
);
631 void FinalizePosition( const wxPoint
& pos
)
633 Move( pos
.x
+ m_fullEditorSize
.x
- m_buttonsWidth
, pos
.y
);
639 int GenId( int id
) const;
641 wxArrayPtrVoid m_buttons
;
642 wxSize m_fullEditorSize
;
647 // -----------------------------------------------------------------------
649 #endif // wxUSE_PROPGRID
651 #endif // _WX_PROPGRID_EDITORS_H_