📄 propgrid.cpp
字号:
// function instead) to allow best use for wxClassInfo::CreateObject.
// * Use wxObject::m_refData as storage for client data.
// * wxVariant values for AddPropertyChoice.
// * Consider: variant values would allow really flexible system.
//
//
// API Questions:
// - id.Ok instead of id.IsOk? Treectrlid has .IsOk so that is probably ok.
//
//
// -----------------------------------------------------------------------
// TODO
// -----------------------------------------------------------------------
//
//
// For Next Release (1.0.1):
//
// Maybe for 1.1:
// * Consider: Match system font size in grid.
// Problem: There is no preferred font point size detection.
// * wxGTK1: Multichoice can't get value correctly.
// * wxGTK1: Control(s) disapper after:
// Splitter centering.
// Collapse expand.
// - Refresh is not enough?
// * Make tab traversal to other controls (Navigate) work like it should.
// * wxMSW: Scrollbar "freezing".
// Symptom: After popup is shown, and even if destroyed, scrollbar in
// the wxScrolledWindow refuses to become hot (but usually still works).
// Ends when another window becomes activated or window is resized
// (horizontally, even programmatically is ok).
// * Font family list (or maybe dialog).
//
// For 1.1+:
// * Locking for globals.
// * GetPropertyAttribute.
// * Splitter position relative change on resize (to prevent twicthing
// caused by scrollbar change but splitter not centering).
// * Multiple delimiters for string tokenizers (e.g. ';' in addition to ',').
// * Consider: Further additions to wxPropertyContainerMethods
// (virtual Insert, Delete and DrawItemAndChildren, and then methods
// that need them). This could reduce size of wxPropertyGridManager
// code.
// * Consider: three-argument wxEnumProperty (choices would be added
// with AddPropertyChoice). Already has this, but with docs too.
// * Error/Warning popups (preferably a balloon tooltip on Win NT-based OS).
// * Consider adding optional images in front of property label.
// * Improve string editor dialog (but how?).
// * Tree buttons to use system colours. What colours to use?
// Native rendering only produces one set of buttons, so that won't
// do (or we would need to use that and another method).
//
// Bug Fixes:
// * wxGTK, no cc: Right-click doesn't occur if right-clicked on control.
// * wxGTK, no cc: TAB-based editor browsing ceases sometimes (try 2nd page, until
// two disabled boolprops).
//
// High Priority:
// * wxMAC port (if I only could!).
//
// Medium Priority:
// * Some (flag) longs to wxuint32s.
// * wxPropertyGridManager's missing methods:
// GetLastProperty.
// * Adding items when focused is no-no.
// * Properly fix DoGetBestSize (both controls). How? It is called but
// result is probably somehow interpreted incorrectly.
// * Other ports?
//
// To Consider:
// * Simple checkbox: Background clear unaligned (see with grey colour scheme).
// Problem: It is caused by the MSW checkmark drawing background clear.
// * Remove hover support to lighten some code (no tooltips, then).
// Would basicly eliminate need for visibility cache (get first visible
// instead viscache refresh and find items around it).
// * Embed page system in wxPropertyGrid. Not wxScrolledWindow to make
// wxPropertyGridManager to inherit from wxPropertyGrid.
// Feb-13-2005: Not a good idea, would simply be complicated in another way.
// Mar-29-2005: Actually, end result would be better (pages would be the top
// level of property hierarchy), but workload in comparison enormous.
// * Custom image horizontal size increment in relation to line height.
// Feb-13-2005: Only real help if people use really big ( ptsz>12 ) fonts.
// So this is real low priority.
// * At some occasions, maybe use FindOrCreatePen and FindOrCreateBrush.
// Feb-13-2005: More bloat for marginal gains.
// * Key event forwarding (use ex flag to mark that).
// Feb-13-2005: Really needed?
// * Visual state saving (which items are expanded and which collapsed,
// which mode is selected).
// Feb-13-2005: More bloat?
// * Manager: SetCustomModeBitmaps. Call before toolbar is actually created.
// Feb-13-2005: More bloat?
// * More drop-down editors (for wxLongStringProperty etc.) instead of modal dialogs.
// Problem: complex, multi-sub-control popups do not work yet (will they ever work?).
// * Replace: replaces one property with another. Must have same label or auto sorting
// must be turned off.
// Feb-13-2005: More bloat?
//
// Low Priority:
// * wxPropertyGridManager::SetFont.
// * Native textctrl spacing to work properly with font sizes > 10.
// * Basic context menu with Reset() and checkable Show Description that toggle the help box.
// * wxCustomEnumProperty - Allows user to set the image as well.
// * GetItemAtY() to use binary search.
// * When focus out from control, selected is drawn in background instead in selforeground,
// like in .NET implementation.
// * Preparations for wxPGProperty direct usage.
// * Refine dialog-position auto-generator.
// * Maybe different colour lines between categories (like light grey ones in .NET).
// (though I don't think its that elegant).
//
//
// Documentation Todo:
// * Set/GetPropertyValue: Strings work for all value types.
// * SetPropertyAttribute.
// * Having graphics glitches? Use Freeze and Thaw.
// * How to do a property that uses choices list (i.e. how to handle wxPGConstants*).
//
/**
Validation Feature:
- Added property value validation scheme. Use like this:
wxIntPropertyValidator int_validator(min,max);
pg->SetPropertyValidator(wxT("MyIntProperty"),int_validator);
Also has wxFloatPropertyValidator that works exactly the same
way, but for properties with double as value type.
To create custom validators, see wxPropertyValidator (base
class for property validators) documentation and progrid.h/
propgrid.cpp code.
#if wxPG_USE_VALIDATORS
m_validator->AssertDataType(wxT("double"));
#endif
....
To wxArrayDoublePropertyClass::SetValueFromString:
#if wxPG_USE_VALIDATORS
else if ( m_validator )
{
wxPGVariant tvariant(tval);
if ( !m_validator->Validate(tvariant,tstr) )
{
ok = FALSE;
break;
}
}
#endif
*/
// -----------------------------------------------------------------------
const wxChar *wxPropertyGridNameStr = wxT("wxPropertyGrid");
const wxChar *wxPGTypeName_long = wxT("long");
const wxChar *wxPGTypeName_bool = wxT("bool");
const wxChar *wxPGTypeName_double = wxT("double");
const wxChar *wxPGTypeName_wxString = wxT("string");
const wxChar *wxPGTypeName_void = wxT("void*");
const wxChar *wxPGTypeName_wxArrayString = wxT("arrstring");
// -----------------------------------------------------------------------
// wxStringProperty
// -----------------------------------------------------------------------
wxPG_BEGIN_PROPERTY_CLASS_BODY(wxStringProperty,wxPGProperty,wxString,const wxString&)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
wxPG_END_PROPERTY_CLASS_BODY()
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxStringProperty,wxString,const wxString&,TextCtrl)
wxStringPropertyClass::wxStringPropertyClass ( const wxString& label, const wxString& name,
const wxString& value ) : wxPGProperty(label,name)
{
DoSetValue(value);
}
wxStringPropertyClass::~wxStringPropertyClass () { }
void wxStringPropertyClass::DoSetValue ( wxPGVariant value )
{
m_value = wxPGVariantToString(value);
wxPG_SetVariantValue(m_value);
}
wxPGVariant wxStringPropertyClass::DoGetValue () const
{
return wxPGVariant(m_value);
}
wxString wxStringPropertyClass::GetValueAsString ( int ) const
{
return m_value;
}
bool wxStringPropertyClass::SetValueFromString ( const wxString& text, int )
{
if ( m_value != text )
return StdValidationProcedure(text);
return FALSE;
}
// -----------------------------------------------------------------------
// wxIntProperty
// -----------------------------------------------------------------------
wxPG_BEGIN_PROPERTY_CLASS_BODY(wxIntProperty,wxPGProperty,long,long)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
wxPG_END_PROPERTY_CLASS_BODY()
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxIntProperty,long,long,TextCtrl)
wxIntPropertyClass::wxIntPropertyClass ( const wxString& label, const wxString& name,
long value ) : wxPGProperty(label,name)
{
DoSetValue(value);
}
wxIntPropertyClass::~wxIntPropertyClass () { }
void wxIntPropertyClass::DoSetValue ( wxPGVariant value )
{
m_value = wxPGVariantToLong(value);
wxPG_SetVariantValue(m_value);
}
wxPGVariant wxIntPropertyClass::DoGetValue () const
{
return wxPGVariant(m_value);
}
wxString wxIntPropertyClass::GetValueAsString ( int ) const
{
wxString temp;
temp.Printf(wxT("%li"),m_value);
return temp;
}
bool wxIntPropertyClass::SetValueFromString ( const wxString& text, int arg_flags )
{
wxString s;
long value;
if ( text.IsNumber() )
{
text.ToLong(&value,0); // we know its number, so need to check retval
if ( m_value != value )
{
return StdValidationProcedure(value);
}
}
else if ( arg_flags & wxPG_REPORT_ERROR )
{
s.Printf ( wxT("! %s: \"%s\" is not a number."), m_label.c_str(), text.c_str() );
ShowError(s);
}
return FALSE;
}
// -----------------------------------------------------------------------
// wxUIntProperty
// -----------------------------------------------------------------------
#define wxPG_UINT_TEMPLATE_MAX 8
static const wxChar* gs_uintTemplates[wxPG_UINT_TEMPLATE_MAX] = {
wxT("%x"),wxT("0x%x"),wxT("$%x"),
wxT("%X"),wxT("0x%X"),wxT("$%X"),
wxT("%u"),wxT("%o")
};
wxPG_BEGIN_PROPERTY_CLASS_BODY(wxUIntProperty,wxPGProperty,long,unsigned long)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
WX_PG_DECLARE_ATTRIBUTE_METHODS()
virtual bool SetValueFromInt ( long value, int flags );
protected:
wxByte m_base;
wxByte m_realBase; // translated to 8,16,etc.
wxByte m_prefix;
wxPG_END_PROPERTY_CLASS_BODY()
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxUIntProperty,long,unsigned long,TextCtrl)
wxUIntPropertyClass::wxUIntPropertyClass ( const wxString& label, const wxString& name,
unsigned long value ) : wxPGProperty(label,name)
{
// Set initial value for the sprintf template
/*if ( !wxPGGlobalVars->m_uintTemplate.length() )
{
wxPGGlobalVars->m_uintTemplate = wxT("%u");
wxPGGlobalVars->m_uintRadix = 10;
}*/
m_base = wxPG_BASE_DEC;
m_realBase = 10;
m_prefix = wxPG_PREFIX_NONE;
DoSetValue((long)value);
}
wxUIntPropertyClass::~wxUIntPropertyClass () { }
void wxUIntPropertyClass::DoSetValue ( wxPGVariant value )
{
m_value = wxPGVariantToLong(value);
}
wxPGVariant wxUIntPropertyClass::DoGetValue () const
{
return wxPGVariant(m_value);
}
wxString wxUIntPropertyClass::GetValueAsString ( int ) const
{
//return wxString::Format(wxPGGlobalVars->m_uintTemplate.c_str(),m_value);
size_t index = m_base + m_prefix;
if ( index >= wxPG_UINT_TEMPLATE_MAX )
index = wxPG_BASE_DEC;
return wxString::Format(gs_uintTemplates[index],m_value);
}
bool wxUIntPropertyClass::SetValueFromString ( const wxString& text, int WXUNUSED(arg_flags) )
{
wxString s;
long value = 0;
const wxChar *start = text.c_str();
if ( text[0] && !wxIsalnum(text[0]) )
start++;
wxChar *end;
value = wxStrtoul(start, &end, (unsigned int)m_realBase);
if ( m_value != value )
{
return StdValidationProcedure(value);
}
return false;
}
bool wxUIntPropertyClass::SetValueFromInt( long value, int WXUNUSED(flags) )
{
if ( m_value != value )
{
m_value = value;
return true;
}
return false;
}
void wxUIntPropertyClass::SetAttribute ( int id, wxVariant value )
{
if ( id == wxPG_UINT_BASE )
{
int val = value.GetLong();
m_realBase = (wxByte) val;
if ( m_realBase > 16 )
m_realBase = 16;
//
// Translate logical base to a template array index
m_base = 7; // oct
if ( val == wxPG_BASE_HEX )
m_base = 3;
else if ( val == wxPG_BASE_DEC )
m_base = 6;
else if ( val == wxPG_BASE_HEXL )
m_base = 0;
}
else if ( id == wxPG_UINT_PREFIX )
m_prefix = (wxByte) value.GetLong();
}
// -----------------------------------------------------------------------
// wxFloatProperty
// -----------------------------------------------------------------------
wxPG_BEGIN_PROPERTY_CLASS_BODY(wxFloatProperty,wxPGProperty,double,double)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
WX_PG_DECLARE_ATTRIBUTE_METHODS()
protected:
int m_precision;
wxPG_END_PROPERTY_CLASS_BODY()
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFloatProperty,double,double,TextCtrl)
wxFloatPropertyClass::wxFloatPropertyClass ( const wxString& label, const wxString& name,
double value ) : wxPGProperty(label,name)
{
m_precision = -1;
DoSetValue(value);
}
wxFloatPropertyClass::~wxFloatPropertyClass () { }
void wxFloatPropertyClass::DoSetValue ( wxPGVariant value )
{
m_value = wxPGVariantToDouble(value);
wxPG_SetVariantValue(m_value);
}
wxPGVariant wxFloatPropertyClass::DoGetValue () const
{
return wxPGVariant(m_value);
}
// This helper method provides standard way for floating point-using
// properties to convert values to string.
void wxPropertyGrid::DoubleToString(wxString& target,
double value,
int precision,
bool removeZeroes,
wxString* precTemplate)
{
if ( precision >= 0 )
{
wxString text1;
if (!precTemplate)
precTemplate = &text1;
if ( !precTemplate->length() )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -