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