summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorRaul Santos <raulsntos@gmail.com>2022-03-06 18:04:29 +0100
committerRaul Santos <raulsntos@gmail.com>2022-06-03 05:19:01 +0200
commit329818f20b455bd5026878ee4ed15df4d50abc62 (patch)
tree89bee7b1fbddcf407dc1d358b03980143d93b48f /editor
parent1baee2189c21ae36c852ddff10f769b1134509ca (diff)
Support explicit values in flag properties, add C# flags support
- Add support for explicit values in properties using `PROPERTY_HINT_FLAGS` that works the same way it does for enums. - Fix enums and flags in VisualScriptEditor (it wasn't considering the explicit value). - Use `PROPERTY_HINT_FLAGS` for C# enums with the FlagsAttribute instead of `PROPERTY_HINT_ENUM`.
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_properties.cpp33
-rw-r--r--editor/editor_properties.h4
-rw-r--r--editor/property_editor.cpp33
3 files changed, 37 insertions, 33 deletions
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 196fba6e9b..e3d4f1cab0 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -733,14 +733,12 @@ void EditorPropertyFlags::_set_read_only(bool p_read_only) {
}
};
-void EditorPropertyFlags::_flag_toggled() {
- uint32_t value = 0;
- for (int i = 0; i < flags.size(); i++) {
- if (flags[i]->is_pressed()) {
- uint32_t val = 1;
- val <<= flag_indices[i];
- value |= val;
- }
+void EditorPropertyFlags::_flag_toggled(int p_index) {
+ uint32_t value = get_edited_object()->get(get_edited_property());
+ if (flags[p_index]->is_pressed()) {
+ value |= flag_values[p_index];
+ } else {
+ value &= ~flag_values[p_index];
}
emit_changed(get_edited_property(), value);
@@ -750,13 +748,7 @@ void EditorPropertyFlags::update_property() {
uint32_t value = get_edited_object()->get(get_edited_property());
for (int i = 0; i < flags.size(); i++) {
- uint32_t val = 1;
- val <<= flag_indices[i];
- if (value & val) {
- flags[i]->set_pressed(true);
- } else {
- flags[i]->set_pressed(false);
- }
+ flags[i]->set_pressed((value & flag_values[i]) == flag_values[i]);
}
}
@@ -764,17 +756,24 @@ void EditorPropertyFlags::setup(const Vector<String> &p_options) {
ERR_FAIL_COND(flags.size());
bool first = true;
+ uint32_t current_val;
for (int i = 0; i < p_options.size(); i++) {
String option = p_options[i].strip_edges();
if (!option.is_empty()) {
CheckBox *cb = memnew(CheckBox);
cb->set_text(option);
cb->set_clip_text(true);
- cb->connect("pressed", callable_mp(this, &EditorPropertyFlags::_flag_toggled));
+ cb->connect("pressed", callable_mp(this, &EditorPropertyFlags::_flag_toggled), varray(i));
add_focusable(cb);
vbox->add_child(cb);
flags.push_back(cb);
- flag_indices.push_back(i);
+ Vector<String> text_split = p_options[i].split(":");
+ if (text_split.size() != 1) {
+ current_val = text_split[1].to_int();
+ } else {
+ current_val = 1 << i;
+ }
+ flag_values.push_back(current_val);
if (first) {
set_label_reference(cb);
first = false;
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 5ee0ba1a6d..a3990db678 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -265,9 +265,9 @@ class EditorPropertyFlags : public EditorProperty {
GDCLASS(EditorPropertyFlags, EditorProperty);
VBoxContainer *vbox = nullptr;
Vector<CheckBox *> flags;
- Vector<int> flag_indices;
+ Vector<uint32_t> flag_values;
- void _flag_toggled();
+ void _flag_toggled(int p_index);
protected:
virtual void _set_read_only(bool p_read_only) override;
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index da67ed79ba..771d34d841 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -105,15 +105,16 @@ void CustomPropertyEditor::_menu_option(int p_which) {
switch (type) {
case Variant::INT: {
if (hint == PROPERTY_HINT_FLAGS) {
- int val = v;
-
- if (val & (1 << p_which)) {
- val &= ~(1 << p_which);
+ int idx = menu->get_item_index(p_which);
+ uint32_t item_value = menu->get_item_metadata(idx);
+ uint32_t value = v;
+ // If the item wasn't previously checked it means it was pressed,
+ // otherwise it was unpressed.
+ if (!menu->is_item_checked(idx)) {
+ v = value | item_value;
} else {
- val |= (1 << p_which);
+ v = value & ~item_value;
}
-
- v = val;
emit_signal(SNAME("variant_changed"));
} else if (hint == PROPERTY_HINT_ENUM) {
v = menu->get_item_metadata(p_which);
@@ -486,15 +487,19 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
set_size(Size2(200, 150) * EDSCALE);
} else if (hint == PROPERTY_HINT_FLAGS) {
Vector<String> flags = hint_text.split(",");
+ uint32_t value = v;
for (int i = 0; i < flags.size(); i++) {
- String flag = flags[i];
- if (flag.is_empty()) {
- continue;
+ uint32_t current_val;
+ Vector<String> text_split = flags[i].split(":");
+ if (text_split.size() != 1) {
+ current_val = text_split[1].to_int();
+ } else {
+ current_val = 1 << i;
}
- menu->add_check_item(flag, i);
- int f = v;
- if (f & (1 << i)) {
- menu->set_item_checked(menu->get_item_index(i), true);
+ menu->add_check_item(text_split[0], current_val);
+ menu->set_item_metadata(i, current_val);
+ if ((value & current_val) == current_val) {
+ menu->set_item_checked(menu->get_item_index(current_val), true);
}
}
menu->set_position(get_position());