///////////////////////////////////////////////////////////////////////////// // Name: wx/propgrid/editors.h // Purpose: wxPropertyGrid editors // Author: Jaakko Salli // Modified by: // Created: 2007-04-14 // RCS-ID: $Id: // Copyright: (c) Jaakko Salli // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_PROPGRID_EDITORS_H_ #define _WX_PROPGRID_EDITORS_H_ #if wxUSE_PROPGRID // ----------------------------------------------------------------------- // wxPGWindowList contains list of editor windows returned by CreateControls. class wxPGWindowList { public: wxPGWindowList() { m_primary = m_secondary = NULL; } void SetSecondary( wxWindow* secondary ) { m_secondary = secondary; } wxWindow* m_primary; wxWindow* m_secondary; #ifndef SWIG wxPGWindowList( wxWindow* a ) { m_primary = a; m_secondary = NULL; }; wxPGWindowList( wxWindow* a, wxWindow* b ) { m_primary = a; m_secondary = b; }; #endif }; // ----------------------------------------------------------------------- /** @class wxPGEditor Base class for custom wxPropertyGrid editors. @remarks - Names of builtin property editors are: TextCtrl, Choice, ComboBox, CheckBox, TextCtrlAndButton, and ChoiceAndButton. Additional editors include SpinCtrl and DatePickerCtrl, but using them requires calling wxPropertyGrid::RegisterAdditionalEditors() prior use. - Pointer to builtin editor is available as wxPGEditor_EditorName (eg. wxPGEditor_TextCtrl). - To add new editor you need to register it first using static function wxPropertyGrid::RegisterEditorClass(), with code like this: @code wxPGEditor *editorPointer = wxPropertyGrid::RegisterEditorClass( new MyEditorClass(), "MyEditor"); @endcode After that, wxPropertyGrid will take ownership of the given object, but you should still store editorPointer somewhere, so you can pass it to wxPGProperty::SetEditor(), or return it from wxPGEditor::DoGetEditorClass(). @library{wxpropgrid} @category{propgrid} */ class WXDLLIMPEXP_PROPGRID wxPGEditor : public wxObject { #ifndef SWIG DECLARE_ABSTRACT_CLASS(wxPGEditor) #endif public: /** Constructor. */ wxPGEditor() : wxObject() { m_clientData = NULL; } /** Destructor. */ virtual ~wxPGEditor(); /** Returns pointer to the name of the editor. For example, wxPG_EDITOR(TextCtrl) has name "TextCtrl". This method is autogenerated for custom editors. */ virtual wxString GetName() const = 0; /** Instantiates editor controls. @param propgrid wxPropertyGrid to which the property belongs (use as parent for control). @param property Property for which this method is called. @param pos Position, inside wxPropertyGrid, to create control(s) to. @param size Initial size for control(s). @remarks - Primary control shall use id wxPG_SUBID1, and secondary (button) control shall use wxPG_SUBID2. - Implementation shoud connect all necessary events to the wxPropertyGrid::OnCustomEditorEvent. For Example: @code // Relays wxEVT_COMMAND_TEXT_UPDATED events of primary editor // control to the OnEvent. control->Connect(control->GetId(), wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent), NULL, propgrid); @endcode OnCustomEditorEvent will then forward events, first to wxPGEditor::OnEvent() and then to wxPGProperty::OnEvent(). */ virtual wxPGWindowList CreateControls(wxPropertyGrid* propgrid, wxPGProperty* property, const wxPoint& pos, const wxSize& size) const = 0; #define wxPG_DECLARE_CREATECONTROLS \ virtual wxPGWindowList \ CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property, \ const wxPoint& pos, const wxSize& sz ) const; /** Loads value from property to the control. */ virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const = 0; /** Used to get the renderer to draw the value with when the control is hidden. Default implementation returns g_wxPGDefaultRenderer. */ //virtual wxPGCellRenderer* GetCellRenderer() const; /** Draws value for given property. */ virtual void DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& text ) const; /** Handles events. Returns true if value in control was modified (see wxPGProperty::OnEvent for more information). @remarks wxPropertyGrid will automatically unfocus the editor when wxEVT_COMMAND_TEXT_ENTER is received and when it results in property value being modified. This happens regardless of editor type (ie. behavior is same for any wxTextCtrl and wxComboBox based editor). */ virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property, wxWindow* wnd_primary, wxEvent& event ) const = 0; #if !defined(SWIG) || defined(CREATE_VCW) /** Returns value from control, via parameter 'variant'. Usually ends up calling property's StringToValue or IntToValue. Returns true if value was different. */ virtual bool GetValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* ctrl ) const; #endif /** Sets value in control to unspecified. */ virtual void SetValueToUnspecified( wxPGProperty* property, wxWindow* ctrl ) const = 0; /** Sets control's value specifically from string. */ virtual void SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const; /** Sets control's value specifically from int (applies to choice etc.). */ virtual void SetControlIntValue( wxPGProperty* property, wxWindow* ctrl, int value ) const; /** Inserts item to existing control. Index -1 means appending. Default implementation does nothing. Returns index of item added. */ virtual int InsertItem( wxWindow* ctrl, const wxString& label, int index ) const; /** Deletes item from existing control. Default implementation does nothing. */ virtual void DeleteItem( wxWindow* ctrl, int index ) const; /** Extra processing when control gains focus. For example, wxTextCtrl based controls should select all text. */ virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const; /** Returns true if control itself can contain the custom image. Default is to return false. */ virtual bool CanContainCustomImage() const; // // This member is public so scripting language bindings // wrapper code can access it freely. void* m_clientData; }; // // Note that we don't use this macro in this file because // otherwise doxygen gets confused. // #define WX_PG_DECLARE_EDITOR_CLASS(CLASSNAME) \ DECLARE_DYNAMIC_CLASS(CLASSNAME) \ public: \ virtual wxString GetName() const; \ private: #define WX_PG_IMPLEMENT_EDITOR_CLASS(EDITOR,CLASSNAME,BASECLASS) \ IMPLEMENT_DYNAMIC_CLASS(CLASSNAME, BASECLASS) \ wxString CLASSNAME::GetName() const \ { \ return wxS(#EDITOR); \ } \ wxPGEditor* wxPGEditor_##EDITOR = (wxPGEditor*) NULL; \ wxPGEditor* wxPGConstruct##EDITOR##EditorClass() \ { \ wxASSERT( !wxPGEditor_##EDITOR ); \ return new CLASSNAME(); \ } #define WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS() \ wxPG_DECLARE_CREATECONTROLS \ virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const; \ virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property, \ wxWindow* primary, wxEvent& event ) const; \ virtual bool GetValueFromControl( wxVariant& variant, \ wxPGProperty* property, \ wxWindow* ctrl ) const; \ virtual void SetValueToUnspecified( wxPGProperty* property, \ wxWindow* ctrl ) const; // // Following are the built-in editor classes. // class WXDLLIMPEXP_PROPGRID wxPGTextCtrlEditor : public wxPGEditor { #ifndef SWIG DECLARE_DYNAMIC_CLASS(wxPGTextCtrlEditor) #endif public: wxPGTextCtrlEditor() {} virtual ~wxPGTextCtrlEditor(); WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS() virtual wxString GetName() const; //virtual wxPGCellRenderer* GetCellRenderer() const; virtual void SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const; virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const; // Provided so that, for example, ComboBox editor can use the same code // (multiple inheritance would get way too messy). static bool OnTextCtrlEvent( wxPropertyGrid* propgrid, wxPGProperty* property, wxWindow* ctrl, wxEvent& event ); static bool GetTextCtrlValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* ctrl ); }; class WXDLLIMPEXP_PROPGRID wxPGChoiceEditor : public wxPGEditor { #ifndef SWIG DECLARE_DYNAMIC_CLASS(wxPGChoiceEditor) #endif public: wxPGChoiceEditor() {} virtual ~wxPGChoiceEditor(); WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS() virtual wxString GetName() const; virtual void SetControlIntValue( wxPGProperty* property, wxWindow* ctrl, int value ) const; virtual void SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const; virtual int InsertItem( wxWindow* ctrl, const wxString& label, int index ) const; virtual void DeleteItem( wxWindow* ctrl, int index ) const; virtual bool CanContainCustomImage() const; // CreateControls calls this with CB_READONLY in extraStyle wxWindow* CreateControlsBase( wxPropertyGrid* propgrid, wxPGProperty* property, const wxPoint& pos, const wxSize& sz, long extraStyle ) const; }; class WXDLLIMPEXP_PROPGRID wxPGComboBoxEditor : public wxPGChoiceEditor { #ifndef SWIG DECLARE_DYNAMIC_CLASS(wxPGComboBoxEditor) #endif public: wxPGComboBoxEditor() {} virtual ~wxPGComboBoxEditor(); // Macro is used for convenience due to different signature with wxPython wxPG_DECLARE_CREATECONTROLS virtual wxString GetName() const; virtual void UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const; virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property, wxWindow* ctrl, wxEvent& event ) const; virtual bool GetValueFromControl( wxVariant& variant, wxPGProperty* property, wxWindow* ctrl ) const; virtual void OnFocus( wxPGProperty* property, wxWindow* wnd ) const; }; // Exclude classes from being able to be derived from in wxPython bindings #ifndef SWIG class WXDLLIMPEXP_PROPGRID wxPGChoiceAndButtonEditor : public wxPGChoiceEditor { public: wxPGChoiceAndButtonEditor() {} virtual ~wxPGChoiceAndButtonEditor(); virtual wxString GetName() const; // Macro is used for convenience due to different signature with wxPython wxPG_DECLARE_CREATECONTROLS DECLARE_DYNAMIC_CLASS(wxPGChoiceAndButtonEditor) }; class WXDLLIMPEXP_PROPGRID wxPGTextCtrlAndButtonEditor : public wxPGTextCtrlEditor { public: wxPGTextCtrlAndButtonEditor() {} virtual ~wxPGTextCtrlAndButtonEditor(); virtual wxString GetName() const; wxPG_DECLARE_CREATECONTROLS DECLARE_DYNAMIC_CLASS(wxPGTextCtrlAndButtonEditor) }; #endif // !SWIG #if wxPG_INCLUDE_CHECKBOX || defined(DOXYGEN) // // Use custom check box code instead of native control // for cleaner (ie. more integrated) look. // class WXDLLIMPEXP_PROPGRID wxPGCheckBoxEditor : public wxPGEditor { #ifndef SWIG DECLARE_DYNAMIC_CLASS(wxPGCheckBoxEditor) #endif public: wxPGCheckBoxEditor() {} virtual ~wxPGCheckBoxEditor(); virtual wxString GetName() const; WX_PG_IMPLEMENT_EDITOR_CLASS_STD_METHODS() virtual void DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& text ) const; //virtual wxPGCellRenderer* GetCellRenderer() const; virtual void SetControlIntValue( wxPGProperty* property, wxWindow* ctrl, int value ) const; }; #endif // ----------------------------------------------------------------------- // Editor class registeration macros #define wxPGRegisterEditorClass(EDITOR) \ if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \ { \ wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \ wxPGConstruct##EDITOR##EditorClass() ); \ } // Use this in RegisterDefaultEditors. #define wxPGRegisterDefaultEditorClass(EDITOR) \ if ( wxPGEditor_##EDITOR == (wxPGEditor*) NULL ) \ { \ wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \ wxPGConstruct##EDITOR##EditorClass(), true ); \ } #define wxPG_INIT_REQUIRED_EDITOR(T) \ wxPGRegisterEditorClass(T) // ----------------------------------------------------------------------- /** @class wxPGEditorDialogAdapter Derive a class from this to adapt an existing editor dialog or function to be used when editor button of a property is pushed. You only need to derive class and implement DoShowDialog() to create and show the dialog, and finally submit the value returned by the dialog via SetValue(). @library{wxpropgrid} @category{propgrid} */ class WXDLLIMPEXP_PROPGRID wxPGEditorDialogAdapter : public wxObject { #ifndef SWIG DECLARE_ABSTRACT_CLASS(wxPGEditorDialogAdapter) #endif public: wxPGEditorDialogAdapter() : wxObject() { m_clientData = NULL; } virtual ~wxPGEditorDialogAdapter() { } bool ShowDialog( wxPropertyGrid* propGrid, wxPGProperty* property ); virtual bool DoShowDialog( wxPropertyGrid* propGrid, wxPGProperty* property ) = 0; void SetValue( wxVariant value ) { m_value = value; } /** This method is typically only used if deriving class from existing adapter with value conversion purposes. */ wxVariant& GetValue() { return m_value; } // // This member is public so scripting language bindings // wrapper code can access it freely. void* m_clientData; private: wxVariant m_value; }; // ----------------------------------------------------------------------- /** @class wxPGMultiButton This class can be used to have multiple buttons in a property editor. You will need to create a new property editor class, override CreateControls, and have it return wxPGMultiButton instance in wxPGWindowList::SetSecondary(). */ class WXDLLIMPEXP_PROPGRID wxPGMultiButton : public wxWindow { public: wxPGMultiButton( wxPropertyGrid* pg, const wxSize& sz ); wxWindow* GetButton( unsigned int i ) { return (wxWindow*) m_buttons[i]; } const wxWindow* GetButton( unsigned int i ) const { return (const wxWindow*) m_buttons[i]; } /** Utility function to be used in event handlers. */ int GetButtonId( unsigned int i ) const { return GetButton(i)->GetId(); } /** Returns number of buttons. */ int GetCount() const { return m_buttons.Count(); } void Add( const wxString& label, int id = -2 ); #if wxUSE_BMPBUTTON void Add( const wxBitmap& bitmap, int id = -2 ); #endif wxSize GetPrimarySize() const { return wxSize(m_fullEditorSize.x - m_buttonsWidth, m_fullEditorSize.y); } void Finalize( wxPropertyGrid* propGrid, const wxPoint& pos ); #ifndef DOXYGEN protected: int GenId( int id ) const; wxArrayPtrVoid m_buttons; wxSize m_fullEditorSize; int m_buttonsWidth; #endif // !DOXYGEN }; // ----------------------------------------------------------------------- #endif // wxUSE_PROPGRID #endif // _WX_PROPGRID_EDITORS_H_