variant << value;
SetValue(variant);
- // If has private child properties then create them here, e.g.:
+ // If has private child properties then create them here. Also
+ // set flag that indicates presence of private children. E.g.:
+ //
+ // SetParentalType(wxPG_PROP_AGGREGATE);
+ //
// AddChild( new wxStringProperty( "Subprop 1",
// wxPG_LABEL,
// value.GetSubProp1() ) );
inline void SetName( const wxString& newName );
+ /**
+ Changes what sort of parent this property is for its children.
+
+ @param flag
+ Use one of the following values: wxPG_PROP_MISC_PARENT (for generic
+ parents), wxPG_PROP_CATEGORY (for categories), or
+ wxPG_PROP_AGGREGATE (for derived property classes with private
+ children).
+
+ @remarks You only need to call this if you use AddChild() to add
+ child properties. Adding properties with
+ wxPropertyGridInterface::Insert() or
+ wxPropertyGridInterface::AppendIn() will automatically set
+ property to use wxPG_PROP_MISC_PARENT style.
+ */
+ void SetParentalType( int flag )
+ {
+ m_flags &= ~(wxPG_PROP_PROPERTY|wxPG_PROP_PARENTAL_FLAGS);
+ m_flags |= flag;
+ }
+
void SetValueToUnspecified()
{
wxVariant val; // Create NULL variant
*/
void AdaptListToValue( wxVariant& list, wxVariant* value ) const;
- /** This is used by properties that have fixed sub-properties. */
+ /**
+ Adds a child property. If you use this instead of
+ wxPropertyGridInterface::Insert() or
+ wxPropertyGridInterface::AppendIn(), then you must set up
+ property's parental type before making the call. To do this,
+ call property's SetParentalType() function with either
+ wxPG_PROP_MISC_PARENT (normal, public children) or with
+ wxPG_PROP_AGGREGATE (private children for subclassed property).
+ For instance:
+
+ @code
+ wxPGProperty* prop = new wxStringProperty(wxS("Property"));
+ prop->SetParentalType(wxPG_PROP_MISC_PARENT);
+ wxPGProperty* prop2 = new wxStringProperty(wxS("Property2"));
+ prop->AddChild(prop2);
+ @endcode
+ */
void AddChild( wxPGProperty* prop );
/** Returns height of children, recursively, and
void DoSetName(const wxString& str) { m_name = str; }
- // Call for after sub-properties added with AddChild
- void PrepareSubProperties();
+ void InitAfterAdded( wxPropertyGridPageState* pageState,
+ wxPropertyGrid* propgrid );
// Removes child property with given pointer. Does not delete it.
void RemoveChild( wxPGProperty* p );
- void SetParentalType( int flag )
- {
- m_flags &= ~(wxPG_PROP_PROPERTY|wxPG_PROP_PARENTAL_FLAGS);
- m_flags |= flag;
- }
-
void SetParentState( wxPropertyGridPageState* pstate )
{ m_parentState = pstate; }
void OnCustomEditorEvent( wxCommandEvent &event );
long GetInternalFlags() const { return m_iFlags; }
+ bool HasInternalFlag( long flag ) const
+ { return (m_iFlags & flag) ? true : false; }
void SetInternalFlag( long flag ) { m_iFlags |= flag; }
void ClearInternalFlag( long flag ) { m_iFlags &= ~(flag); }
void IncFrozen() { m_frozen++; }
*/
int HitTestH( int x, int* pSplitterHit, int* pSplitterHitOffset ) const;
- int PrepareToAddItem ( wxPGProperty* property,
+ bool PrepareToAddItem( wxPGProperty* property,
wxPGProperty* scheduledParent );
/** If visible, then this is pointer to wxPropertyGrid.
int AddChoice( const wxString& label, int value = wxPG_INVALID_VALUE );
/**
- Properties which have private child properties should add them
- with this function, called in their constructor.
+ Adds a child property. If you use this instead of
+ wxPropertyGridInterface::Insert() or
+ wxPropertyGridInterface::AppendIn(), then you must set up
+ property's parental type before making the call. To do this,
+ call property's SetParentalType() function with either
+ wxPG_PROP_MISC_PARENT (normal, public children) or with
+ wxPG_PROP_AGGREGATE (private children for subclassed property).
+ For instance:
+
+ @code
+ wxPGProperty* prop = new wxStringProperty(wxS("Property"));
+ prop->SetParentalType(wxPG_PROP_MISC_PARENT);
+ wxPGProperty* prop2 = new wxStringProperty(wxS("Property2"));
+ prop->AddChild(prop2);
+ @endcode
*/
void AddChild( wxPGProperty* property );
*/
void SetName( const wxString& newName );
+ /**
+ Changes what sort of parent this property is for its children.
+
+ @param flag
+ Use one of the following values: wxPG_PROP_MISC_PARENT (for generic
+ parents), wxPG_PROP_CATEGORY (for categories), or
+ wxPG_PROP_AGGREGATE (for derived property classes with private
+ children).
+
+ @remarks You only need to call this if you use AddChild() to add
+ child properties. Adding properties with
+ wxPropertyGridInterface::Insert() or
+ wxPropertyGridInterface::AppendIn() will automatically set
+ property to use wxPG_PROP_MISC_PARENT style.
+ */
+ void SetParentalType( int flag );
+
/** Sets wxValidator for a property */
void SetValidator( const wxValidator& validator );
: wxPGProperty(label,name)
{
SetValue( WXVARIANT(value) );
+ SetParentalType(wxPG_PROP_AGGREGATE);
AddChild( new wxFloatProperty(wxT("X"),wxPG_LABEL,value.x) );
AddChild( new wxFloatProperty(wxT("Y"),wxPG_LABEL,value.y) );
AddChild( new wxFloatProperty(wxT("Z"),wxPG_LABEL,value.z) );
: wxPGProperty(label,name)
{
SetValue( WXVARIANT(value) );
+ SetParentalType(wxPG_PROP_AGGREGATE);
AddChild( new wxVectorProperty(wxT("A"),wxPG_LABEL,value.a) );
AddChild( new wxVectorProperty(wxT("B"),wxPG_LABEL,value.b) );
AddChild( new wxVectorProperty(wxT("C"),wxPG_LABEL,value.c) );
//
// Test how non-editable composite strings appear
- pid = pg->Append( new wxStringProperty(wxT("wxWidgets Traits"), wxPG_LABEL, wxT("<composed>")) );
+ pid = new wxStringProperty(wxT("wxWidgets Traits"), wxPG_LABEL, wxT("<composed>"));
pg->SetPropertyReadOnly(pid);
- pg->AppendIn(pid, new wxStringProperty(wxT("Latest Release"), wxPG_LABEL, wxT("2.8.8")) );
- pg->AppendIn(pid, new wxBoolProperty(wxT("Win API"), wxPG_LABEL, true) );
+ //
+ // For testing purposes, combine two methods of adding children
+ //
+
+ // AddChild() requires that we call this
+ pid->SetParentalType(wxPG_PROP_MISC_PARENT);
+
+ pid->AddChild( new wxStringProperty(wxT("Latest Release"), wxPG_LABEL, wxT("2.8.8")));
+ pid->AddChild( new wxBoolProperty(wxT("Win API"), wxPG_LABEL, true) );
+
+ pg->Append( pid );
+
pg->AppendIn(pid, new wxBoolProperty(wxT("QT"), wxPG_LABEL, false) );
pg->AppendIn(pid, new wxBoolProperty(wxT("Cocoa"), wxPG_LABEL, true) );
pg->AppendIn(pid, new wxBoolProperty(wxT("BeOS"), wxPG_LABEL, false) );
// (instead of calling SetValue) in derived (wxObject) properties.
m_value_wxFontData << value;
+ SetParentalType(wxPG_PROP_AGGREGATE);
+
// Add extra children.
AddChild( new wxColourProperty(_("Colour"), wxPG_LABEL,
fontData.GetColour() ) );
const wxSize& value) : wxPGProperty(label,name)
{
SetValueI(value);
+ SetParentalType(wxPG_PROP_AGGREGATE);
AddChild( new wxIntProperty(wxT("Width"),wxPG_LABEL,value.x) );
AddChild( new wxIntProperty(wxT("Height"),wxPG_LABEL,value.y) );
}
const wxPoint& value) : wxPGProperty(label,name)
{
SetValueI(value);
+ SetParentalType(wxPG_PROP_AGGREGATE);
AddChild( new wxIntProperty(wxT("X"),wxPG_LABEL,value.x) );
AddChild( new wxIntProperty(wxT("Y"),wxPG_LABEL,value.y) );
}
wxFont font;
font << m_value;
+ SetParentalType(wxPG_PROP_AGGREGATE);
+
AddChild( new wxIntProperty( _("Point Size"), wxS("Point Size"),(long)font.GetPointSize() ) );
AddChild( new wxEnumProperty(_("Family"), wxS("PointSize"),
Init();
}
+void wxPGProperty::InitAfterAdded( wxPropertyGridPageState* pageState,
+ wxPropertyGrid* propgrid )
+{
+ //
+ // Called after property has been added to grid or page
+ // (so propgrid can be NULL, too).
+
+ wxPGProperty* parent = m_parent;
+ bool parentIsRoot = parent->IsKindOf(CLASSINFO(wxPGRootProperty));
+
+ m_parentState = pageState;
+
+ if ( !parentIsRoot )
+ {
+ m_bgColIndex = parent->m_bgColIndex;
+ m_fgColIndex = parent->m_fgColIndex;
+ }
+
+ // If in hideable adding mode, or if assigned parent is hideable, then
+ // make this one hideable.
+ if (
+ ( !parentIsRoot && parent->HasFlag(wxPG_PROP_HIDDEN) ) ||
+ ( propgrid && (propgrid->HasInternalFlag(wxPG_FL_ADDING_HIDEABLES)) )
+ )
+ SetFlag( wxPG_PROP_HIDDEN );
+
+ // Set custom image flag.
+ int custImgHeight = OnMeasureImage().y;
+ if ( custImgHeight < 0 )
+ {
+ SetFlag(wxPG_PROP_CUSTOMIMAGE);
+ }
+
+ if ( propgrid && (propgrid->HasFlag(wxPG_LIMITED_EDITING)) )
+ SetFlag(wxPG_PROP_NOEDITOR);
+
+ // Make sure parent has some parental flags
+ if ( !parent->HasFlag(wxPG_PROP_PARENTAL_FLAGS) )
+ parent->SetParentalType(wxPG_PROP_MISC_PARENT);
+
+ if ( !IsCategory() )
+ {
+ // This is not a category.
+
+ // Depth.
+ //
+ unsigned char depth = 1;
+ if ( !parentIsRoot )
+ {
+ depth = parent->m_depth;
+ if ( !parent->IsCategory() )
+ depth++;
+ }
+ m_depth = depth;
+ unsigned char greyDepth = depth;
+
+ if ( !parentIsRoot )
+ {
+ wxPropertyCategory* pc;
+
+ if ( parent->IsCategory() )
+ pc = (wxPropertyCategory* ) parent;
+ else
+ // This conditional compile is necessary to
+ // bypass some compiler bug.
+ pc = pageState->GetPropertyCategory(parent);
+
+ if ( pc )
+ greyDepth = pc->GetDepth();
+ else
+ greyDepth = parent->m_depthBgCol;
+ }
+
+ m_depthBgCol = greyDepth;
+ }
+ else
+ {
+ // This is a category.
+
+ // depth
+ unsigned char depth = 1;
+ if ( !parentIsRoot )
+ {
+ depth = parent->m_depth + 1;
+ }
+ m_depth = depth;
+ m_depthBgCol = depth;
+ }
+
+ //
+ // Has initial children
+ if ( GetChildCount() )
+ {
+ FlagType parentalFlags = m_flags & wxPG_PROP_PARENTAL_FLAGS;
+
+ // Check parental flags
+ wxASSERT_MSG( parentalFlags,
+ "Call SetFlag(wxPG_PROP_MISC_PARENT) or"
+ "SetFlag(wxPG_PROP_AGGREGATE) before calling"
+ "wxPGProperty::AddChild()." );
+
+ if ( HasFlag(wxPG_PROP_AGGREGATE) )
+ {
+ // Properties with private children are not expanded by default.
+ SetExpanded(false);
+ }
+ else if ( propgrid && propgrid->HasFlag(wxPG_HIDE_MARGIN) )
+ {
+ // ...unless it cannot be expanded by user and therefore must
+ // remain visible at all times
+ SetExpanded(true);
+ }
+
+ //
+ // Prepare children recursively
+ for ( unsigned int i=0; i<GetChildCount(); i++ )
+ {
+ wxPGProperty* child = Item(i);
+ child->InitAfterAdded(pageState, pageState->GetGrid());
+ }
+
+ if ( propgrid && (propgrid->GetExtraStyle() & wxPG_EX_AUTO_UNSPECIFIED_VALUES) )
+ SetFlagRecursively(wxPG_PROP_AUTO_UNSPECIFIED, true);
+ }
+}
+
wxPGProperty::wxPGProperty()
: wxObject()
{
return true;
}
-// Call for after sub-properties added with AddChild
-void wxPGProperty::PrepareSubProperties()
-{
- wxPropertyGridPageState* state = GetParentState();
-
- wxASSERT(state);
-
- if ( !GetChildCount() )
- return;
-
- wxByte depth = m_depth + 1;
- wxByte depthBgCol = m_depthBgCol;
-
- FlagType inheritFlags = m_flags & wxPG_INHERITED_PROPFLAGS;
-
- wxByte bgColIndex = m_bgColIndex;
- wxByte fgColIndex = m_fgColIndex;
-
- //
- // Set some values to the children
- //
- size_t i = 0;
- wxPGProperty* nparent = this;
-
- while ( i < nparent->GetChildCount() )
- {
- wxPGProperty* np = nparent->Item(i);
-
- np->m_parentState = state;
- np->m_flags |= inheritFlags; // Hideable also if parent.
- np->m_depth = depth;
- np->m_depthBgCol = depthBgCol;
- np->m_bgColIndex = bgColIndex;
- np->m_fgColIndex = fgColIndex;
-
- // Also handle children of children
- if ( np->GetChildCount() > 0 )
- {
- nparent = np;
- i = 0;
-
- // Init
- nparent->SetParentalType(wxPG_PROP_AGGREGATE);
- nparent->SetExpanded(false);
- depth++;
- }
- else
- {
- // Next sibling
- i++;
- }
-
- // After reaching last sibling, go back to processing
- // siblings of the parent
- while ( i >= nparent->GetChildCount() )
- {
- // Exit the loop when top parent hit
- if ( nparent == this )
- break;
-
- depth--;
-
- i = nparent->GetIndexInParent() + 1;
- nparent = nparent->GetParent();
- }
- }
-}
-
// Call after fixed sub-properties added/removed after creation.
// if oldSelInd >= 0 and < new max items, then selection is
// moved to it. Note: oldSelInd -2 indicates that this property
wxPropertyGridPageState* state = GetParentState();
wxPropertyGrid* grid = state->GetGrid();
- PrepareSubProperties();
+ //
+ // Re-repare children (recursively)
+ for ( unsigned int i=0; i<GetChildCount(); i++ )
+ {
+ wxPGProperty* child = Item(i);
+ child->InitAfterAdded(state, grid);
+ }
wxPGProperty* sel = (wxPGProperty*) NULL;
if ( oldSelInd >= (int)m_children.size() )
DrawItemAndChildren(p);
wxPGProperty* parent = p->GetParent();
- while ( (parent->GetFlags() & wxPG_PROP_PARENTAL_FLAGS) == wxPG_PROP_MISC_PARENT )
+ while ( parent &&
+ (parent->GetFlags() & wxPG_PROP_PARENTAL_FLAGS) == wxPG_PROP_MISC_PARENT )
{
DrawItem(parent);
parent = parent->GetParent();
// wxPropertyGridPageState property adding and removal
// -----------------------------------------------------------------------
-int wxPropertyGridPageState::PrepareToAddItem( wxPGProperty* property,
- wxPGProperty* scheduledParent )
+bool wxPropertyGridPageState::PrepareToAddItem( wxPGProperty* property,
+ wxPGProperty* scheduledParent )
{
wxPropertyGrid* propGrid = m_pPropGrid;
{
delete property;
m_currentCategory = pwc;
- return 2; // Tells the caller what we did.
+ return false;
}
}
}
{
bool selRes = propGrid->ClearSelection();
wxPG_CHECK_MSG_DBG( selRes,
- -1,
+ true,
wxT("failed to deselect a property (editor probably had invalid value)") );
}
- if ( scheduledParent )
- {
- // Use parent's colours.
- property->m_bgColIndex = scheduledParent->m_bgColIndex;
- property->m_fgColIndex = scheduledParent->m_fgColIndex;
-
- // Fix no parent does not yet have parenting flag yet, set one now
- if ( !scheduledParent->HasFlag(wxPG_PROP_PARENTAL_FLAGS) )
- scheduledParent->SetParentalType(wxPG_PROP_MISC_PARENT);
- //scheduledParent->SetFlag(wxPG_PROP_MISC_PARENT);
- }
-
- // If in hideable adding mode, or if assigned parent is hideable, then
- // make this one hideable.
- if (
- ( scheduledParent && (scheduledParent->m_flags & wxPG_PROP_HIDDEN) ) ||
- ( propGrid && (propGrid->m_iFlags & wxPG_FL_ADDING_HIDEABLES) )
- )
- property->SetFlag( wxPG_PROP_HIDDEN );
-
- // Set custom image flag.
- int custImgHeight = property->OnMeasureImage().y;
- if ( custImgHeight < 0 /*|| custImgHeight > 1*/ )
- {
- property->m_flags |= wxPG_PROP_CUSTOMIMAGE;
- }
-
- if ( propGrid && (propGrid->GetWindowStyleFlag() & wxPG_LIMITED_EDITING) )
- property->m_flags |= wxPG_PROP_NOEDITOR;
+ // NULL parent == root parent
+ if ( !scheduledParent )
+ scheduledParent = DoGetRoot();
- if ( !property->IsCategory() )
- {
- // This is not a category.
+ property->m_parent = scheduledParent;
- //wxASSERT_MSG( property->GetEditorClass(), wxT("Editor class not initialized!") );
-
- // Depth.
- //
- unsigned char depth = 1;
- if ( scheduledParent )
- {
- depth = scheduledParent->m_depth;
- if ( !scheduledParent->IsCategory() )
- depth++;
- }
- property->m_depth = depth;
- unsigned char greyDepth = depth;
-
- if ( scheduledParent )
- {
- wxPropertyCategory* pc;
-
- if ( scheduledParent->IsCategory() || scheduledParent->IsRoot() )
- pc = (wxPropertyCategory*)scheduledParent;
- else
- // This conditional compile is necessary to
- // bypass some compiler bug.
- pc = GetPropertyCategory(scheduledParent);
-
- if ( pc )
- greyDepth = pc->GetDepth();
- else
- greyDepth = scheduledParent->m_depthBgCol;
- }
+ property->InitAfterAdded(this, propGrid);
- property->m_depthBgCol = greyDepth;
-
- // Prepare children pre-added children
- if ( property->GetChildCount() )
- {
- property->SetParentalType(wxPG_PROP_AGGREGATE);
-
- property->SetExpanded(false); // Properties with children are not expanded by default.
- if ( propGrid && propGrid->GetWindowStyleFlag() & wxPG_HIDE_MARGIN )
- property->SetExpanded(true); // ...unless it cannot be expanded.
-
- property->PrepareSubProperties();
-
- return -1;
- }
-
- if ( propGrid && (propGrid->GetExtraStyle() & wxPG_EX_AUTO_UNSPECIFIED_VALUES) )
- property->SetFlagRecursively(wxPG_PROP_AUTO_UNSPECIFIED, true);
-
- return 0;
- }
- else
+ if ( property->IsCategory() )
{
- // This is a category.
-
- // depth
- unsigned char depth = 1;
- if ( scheduledParent )
- {
- depth = scheduledParent->m_depth + 1;
- }
- property->m_depth = depth;
- property->m_depthBgCol = depth;
+ wxPropertyCategory* pc = wxStaticCast(property, wxPropertyCategory);
- m_currentCategory = (wxPropertyCategory*)property;
+ m_currentCategory = pc;
- wxPropertyCategory* pc = (wxPropertyCategory*)property;
-
- // Calculate text extent for caption item.
+ // Calculate text extent for category caption
if ( propGrid )
pc->CalculateTextExtent(propGrid, propGrid->GetCaptionFont());
-
- return 1;
}
+
+ return true;
}
// -----------------------------------------------------------------------
wxNullProperty,
wxT("when adding properties to fixed parents, use BeginAddChildren and EndAddChildren.") );
- int parenting = PrepareToAddItem( property, (wxPropertyCategory*)parent );
+ bool res = PrepareToAddItem( property, (wxPropertyCategory*)parent );
- // This type of invalid parenting value indicates we should exit now, returning
- // id of most recent category.
- if ( parenting > 1 )
+ // PrepareToAddItem() may just decide to use use current category
+ // instead of adding new one.
+ if ( !res )
return m_currentCategory;
// Note that item must be added into current mode later.
// Categorized mode
// Only add non-categories to m_abcArray.
- if ( m_abcArray && parenting <= 0 )
+ if ( m_abcArray && !property->IsCategory() )
m_abcArray->AddChild2( property, -1, false );
// Add to current mode.
m_regularArray.AddChild2( property, -1, false );
// Add to current mode (no categories).
- if ( parenting <= 0 )
+ if ( !property->IsCategory() )
m_abcArray->AddChild2( property, index );
}
}
void wxFlagsProperty::Init()
{
- SetFlag(wxPG_PROP_AGGREGATE); // This is must be done here to support flag props
- // with inital zero children.
+ SetParentalType(wxPG_PROP_AGGREGATE);
long value = m_value;