diff options
author | Raul Santos <raulsntos@gmail.com> | 2022-03-06 18:04:29 +0100 |
---|---|---|
committer | Raul Santos <raulsntos@gmail.com> | 2022-06-03 05:19:01 +0200 |
commit | 329818f20b455bd5026878ee4ed15df4d50abc62 (patch) | |
tree | 89bee7b1fbddcf407dc1d358b03980143d93b48f /editor | |
parent | 1baee2189c21ae36c852ddff10f769b1134509ca (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.cpp | 33 | ||||
-rw-r--r-- | editor/editor_properties.h | 4 | ||||
-rw-r--r-- | editor/property_editor.cpp | 33 |
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()); |