📄 configitem.cpp
字号:
wxTreeItemId treeItem = GetTreeItemId();
DetachFromTree();
// Will delete the branch, but not the config items.
wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->Delete(treeItem);
}
/// Hide from tree: make sure tree deletions won't delete
/// the config items
void ctConfigItem::DetachFromTree()
{
wxTreeItemId item = GetTreeItemId();
ctTreeItemData* data = (ctTreeItemData*) wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetItemData(item);
data->SetConfigItem(NULL);
m_treeItemId = wxTreeItemId();
for ( wxObjectList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* child = (ctConfigItem*) node->GetData();
child->DetachFromTree();
}
}
/// Attach: insert after the given position
void ctConfigItem::Attach(ctConfigItem* parent, ctConfigItem* insertBefore)
{
if (parent)
{
SetParent(parent);
if (insertBefore)
{
wxObjectList::compatibility_iterator node = parent->GetChildren().Member(insertBefore);
if (node)
parent->GetChildren().Insert(node, this);
else
parent->GetChildren().Append(this);
}
else
parent->GetChildren().Append(this);
}
else
{
GetDocument()->SetTopItem(this);
}
}
/// Can have children?
bool ctConfigItem::CanHaveChildren() const
{
return (GetType() == ctTypeGroup ||
GetType() == ctTypeCheckGroup ||
GetType() == ctTypeRadioGroup);
}
// An item is in the active context if:
// The context field is empty; or
// The context field contains a symbol that is currently enabled.
bool ctConfigItem::IsInActiveContext()
{
wxString context = GetPropertyString(wxT("context"));
if (context.IsEmpty())
return true;
wxList contextItems;
StringToItems(GetDocument()->GetTopItem(), context, contextItems);
for ( wxObjectList::compatibility_iterator node = contextItems.GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* otherItem = (ctConfigItem*) node->GetData();
if (otherItem->IsEnabled())
return true;
}
return false;
}
/// Evaluate the requires properties:
/// if any of the 'requires' items are disabled,
/// then this one is disabled (and inactive).
void ctConfigItem::EvaluateDependencies()
{
// For debugging purposes
wxString name = GetName();
wxList items;
wxString requires = GetPropertyString(wxT("requires"));
wxString precludes = GetPropertyString(wxT("precludes"));
wxString enabledIf = GetPropertyString(wxT("enabled-if"));
wxString enabledIfNot = GetPropertyString(wxT("enabled-if-not"));
wxString indeterminateIf = GetPropertyString(wxT("indeterminate-if"));
bool active = true;
bool enabled = IsEnabled();
bool oldEnabled = enabled;
bool oldActive = IsActive();
bool explicitlyEnabled = false;
bool explicitlyDisabled = false;
bool inActiveContext = IsInActiveContext();
// Add the parent to the list of dependencies, if the
// parent is a check or radio group.
ctConfigItem* parent = GetParent();
if (parent &&
(parent->GetType() == ctTypeCheckGroup ||
parent->GetType() == ctTypeRadioGroup))
items.Append(parent);
wxList tempItems;
StringToItems(GetDocument()->GetTopItem(), requires, tempItems);
wxObjectList::compatibility_iterator node;
for ( node = tempItems.GetFirst(); node; node = node->GetNext() )
{
// Only consider the dependency if both items are in
// an active context.
// Each is in the active context if:
// The context field is empty; or
// The context field contains a symbol that is currently enabled.
ctConfigItem* otherItem = (ctConfigItem*) node->GetData();
if (inActiveContext && otherItem->IsInActiveContext())
items.Append(otherItem);
}
{
int enabledCount = 0;
for ( node = items.GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* otherItem = (ctConfigItem*) node->GetData();
if (otherItem->IsEnabled())
{
enabledCount ++;
}
}
if (items.GetCount() > 0 && enabledCount == 0)
{
// None of the items were enabled
enabled = false;
active = false;
explicitlyDisabled = true;
}
}
items.Clear();
if (!enabledIfNot.IsEmpty())
{
StringToItems(GetDocument()->GetTopItem(), enabledIfNot, items);
int disabledCount = 0;
int inContextCount = 0;
for ( wxObjectList::compatibility_iterator node = items.GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* otherItem = (ctConfigItem*) node->GetData();
if (inActiveContext && otherItem->IsInActiveContext())
{
// Make this enabled and inactive, _unless_ it's
// already been explicitly disabled in the previous
// requires evaluation (it really _has_ to be off)
if (!otherItem->IsEnabled())
{
disabledCount ++;
}
inContextCount ++;
}
}
// Enable if there were no related items that were enabled
if (inContextCount > 0 && (disabledCount == inContextCount) && !explicitlyDisabled)
{
explicitlyEnabled = true;
enabled = true;
active = false;
}
}
items.Clear();
if (!enabledIf.IsEmpty())
{
StringToItems(GetDocument()->GetTopItem(), enabledIf, items);
int enabledCount = 0;
int inContextCount = 0;
for ( wxObjectList::compatibility_iterator node = items.GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* otherItem = (ctConfigItem*) node->GetData();
wxString otherName = otherItem->GetName();
if (inActiveContext && otherItem->IsInActiveContext())
{
// Make this enabled and inactive, _unless_ it's
// already been explicitly disabled in the previous
// requires evaluation (it really _has_ to be off)
if (otherItem->IsEnabled())
{
enabledCount ++;
}
inContextCount ++;
}
}
// Enable if there were no related items that were disabled
if (inContextCount > 0 && (enabledCount > 0) && !explicitlyDisabled)
{
explicitlyEnabled = true;
enabled = true;
active = false;
}
}
items.Clear();
if (!precludes.IsEmpty())
{
StringToItems(GetDocument()->GetTopItem(), precludes, items);
int enabledCount = 0;
// int disabledCount = 0;
int inContextCount = 0;
for ( wxObjectList::compatibility_iterator node = items.GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* otherItem = (ctConfigItem*) node->GetData();
if (inActiveContext && otherItem->IsInActiveContext())
{
// Make this disabled and inactive, _unless_ it's
// already been explicitly enabled in the previous
// requires evaluation (it really _has_ to be on)
// if (!otherItem->IsEnabled())
if (otherItem->IsEnabled())
{
enabledCount ++;
// disabledCount ++;
}
inContextCount ++;
}
}
// Disable if there were no related items that were disabled
if (inContextCount > 0 && (enabledCount > 0) && !explicitlyEnabled)
// if (inContextCount > 0 && (disabledCount > 0) && !explicitlyEnabled)
{
enabled = false;
active = false;
explicitlyDisabled = true;
}
}
// Indeterminate overrides the others, and
// makes the item active.
items.Clear();
if (!indeterminateIf.IsEmpty())
{
StringToItems(GetDocument()->GetTopItem(), indeterminateIf, items);
int enabledCount = 0;
int inContextCount = 0;
for ( wxObjectList::compatibility_iterator node = items.GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* otherItem = (ctConfigItem*) node->GetData();
if (inActiveContext && otherItem->IsInActiveContext())
{
if (otherItem->IsEnabled())
{
enabledCount ++;
}
inContextCount ++;
}
}
if (inContextCount > 0 && enabledCount > 0)
{
active = true;
explicitlyEnabled = false;
explicitlyDisabled = false;
}
}
// Finally check a sort of dependency: whether our
// context is active. If not, make this inactive.
if (!IsInActiveContext())
active = false;
else
{
// If we didn't explicitly enable or disable it,
// then we should make it active.
if (!explicitlyEnabled && !explicitlyDisabled)
active = true;
}
SetActive(active);
// If going active, set enabled state to the default state
if (active &&
oldActive != active &&
(GetType() == ctTypeBoolCheck || GetType() == ctTypeCheckGroup) &&
m_properties.FindProperty(wxT("default-state")))
{
bool defaultState = m_properties.FindProperty(wxT("default-state"))->GetVariant().GetBool();
enabled = defaultState;
}
Enable(enabled);
// Deal with setting a radio button
if (enabled && enabled != oldEnabled &&
(GetType() == ctTypeBoolRadio || GetType() == ctTypeRadioGroup))
{
wxList considered;
PropagateRadioButton(considered);
}
}
/// Get description, which may be dynamically
/// generated depending on the property.
wxString ctConfigItem::GetDescription(ctProperty* property)
{
if (property->GetName() == wxT("description"))
{
wxString value(property->GetValue());
if (value.IsEmpty())
return wxT("Double-click on <B>description</B> to write a brief explanation of the setting.<P>");
else
return value;
}
else if (property->GetName() == wxT("notes"))
{
wxString value(property->GetValue());
if (value.IsEmpty())
return wxT("Double-click on <B>notes</B> to write notes about this setting.<P>");
else
return value;
}
return property->GetDescription();
}
/// Get the title for the property editor
wxString ctConfigItem::GetTitle()
{
wxString title(GetName());
if (GetType() == ctTypeCheckGroup ||
GetType() == ctTypeRadioGroup ||
GetType() == ctTypeBoolCheck ||
GetType() == ctTypeBoolRadio)
{
if (IsEnabled())
title = title + _T(" - enabled");
else
title = title + _T(" - disabled");
}
return title;
}
/// Propagate a change in enabled/disabled status
void ctConfigItem::PropagateChange(wxList& considered)
{
if (GetType() == ctTypeCheckGroup ||
GetType() == ctTypeRadioGroup ||
GetType() == ctTypeBoolCheck ||
GetType() == ctTypeBoolRadio)
{
// TODO: what about string, integer? Can they have
// dependencies?
for ( wxObjectList::compatibility_iterator node = GetDependents().GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* child = (ctConfigItem*) node->GetData();
// Avoid loops
if (!considered.Member(child))
{
considered.Append(child);
child->EvaluateDependencies();
child->Sync();
child->PropagateChange(considered);
}
}
}
}
/// Process radio button selection
void ctConfigItem::PropagateRadioButton(wxList& considered)
{
if ((GetType() == ctTypeBoolRadio || GetType() == ctTypeRadioGroup) && IsEnabled())
{
wxString mutuallyExclusive(GetPropertyString(wxT("exclusivity")));
wxList list;
StringToItems(GetDocument()->GetTopItem(), mutuallyExclusive, list);
for ( wxObjectList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext() )
{
ctConfigItem* child = (ctConfigItem*) node->GetData();
if (child->IsEnabled() && child != this)
{
child->Enable(false);
child->Sync();
if (!considered.Member(child))
child->PropagateChange(considered);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -