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 use 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 // 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));
127 OnCustomEditorEvent will then forward events, first to
128 wxPGEditor::OnEvent and then to wxPGProperty::OnEvent.
131 virtual wxPGWindowList
CreateControls(wxPropertyGrid
* propgrid
,
132 wxPGProperty
* property
,
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;
140 /** Loads value from property to the control. */
141 virtual void UpdateControl( wxPGProperty
* property
,
142 wxWindow
* ctrl
) const = 0;
145 Used to get the renderer to draw the value with when the control is
148 Default implementation returns g_wxPGDefaultRenderer.
150 //virtual wxPGCellRenderer* GetCellRenderer() const;
152 /** Draws value for given property.
154 virtual void DrawValue( wxDC
& dc
,
156 wxPGProperty
* property
,
157 const wxString
& text
) const;
159 /** Handles events. Returns true if value in control was modified
160 (see wxPGProperty::OnEvent for more information).
162 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
163 wxWindow
* wnd_primary
, wxEvent
& event
) const = 0;
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.
170 virtual bool GetValueFromControl( wxVariant
& variant
,
171 wxPGProperty
* property
,
172 wxWindow
* ctrl
) const;
175 /** Sets value in control to unspecified. */
176 virtual void SetValueToUnspecified( wxPGProperty
* property
,
177 wxWindow
* ctrl
) const = 0;
179 /** Sets control's value specifically from string. */
180 virtual void SetControlStringValue( wxPGProperty
* property
,
182 const wxString
& txt
) const;
184 /** Sets control's value specifically from int (applies to choice etc.). */
185 virtual void SetControlIntValue( wxPGProperty
* property
,
189 /** Inserts item to existing control. Index -1 means appending.
190 Default implementation does nothing. Returns index of item added.
192 virtual int InsertItem( wxWindow
* ctrl
,
193 const wxString
& label
,
196 /** Deletes item from existing control.
197 Default implementation does nothing.
199 virtual void DeleteItem( wxWindow
* ctrl
, int index
) const;
201 /** Extra processing when control gains focus. For example, wxTextCtrl
202 based controls should select all text.
204 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
206 /** Returns true if control itself can contain the custom image. Default is
209 virtual bool CanContainCustomImage() const;
212 // This member is public so scripting language bindings
213 // wrapper code can access it freely.
219 // Note that we don't use this macro in this file because
220 // otherwise doxygen gets confused.
222 #define WX_PG_DECLARE_EDITOR_CLASS(CLASSNAME) \
223 DECLARE_DYNAMIC_CLASS(CLASSNAME) \
225 virtual wxString GetName() const; \
229 #define WX_PG_IMPLEMENT_EDITOR_CLASS(EDITOR,CLASSNAME,BASECLASS) \
230 IMPLEMENT_DYNAMIC_CLASS(CLASSNAME, BASECLASS) \
231 wxString CLASSNAME::GetName() const \
233 return wxS(#EDITOR); \
235 wxPGEditor* wxPGEditor_##EDITOR = (wxPGEditor*) NULL; \
236 wxPGEditor* wxPGConstruct##EDITOR##EditorClass() \
238 wxASSERT( !wxPGEditor_##EDITOR ); \
239 return new CLASSNAME(); \
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;
256 // Following are the built-in editor classes.
259 class WXDLLIMPEXP_PROPGRID wxPGTextCtrlEditor
: public wxPGEditor
262 DECLARE_DYNAMIC_CLASS(wxPGTextCtrlEditor
)
265 wxPGTextCtrlEditor() {}
266 virtual ~wxPGTextCtrlEditor();
268 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
269 virtual wxString
GetName() const;
271 //virtual wxPGCellRenderer* GetCellRenderer() const;
272 virtual void SetControlStringValue( wxPGProperty
* property
,
274 const wxString
& txt
) const;
275 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
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
,
284 static bool GetTextCtrlValueFromControl( wxVariant
& variant
,
285 wxPGProperty
* property
,
291 class WXDLLIMPEXP_PROPGRID wxPGChoiceEditor
: public wxPGEditor
294 DECLARE_DYNAMIC_CLASS(wxPGChoiceEditor
)
297 wxPGChoiceEditor() {}
298 virtual ~wxPGChoiceEditor();
300 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
301 virtual wxString
GetName() const;
303 virtual void SetControlIntValue( wxPGProperty
* property
,
306 virtual void SetControlStringValue( wxPGProperty
* property
,
308 const wxString
& txt
) const;
310 virtual int InsertItem( wxWindow
* ctrl
,
311 const wxString
& label
,
313 virtual void DeleteItem( wxWindow
* ctrl
, int index
) const;
314 virtual bool CanContainCustomImage() const;
316 // CreateControls calls this with CB_READONLY in extraStyle
317 wxWindow
* CreateControlsBase( wxPropertyGrid
* propgrid
,
318 wxPGProperty
* property
,
321 long extraStyle
) const;
326 class WXDLLIMPEXP_PROPGRID wxPGComboBoxEditor
: public wxPGChoiceEditor
329 DECLARE_DYNAMIC_CLASS(wxPGComboBoxEditor
)
332 wxPGComboBoxEditor() {}
333 virtual ~wxPGComboBoxEditor();
335 // Macro is used for convenience due to different signature with wxPython
336 wxPG_DECLARE_CREATECONTROLS
338 virtual wxString
GetName() const;
340 virtual void UpdateControl( wxPGProperty
* property
, wxWindow
* ctrl
) const;
342 virtual bool OnEvent( wxPropertyGrid
* propgrid
, wxPGProperty
* property
,
343 wxWindow
* ctrl
, wxEvent
& event
) const;
345 virtual bool GetValueFromControl( wxVariant
& variant
,
346 wxPGProperty
* property
,
347 wxWindow
* ctrl
) const;
349 virtual void OnFocus( wxPGProperty
* property
, wxWindow
* wnd
) const;
354 // Exclude classes from being able to be derived from in wxPython bindings
357 class WXDLLIMPEXP_PROPGRID wxPGChoiceAndButtonEditor
: public wxPGChoiceEditor
360 wxPGChoiceAndButtonEditor() {}
361 virtual ~wxPGChoiceAndButtonEditor();
362 virtual wxString
GetName() const;
364 // Macro is used for convenience due to different signature with wxPython
365 wxPG_DECLARE_CREATECONTROLS
367 DECLARE_DYNAMIC_CLASS(wxPGChoiceAndButtonEditor
)
370 class WXDLLIMPEXP_PROPGRID
371 wxPGTextCtrlAndButtonEditor
: public wxPGTextCtrlEditor
374 wxPGTextCtrlAndButtonEditor() {}
375 virtual ~wxPGTextCtrlAndButtonEditor();
376 virtual wxString
GetName() const;
377 wxPG_DECLARE_CREATECONTROLS
379 DECLARE_DYNAMIC_CLASS(wxPGTextCtrlAndButtonEditor
)
385 #if wxPG_INCLUDE_CHECKBOX || defined(DOXYGEN)
388 // Use custom check box code instead of native control
389 // for cleaner (ie. more integrated) look.
391 class WXDLLIMPEXP_PROPGRID wxPGCheckBoxEditor
: public wxPGEditor
394 DECLARE_DYNAMIC_CLASS(wxPGCheckBoxEditor
)
397 wxPGCheckBoxEditor() {}
398 virtual ~wxPGCheckBoxEditor();
400 virtual wxString
GetName() const;
401 WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
403 virtual void DrawValue( wxDC
& dc
,
405 wxPGProperty
* property
,
406 const wxString
& text
) const;
407 //virtual wxPGCellRenderer* GetCellRenderer() const;
409 virtual void SetControlIntValue( wxPGProperty
* property
,
417 // -----------------------------------------------------------------------
418 // Editor class registeration macros
420 #define wxPGRegisterEditorClass(EDITOR) \
421 if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
423 wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
424 wxPGConstruct##EDITOR##EditorClass(), wxS(#EDITOR) ); \
427 // Use this in RegisterDefaultEditors.
428 #define wxPGRegisterDefaultEditorClass(EDITOR) \
429 if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
431 wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
432 wxPGConstruct##EDITOR##EditorClass(), wxS(#EDITOR), true ); \
435 #define wxPG_INIT_REQUIRED_EDITOR(T) \
436 wxPGRegisterEditorClass(T)
439 // -----------------------------------------------------------------------
441 /** @class wxPGEditorDialogAdapter
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.
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
453 class WXDLLIMPEXP_PROPGRID wxPGEditorDialogAdapter
: public wxObject
456 DECLARE_ABSTRACT_CLASS(wxPGEditorDialogAdapter
)
459 wxPGEditorDialogAdapter()
465 virtual ~wxPGEditorDialogAdapter() { }
467 bool ShowDialog( wxPropertyGrid
* propGrid
, wxPGProperty
* property
);
469 virtual bool DoShowDialog( wxPropertyGrid
* propGrid
,
470 wxPGProperty
* property
) = 0;
472 void SetValue( wxVariant value
)
478 This method is typically only used if deriving class from existing
479 adapter with value conversion purposes.
481 wxVariant
& GetValue() { return m_value
; }
484 // This member is public so scripting language bindings
485 // wrapper code can access it freely.
492 // -----------------------------------------------------------------------
495 /** @class wxPGMultiButton
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
505 #include <wx/propgrid/editors.h>
507 class wxMultiButtonTextCtrlEditor : public wxPGTextCtrlEditor
509 WX_PG_DECLARE_EDITOR_CLASS(wxMultiButtonTextCtrlEditor)
511 wxMultiButtonTextCtrlEditor() {}
512 virtual ~wxMultiButtonTextCtrlEditor() {}
514 wxPG_DECLARE_CREATECONTROLS
515 virtual bool OnEvent( wxPropertyGrid* propGrid,
516 wxPGProperty* property,
518 wxEvent& event ) const;
522 WX_PG_IMPLEMENT_EDITOR_CLASS(MultiButtonTextCtrlEditor,
523 wxMultiButtonTextCtrlEditor,
527 wxMultiButtonTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid,
528 wxPGProperty* property,
530 const wxSize& sz ) const
532 // Create and populate buttons-subwindow
533 wxPGMultiButton* buttons = new wxPGMultiButton( propGrid, sz );
535 // Add two regular buttons
536 buttons->Add( "..." );
538 // Add a bitmap button
539 buttons->Add( wxArtProvider::GetBitmap(wxART_FOLDER) );
541 // Create the 'primary' editor control (textctrl in this case)
542 wxPGWindowList wndList = wxPGTextCtrlEditor::CreateControls(
546 buttons->GetPrimarySize()
549 // Finally, move buttons-subwindow to correct position and make sure
550 // returned wxPGWindowList contains our custom button list.
551 buttons->FinalizePosition(pos);
553 wndList.SetSecondary( buttons );
557 bool wxMultiButtonTextCtrlEditor::OnEvent( wxPropertyGrid* propGrid,
558 wxPGProperty* property,
560 wxEvent& event ) const
562 if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
564 wxPGMultiButton* buttons = (wxPGMultiButton*)
565 propGrid->GetEditorControlSecondary();
567 if ( event.GetId() == buttons->GetButtonId(0) )
569 // Do something when first button is pressed
572 if ( event.GetId() == buttons->GetButtonId(1) )
574 // Do something when first button is pressed
577 if ( event.GetId() == buttons->GetButtonId(2) )
579 // Do something when second button is pressed
583 return wxPGTextCtrlEditor::OnEvent(propGrid, property, ctrl, event);
588 Further to use this editor, code like this can be used:
592 // Register editor class - needs only to be called once
593 wxPGRegisterEditorClass( MultiButtonTextCtrlEditor );
595 // Insert the property that will have multiple buttons
596 propGrid->Append( new wxLongStringProperty("MultipleButtons",
599 // Change property to use editor created in the previous code segment
600 propGrid->SetPropertyEditor( "MultipleButtons",
601 wxPG_EDITOR(MultiButtonTextCtrlEditor) );
608 class WXDLLIMPEXP_PROPGRID wxPGMultiButton
: public wxWindow
611 wxPGMultiButton( wxPropertyGrid
* pg
, const wxSize
& sz
);
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
]; }
617 /** Utility function to be used in event handlers.
619 int GetButtonId( unsigned int i
) const { return GetButton(i
)->GetId(); }
621 /** Returns number of buttons.
623 int GetCount() const { return m_buttons
.Count(); }
625 void Add( const wxString
& label
, int id
= -2 );
627 void Add( const wxBitmap
& bitmap
, int id
= -2 );
630 wxSize
GetPrimarySize() const
632 return wxSize(m_fullEditorSize
.x
- m_buttonsWidth
, m_fullEditorSize
.y
);
635 void FinalizePosition( const wxPoint
& pos
)
637 Move( pos
.x
+ m_fullEditorSize
.x
- m_buttonsWidth
, pos
.y
);
643 int GenId( int id
) const;
645 wxArrayPtrVoid m_buttons
;
646 wxSize m_fullEditorSize
;
651 // -----------------------------------------------------------------------
653 #endif // wxUSE_PROPGRID
655 #endif // _WX_PROPGRID_EDITORS_H_