diff --git a/include/wx/propgrid/props.h b/include/wx/propgrid/props.h index 41d9e97035..d7455479c1 100644 --- a/include/wx/propgrid/props.h +++ b/include/wx/propgrid/props.h @@ -154,10 +154,35 @@ public: #endif // wxUSE_VALIDATORS +// Base class for numeric properties. +// Cannot be instantiated directly. +class WXDLLIMPEXP_PROPGRID wxNumericProperty : public wxPGProperty +{ + wxDECLARE_ABSTRACT_CLASS(wxNumericProperty); +public: + virtual ~wxNumericProperty(); + + virtual bool DoSetAttribute(const wxString& name, wxVariant& value) wxOVERRIDE; + + virtual wxVariant AddSpinStepValue(long stepScale) const = 0; + + wxVariant GetMinVal() const { return m_minVal; } + wxVariant GetMaxVal() const { return m_maxVal; } + bool UseSpinMotion() const { return m_spinMotion; } + +protected: + wxNumericProperty(const wxString& label, const wxString& name); + + wxVariant m_minVal; + wxVariant m_maxVal; + bool m_spinMotion; + wxVariant m_spinStep; + bool m_spinWrap; +}; // Basic property with integer value. // Seamlessly supports 64-bit integer (wxLongLong) on overflow. -class WXDLLIMPEXP_PROPGRID wxIntProperty : public wxPGProperty +class WXDLLIMPEXP_PROPGRID wxIntProperty : public wxNumericProperty { WX_PG_DECLARE_PROPERTY_CLASS(wxIntProperty) public: @@ -182,37 +207,36 @@ public: int argFlags = 0 ) const wxOVERRIDE; static wxValidator* GetClassValidator(); virtual wxValidator* DoGetValidator() const wxOVERRIDE; + virtual wxVariant AddSpinStepValue(long stepScale) const wxOVERRIDE; // Validation helpers. #if wxUSE_LONGLONG - static bool DoValidation( const wxPGProperty* property, + static bool DoValidation( const wxNumericProperty* property, wxLongLong& value, wxPGValidationInfo* pValidationInfo, int mode = wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ); #if defined(wxLongLong_t) - static bool DoValidation( const wxPGProperty* property, + static bool DoValidation( const wxNumericProperty* property, wxLongLong_t& value, wxPGValidationInfo* pValidationInfo, int mode = wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ); #endif // wxLongLong_t #endif // wxUSE_LONGLONG - static bool DoValidation(const wxPGProperty* property, + static bool DoValidation(const wxNumericProperty* property, long& value, wxPGValidationInfo* pValidationInfo, int mode = wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); - -protected: }; // ----------------------------------------------------------------------- // Basic property with unsigned integer value. // Seamlessly supports 64-bit integer (wxULongLong) on overflow. -class WXDLLIMPEXP_PROPGRID wxUIntProperty : public wxPGProperty +class WXDLLIMPEXP_PROPGRID wxUIntProperty : public wxNumericProperty { WX_PG_DECLARE_PROPERTY_CLASS(wxUIntProperty) public: @@ -236,6 +260,7 @@ public: virtual bool IntToValue( wxVariant& variant, int number, int argFlags = 0 ) const wxOVERRIDE; + virtual wxVariant AddSpinStepValue(long stepScale) const wxOVERRIDE; protected: wxByte m_base; @@ -246,18 +271,18 @@ private: // Validation helpers. #if wxUSE_LONGLONG - static bool DoValidation(const wxPGProperty* property, + static bool DoValidation(const wxNumericProperty* property, wxULongLong& value, wxPGValidationInfo* pValidationInfo, int mode =wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); #if defined(wxULongLong_t) - static bool DoValidation(const wxPGProperty* property, + static bool DoValidation(const wxNumericProperty* property, wxULongLong_t& value, wxPGValidationInfo* pValidationInfo, int mode =wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); #endif // wxULongLong_t #endif // wxUSE_LONGLONG - static bool DoValidation(const wxPGProperty* property, + static bool DoValidation(const wxNumericProperty* property, long& value, wxPGValidationInfo* pValidationInfo, int mode = wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); @@ -266,7 +291,7 @@ private: // ----------------------------------------------------------------------- // Basic property with double-precision floating point value. -class WXDLLIMPEXP_PROPGRID wxFloatProperty : public wxPGProperty +class WXDLLIMPEXP_PROPGRID wxFloatProperty : public wxNumericProperty { WX_PG_DECLARE_PROPERTY_CLASS(wxFloatProperty) public: @@ -285,13 +310,14 @@ public: wxPGValidationInfo& validationInfo ) const wxOVERRIDE; // Validation helper. - static bool DoValidation( const wxPGProperty* property, + static bool DoValidation( const wxNumericProperty* property, double& value, wxPGValidationInfo* pValidationInfo, int mode = wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ); static wxValidator* GetClassValidator(); virtual wxValidator* DoGetValidator () const wxOVERRIDE; + virtual wxVariant AddSpinStepValue(long stepScale) const wxOVERRIDE; protected: int m_precision; diff --git a/interface/wx/propgrid/property.h b/interface/wx/propgrid/property.h index 5589129d0d..ff6edffe23 100644 --- a/interface/wx/propgrid/property.h +++ b/interface/wx/propgrid/property.h @@ -54,11 +54,15 @@ struct wxPGPaintData */ #define wxPG_ATTR_DEFAULT_VALUE wxS("DefaultValue") -/** Universal, @c int or @c double. Minimum value for numeric properties. +/** Built-in attribute specific to wxNumericProperty and derived properties, + like wxIntProperty, wxUIntProperty, wxFloatProperty, @c int or @c double. + Minimum value for the property. */ #define wxPG_ATTR_MIN wxS("Min") -/** Universal, @c int or @c double. Maximum value for numeric properties. +/** Built-in attribute specific to wxNumericProperty and derived properties, + like wxIntProperty, wxUIntProperty, wxFloatProperty, @c int or @c double. + Maximum value for the property. */ #define wxPG_ATTR_MAX wxS("Max") @@ -186,17 +190,23 @@ struct wxPGPaintData */ #define wxPG_DATE_PICKER_STYLE wxS("PickerStyle") -/** SpinCtrl editor, @c int or @c double. How much number changes when button - is pressed (or up/down on keyboard). +/** Built-in attribute specific to wxNumericProperty and derived properties, + like wxIntProperty, wxUIntProperty, wxFloatProperty, used by SpinCtrl editor, + @c int or @c double type. How much number changes when button is pressed + (or up/down on keyboard). */ #define wxPG_ATTR_SPINCTRL_STEP wxS("Step") -/** SpinCtrl editor, @c bool. If @true, value wraps at Min/Max. +/** Built-in attribute specific to wxNumericProperty and derived properties, + like wxIntProperty, wxUIntProperty, wxFloatProperty, used by SpinCtrl editor, + @c bool. If @true, value wraps at Min/Max. */ #define wxPG_ATTR_SPINCTRL_WRAP wxS("Wrap") -/** SpinCtrl editor, @c bool. If @true, value can also by changed by moving - mouse when left mouse button is being pressed. +/** Built-in attribute specific to wxNumericProperty and derived properties, + like wxIntProperty, wxUIntProperty, wxFloatProperty, used by SpinCtrl editor, + @c bool. If @true, value can also by changed by moving mouse when left + mouse button is being pressed. */ #define wxPG_ATTR_SPINCTRL_MOTION wxS("MotionSpin") @@ -461,7 +471,7 @@ wxPG_PROP_CLASS_SPECIFIC_3 = 0x00400000 @subsection wxIntProperty - Like wxStringProperty, but converts text to a signed long integer. + It derives from wxNumericProperty and displays value as a signed long integer. wxIntProperty seamlessly supports 64-bit integers (i.e. wxLongLong) on overlfow. To safely convert variant to integer, use code like this: @@ -498,6 +508,9 @@ wxPG_PROP_CLASS_SPECIFIC_3 = 0x00400000 Supported special attributes: - ::wxPG_ATTR_MIN, ::wxPG_ATTR_MAX to specify acceptable value range. + - ::wxPG_ATTR_SPINCTRL_STEP, ::wxPG_ATTR_SPINCTRL_WRAP, + ::wxPG_ATTR_SPINCTRL_MOTION: Sets SpinCtrl editor parameters. + @see @ref propgrid_property_attributes @subsection wxUIntProperty @@ -517,6 +530,8 @@ wxPG_PROP_CLASS_SPECIFIC_3 = 0x00400000 - ::wxPG_UINT_PREFIX: Defines displayed prefix. Possible values are ::wxPG_PREFIX_NONE, ::wxPG_PREFIX_0x and ::wxPG_PREFIX_DOLLAR_SIGN. Only ::wxPG_PREFIX_NONE works with decimal and octal numbers. + - ::wxPG_ATTR_SPINCTRL_STEP, ::wxPG_ATTR_SPINCTRL_WRAP, + ::wxPG_ATTR_SPINCTRL_MOTION: Sets SpinCtrl editor parameters. @see @ref propgrid_property_attributes @remarks @@ -540,6 +555,8 @@ wxPG_PROP_CLASS_SPECIFIC_3 = 0x00400000 - ::wxPG_FLOAT_PRECISION: Sets the (max) precision used when floating point value is rendered as text. The default -1 means shortest floating-point 6-digit representation. + - ::wxPG_ATTR_SPINCTRL_STEP, ::wxPG_ATTR_SPINCTRL_WRAP, + ::wxPG_ATTR_SPINCTRL_MOTION: Sets SpinCtrl editor parameters. @see @ref propgrid_property_attributes @subsection wxBoolProperty diff --git a/interface/wx/propgrid/props.h b/interface/wx/propgrid/props.h index b36c29a8ad..f0403ceca3 100644 --- a/interface/wx/propgrid/props.h +++ b/interface/wx/propgrid/props.h @@ -100,6 +100,68 @@ public: virtual bool Validate(wxWindow* parent); }; +/** @class wxNumericProperty + @ingroup classes + + This is an abstract class which serves as a base class for numeric properties, + like wxIntProperty, wxUIntProperty, wxFloatProperty. + + Supported special attributes: + - ::wxPG_ATTR_MIN, ::wxPG_ATTR_MAX: Specify acceptable value range. + - ::wxPG_ATTR_SPINCTRL_STEP: How much number changes when SpinCtrl editor + button is pressed (or up/down on keyboard). + - ::wxPG_ATTR_SPINCTRL_WRAP: Specify if value modified with SpinCtrl editor + wraps at Min/Max. + - ::wxPG_ATTR_SPINCTRL_MOTION: Specify if value can also by changed with + SpinCtrl editor by moving mouse when left mouse button is being pressed. +*/ +class wxNumericProperty : public wxPGProperty +{ +public: + virtual ~wxNumericProperty(); + + virtual bool DoSetAttribute(const wxString& name, wxVariant& value); + + /** + Returns what would be the new value of the property after adding + SpinCtrl editor step to the current value. Current value range + and wrapping (if enabled) are taken into account. + This member has to be implemented in derived properties. + + @param stepScale + SpinCtrl editor step is first multiplied by this factor and next + added to the current value. + + @return + Value which property would have after adding SpinCtrl editor step. + + @remark + Current property value is not changed. + */ + virtual wxVariant AddSpinStepValue(long stepScale) const = 0; + + /** + Return @true if value can be changed with SpinCtrl editor by moving + the mouse. + */ + bool UseSpinMotion() const; + + wxVariant GetMinVal() const; + wxVariant GetMaxVal() const; + +protected: + /** + Constructor is protected because wxNumericProperty is only a base + class for other numeric property classes. + */ + wxNumericProperty(const wxString& label, const wxString& name); + + wxVariant m_minVal; + wxVariant m_maxVal; + bool m_spinMotion; + wxVariant m_spinStep; + bool m_spinWrap; +}; /** @class wxIntProperty @@ -141,9 +203,11 @@ public: Supported special attributes: - - ::wxPG_ATTR_MIN, ::wxPG_ATTR_MAX: Specify acceptable value range. + - ::wxPG_ATTR_MIN, ::wxPG_ATTR_MAX, ::wxPG_ATTR_SPINCTRL_STEP, + ::wxPG_ATTR_SPINCTRL_WRAP, ::wxPG_ATTR_SPINCTRL_MOTION: + like in wxNumericProperty. */ -class wxIntProperty : public wxPGProperty +class wxIntProperty : public wxNumericProperty { public: wxIntProperty( const wxString& label = wxPG_LABEL, @@ -165,6 +229,7 @@ public: int argFlags = 0 ) const; static wxValidator* GetClassValidator(); virtual wxValidator* DoGetValidator() const; + virtual wxVariant AddSpinStepValue(long stepScale) const; /** Validation helper. */ @@ -182,19 +247,21 @@ public: Seamlessly supports 64-bit integer (wxULongLong) on overflow. Supported special attributes: - - ::wxPG_ATTR_MIN, ::wxPG_ATTR_MAX: Specify acceptable value range. - ::wxPG_UINT_BASE: Define base. Valid constants are ::wxPG_BASE_OCT, ::wxPG_BASE_DEC, ::wxPG_BASE_HEX and ::wxPG_BASE_HEXL (lowercase characters). Arbitrary bases are not supported. - ::wxPG_UINT_PREFIX: Possible values are ::wxPG_PREFIX_NONE, ::wxPG_PREFIX_0x, and ::wxPG_PREFIX_DOLLAR_SIGN. Only ::wxPG_PREFIX_NONE works with Decimal and Octal numbers. + - ::wxPG_ATTR_MIN, ::wxPG_ATTR_MAX, ::wxPG_ATTR_SPINCTRL_STEP, + ::wxPG_ATTR_SPINCTRL_WRAP, ::wxPG_ATTR_SPINCTRL_MOTION: + like in wxNumericProperty. @remarks - For example how to use seamless 64-bit integer support, see wxIntProperty documentation (just use wxULongLong instead of wxLongLong). */ -class wxUIntProperty : public wxPGProperty +class wxUIntProperty : public wxNumericProperty { public: wxUIntProperty( const wxString& label = wxPG_LABEL, @@ -215,6 +282,8 @@ public: virtual bool IntToValue( wxVariant& variant, int number, int argFlags = 0 ) const; + virtual wxVariant AddSpinStepValue(long stepScale) const; + protected: wxByte m_base; wxByte m_realBase; // translated to 8,16,etc. @@ -229,8 +298,11 @@ protected: Supported special attributes: - ::wxPG_FLOAT_PRECISION: Sets the (max) precision used when floating point value is rendered as text. The default -1 means infinite precision. + - ::wxPG_ATTR_MIN, ::wxPG_ATTR_MAX, ::wxPG_ATTR_SPINCTRL_STEP, + ::wxPG_ATTR_SPINCTRL_WRAP, ::wxPG_ATTR_SPINCTRL_MOTION: + like in wxNumericProperty. */ -class wxFloatProperty : public wxPGProperty +class wxFloatProperty : public wxNumericProperty { public: wxFloatProperty( const wxString& label = wxPG_LABEL, @@ -255,6 +327,7 @@ public: wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ); static wxValidator* GetClassValidator(); virtual wxValidator* DoGetValidator () const; + virtual wxVariant AddSpinStepValue(long stepScale) const; protected: int m_precision; diff --git a/samples/propgrid/propgrid.cpp b/samples/propgrid/propgrid.cpp index 43cc8d3d1f..2d89e03189 100644 --- a/samples/propgrid/propgrid.cpp +++ b/samples/propgrid/propgrid.cpp @@ -1191,7 +1191,7 @@ void FormMain::PopulateWithExamples () pg->Append( new wxIntProperty ( "SpinCtrl", wxPG_LABEL, 0L ) ); pg->SetPropertyEditor( "SpinCtrl", wxPGEditor_SpinCtrl ); - pg->SetPropertyAttribute( "SpinCtrl", wxPG_ATTR_MIN, -10L ); // Use constants instead of string + pg->SetPropertyAttribute( "SpinCtrl", wxPG_ATTR_MIN, -2L ); // Use constants instead of string pg->SetPropertyAttribute( "SpinCtrl", wxPG_ATTR_MAX, 16384L ); // for reduced binary size. pg->SetPropertyAttribute( "SpinCtrl", wxPG_ATTR_SPINCTRL_STEP, 2L ); pg->SetPropertyAttribute( "SpinCtrl", wxPG_ATTR_SPINCTRL_MOTION, true ); diff --git a/src/propgrid/advprops.cpp b/src/propgrid/advprops.cpp index 45a305942f..d967c01609 100644 --- a/src/propgrid/advprops.cpp +++ b/src/propgrid/advprops.cpp @@ -257,38 +257,48 @@ wxPGSpinCtrlEditor::~wxPGSpinCtrlEditor() wxPGWindowList wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property, const wxPoint& pos, const wxSize& sz ) const { - const int margin = 1; - wxSpinButton* wnd2; + wxSize tcSz; + wxNumericProperty* prop = wxDynamicCast(property, wxNumericProperty); + if ( prop ) + { + const int margin = 1; #if IS_MOTION_SPIN_SUPPORTED - if ( property->GetAttributeAsLong(wxPG_ATTR_SPINCTRL_MOTION, 0) ) - { - wnd2 = new wxPGSpinButton(); - } - else + if ( prop->UseSpinMotion() ) + { + wnd2 = new wxPGSpinButton(); + } + else #endif - { - wnd2 = new wxSpinButton(); - } + { + wnd2 = new wxSpinButton(); + } #ifdef __WXMSW__ - wnd2->Hide(); + wnd2->Hide(); #endif - wnd2->Create( propgrid->GetPanel(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL ); - // Scale spin button to the required height (row height) - wxSize butSz = wnd2->GetBestSize(); + wnd2->Create(propgrid->GetPanel(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL); + // Scale spin button to the required height (row height) + wxSize butSz = wnd2->GetBestSize(); #ifdef __WXGTK3__ - // Under GTK+ 3 spin button is always horizontal and cannot be downscaled - int butWidth = butSz.x; + // Under GTK+ 3 spin button is always horizontal and cannot be downscaled + int butWidth = butSz.x; #else - double sc = (double)sz.y / butSz.y; - int butWidth = wxMax(18, wxRound(sc*butSz.x)); + double sc = (double)sz.y / butSz.y; + int butWidth = wxMax(18, wxRound(sc*butSz.x)); #endif - wxSize tcSz(sz.x - butWidth - margin, sz.y); - wnd2->SetSize(pos.x + tcSz.x + margin, pos.y, butWidth, sz.y); - wnd2->SetRange( INT_MIN, INT_MAX ); - wnd2->SetValue( 0 ); + tcSz.Set(sz.x - butWidth - margin, sz.y); + wnd2->SetSize(pos.x + tcSz.x + margin, pos.y, butWidth, sz.y); + wnd2->SetRange(INT_MIN, INT_MAX); + wnd2->SetValue(0); + } + else + { + wxFAIL_MSG( "SpinCtrl editor can be assigned only to numeric property" ); + tcSz.Set(sz.x, sz.y); + wnd2 = NULL; + } wxWindow* wnd1 = wxPGTextCtrlEditor::CreateControls(propgrid, property, pos, tcSz).m_primary; #if wxUSE_VALIDATORS @@ -301,139 +311,63 @@ wxPGWindowList wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid* propgrid, wxP } // Control's events are redirected here -bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property, - wxWindow* wnd, wxEvent& event ) const +bool wxPGSpinCtrlEditor::OnEvent(wxPropertyGrid* propgrid, wxPGProperty* property, + wxWindow* wnd, wxEvent& event) const { - wxEventType evtType = event.GetEventType(); - bool bigStep = false; - - if ( evtType == wxEVT_KEY_DOWN ) + wxNumericProperty* prop = wxDynamicCast(property, wxNumericProperty); + if ( prop ) { - wxKeyEvent& keyEvent = (wxKeyEvent&)event; - int keycode; - keycode = keyEvent.GetKeyCode(); + wxEventType evtType = event.GetEventType(); + bool bigStep = false; - if ( keycode == WXK_UP ) - evtType = wxEVT_SCROLL_LINEUP; - else if ( keycode == WXK_DOWN ) - evtType = wxEVT_SCROLL_LINEDOWN; - else if ( keycode == WXK_PAGEUP ) + if ( evtType == wxEVT_KEY_DOWN ) { - evtType = wxEVT_SCROLL_LINEUP; - bigStep = true; + wxKeyEvent& keyEvent = (wxKeyEvent&)event; + int keycode; + keycode = keyEvent.GetKeyCode(); + + if ( keycode == WXK_UP ) + evtType = wxEVT_SCROLL_LINEUP; + else if ( keycode == WXK_DOWN ) + evtType = wxEVT_SCROLL_LINEDOWN; + else if ( keycode == WXK_PAGEUP ) + { + evtType = wxEVT_SCROLL_LINEUP; + bigStep = true; + } + else if ( keycode == WXK_PAGEDOWN ) + { + evtType = wxEVT_SCROLL_LINEDOWN; + bigStep = true; + } } - else if ( keycode == WXK_PAGEDOWN ) + + if ( evtType == wxEVT_SCROLL_LINEUP || evtType == wxEVT_SCROLL_LINEDOWN ) { - evtType = wxEVT_SCROLL_LINEDOWN; - bigStep = true; + int spins = 1; +#if IS_MOTION_SPIN_SUPPORTED + if ( prop->UseSpinMotion() ) + { + wxPGSpinButton* spinButton = + (wxPGSpinButton*)propgrid->GetEditorControlSecondary(); + + if ( spinButton ) + spins = spinButton->GetSpins(); + } +#endif + + long stepScale = (evtType == wxEVT_SCROLL_LINEUP) ? 1L : -1L; + if ( bigStep ) + stepScale *= 10L; + stepScale *= spins; + + wxVariant v = prop->AddSpinStepValue(stepScale); + SetControlStringValue(prop, propgrid->GetEditorControl(), prop->ValueToString(v)); + return true; } } - - if ( evtType == wxEVT_SCROLL_LINEUP || evtType == wxEVT_SCROLL_LINEDOWN ) - { - int spins = 1; - #if IS_MOTION_SPIN_SUPPORTED - if ( property->GetAttributeAsLong(wxPG_ATTR_SPINCTRL_MOTION, 0) ) - { - wxPGSpinButton* spinButton = - (wxPGSpinButton*) propgrid->GetEditorControlSecondary(); - - if ( spinButton ) - spins = spinButton->GetSpins(); - } - #endif - - wxString s; - // Can't use wnd since it might be clipper window - wxTextCtrl* tc = wxDynamicCast(propgrid->GetEditorControl(), wxTextCtrl); - - if ( tc ) - s = tc->GetValue(); - else - s = property->GetValueAsString(wxPG_FULL_VALUE); - - int mode = wxPG_PROPERTY_VALIDATION_SATURATE; - - if ( property->GetAttributeAsLong(wxPG_ATTR_SPINCTRL_WRAP, 0) ) - mode = wxPG_PROPERTY_VALIDATION_WRAP; - - if ( property->GetValueType() == wxPG_VARIANT_TYPE_DOUBLE ) - { - double v_d; - double step = property->GetAttributeAsDouble(wxPG_ATTR_SPINCTRL_STEP, 1.0); - - // Try double - if ( s.ToDouble(&v_d) ) - { - if ( bigStep ) - step *= 10.0; - - step *= (double) spins; - - if ( evtType == wxEVT_SCROLL_LINEUP ) v_d += step; - else v_d -= step; - - // Min/Max check - wxFloatProperty::DoValidation(property, v_d, NULL, mode); - - wxVariant v(v_d); - s = property->ValueToString(v, 0); - } - else - { - return false; - } - } - else - { - long step = property->GetAttributeAsLong(wxPG_ATTR_SPINCTRL_STEP, 1); -#if defined(wxLongLong_t) && wxUSE_LONGLONG - wxLongLong_t v_ll; - // Try long long - if ( s.ToLongLong(&v_ll, 10) ) -#else - long v_ll; - // Try long - if ( s.ToLong(&v_ll, 10) ) -#endif - { - if ( bigStep ) - step *= 10; - - step *= spins; - - if ( evtType == wxEVT_SCROLL_LINEUP ) v_ll += step; - else v_ll -= step; - - // Min/Max check - wxIntProperty::DoValidation(property, v_ll, NULL, mode); - -#if defined(wxLongLong_t) && wxUSE_LONGLONG - s = wxLongLong(v_ll).ToString(); -#else - s = wxString::Format(wxS("%ld"), v_ll); -#endif - } - else - { - return false; - } - } - - if ( tc ) - { - int ip = tc->GetInsertionPoint(); - int lp = tc->GetLastPosition(); - tc->SetValue(s); - tc->SetInsertionPoint(ip+(tc->GetLastPosition()-lp)); - } - - return true; - } - - return wxPGTextCtrlEditor::OnEvent(propgrid,property,wnd,event); + return wxPGTextCtrlEditor::OnEvent(propgrid, property, wnd, event); } - #endif // wxUSE_SPINBTN diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index 3d6000baeb..8e3785cadb 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -214,21 +214,69 @@ bool wxNumericPropertyValidator::Validate(wxWindow* parent) #endif // wxUSE_VALIDATORS +// ----------------------------------------------------------------------- +// wxNumericProperty +// ----------------------------------------------------------------------- + +wxIMPLEMENT_ABSTRACT_CLASS(wxNumericProperty, wxPGProperty) + +wxNumericProperty::wxNumericProperty(const wxString& label, const wxString& name) + : wxPGProperty(label, name) + , m_spinMotion(false) + , m_spinStep(1L) + , m_spinWrap(false) +{ +} + +wxNumericProperty::~wxNumericProperty() +{ +} + +bool wxNumericProperty::DoSetAttribute(const wxString& name, wxVariant& value) +{ + if ( name == wxPG_ATTR_MIN ) + { + m_minVal = value; + return true; + } + else if ( name == wxPG_ATTR_MAX ) + { + m_maxVal = value; + return true; + } + else if ( name == wxPG_ATTR_SPINCTRL_MOTION ) + { + m_spinMotion = value.GetBool(); + return true; + } + else if ( name == wxPG_ATTR_SPINCTRL_STEP ) + { + m_spinStep = value; + return true; + } + else if ( name == wxPG_ATTR_SPINCTRL_WRAP ) + { + m_spinWrap = value.GetBool(); + return true; + } + return wxPGProperty::DoSetAttribute(name, value); +} + // ----------------------------------------------------------------------- // wxIntProperty // ----------------------------------------------------------------------- -wxPG_IMPLEMENT_PROPERTY_CLASS(wxIntProperty,wxPGProperty,TextCtrl) +wxPG_IMPLEMENT_PROPERTY_CLASS(wxIntProperty,wxNumericProperty,TextCtrl) wxIntProperty::wxIntProperty( const wxString& label, const wxString& name, - long value ) : wxPGProperty(label,name) + long value ) : wxNumericProperty(label,name) { SetValue(value); } #if wxUSE_LONGLONG wxIntProperty::wxIntProperty( const wxString& label, const wxString& name, - const wxLongLong& value ) : wxPGProperty(label,name) + const wxLongLong& value ) : wxNumericProperty(label,name) { SetValue(wxVariant(value)); } @@ -364,7 +412,7 @@ double GetRoundedValue(const wxPGProperty* prop, double value) // Note that 'value' is reference on purpose, so we can write // back to it when mode is wxPG_PROPERTY_VALIDATION_SATURATE or wxPG_PROPERTY_VALIDATION_WRAP. template -bool NumericValidation( const wxPGProperty* property, +bool NumericValidation( const wxNumericProperty* property, T& value, wxPGValidationInfo* pValidationInfo, int mode, T defMin, T defMax) @@ -378,7 +426,7 @@ bool NumericValidation( const wxPGProperty* property, // Round current value to the required precision, if applicable value = GetRoundedValue(property, value); - variant = property->GetAttribute(wxPG_ATTR_MIN); + variant = property->GetMinVal(); if ( !variant.IsNull() ) { minOk = variant.Convert(&min); @@ -389,7 +437,7 @@ bool NumericValidation( const wxPGProperty* property, min = GetRoundedValue(property, min); } - variant = property->GetAttribute(wxPG_ATTR_MAX); + variant = property->GetMaxVal(); if ( !variant.IsNull() ) { maxOk = variant.Convert(&max); @@ -466,7 +514,7 @@ bool NumericValidation( const wxPGProperty* property, } // namespace #if wxUSE_LONGLONG -bool wxIntProperty::DoValidation( const wxPGProperty* property, +bool wxIntProperty::DoValidation( const wxNumericProperty* property, wxLongLong& value, wxPGValidationInfo* pValidationInfo, int mode ) @@ -478,7 +526,7 @@ bool wxIntProperty::DoValidation( const wxPGProperty* property, } #if defined(wxLongLong_t) -bool wxIntProperty::DoValidation( const wxPGProperty* property, +bool wxIntProperty::DoValidation( const wxNumericProperty* property, wxLongLong_t& value, wxPGValidationInfo* pValidationInfo, int mode ) @@ -489,7 +537,7 @@ bool wxIntProperty::DoValidation( const wxPGProperty* property, #endif // wxLongLong_t #endif // wxUSE_LONGLONG -bool wxIntProperty::DoValidation(const wxPGProperty* property, +bool wxIntProperty::DoValidation(const wxNumericProperty* property, long& value, wxPGValidationInfo* pValidationInfo, int mode) @@ -529,6 +577,37 @@ wxValidator* wxIntProperty::DoGetValidator() const return GetClassValidator(); } +wxVariant wxIntProperty::AddSpinStepValue(long stepScale) const +{ + int mode = m_spinWrap ? wxPG_PROPERTY_VALIDATION_WRAP + : wxPG_PROPERTY_VALIDATION_SATURATE; + wxVariant value = GetValue(); + if ( value.GetType() == wxPG_VARIANT_TYPE_LONG ) + { + long v = value.GetLong(); + long step = m_spinStep.GetLong(); + v += (step * stepScale); + DoValidation(this, v, NULL, mode); + value = v; + } +#if wxUSE_LONGLONG + else if ( value.GetType() == wxPG_VARIANT_TYPE_LONGLONG ) + { + wxLongLong v = value.GetLongLong(); + wxLongLong step = m_spinStep.GetLongLong(); + v += (step * stepScale); + DoValidation(this, v, NULL, mode); + value = v; + } +#endif // wxUSE_LONGLONG + else + { + wxFAIL_MSG("Unknown value type"); + } + + return value; +} + // ----------------------------------------------------------------------- // wxUIntProperty // ----------------------------------------------------------------------- @@ -546,7 +625,7 @@ enum wxPG_UINT_TEMPLATE_MAX }; -wxPG_IMPLEMENT_PROPERTY_CLASS(wxUIntProperty,wxPGProperty,TextCtrl) +wxPG_IMPLEMENT_PROPERTY_CLASS(wxUIntProperty,wxNumericProperty,TextCtrl) void wxUIntProperty::Init() { @@ -556,7 +635,7 @@ void wxUIntProperty::Init() } wxUIntProperty::wxUIntProperty( const wxString& label, const wxString& name, - unsigned long value ) : wxPGProperty(label,name) + unsigned long value ) : wxNumericProperty(label,name) { Init(); SetValue((long)value); @@ -564,7 +643,7 @@ wxUIntProperty::wxUIntProperty( const wxString& label, const wxString& name, #if wxUSE_LONGLONG wxUIntProperty::wxUIntProperty( const wxString& label, const wxString& name, - const wxULongLong& value ) : wxPGProperty(label,name) + const wxULongLong& value ) : wxNumericProperty(label,name) { Init(); SetValue(wxVariant(value)); @@ -712,7 +791,7 @@ bool wxUIntProperty::IntToValue( wxVariant& variant, int number, int WXUNUSED(ar } #if wxUSE_LONGLONG -bool wxUIntProperty::DoValidation(const wxPGProperty* property, +bool wxUIntProperty::DoValidation(const wxNumericProperty* property, wxULongLong& value, wxPGValidationInfo* pValidationInfo, int mode ) @@ -722,7 +801,7 @@ bool wxUIntProperty::DoValidation(const wxPGProperty* property, } #if defined(wxULongLong_t) -bool wxUIntProperty::DoValidation(const wxPGProperty* property, +bool wxUIntProperty::DoValidation(const wxNumericProperty* property, wxULongLong_t& value, wxPGValidationInfo* pValidationInfo, int mode ) @@ -733,7 +812,7 @@ bool wxUIntProperty::DoValidation(const wxPGProperty* property, #endif // wxULongLong_t #endif // wxUSE_LONGLONG -bool wxUIntProperty::DoValidation(const wxPGProperty* property, +bool wxUIntProperty::DoValidation(const wxNumericProperty* property, long& value, wxPGValidationInfo* pValidationInfo, int mode) @@ -794,19 +873,50 @@ bool wxUIntProperty::DoSetAttribute( const wxString& name, wxVariant& value ) m_prefix = (wxByte) value.GetLong(); return true; } - return wxPGProperty::DoSetAttribute(name, value); + return wxNumericProperty::DoSetAttribute(name, value); +} + +wxVariant wxUIntProperty::AddSpinStepValue(long stepScale) const +{ + int mode = m_spinWrap ? wxPG_PROPERTY_VALIDATION_WRAP + : wxPG_PROPERTY_VALIDATION_SATURATE; + wxVariant value = GetValue(); + if ( value.GetType() == wxPG_VARIANT_TYPE_LONG ) + { + long v = value.GetLong(); + long step = m_spinStep.GetLong(); + v += (step * stepScale); + DoValidation(this, v, NULL, mode); + value = v; + } +#if wxUSE_LONGLONG + else if ( value.GetType() == wxPG_VARIANT_TYPE_ULONGLONG ) + { + wxULongLong v = value.GetULongLong(); + wxULongLong step = m_spinStep.GetULongLong(); + v += (step * stepScale); + DoValidation(this, v, NULL, mode); + value = v; + } +#endif // wxUSE_LONGLONG + else + { + wxFAIL_MSG("Unknown value type"); + } + + return value; } // ----------------------------------------------------------------------- // wxFloatProperty // ----------------------------------------------------------------------- -wxPG_IMPLEMENT_PROPERTY_CLASS(wxFloatProperty,wxPGProperty,TextCtrl) +wxPG_IMPLEMENT_PROPERTY_CLASS(wxFloatProperty,wxNumericProperty,TextCtrl) wxFloatProperty::wxFloatProperty( const wxString& label, const wxString& name, double value ) - : wxPGProperty(label,name) + : wxNumericProperty(label,name) { m_precision = -1; SetValue(value); @@ -927,7 +1037,7 @@ bool wxFloatProperty::StringToValue( wxVariant& variant, const wxString& text, i return false; } -bool wxFloatProperty::DoValidation( const wxPGProperty* property, +bool wxFloatProperty::DoValidation( const wxNumericProperty* property, double& value, wxPGValidationInfo* pValidationInfo, int mode ) @@ -954,7 +1064,7 @@ bool wxFloatProperty::DoSetAttribute( const wxString& name, wxVariant& value ) m_precision = value.GetLong(); return true; } - return wxPGProperty::DoSetAttribute(name, value); + return wxNumericProperty::DoSetAttribute(name, value); } wxValidator* @@ -977,6 +1087,20 @@ wxValidator* wxFloatProperty::DoGetValidator() const return GetClassValidator(); } +wxVariant wxFloatProperty::AddSpinStepValue(long stepScale) const +{ + int mode = m_spinWrap ? wxPG_PROPERTY_VALIDATION_WRAP + : wxPG_PROPERTY_VALIDATION_SATURATE; + wxVariant value = GetValue(); + double v = value.GetDouble(); + double step = m_spinStep.GetDouble(); + v += (step * stepScale); + DoValidation(this, v, NULL, mode); + value = v; + + return value; +} + // ----------------------------------------------------------------------- // wxBoolProperty // -----------------------------------------------------------------------