1
/////////////////////////////////////////////////////////////////////////////
3
// Purpose: wxPropertyGrid editors
4
// Author: Jaakko Salli
6
// Created: Apr-14-2007
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
@brief Base for property editor classes.
52
wxPGEditor::CreateControls should Connect all necessary events to the
53
wxPropertyGrid::OnCustomEditorEvent. For Example:
55
// Relays wxEVT_COMMAND_TEXT_UPDATED events of primary editor
56
// control to the OnEvent.
57
// NOTE: This event in particular is actually automatically conveyed, but
58
// it is just used as an example.
59
propgrid->Connect( wxPG_SUBID1, wxEVT_COMMAND_TEXT_UPDATED,
60
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
61
&wxPropertyGrid::OnCustomEditorEvent );
63
OnCustomEditorEvent will then forward events, first to wxPGEditor::OnEvent
64
and then to wxPGProperty::OnEvent.
65
- You need to call macro wxPGRegisterEditorClass(EditorName) before using a custom editor class.
66
- See propgrid.cpp for how builtin editors works (starting from wxPGTextCtrlEditor).
68
class WXDLLIMPEXP_PG wxPGEditor : public wxObject
71
DECLARE_ABSTRACT_CLASS(wxPGEditor)
79
#if defined(__WXPYTHON__)
80
m_scriptObject = NULL;
85
virtual ~wxPGEditor();
87
/** Returns pointer to the name of the editor. For example, wxPG_EDITOR(TextCtrl)
88
has name "TextCtrl". This method is autogenerated for custom editors.
90
virtual wxPG_CONST_WXCHAR_PTR GetName() const = 0;
92
/** Instantiates editor controls.
94
- Primary control shall use id wxPG_SUBID1, and secondary (button) control
95
shall use wxPG_SUBID2.
97
wxPropertyGrid to which the property belongs (use as parent for control).
99
Property for which this method is called.
101
Position, inside wxPropertyGrid, to create control(s) to.
103
Initial size for control(s).
105
virtual wxPGWindowList CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property,
106
const wxPoint& pos, const wxSize& size ) const = 0;
107
#define wxPG_DECLARE_CREATECONTROLS \
108
virtual wxPGWindowList CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property, \
109
const wxPoint& pos, const wxSize& sz ) const;
111
/** Loads value from property to the control. */
112
virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const = 0;
114
/** Used to get the renderer to draw the value with when the control is hidden.
116
Default implementation returns g_wxPGDefaultRenderer.
118
//virtual wxPGCellRenderer* GetCellRenderer() const;
120
/** Draws value for given property.
122
virtual void DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& text ) const;
124
/** Handles events. Returns true if value in control was modified
125
(see wxPGProperty::OnEvent for more information).
127
virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
128
wxWindow* wnd_primary, wxEvent& event ) const = 0;
135
/** Returns value from control, via parameter 'variant'.
136
Usually ends up calling property's StringToValue or IntToValue.
137
Returns true if value was different.
139
virtual bool GetValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* ctrl ) const WX_PG_NOT_PURE_IN_WXPYTHON;
143
virtual wxPGVariantAndBool PyGetValueFromControl( wxPGProperty* property, wxWindow* ctrl ) const;
146
bool ActualGetValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* ctrl ) const
149
if ( m_scriptObject )
151
wxPGVariantAndBool vab = PyGetValueFromControl(property, ctrl);
152
if ( vab.m_valueValid )
153
variant = vab.m_value;
157
return GetValueFromControl(variant, property, ctrl);
160
/** Sets value in control to unspecified. */
161
virtual void SetValueToUnspecified( wxPGProperty* property, wxWindow* ctrl ) const = 0;
163
/** Sets control's value specifically from string. */
164
virtual void SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const;
166
/** Sets control's value specifically from int (applies to choice etc.). */
167
virtual void SetControlIntValue( wxPGProperty* property, wxWindow* ctrl, int value ) const;
169
/** Inserts item to existing control. Index -1 means appending.
170
Default implementation does nothing. Returns index of item added.
172
virtual int InsertItem( wxWindow* ctrl, const wxString& label, int index ) const;
174
/** Deletes item from existing control.
175
Default implementation does nothing.
177
virtual void DeleteItem( wxWindow* ctrl, int index ) const;
179
/** Extra processing when control gains focus. For example, wxTextCtrl
180
based controls should select all text.
182
virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const;
184
/** Returns true if control itself can contain the custom image. Default is
187
virtual bool CanContainCustomImage() const;
189
#if defined(__WXPYTHON__) && !defined(SWIG)
190
// This is the python object that contains and owns the C++ representation.
191
PyObject* m_scriptObject;
199
// Note that we don't use this macro in this file because
200
// otherwise doxygen gets confused.
202
#define WX_PG_DECLARE_EDITOR_CLASS(CLASSNAME) \
203
DECLARE_DYNAMIC_CLASS(CLASSNAME) \
205
virtual wxPG_CONST_WXCHAR_PTR GetName() const; \
209
#define WX_PG_IMPLEMENT_EDITOR_CLASS(EDITOR,CLASSNAME,BASECLASS) \
210
IMPLEMENT_DYNAMIC_CLASS(CLASSNAME, BASECLASS) \
211
wxPG_CONST_WXCHAR_PTR CLASSNAME::GetName() const \
213
return wxT(#EDITOR); \
215
wxPGEditor* wxPGEditor_##EDITOR = (wxPGEditor*) NULL; \
216
wxPGEditor* wxPGConstruct##EDITOR##EditorClass() \
218
wxASSERT( !wxPGEditor_##EDITOR ); \
219
return new CLASSNAME(); \
223
#define WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS() \
224
wxPG_DECLARE_CREATECONTROLS \
225
virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const; \
226
virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property, \
227
wxWindow* primary, wxEvent& event ) const; \
228
virtual bool GetValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* ctrl ) const; \
229
virtual void SetValueToUnspecified( wxPGProperty* property, wxWindow* ctrl ) const;
233
// Following are the built-in editor classes.
236
class WXDLLIMPEXP_PG wxPGTextCtrlEditor : public wxPGEditor
239
DECLARE_DYNAMIC_CLASS(wxPGTextCtrlEditor)
242
wxPGTextCtrlEditor() {}
243
virtual ~wxPGTextCtrlEditor();
245
WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
246
virtual wxPG_CONST_WXCHAR_PTR GetName() const;
248
//virtual wxPGCellRenderer* GetCellRenderer() const;
249
virtual void SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const;
250
virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const;
252
// Provided so that, for example, ComboBox editor can use the same code
253
// (multiple inheritance would get way too messy).
254
static bool OnTextCtrlEvent( wxPropertyGrid* propgrid,
255
wxPGProperty* property,
259
static bool GetTextCtrlValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* ctrl );
264
class WXDLLIMPEXP_PG wxPGChoiceEditor : public wxPGEditor
267
DECLARE_DYNAMIC_CLASS(wxPGChoiceEditor)
270
wxPGChoiceEditor() {}
271
virtual ~wxPGChoiceEditor();
273
WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
274
virtual wxPG_CONST_WXCHAR_PTR GetName() const;
276
virtual void SetControlIntValue( wxPGProperty* property, wxWindow* ctrl, int value ) const;
277
virtual void SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const;
279
virtual int InsertItem( wxWindow* ctrl, const wxString& label, int index ) const;
280
virtual void DeleteItem( wxWindow* ctrl, int index ) const;
281
virtual bool CanContainCustomImage() const;
283
// CreateControls calls this with CB_READONLY in extraStyle
284
wxWindow* CreateControlsBase( wxPropertyGrid* propgrid,
285
wxPGProperty* property,
288
long extraStyle ) const;
293
class WXDLLIMPEXP_PG wxPGComboBoxEditor : public wxPGChoiceEditor
296
DECLARE_DYNAMIC_CLASS(wxPGComboBoxEditor)
299
wxPGComboBoxEditor() {}
300
virtual ~wxPGComboBoxEditor();
302
wxPG_DECLARE_CREATECONTROLS // Macro is used for conviency due to different signature with wxPython
304
virtual wxPG_CONST_WXCHAR_PTR GetName() const;
306
virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const;
308
virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
309
wxWindow* ctrl, wxEvent& event ) const;
311
virtual bool GetValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* ctrl ) const;
313
virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const;
318
class WXDLLIMPEXP_PG wxPGChoiceAndButtonEditor : public wxPGChoiceEditor
321
DECLARE_DYNAMIC_CLASS(wxPGChoiceAndButtonEditor)
324
wxPGChoiceAndButtonEditor() {}
325
virtual ~wxPGChoiceAndButtonEditor();
326
virtual wxPG_CONST_WXCHAR_PTR GetName() const;
327
wxPG_DECLARE_CREATECONTROLS // Macro is used for conviency due to different signature with wxPython
331
class WXDLLIMPEXP_PG wxPGTextCtrlAndButtonEditor : public wxPGTextCtrlEditor
334
DECLARE_DYNAMIC_CLASS(wxPGTextCtrlAndButtonEditor)
337
wxPGTextCtrlAndButtonEditor() {}
338
virtual ~wxPGTextCtrlAndButtonEditor();
339
virtual wxPG_CONST_WXCHAR_PTR GetName() const;
340
wxPG_DECLARE_CREATECONTROLS
344
#if wxPG_INCLUDE_CHECKBOX || defined(DOXYGEN)
347
// Use custom check box code instead of native control
348
// for cleaner (ie. more integrated) look.
350
class WXDLLIMPEXP_PG wxPGCheckBoxEditor : public wxPGEditor
353
DECLARE_DYNAMIC_CLASS(wxPGCheckBoxEditor)
356
wxPGCheckBoxEditor() {}
357
virtual ~wxPGCheckBoxEditor();
359
virtual wxPG_CONST_WXCHAR_PTR GetName() const;
360
WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS()
362
virtual void DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& text ) const;
363
//virtual wxPGCellRenderer* GetCellRenderer() const;
365
virtual void SetControlIntValue( wxPGProperty* property, wxWindow* ctrl, int value ) const;
371
// -----------------------------------------------------------------------
372
// Editor class registeration macros
374
#define wxPGRegisterEditorClass(EDITOR) \
375
if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
377
wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( wxPGConstruct##EDITOR##EditorClass(), wxT(#EDITOR) ); \
380
// Use this in RegisterDefaultEditors.
381
#define wxPGRegisterDefaultEditorClass(EDITOR) \
382
if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \
384
wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( wxPGConstruct##EDITOR##EditorClass(), wxT(#EDITOR), true ); \
387
#define wxPG_INIT_REQUIRED_EDITOR(T) \
388
wxPGRegisterEditorClass(T)
391
// -----------------------------------------------------------------------
393
/** @class wxPGEditorDialogAdapter
396
Derive a class from this to adapt an existing editor dialog or function to
397
be used when editor button of a property is pushed.
399
You only need to derive class and implement DoShowDialog() to create and
400
show the dialog, and finally submit the value returned by the dialog
403
class WXDLLIMPEXP_PG wxPGEditorDialogAdapter : public wxObject
406
DECLARE_ABSTRACT_CLASS(wxPGEditorDialogAdapter)
409
wxPGEditorDialogAdapter()
412
#if defined(__WXPYTHON__)
413
m_scriptObject = NULL;
417
virtual ~wxPGEditorDialogAdapter() { }
419
bool ShowDialog( wxPropertyGrid* propGrid, wxPGProperty* property );
421
virtual bool DoShowDialog( wxPropertyGrid* propGrid, wxPGProperty* property ) = 0;
423
void SetValue( wxVariant value )
428
/** This method is typically only used if deriving class from existing adapter
429
with value conversion purposes.
431
wxVariant& GetValue()
436
#if defined(__WXPYTHON__) && !defined(SWIG)
437
// This is the python object that contains and owns the C++ representation.
438
PyObject* m_scriptObject;
446
// -----------------------------------------------------------------------
449
/** @class wxPGMultiButton
452
This class can be used to have multiple buttons in a property editor.
453
You will need to create a new property editor class, override CreateControls,
454
and have it return wxPGMultiButton instance in wxPGWindowList::SetSecondary().
455
For instance, here we add three buttons to a textctrl editor:
459
#include <wx/propgrid/editors.h>
461
class wxMultiButtonTextCtrlEditor : public wxPGTextCtrlEditor
463
WX_PG_DECLARE_EDITOR_CLASS(wxMultiButtonTextCtrlEditor)
465
wxMultiButtonTextCtrlEditor() {}
466
virtual ~wxMultiButtonTextCtrlEditor() {}
468
wxPG_DECLARE_CREATECONTROLS
469
virtual bool OnEvent( wxPropertyGrid* propGrid,
470
wxPGProperty* property,
472
wxEvent& event ) const;
476
WX_PG_IMPLEMENT_EDITOR_CLASS(MultiButtonTextCtrlEditor, wxMultiButtonTextCtrlEditor,
479
wxPGWindowList wxMultiButtonTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid,
480
wxPGProperty* property,
482
const wxSize& sz ) const
484
// Create and populate buttons-subwindow
485
wxPGMultiButton* buttons = new wxPGMultiButton( propGrid, sz );
487
// Add two regular buttons
488
buttons->Add( wxT("...") );
489
buttons->Add( wxT("A") );
490
// Add a bitmap button
491
buttons->Add( wxArtProvider::GetBitmap(wxART_FOLDER) );
493
// Create the 'primary' editor control (textctrl in this case)
494
wxPGWindowList wndList = wxPGTextCtrlEditor::CreateControls
495
( propGrid, property, pos, buttons->GetPrimarySize() );
497
// Finally, move buttons-subwindow to correct position and make sure
498
// returned wxPGWindowList contains our custom button list.
499
buttons->FinalizePosition(pos);
501
wndList.SetSecondary( buttons );
505
bool wxMultiButtonTextCtrlEditor::OnEvent( wxPropertyGrid* propGrid,
506
wxPGProperty* property,
508
wxEvent& event ) const
510
if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
512
wxPGMultiButton* buttons = (wxPGMultiButton*) propGrid->GetEditorControlSecondary();
514
if ( event.GetId() == buttons->GetButtonId(0) )
516
// Do something when first button is pressed
519
if ( event.GetId() == buttons->GetButtonId(1) )
521
// Do something when first button is pressed
524
if ( event.GetId() == buttons->GetButtonId(2) )
526
// Do something when second button is pressed
530
return wxPGTextCtrlEditor::OnEvent(propGrid, property, ctrl, event);
535
Further to use this editor, code like this can be used:
539
// Register editor class - needs only to be called once
540
wxPGRegisterEditorClass( MultiButtonTextCtrlEditor );
542
// Insert the property that will have multiple buttons
543
propGrid->Append( new wxLongStringProperty(wxT("MultipleButtons"), wxPG_LABEL) );
545
// Change property to use editor created in the previous code segment
546
propGrid->SetPropertyEditor( wxT("MultipleButtons"), wxPG_EDITOR(MultiButtonTextCtrlEditor) );
550
class WXDLLIMPEXP_PG wxPGMultiButton : public wxWindow
554
wxPGMultiButton( wxPropertyGrid* pg, const wxSize& sz );
556
virtual ~wxPGMultiButton() { }
558
wxWindow* GetButton( unsigned int i ) { return (wxWindow*) m_buttons[i]; }
559
const wxWindow* GetButton( unsigned int i ) const { return (const wxWindow*) m_buttons[i]; }
561
/** Utility function to be used in event handlers.
563
int GetButtonId( unsigned int i ) const { return GetButton(i)->GetId(); }
565
/** Returns number of buttons.
567
int GetCount() const { return (int) m_buttons.size(); }
569
void Add( const wxString& label, int id = -2 );
571
void Add( const wxBitmap& bitmap, int id = -2 );
574
wxSize GetPrimarySize() const
576
return wxSize(m_fullEditorSize.x - m_buttonsWidth, m_fullEditorSize.y);
579
void FinalizePosition( const wxPoint& pos )
581
Move( pos.x + m_fullEditorSize.x - m_buttonsWidth, pos.y );
587
int GenId( int id ) const;
589
wxArrayPtrVoid m_buttons;
590
wxSize m_fullEditorSize;
595
// -----------------------------------------------------------------------
597
#endif // _WX_PROPGRID_EDITORS_H_