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_
15 // -----------------------------------------------------------------------
16 // wxPGWindowList contains list of editor windows returned by CreateControls.
23 m_primary
= m_secondary
= NULL
;
26 void SetSecondary( wxWindow
* secondary
) { m_secondary
= secondary
; }
29 wxWindow
* m_secondary
;
32 wxPGWindowList( wxWindow
* a
)
37 wxPGWindowList( wxWindow
* a
, wxWindow
* b
)
45 // -----------------------------------------------------------------------
49 Base class for custom wxPropertyGrid editors.
52 - Names of builtin property editors are: TextCtrl, Choice,
53 ComboBox, CheckBox, TextCtrlAndButton, and ChoiceAndButton. Additional
54 editors include SpinCtrl and DatePickerCtrl, but using them requires
55 calling wxPropertyGrid::RegisterAdditionalEditors() prior use.
57 - Pointer to builtin editor is available as wxPGEditor_EditorName
58 (eg. wxPGEditor_TextCtrl).
60 - To add new editor you need to register it first using static function
61 wxPropertyGrid::RegisterEditorClass(), with code like this:
63 wxPGEditor *editorPointer = wxPropertyGrid::RegisterEditorClass(
64 new MyEditorClass(), "MyEditor");
66 After that, wxPropertyGrid will take ownership of the given object, but
67 you should still store editorPointer somewhere, so you can pass it to
68 wxPGProperty::SetEditor(), or return it from
69 wxPGEditor::DoGetEditorClass().
74 class WXDLLIMPEXP_PROPGRID wxPGEditor
: public wxObject
77 DECLARE_ABSTRACT_CLASS(wxPGEditor
)
89 virtual ~wxPGEditor();
92 Returns pointer to the name of the editor. For example,
93 wxPG_EDITOR(TextCtrl) has name "TextCtrl". This method is autogenerated
96 virtual wxString
GetName() const = 0;
99 Instantiates editor controls.
102 wxPropertyGrid to which the property belongs (use as parent for
105 Property for which this method is called.
107 Position, inside wxPropertyGrid, to create control(s) to.
109 Initial size for control(s).
112 - Primary control shall use id wxPG_SUBID1, and secondary (button)
113 control shall use wxPG_SUBID2.
114 - Implementation shoud use connect all necessary events to the
115 wxPropertyGrid::OnCustomEditorEvent. For Example:
117 // Relays wxEVT_COMMAND_TEXT_UPDATED events of primary editor
118 // control to the OnEvent.
119 // NOTE: This event in particular is actually automatically
120 // conveyed, but it is just used as an example.
121 propgrid->Connect(wxPG_SUBID1, wxEVT_COMMAND_TEXT_UPDATED,
122 wxCommandEventHandler(
123 wxPropertyGrid::OnCustomEditorEvent));
125 OnCustomEditorEvent will then forward events, first to
126 wxPGEditor::OnEvent and then to wxPGProperty::OnEvent.
129 virtual wxPGWindowList
CreateControls(wxPropertyGrid
* propgrid
,
130 wxPGProperty
* property
,
132 const wxSize
& size
) const = 0;
133 #define wxPG_DECLARE_CREATECONTROLS \
134 virtual wxPGWindowList \
135 CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property, \
136 const wxPoint& pos, const wxSize& sz ) const;
138 /** Loads value from property to the control. */
139 virtual void UpdateControl( wxPGProperty
* property
,
140 wxWindow
* ctrl
) const = 0;
143 Used to get the renderer to draw the value with when the control is
146 Default implementation returns g_wxPGDefaultRenderer.
148 //virtual wxPGCellRenderer* GetCellRenderer() const;
150 /** Draws value for given property.
152 virtual void DrawValue( wxDC
& dc
,
154 wxPGProperty
* property
,
155 const wxString
& text
) const;
157 /** Handles events. Returns true if value in control was modified
158 (see wxPGProperty::OnEvent for more information).
160 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
161 wxWindow
* wnd_primary
, wxEvent
& event
) const = 0;
163 #if !defined(SWIG) || defined(CREATE_VCW)
164 /** Returns value from control, via parameter 'variant'.
165 Usually ends up calling property's StringToValue or IntToValue.
166 Returns true if value was different.
168 virtual bool GetValueFromControl( wxVariant
& variant
,
169 wxPGProperty
* property
,
170 wxWindow
* ctrl
) const;
173 /** Sets value in control to unspecified. */
174 virtual void SetValueToUnspecified( wxPGProperty
* property
,
175 wxWindow
* ctrl
) const = 0;
177 /** Sets control's value specifically from string. */
178 virtual void SetControlStringValue( wxPGProperty
* property
,
180 const wxString
& txt
) const;
182 /** Sets control's value specifically from int (applies to choice etc.). */
183 virtual void SetControlIntValue( wxPGProperty
* property
,
187 /** Inserts item to existing control. Index -1 means appending.
188 Default implementation does nothing. Returns index of item added.
190 virtual int InsertItem( wxWindow
* ctrl
,
191 const wxString
& label
,
194 /** Deletes item from existing control.
195 Default implementation does nothing.
197 virtual void DeleteItem( wxWindow
* ctrl
, int index
) const;
199 /** Extra processing when control gains focus. For example, wxTextCtrl
200 based controls should select all text.
202 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
204 /** Returns true if control itself can contain the custom image. Default is
207 virtual bool CanContainCustomImage() const;
210 // This member is public so scripting language bindings
211 // wrapper code can access it freely.
217 // Note that we don't use this macro in this file because
218 // otherwise doxygen gets confused.
220 #define WX_PG_DECLARE_EDITOR_CLASS(CLASSNAME) \
221 DECLARE_DYNAMIC_CLASS(CLASSNAME) \
223 virtual wxString GetName() const; \
227 #define WX_PG_IMPLEMENT_EDITOR_CLASS(EDITOR,CLASSNAME,BASECLASS) \
228 IMPLEMENT_DYNAMIC_CLASS(CLASSNAME, BASECLASS) \
229 wxString CLASSNAME::GetName() const \
231 return wxS(#EDITOR); \
233 wxPGEditor* wxPGEditor_##EDITOR = (wxPGEditor*) NULL; \
234 wxPGEditor* wxPGConstruct##EDITOR##EditorClass() \
236 wxASSERT( !wxPGEditor_##EDITOR ); \
237 return new CLASSNAME(); \
241 #define WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS() \
242 wxPG_DECLARE_CREATECONTROLS \
243 virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const; \
244 virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property, \
245 wxWindow* primary, wxEvent& event ) const; \
246 virtual bool GetValueFromControl( wxVariant& variant, \
247 wxPGProperty* property, \
248 wxWindow* ctrl ) const; \
249 virtual void SetValueToUnspecified( wxPGProperty* property, \
250 wxWindow* ctrl ) const;
254 // Following are the built-in editor classes.
257 class WXDLLIMPEXP_PROPGRID wxPGTextCtrlEditor
: public wxPGEditor
260 DECLARE_DYNAMIC_CLASS(wxPGTextCtrlEditor
)
263 wxPGTextCtrlEditor() {}
264 virtual ~wxPGTextCtrlEditor();
266 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
267 virtual wxString
GetName() const;
269 //virtual wxPGCellRenderer* GetCellRenderer() const;
270 virtual void SetControlStringValue( wxPGProperty
* property
,
272 const wxString
& txt
) const;
273 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
275 // Provided so that, for example, ComboBox editor can use the same code
276 // (multiple inheritance would get way too messy).
277 static bool OnTextCtrlEvent( wxPropertyGrid
* propgrid
,
278 wxPGProperty
* property
,
282 static bool GetTextCtrlValueFromControl( wxVariant
& variant
,
283 wxPGProperty
* property
,
289 class WXDLLIMPEXP_PROPGRID wxPGChoiceEditor
: public wxPGEditor
292 DECLARE_DYNAMIC_CLASS(wxPGChoiceEditor
)
295 wxPGChoiceEditor() {}
296 virtual ~wxPGChoiceEditor();
298 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
299 virtual wxString
GetName() const;
301 virtual void SetControlIntValue( wxPGProperty
* property
,
304 virtual void SetControlStringValue( wxPGProperty
* property
,
306 const wxString
& txt
) const;
308 virtual int InsertItem( wxWindow
* ctrl
,
309 const wxString
& label
,
311 virtual void DeleteItem( wxWindow
* ctrl
, int index
) const;
312 virtual bool CanContainCustomImage() const;
314 // CreateControls calls this with CB_READONLY in extraStyle
315 wxWindow
* CreateControlsBase( wxPropertyGrid
* propgrid
,
316 wxPGProperty
* property
,
319 long extraStyle
) const;
324 class WXDLLIMPEXP_PROPGRID wxPGComboBoxEditor
: public wxPGChoiceEditor
327 DECLARE_DYNAMIC_CLASS(wxPGComboBoxEditor
)
330 wxPGComboBoxEditor() {}
331 virtual ~wxPGComboBoxEditor();
333 // Macro is used for convenience due to different signature with wxPython
334 wxPG_DECLARE_CREATECONTROLS
336 virtual wxString
GetName() const;
338 virtual void UpdateControl( wxPGProperty
* property
, wxWindow
* ctrl
) const;
340 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
341 wxWindow
* ctrl
, wxEvent
& event
) const;
343 virtual bool GetValueFromControl( wxVariant
& variant
,
344 wxPGProperty
* property
,
345 wxWindow
* ctrl
) const;
347 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
352 // Exclude classes from being able to be derived from in wxPython bindings
355 class WXDLLIMPEXP_PROPGRID wxPGChoiceAndButtonEditor
: public wxPGChoiceEditor
358 wxPGChoiceAndButtonEditor() {}
359 virtual ~wxPGChoiceAndButtonEditor();
360 virtual wxString
GetName() const;
362 // Macro is used for convenience due to different signature with wxPython
363 wxPG_DECLARE_CREATECONTROLS
365 DECLARE_DYNAMIC_CLASS(wxPGChoiceAndButtonEditor
)
368 class WXDLLIMPEXP_PROPGRID
369 wxPGTextCtrlAndButtonEditor
: public wxPGTextCtrlEditor
372 wxPGTextCtrlAndButtonEditor() {}
373 virtual ~wxPGTextCtrlAndButtonEditor();
374 virtual wxString
GetName() const;
375 wxPG_DECLARE_CREATECONTROLS
377 DECLARE_DYNAMIC_CLASS(wxPGTextCtrlAndButtonEditor
)
383 #if wxPG_INCLUDE_CHECKBOX || defined(DOXYGEN)
386 // Use custom check box code instead of native control
387 // for cleaner (ie. more integrated) look.
389 class WXDLLIMPEXP_PROPGRID wxPGCheckBoxEditor
: public wxPGEditor
392 DECLARE_DYNAMIC_CLASS(wxPGCheckBoxEditor
)
395 wxPGCheckBoxEditor() {}
396 virtual ~wxPGCheckBoxEditor();
398 virtual wxString
GetName() const;
399 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
401 virtual void DrawValue( wxDC
& dc
,
403 wxPGProperty
* property
,
404 const wxString
& text
) const;
405 //virtual wxPGCellRenderer* GetCellRenderer() const;
407 virtual void SetControlIntValue( wxPGProperty
* property
,
415 // -----------------------------------------------------------------------
416 // Editor class registeration macros
418 #define wxPGRegisterEditorClass(EDITOR) \
419 if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
421 wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
422 wxPGConstruct##EDITOR##EditorClass(), wxS(#EDITOR) ); \
425 // Use this in RegisterDefaultEditors.
426 #define wxPGRegisterDefaultEditorClass(EDITOR) \
427 if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
429 wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
430 wxPGConstruct##EDITOR##EditorClass(), wxS(#EDITOR), true ); \
433 #define wxPG_INIT_REQUIRED_EDITOR(T) \
434 wxPGRegisterEditorClass(T)
437 // -----------------------------------------------------------------------
439 /** @class wxPGEditorDialogAdapter
441 Derive a class from this to adapt an existing editor dialog or function to
442 be used when editor button of a property is pushed.
444 You only need to derive class and implement DoShowDialog() to create and
445 show the dialog, and finally submit the value returned by the dialog
451 class WXDLLIMPEXP_PROPGRID wxPGEditorDialogAdapter
: public wxObject
454 DECLARE_ABSTRACT_CLASS(wxPGEditorDialogAdapter
)
457 wxPGEditorDialogAdapter()
463 virtual ~wxPGEditorDialogAdapter() { }
465 bool ShowDialog( wxPropertyGrid
* propGrid
, wxPGProperty
* property
);
467 virtual bool DoShowDialog( wxPropertyGrid
* propGrid
,
468 wxPGProperty
* property
) = 0;
470 void SetValue( wxVariant value
)
476 This method is typically only used if deriving class from existing
477 adapter with value conversion purposes.
479 wxVariant
& GetValue() { return m_value
; }
482 // This member is public so scripting language bindings
483 // wrapper code can access it freely.
490 // -----------------------------------------------------------------------
493 /** @class wxPGMultiButton
495 This class can be used to have multiple buttons in a property editor.
496 You will need to create a new property editor class, override
497 CreateControls, and have it return wxPGMultiButton instance in
498 wxPGWindowList::SetSecondary(). For instance, here we add three buttons to
503 #include <wx/propgrid/editors.h>
505 class wxMultiButtonTextCtrlEditor : public wxPGTextCtrlEditor
507 WX_PG_DECLARE_EDITOR_CLASS(wxMultiButtonTextCtrlEditor)
509 wxMultiButtonTextCtrlEditor() {}
510 virtual ~wxMultiButtonTextCtrlEditor() {}
512 wxPG_DECLARE_CREATECONTROLS
513 virtual bool OnEvent( wxPropertyGrid* propGrid,
514 wxPGProperty* property,
516 wxEvent& event ) const;
520 WX_PG_IMPLEMENT_EDITOR_CLASS(MultiButtonTextCtrlEditor,
521 wxMultiButtonTextCtrlEditor,
525 wxMultiButtonTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid,
526 wxPGProperty* property,
528 const wxSize& sz ) const
530 // Create and populate buttons-subwindow
531 wxPGMultiButton* buttons = new wxPGMultiButton( propGrid, sz );
533 // Add two regular buttons
534 buttons->Add( "..." );
536 // Add a bitmap button
537 buttons->Add( wxArtProvider::GetBitmap(wxART_FOLDER) );
539 // Create the 'primary' editor control (textctrl in this case)
540 wxPGWindowList wndList = wxPGTextCtrlEditor::CreateControls(
544 buttons->GetPrimarySize()
547 // Finally, move buttons-subwindow to correct position and make sure
548 // returned wxPGWindowList contains our custom button list.
549 buttons->FinalizePosition(pos);
551 wndList.SetSecondary( buttons );
555 bool wxMultiButtonTextCtrlEditor::OnEvent( wxPropertyGrid* propGrid,
556 wxPGProperty* property,
558 wxEvent& event ) const
560 if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
562 wxPGMultiButton* buttons = (wxPGMultiButton*)
563 propGrid->GetEditorControlSecondary();
565 if ( event.GetId() == buttons->GetButtonId(0) )
567 // Do something when first button is pressed
570 if ( event.GetId() == buttons->GetButtonId(1) )
572 // Do something when first button is pressed
575 if ( event.GetId() == buttons->GetButtonId(2) )
577 // Do something when second button is pressed
581 return wxPGTextCtrlEditor::OnEvent(propGrid, property, ctrl, event);
586 Further to use this editor, code like this can be used:
590 // Register editor class - needs only to be called once
591 wxPGRegisterEditorClass( MultiButtonTextCtrlEditor );
593 // Insert the property that will have multiple buttons
594 propGrid->Append( new wxLongStringProperty("MultipleButtons",
597 // Change property to use editor created in the previous code segment
598 propGrid->SetPropertyEditor( "MultipleButtons",
599 wxPG_EDITOR(MultiButtonTextCtrlEditor) );
606 class WXDLLIMPEXP_PROPGRID wxPGMultiButton
: public wxWindow
609 wxPGMultiButton( wxPropertyGrid
* pg
, const wxSize
& sz
);
611 wxWindow
* GetButton( unsigned int i
) { return (wxWindow
*) m_buttons
[i
]; }
612 const wxWindow
* GetButton( unsigned int i
) const
613 { return (const wxWindow
*) m_buttons
[i
]; }
615 /** Utility function to be used in event handlers.
617 int GetButtonId( unsigned int i
) const { return GetButton(i
)->GetId(); }
619 /** Returns number of buttons.
621 int GetCount() const { return m_buttons
.Count(); }
623 void Add( const wxString
& label
, int id
= -2 );
625 void Add( const wxBitmap
& bitmap
, int id
= -2 );
628 wxSize
GetPrimarySize() const
630 return wxSize(m_fullEditorSize
.x
- m_buttonsWidth
, m_fullEditorSize
.y
);
633 void FinalizePosition( const wxPoint
& pos
)
635 Move( pos
.x
+ m_fullEditorSize
.x
- m_buttonsWidth
, pos
.y
);
641 int GenId( int id
) const;
643 wxArrayPtrVoid m_buttons
;
644 wxSize m_fullEditorSize
;
649 // -----------------------------------------------------------------------
651 #endif // _WX_PROPGRID_EDITORS_H_