Qt Editor: Move editor props from EditorProp_* to an EditorProp proplist

qteditor
Sven Eberhardt 2016-07-13 17:18:08 -04:00
parent f780a55e0f
commit 28d2172b78
16 changed files with 118 additions and 98 deletions

View File

@ -1180,7 +1180,8 @@ func Definition(def) {
// Set perspective
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,1000,5000), Trans_Rotate(70,0,1,0)), def);
EditorProp_skin = { Type="enum", Set="SetSkin", Options = [
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.skin = { Type="enum", Set="SetSkin", Options = [
{ Value=0, Name="Adventurer"},
{ Value=1, Name="Steampunk"},
{ Value=2, Name="Alchemist"},
@ -1189,5 +1190,3 @@ func Definition(def) {
_inherited(def);
}
local EditorProp_skin;

View File

@ -153,4 +153,4 @@ func SaveScenarioObject(props)
/* Editor props */
local EditorProp_spawn_id = { Type="def", Filter="Collectible", Set="SetSpawnObject" };
local EditorProps = { spawn_id = { Type = "def", Filter = "Collectible", Set = "SetSpawnObject" } };

View File

@ -22,16 +22,17 @@ public func Definition(def)
{
def.starting_crew = GetDefaultCrew();
def.starting_material = GetDefaultMaterial();
def.EditorProp_starting_players = EditorBase.PlayerMask;
def.EditorProp_starting_knowledge = { Name="$Knowledge$", Type="enum", OptionKey="Option", Options = [
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.starting_players = EditorBase.PlayerMask;
def.EditorProps.starting_knowledge = { Name="$Knowledge$", Type="enum", OptionKey="Option", Options = [
{ Name="$None$" },
{ Name="$All$", Value={ Option="all" } },
{ Name="$AllExcept$", Value={ Option="allexcept", Data=[] }, ValueKey="Data", Delegate=EditorBase.IDSet },
{ Name="$Specific$", Value={ Option="idlist", Data=[] }, ValueKey="Data", Delegate=EditorBase.IDSet },
] };
def.EditorProp_starting_crew = EditorBase->GetConditionalIDList("IsClonk", "$Crew$", Clonk);
def.EditorProp_starting_material = EditorBase->GetConditionalIDList("Collectible", "$StartingMaterial$", nil);
def.EditorProp_starting_wealth = { Name="$Wealth$", Type="int", Min=0 };
def.EditorProps.starting_crew = EditorBase->GetConditionalIDList("IsClonk", "$Crew$", Clonk);
def.EditorProps.starting_material = EditorBase->GetConditionalIDList("Collectible", "$StartingMaterial$", nil);
def.EditorProps.starting_wealth = { Name="$Wealth$", Type="int", Min=0 };
return true;
}

View File

@ -110,6 +110,7 @@ local Name = "$Name$";
func Definition(def)
{
def.EditorProp_construction_list = EditorBase.IDList;
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.construction_list = EditorBase.IDList;
return true;
}

View File

@ -40,9 +40,10 @@ func AddAI(object clonk)
SetGuardRange(clonk, fx.home_x-AI_DefGuardRangeX, fx.home_y-AI_DefGuardRangeY, AI_DefGuardRangeX*2, AI_DefGuardRangeY*2);
SetMaxAggroDistance(clonk, AI_DefMaxAggroDistance);
// AI editor stuff
fx.EditorProp_guard_range = { Name="$GuardRange$", Type="rect", Storage="proplist", Color=0xff00, Relative=false };
fx.EditorProp_ignore_allies = { Name="$IgnoreAllies$", Type="bool" };
fx.EditorProp_max_aggro_distance = { Name="$MaxAggroDistance$", Type="circle", Color=0x808080 };
fx.EditorProps = {};
fx.EditorProps.guard_range = { Name="$GuardRange$", Type="rect", Storage="proplist", Color=0xff00, Relative=false };
fx.EditorProps.ignore_allies = { Name="$IgnoreAllies$", Type="bool" };
fx.EditorProps.max_aggro_distance = { Name="$MaxAggroDistance$", Type="circle", Color=0x808080 };
return fx;
}
@ -753,5 +754,6 @@ private func GetBallisticAngle(int dx, int dy, int v, int max_angle)
func Definition(def)
{
Clonk.EditorProp_AI = { Type = "has_effect", Effect = "AI", Set = "AI->SetAI", Global = true };
if (!Clonk.EditorProps) Clonk.EditorProps = {};
Clonk.EditorProps.AI = { Type = "has_effect", Effect = "AI", Set = "AI->SetAI", Global = true };
}

View File

@ -650,33 +650,34 @@ public func IsDialogue() { return true; }
public func Definition(def)
{
// Actions provided by this definition
UserAction->AddEvaluator("Action", "$Dialogue$", "$Message$", "message", [def, def.EvalAct_Message], def.GetDefaultMessageProp, { Type="proplist", Display="{{Speaker}}: \"{{Text}}\" {{Options}}", Elements = {
EditorProp_Speaker = new UserAction.Evaluator.Object { Name = "$Speaker$" },
EditorProp_Text = { Type="string" },
EditorProp_TargetPlayers = new UserAction.Evaluator.PlayerList { Name = "$TargetPlayers$" },
EditorProp_AfterMessage = { Type="enum", Options = [{ Name="$ContinueAction$" }, { Name="$WaitForNext$", Value="next" }, { Name="$SuspendAction$", Value="suspend" }, { Name="$StopAction$", Value="stop" }, { Name="$WaitTime$", Value=60, Type=C4V_Int, Delegate={ Type="int", Min=1 } }] },
EditorProp_Options = { Name="$Options$", Type="array", Display=3, Elements = { Type="proplist", Display="({{Goto}}) {{Text}}", DefaultValue = { Text="$DefaultOptionText$", Goto=0 }, Elements = {
EditorProp_Text = { Type="string" },
EditorProp_Goto = { Type="int", Min=0 }
UserAction->AddEvaluator("Action", "$Dialogue$", "$Message$", "message", [def, def.EvalAct_Message], def.GetDefaultMessageProp, { Type="proplist", Display="{{Speaker}}: \"{{Text}}\" {{Options}}", EditorProps = {
Speaker = new UserAction.Evaluator.Object { Name = "$Speaker$" },
Text = { Type="string" },
TargetPlayers = new UserAction.Evaluator.PlayerList { Name = "$TargetPlayers$" },
AfterMessage = { Type="enum", Options = [{ Name="$ContinueAction$" }, { Name="$WaitForNext$", Value="next" }, { Name="$SuspendAction$", Value="suspend" }, { Name="$StopAction$", Value="stop" }, { Name="$WaitTime$", Value=60, Type=C4V_Int, Delegate={ Type="int", Min=1 } }] },
Options = { Name="$Options$", Type="array", Display=3, Elements = { Type="proplist", Display="({{Goto}}) {{Text}}", DefaultValue = { Text="$DefaultOptionText$", Goto=0 }, EditorProps = {
Text = { Type="string" },
Goto = { Type="int", Min=0 }
} } }
} } );
UserAction->AddEvaluator("Action", "$Dialogue$", "$SetAttention$", "dialogue_set_attention", [def, def.EvalAct_SetAttention], { Target = { Option="action_object" }, Status = { Option="bool_constant", Value=true } }, { Type="proplist", Display="{{Target}}: {{Status}}", Elements = {
EditorProp_Target = UserAction->GetObjectEvaluator("IsDialogue", "$Dialogue$"),
EditorProp_Status = new UserAction.Evaluator.Boolean { Name = "$Status$" }
UserAction->AddEvaluator("Action", "$Dialogue$", "$SetAttention$", "dialogue_set_attention", [def, def.EvalAct_SetAttention], { Target = { Option="action_object" }, Status = { Option="bool_constant", Value=true } }, { Type="proplist", Display="{{Target}}: {{Status}}", EditorProps = {
Target = UserAction->GetObjectEvaluator("IsDialogue", "$Dialogue$"),
Status = new UserAction.Evaluator.Boolean { Name = "$Status$" }
} } );
UserAction->AddEvaluator("Action", "$Dialogue$", "$SetEnabled$", "dialogue_set_enabled", [def, def.EvalAct_SetEnabled], { Target = { Option="action_object" }, Status = { Option="bool_constant", Value=true } }, { Type="proplist", Display="{{Target}}: {{Status}}", Elements = {
EditorProp_Target = UserAction->GetObjectEvaluator("IsDialogue", "$Dialogue$"),
EditorProp_Status = new UserAction.Evaluator.Boolean { Name = "$Status$" }
UserAction->AddEvaluator("Action", "$Dialogue$", "$SetEnabled$", "dialogue_set_enabled", [def, def.EvalAct_SetEnabled], { Target = { Option="action_object" }, Status = { Option="bool_constant", Value=true } }, { Type="proplist", Display="{{Target}}: {{Status}}", EditorProps = {
Target = UserAction->GetObjectEvaluator("IsDialogue", "$Dialogue$"),
Status = new UserAction.Evaluator.Boolean { Name = "$Status$" }
} } );
UserAction->AddEvaluator("Object", nil, "$NPC$", "npc", [def, def.EvalObj_NPC]);
// Clonks can create a dialogue
Clonk.EditorAction_Dialogue = { Name="$Dialogue$", Command="SetDialogue(GetName(), true, true)", Select=true };
// Dialogue EditorProps
def.EditorProp_user_dialogue = { Name="$Dialogue$", Type="enum", OptionKey="Option", Options = [ { Name="$NoDialogue$" }, new UserAction.EvaluatorDefs.sequence { Group=nil } ] };
def.EditorProp_user_dialogue_allow_parallel = UserAction.PropParallel;
def.EditorProp_user_dialogue_progress_mode = UserAction.PropProgressMode;
def.EditorProp_dlg_attention = { Name="$Attention$ (!)", Type="bool", Set="SetAttention" };
def.EditorProp_dlg_interact = { Name="$Enabled$", Type="bool", Set="SetEnabled" };
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.user_dialogue = { Name="$Dialogue$", Type="enum", OptionKey="Option", Options = [ { Name="$NoDialogue$" }, new UserAction.EvaluatorDefs.sequence { Group=nil } ] };
def.EditorProps.user_dialogue_allow_parallel = UserAction.PropParallel;
def.EditorProps.user_dialogue_progress_mode = UserAction.PropProgressMode;
def.EditorProps.dlg_attention = { Name="$Attention$ (!)", Type="bool", Set="SetAttention" };
def.EditorProps.dlg_interact = { Name="$Enabled$", Type="bool", Set="SetEnabled" };
}
private func GetDefaultMessageProp(object target_object)

View File

@ -6,9 +6,11 @@ local Name = "EditorBase";
public func Construction() { RemoveObject(); }
// Basic properties of all objects
local EditorProp_Invincibility = { Type = "has_effect", Effect = "IntInvincible", Set = "SetInvincibility" };
local EditorProp_PlayerColor = { Type = "color", AsyncGet = "GetColor", Set = "SetColor" };
local EditorProp_Name = { Type = "string", AsyncGet = "GetName", Set = "SetName" };
local EditorProps = {
Invincibility = { Type = "has_effect", Effect = "IntInvincible", Set = "SetInvincibility" },
PlayerColor = { Type = "color", AsyncGet = "GetColor", Set = "SetColor" },
Name = { Type = "string", AsyncGet = "GetName", Set = "SetName" }
};
local Plane = 1;
local CountedID, IDList, AnyDef, IDSet, PlayerNumber, TeamID, PlayerMask;
@ -17,10 +19,9 @@ local DefinitionPriority=100; // Call this definition early to allow EditorProp
func Definition(def)
{
// Property delegate types
CountedID = { Type = "proplist", Display = "{{count}}x{{id}}", DefaultValue = { count=1, id=nil }, Elements = {
Name = "$IDListEntry$",
EditorProp_count = { Type = "int", Min = 1 },
EditorProp_id = { Type = "def" } } };
CountedID = { Type = "proplist", Display = "{{count}}x{{id}}", DefaultValue = { count=1, id=nil }, Name = "$IDListEntry$", EditorProps = {
count = { Type = "int", Min = 1 },
id = { Type = "def" } } };
IDList = { Name = "ID list", Type = "array", Display = 3, Elements = CountedID };
AnyDef = { Type = "def" };
IDSet = { Name = "ID set", Type = "array", Display = 5, Elements = AnyDef };
@ -63,10 +64,9 @@ public func EvaluatePlayers(proplist mask)
// Return an ID-List EditorProp with only IDs available that meet the condition
public func GetConditionalIDList(string condition, string name, proplist default_id)
{
var counted_id = { Type = "proplist", Display = "{{count}}x{{id}}", DefaultValue = { count=1, id=default_id }, Elements = {
Name = Format("$Entry$", name),
EditorProp_count = { Type = "int", Min = 1 },
EditorProp_id = { Type = "def", Filter=condition } } };
var counted_id = { Type = "proplist", Display = "{{count}}x{{id}}", DefaultValue = { count=1, id=default_id }, Name = Format("$Entry$", name), EditorProps = {
count = { Type = "int", Min = 1 },
id = { Type = "def", Filter=condition } } };
return { Name = name, Type = "array", Display = 3, Elements = counted_id };
}

View File

@ -3,6 +3,8 @@
Cutscene to be watched by all players.
Start calling global func StartSequence, stop using StopSequence
Can also be used as a trigger object for UserActions.
@author Sven
*/

View File

@ -60,16 +60,16 @@ func Definition(def)
// Action evaluators
EvaluatorCallbacks = {};
EvaluatorDefs = {};
AddEvaluator("Action", "$Sequence$", "$Sequence$", "sequence", [def, def.EvalAct_Sequence], { Actions=[] }, { Type="proplist", DescendPath="Actions", Display="{{Actions}}", Elements = {
EditorProp_Actions = { Name="$Actions$", Type="array", Elements=Evaluator.Action },
AddEvaluator("Action", "$Sequence$", "$Sequence$", "sequence", [def, def.EvalAct_Sequence], { Actions=[] }, { Type="proplist", DescendPath="Actions", Display="{{Actions}}", EditorProps = {
Actions = { Name="$Actions$", Type="array", Elements=Evaluator.Action },
} } );
AddEvaluator("Action", "$Sequence$", "$Goto$", "goto", [def, def.EvalAct_Goto], { Index=0 }, { Type="proplist", Display="{{Index}}", Elements = {
EditorProp_Index = { Name="$Index$", Type="int", Min=0 }
AddEvaluator("Action", "$Sequence$", "$Goto$", "goto", [def, def.EvalAct_Goto], { Index=0 }, { Type="proplist", Display="{{Index}}", EditorProps = {
Index = { Name="$Index$", Type="int", Min=0 }
} } );
AddEvaluator("Action", "$Sequence$", "$StopSequence$", "stop_sequence", [def, def.EvalAct_StopSequence]);
AddEvaluator("Action", "$Sequence$", "$SuspendSequence$", "suspend_sequence", [def, def.EvalAct_SuspendSequence]);
AddEvaluator("Action", "$Sequence$", "$Wait$", "wait", [def, def.EvalAct_Wait], { Time=60 }, { Type="proplist", Display="{{Time}}", Elements = {
EditorProp_Time = { Name="$Time$", Type="int", Min=1 }
AddEvaluator("Action", "$Sequence$", "$Wait$", "wait", [def, def.EvalAct_Wait], { Time=60 }, { Type="proplist", Display="{{Time}}", EditorProps = {
Time = { Name="$Time$", Type="int", Min=1 }
} } );
// Object evaluators
AddEvaluator("Object", nil, "$ActionObject$", "action_object", [def, def.EvalObj_ActionObject]);
@ -119,10 +119,10 @@ public func AddEvaluator(string eval_type, string group, string name, string ide
var action_def = { Name=name, Group=group, Value=default_val, OptionKey="Option", Delegate=delegate, Get=default_get }, n;
if (delegate)
{
if (delegate.Elements)
if (delegate.EditorProps)
{
// Proplist of array parameter for this evaluator: Descend path title should be name
delegate.Elements.Name = name;
delegate.Name = name;
}
else
{

View File

@ -108,15 +108,16 @@ local Touchable = 2;
local EditCursorCommands = ["ControlUp()", "ControlDown()", "ConnectNearestDoor()"];
local Plane = 200;
local Components = {Wood = 3, Metal = 1};
local EditorProp_targetdoor = { Name="$Target$", Type="object", Filter="IsSwitchTarget" };
local up_action, down_action; // Custom editor-selected actions on switch handling
func Definition(def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Scale(800), Trans_Translate(0,0,0),Trans_Rotate(-20,1,0,0),Trans_Rotate(-30,0,1,0)), def);
SetProperty("MeshTransformation", Trans_Rotate(-13,0,1,0), def);
def.EditorProp_up_action = new UserAction.Prop { Name="$UpAction$" };
def.EditorProp_down_action = new UserAction.Prop { Name="$DownAction$" };
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.targetdoor = { Name = "$Target$", Type = "object", Filter = "IsSwitchTarget" };
def.EditorProps.up_action = new UserAction.Prop { Name="$UpAction$" };
def.EditorProps.down_action = new UserAction.Prop { Name="$DownAction$" };
}

View File

@ -305,7 +305,7 @@ C4PropertyDelegateDescendPath::C4PropertyDelegateDescendPath(const class C4Prope
{
if (props)
{
info_proplist = C4VPropList(props->GetPropertyPropList(P_Elements));
info_proplist = C4VPropList(props); // Descend info is this definition
edit_on_selection = props->GetPropertyBool(P_EditOnSelection, edit_on_selection);
descend_path = props->GetPropertyStr(P_DescendPath);
}
@ -333,29 +333,30 @@ QWidget *C4PropertyDelegateDescendPath::CreateEditor(const class C4PropertyDeleg
bool is_proplist = !!val.getPropList(), is_array = !!val.getArray();
if (is_proplist || is_array)
{
C4String *name_override = is_array ? GetNameStr() : nullptr;
C4PropList *info_proplist = this->info_proplist.getPropList();
// Allow descending into a sub-path
C4PropertyPath descend_property_path(editor->property_path);
if (is_proplist && descend_path)
{
// Descend value into sub-path
val._getPropList()->GetPropertyByS(descend_path.Get(), &val);
// Descend info_proplist into sub-path
if (info_proplist)
{
C4Value sub_info_proplist_val;
info_proplist->GetPropertyByS(::Strings.RegString(FormatString("EditorProp_%s", descend_path.Get()->GetCStr()).getData()), &sub_info_proplist_val);
C4PropList *sub_info_proplist = sub_info_proplist_val.getPropList();
if (sub_info_proplist)
C4PropList *info_editorprops = info_proplist->GetPropertyPropList(P_EditorProps);
if (info_editorprops)
{
if (val.getArray()) name_override = sub_info_proplist->GetPropertyStr(P_Name);
info_proplist = sub_info_proplist->GetPropertyPropList(P_Elements);
C4Value sub_info_proplist_val;
info_editorprops->GetPropertyByS(descend_path.Get(), &sub_info_proplist_val);
info_proplist = sub_info_proplist_val.getPropList();
}
}
// Descend property path into sub-path
descend_property_path = C4PropertyPath(descend_property_path, descend_path->GetCStr());
}
// No info proplist: Fall back to regular proplist viewing mode
if (!info_proplist) info_proplist = val.getPropList();
this->factory->GetPropertyModel()->DescendPath(val, info_proplist, descend_property_path, name_override);
this->factory->GetPropertyModel()->DescendPath(val, info_proplist, descend_property_path);
::Console.EditCursor.InvalidateSelection();
}
});
@ -377,7 +378,13 @@ QString C4PropertyDelegateArray::GetDisplayString(const C4Value &v, C4Object *ob
C4ValueArray *arr = v.getArray();
if (!arr) return QString(LoadResStr("IDS_CNS_INVALID"));
int32_t n = v._getArray()->GetSize();
if (!element_delegate) element_delegate = factory->GetDelegateByValue(info_proplist);
if (!element_delegate)
{
C4Value element_delegate_value;
C4PropList *info_proplist = this->info_proplist.getPropList();
if (info_proplist) info_proplist->GetProperty(P_Elements, &element_delegate_value);
element_delegate = factory->GetDelegateByValue(element_delegate_value);
}
if (max_array_display && n)
{
QString result = "[";
@ -413,6 +420,7 @@ QString C4PropertyDelegatePropList::GetDisplayString(const C4Value &v, C4Object
if (!data) return QString(LoadResStr("IDS_CNS_INVALID"));
if (!display_string) return QString("{...}");
C4PropList *info_proplist = this->info_proplist.getPropList();
C4PropList *info_editorprops = info_proplist ? info_proplist->GetPropertyPropList(P_EditorProps) : nullptr;
// Replace all {{name}} by property values of name
QString result = display_string->GetCStr();
int32_t pos0, pos1;
@ -423,13 +431,14 @@ QString C4PropertyDelegatePropList::GetDisplayString(const C4Value &v, C4Object
if (pos1 < 0) break; // placeholder not closed
// Get child value
QString substring = result.mid(pos0+2, pos1-pos0-2);
if (!data->GetPropertyByS(::Strings.RegString(substring.toUtf8()), &cv)) cv.Set0();
C4RefCntPointer<C4String> psubstring = ::Strings.RegString(substring.toUtf8());
if (!data->GetPropertyByS(psubstring.Get(), &cv)) cv.Set0();
// Try to display using child delegate
QString display_value;
if (info_proplist)
if (info_editorprops)
{
C4Value child_delegate_val;
if (info_proplist->GetPropertyByS(::Strings.RegString("EditorProp_" + substring.toUtf8()), &child_delegate_val))
if (info_editorprops->GetPropertyByS(psubstring.Get(), &child_delegate_val))
{
C4PropertyDelegate *child_delegate = factory->GetDelegateByValue(child_delegate_val);
if (child_delegate)
@ -1251,7 +1260,7 @@ QWidget *C4PropertyDelegateC4ValueInput::CreateEditor(const class C4PropertyDele
C4Value val = editor->property_path.ResolveValue();
if (val.getPropList() || val.getArray())
{
this->factory->GetPropertyModel()->DescendPath(val, val.getPropList(), editor->property_path, nullptr);
this->factory->GetPropertyModel()->DescendPath(val, val.getPropList(), editor->property_path);
::Console.EditCursor.InvalidateSelection();
}
});
@ -1496,8 +1505,7 @@ C4ConsoleQtPropListModel::~C4ConsoleQtPropListModel()
bool C4ConsoleQtPropListModel::AddPropertyGroup(C4PropList *add_proplist, int32_t group_index, QString name, C4PropList *target_proplist, C4Object *base_effect_object, C4String *default_selection, int32_t *default_selection_index)
{
const char *editor_prop_prefix = "EditorProp_";
auto new_properties = add_proplist->GetSortedLocalProperties(editor_prop_prefix, target_proplist);
auto new_properties = add_proplist->GetSortedLocalProperties(false);
if (!new_properties.size()) return false;
if (property_groups.size() == group_index)
{
@ -1523,8 +1531,8 @@ bool C4ConsoleQtPropListModel::AddPropertyGroup(C4PropList *add_proplist, int32_
else
prop->property_path = target_path;
// ID for default selection memory
const char *prop_id = new_properties[i]->GetCStr() + strlen(editor_prop_prefix);
if (default_selection && default_selection->GetData() == prop_id) *default_selection_index = i;
C4String *prop_id = new_properties[i];
if (default_selection == prop_id) *default_selection_index = i;
// Property data
prop->key = NULL;
prop->display_name = NULL;
@ -1539,8 +1547,8 @@ bool C4ConsoleQtPropListModel::AddPropertyGroup(C4PropList *add_proplist, int32_
prop->display_name = published_prop->GetPropertyStr(P_Name);
prop->delegate_info.SetPropList(published_prop);
}
if (!prop->key) properties.props[i].key = ::Strings.RegString(prop_id);
if (!prop->display_name) properties.props[i].display_name = ::Strings.RegString(new_properties[i]->GetCStr() + strlen(editor_prop_prefix));
if (!prop->key) properties.props[i].key = prop_id;
if (!prop->display_name) properties.props[i].display_name = prop_id;
prop->delegate = delegate_factory->GetDelegateByValue(prop->delegate_info);
C4Value v;
C4Value v_target_proplist = C4VPropList(target_proplist);
@ -1574,20 +1582,18 @@ void C4ConsoleQtPropListModel::SetBasePropList(C4PropList *new_proplist)
info_proplist.SetPropList(target_value.getObj());
target_path = C4PropertyPath(new_proplist);
target_path_stack.clear();
name_override = nullptr;
UpdateValue(true);
delegate_factory->OnPropListChanged();
}
void C4ConsoleQtPropListModel::DescendPath(const C4Value &new_value, C4PropList *new_info_proplist, const C4PropertyPath &new_path, C4String *new_name_override)
void C4ConsoleQtPropListModel::DescendPath(const C4Value &new_value, C4PropList *new_info_proplist, const C4PropertyPath &new_path)
{
// Add previous proplist to stack
target_path_stack.push_back(TargetStackEntry(target_path, target_value, info_proplist, name_override.Get()));
target_path_stack.push_back(TargetStackEntry(target_path, target_value, info_proplist));
// descend
target_value = new_value;
info_proplist.SetPropList(new_info_proplist);
target_path = new_path;
name_override = new_name_override;
UpdateValue(true);
delegate_factory->OnPropListChanged();
}
@ -1612,7 +1618,6 @@ void C4ConsoleQtPropListModel::AscendPath()
target_path = entry.path;
target_value = entry.value;
info_proplist = entry.info_proplist;
name_override = entry.name_override;
UpdateValue(true);
break;
}
@ -1695,22 +1700,24 @@ int32_t C4ConsoleQtPropListModel::UpdateValuePropList(C4PropList *target_proplis
for (C4Effect *fx = obj->pEffects; fx; fx = fx->pNext)
{
QString name = fx->GetName();
if (AddPropertyGroup(fx, num_groups, name, fx, obj, nullptr, nullptr))
C4PropList *effect_editorprops = fx->GetPropertyPropList(P_EditorProps);
if (effect_editorprops && AddPropertyGroup(effect_editorprops, num_groups, name, fx, obj, nullptr, nullptr))
++num_groups;
}
}
// Properties from object (but not on definition)
if (obj || !info_proplist->GetDef())
{
for (C4PropList *check_proplist = info_proplist; check_proplist; check_proplist = check_proplist->GetPrototype())
C4PropList *info_editorprops = info_proplist->GetPropertyPropList(P_EditorProps);
if (info_editorprops)
{
QString name;
C4PropListStatic *proplist_static = check_proplist->IsStatic();
C4PropListStatic *proplist_static = info_proplist->IsStatic();
if (proplist_static)
name = QString(proplist_static->GetDataString().getData());
else
name = check_proplist->GetName();
if (AddPropertyGroup(check_proplist, num_groups, name, target_proplist, nullptr, default_selection, default_selection_index))
name = info_proplist->GetName();
if (AddPropertyGroup(info_editorprops, num_groups, name, target_proplist, nullptr, default_selection, default_selection_index))
++num_groups;
// Assign group for default selection
if (*default_selection_index >= 0)
@ -1725,8 +1732,11 @@ int32_t C4ConsoleQtPropListModel::UpdateValuePropList(C4PropList *target_proplis
{
C4Def *editor_base = C4Id2Def(C4ID::EditorBase);
if (editor_base)
if (AddPropertyGroup(editor_base, num_groups, LoadResStr("IDS_CNS_OBJECT"), target_proplist, nullptr, nullptr, nullptr))
{
C4PropList *info_editorprops = editor_base->GetPropertyPropList(P_EditorProps);
if (AddPropertyGroup(info_editorprops, num_groups, LoadResStr("IDS_CNS_OBJECT"), target_proplist, nullptr, nullptr, nullptr))
++num_groups;
}
}
}
// Always: Internal properties
@ -1758,14 +1768,17 @@ int32_t C4ConsoleQtPropListModel::UpdateValueArray(C4ValueArray *target_array, i
layout_valid = false;
property_groups.resize(1);
}
property_groups[0].name = (name_override ? name_override->GetCStr() : LoadResStr("IDS_CNS_ARRAYEDIT"));
C4PropList *info_proplist = this->info_proplist.getPropList();
C4Value elements_delegate_value;
if (info_proplist) info_proplist->GetProperty(P_Elements, &elements_delegate_value);
property_groups[0].name = (info_proplist ? info_proplist->GetName() : LoadResStr("IDS_CNS_ARRAYEDIT"));
PropertyGroup &properties = property_groups[0];
if (properties.props.size() != target_array->GetSize())
{
layout_valid = false;
properties.props.resize(target_array->GetSize());
}
C4PropertyDelegate *item_delegate = delegate_factory->GetDelegateByValue(info_proplist);
C4PropertyDelegate *item_delegate = delegate_factory->GetDelegateByValue(elements_delegate_value);
for (int32_t i = 0; i < properties.props.size(); ++i)
{
Property &prop = properties.props[i];
@ -1773,7 +1786,7 @@ int32_t C4ConsoleQtPropListModel::UpdateValueArray(C4ValueArray *target_array, i
prop.parent_value = target_value;
prop.display_name = ::Strings.RegString(FormatString("%d", (int)i).getData());
prop.key = nullptr;
prop.delegate_info = info_proplist;
prop.delegate_info = elements_delegate_value;
prop.delegate = item_delegate;
prop.about_to_edit = false;
prop.group_idx = 0;

View File

@ -486,10 +486,9 @@ public:
// TODO: Would be nice to store only path without values and info_proplist. However, info_proplist is hard to resolve when traversing up
// So just keep the value for now and hope that proplists do not change during selection
C4Value value, info_proplist;
C4RefCntPointer<C4String> name_override;
TargetStackEntry(const C4PropertyPath &path, const C4Value &value, const C4Value &info_proplist, C4String *name_override)
: path(path), value(value), info_proplist(info_proplist), name_override(name_override) {}
TargetStackEntry(const C4PropertyPath &path, const C4Value &value, const C4Value &info_proplist)
: path(path), value(value), info_proplist(info_proplist) {}
};
struct EditedPath // Information about how to find currently edited element (to restore after model update)
{
@ -501,7 +500,6 @@ private:
C4Value base_proplist; // Parent-most value, i.e. object or effect selected in editor through
C4Value info_proplist; // Proplist from which available properties are derived. May differ from target_proplist in child proplists.
C4PropertyPath target_path; // script path to target proplist to set values
C4RefCntPointer<C4String> name_override; // String to override the name on the first group instead of using info_proplist->GetName() (used only for arrays)
std::list<TargetStackEntry> target_path_stack; // stack of target paths descended into by setting child properties
std::vector<PropertyGroup> property_groups;
QFont header_font;
@ -516,7 +514,7 @@ public:
bool AddPropertyGroup(C4PropList *add_proplist, int32_t group_index, QString name, C4PropList *ignore_overridden, C4Object *base_effect_object, C4String *default_selection, int32_t *default_selection_index);
void SetBasePropList(C4PropList *new_proplist); // Clear stack and select new proplist
void DescendPath(const C4Value &new_value, C4PropList *new_info_proplist, const C4PropertyPath &new_path, C4String *new_name_override); // Add proplist to stack
void DescendPath(const C4Value &new_value, C4PropList *new_info_proplist, const C4PropertyPath &new_path); // Add proplist to stack
void AscendPath(); // go back one element in target path stack
void UpdateValue(bool select_default);

View File

@ -469,13 +469,13 @@ void C4PropList::AppendDataString(StdStrBuf * out, const char * delim, int depth
}
}
std::vector< C4String * > C4PropList::GetSortedLocalProperties() const
std::vector< C4String * > C4PropList::GetSortedLocalProperties(bool add_prototype) const
{
// return property list without descending into prototype
std::list<const C4Property *> sorted_props = Properties.GetSortedListOfElementPointers();
std::vector< C4String * > result;
result.reserve(sorted_props.size() + 1);
result.push_back(&::Strings.P[P_Prototype]); // implicit prototype for every prop list
result.reserve(sorted_props.size() + add_prototype);
if (add_prototype) result.push_back(&::Strings.P[P_Prototype]); // implicit prototype for every prop list
for (auto p : sorted_props) result.push_back(p->Key);
return result;
}

View File

@ -136,7 +136,7 @@ public:
void CompileFunc(StdCompiler *pComp, C4ValueNumbers *);
void AppendDataString(StdStrBuf * out, const char * delim, int depth = 3) const;
std::vector< C4String * > GetSortedLocalProperties() const;
std::vector< C4String * > GetSortedLocalProperties(bool add_prototype=true) const;
std::vector< C4String * > GetSortedLocalProperties(const char *prefix, const C4PropList *ignore_overridden) const;
std::vector< C4String * > GetSortedProperties(const char *prefix, C4PropList *ignore_parent = nullptr) const;

View File

@ -271,6 +271,7 @@ C4StringTable::C4StringTable()
P[P_Storage] = "Storage";
P[P_Elements] = "Elements";
P[P_EditOnSelection] = "EditOnSelection";
P[P_EditorProps] = "EditorProps";
P[P_DefaultEditorProp] = "DefaultEditorProp";
P[P_CopyDefault] = "CopyDefault";
P[P_Display] = "Display";

View File

@ -495,6 +495,7 @@ enum C4PropertyName
P_Storage,
P_Elements,
P_EditOnSelection,
P_EditorProps,
P_DefaultEditorProp,
P_CopyDefault,
P_Display,