Qt Editor: Add EditorActions.

Replacing the old EditCursorCommands (which nobody knew). Objects now publish their commands directly on the property viewer.
qteditor
Sven Eberhardt 2016-06-19 00:08:09 -04:00
parent 6aa926bffa
commit 34289fa18a
7 changed files with 80 additions and 3 deletions

View File

@ -504,6 +504,13 @@
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="objectActionPanel">
<property name="verticalSpacing">
<number>6</number>
</property>
</layout>
</item>
<item>
<widget class="QTreeView" name="propertyTable">
<property name="acceptDrops">

View File

@ -709,6 +709,7 @@ void C4ConsoleGUIState::PropertyDlgUpdate(C4EditCursorSelection &rSelection, boo
ui.propertyTable->setEnabled(false);
ui.selectionInfoLabel->setText(rSelection.GetDataString().getData());
ui.propertyEditAscendPathButton->hide();
UpdateActionObject(nullptr);
}
else
{
@ -720,6 +721,7 @@ void C4ConsoleGUIState::PropertyDlgUpdate(C4EditCursorSelection &rSelection, boo
ui.propertyTable->setFirstColumnSpanned(0, QModelIndex(), true);
ui.propertyTable->setFirstColumnSpanned(1, QModelIndex(), true);
ui.propertyTable->expand(property_model->index(0, 0, QModelIndex()));
UpdateActionObject(new_list->GetObject());
}
else if (::Console.EditCursor.IsSelectionInvalidated())
{
@ -905,3 +907,64 @@ void C4ConsoleGUIState::ClearGamePointers()
{
if (property_delegate_factory) property_delegate_factory->ClearDelegates();
}
void C4ConsoleGUIState::UpdateActionObject(C4Object *new_action_object)
{
// No change? Do not recreate buttons then because it may interfere with their usage
C4Object *prev_object = action_object.getObj();
if (new_action_object && prev_object == new_action_object) return;
action_object = C4VObj(new_action_object);
// Clear old action buttons
int32_t i = ui.objectActionPanel->count();
while (i--)
{
ui.objectActionPanel->itemAt(i)->widget()->deleteLater();
}
// Create new buttons
// Actions are defined as locals prefixed EditorAction_ containing proplists
if (!new_action_object) return;
const char *editor_action_prefix = "EditorAction_";
auto new_properties = new_action_object->GetSortedProperties(editor_action_prefix, &::ScriptEngine);
int row = 0, column = 0;
for (C4String *action_def_id : new_properties)
{
// Get action definition proplist
C4Value action_def_val;
if (!new_action_object->GetPropertyByS(action_def_id, &action_def_val))
{
// property disappeared (cannot happen)
continue;
}
C4PropList *action_def = action_def_val.getPropList();
if (!action_def)
{
// property is of wrong type (can happen; scripter error)
continue;
}
// Get action name
C4String *action_name = action_def->GetPropertyStr(P_Name);
if (!action_name)
{
// Fallback to identifier for unnamed actions
action_name = ::Strings.RegString(action_def_id->GetCStr() + strlen(editor_action_prefix));
}
// Script command to execute
C4RefCntPointer<C4String> script_command = action_def->GetPropertyStr(P_Command);
int32_t object_number = new_action_object->Number;
// Create action button
QPushButton *btn = new QPushButton(action_name->GetCStr(), window.get());
if (script_command)
{
btn->connect(btn, &QPushButton::pressed, btn, [script_command, object_number]()
{
::Console.EditCursor.EMControl(CID_Script, new C4ControlScript(script_command->GetCStr(), object_number, false));
});
}
ui.objectActionPanel->addWidget(btn, row, column);
if (++column >= 3)
{
column = 0;
++row;
}
}
}

View File

@ -178,6 +178,9 @@ public:
// Updating states to prevent callbacks on internal selection updates
int32_t is_object_selection_updating;
// Currently selected single object
C4Value action_object;
C4ConsoleGUIState(C4ConsoleGUI *console);
~C4ConsoleGUIState();
@ -214,6 +217,7 @@ public:
void SetObjectSelection(class C4EditCursorSelection &rSelection);
void OnObjectListSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
void OnCreatorCurrentChanged(const QModelIndex & current, const QModelIndex & previous);
void UpdateActionObject(C4Object *new_action_object);
bool CreateNewScenario(StdStrBuf *out_filename); // show "new scenario" dialogue; return true if new scenario is created

View File

@ -499,7 +499,7 @@ std::vector< C4String * > C4PropList::GetSortedLocalProperties(const char *prefi
return result;
}
std::vector< C4String * > C4PropList::GetSortedProperties(const char *prefix) const
std::vector< C4String * > C4PropList::GetSortedProperties(const char *prefix, C4PropList *ignore_parent) const
{
// Return property list with descending into prototype
// But do not include Prototype property
@ -509,9 +509,10 @@ std::vector< C4String * > C4PropList::GetSortedProperties(const char *prefix) co
{
for (const C4Property *pp = p->Properties.First(); pp; pp = p->Properties.Next(pp))
if (pp->Key != &::Strings.P[P_Prototype])
if (!prefix || !pp->Key->GetData().BeginsWith(prefix))
if (!prefix || pp->Key->GetData().BeginsWith(prefix))
result.push_back(pp->Key);
p = p->GetPrototype();
if (p == ignore_parent) break;
} while (p);
// Sort
std::sort(result.begin(), result.end(), [](const C4String *a, const C4String *b) -> bool

View File

@ -137,7 +137,7 @@ public:
void AppendDataString(StdStrBuf * out, const char * delim, int depth = 3) const;
std::vector< C4String * > GetSortedLocalProperties() const;
std::vector< C4String * > GetSortedLocalProperties(const char *prefix, const C4PropList *ignore_overridden) const;
std::vector< C4String * > GetSortedProperties(const char *prefix) const;
std::vector< C4String * > GetSortedProperties(const char *prefix, C4PropList *ignore_parent = nullptr) const;
bool operator==(const C4PropList &b) const;
#ifdef _DEBUG

View File

@ -270,6 +270,7 @@ C4StringTable::C4StringTable()
P[P_DefaultValue] = "DefaultValue";
P[P_DefinitionPriority] = "DefinitionPriority";
P[P_Group] = "Group";
P[P_Command] = "Command";
P[DFA_WALK] = "WALK";
P[DFA_FLIGHT] = "FLIGHT";
P[DFA_KNEEL] = "KNEEL";

View File

@ -494,6 +494,7 @@ enum C4PropertyName
P_DefaultValue,
P_DefinitionPriority,
P_Group,
P_Command,
// Default Action Procedures
DFA_WALK,
DFA_FLIGHT,