diff options
Diffstat (limited to 'editor')
443 files changed, 13864 insertions, 12183 deletions
diff --git a/editor/SCsub b/editor/SCsub index c217f162b4..32ad88add5 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -24,7 +24,7 @@ def _make_doc_data_class_path(to_path): g.close() -if env["tools"]: +if env.editor_build: # Register exporters reg_exporters_inc = '#include "register_exporters.h"\n' reg_exporters = "void register_exporters() {\n" diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index b6348c5952..c376d5434f 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -28,731 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "action_map_editor.h" +#include "editor/action_map_editor.h" -#include "core/input/input_map.h" -#include "core/os/keyboard.h" #include "editor/editor_scale.h" -#include "scene/gui/separator.h" - -///////////////////////////////////////// - -// Maps to 2*axis if value is neg, or 2*axis+1 if value is pos. -static const char *_joy_axis_descriptions[(size_t)JoyAxis::MAX * 2] = { - TTRC("Left Stick Left, Joystick 0 Left"), - TTRC("Left Stick Right, Joystick 0 Right"), - TTRC("Left Stick Up, Joystick 0 Up"), - TTRC("Left Stick Down, Joystick 0 Down"), - TTRC("Right Stick Left, Joystick 1 Left"), - TTRC("Right Stick Right, Joystick 1 Right"), - TTRC("Right Stick Up, Joystick 1 Up"), - TTRC("Right Stick Down, Joystick 1 Down"), - TTRC("Joystick 2 Left"), - TTRC("Left Trigger, Sony L2, Xbox LT, Joystick 2 Right"), - TTRC("Joystick 2 Up"), - TTRC("Right Trigger, Sony R2, Xbox RT, Joystick 2 Down"), - TTRC("Joystick 3 Left"), - TTRC("Joystick 3 Right"), - TTRC("Joystick 3 Up"), - TTRC("Joystick 3 Down"), - TTRC("Joystick 4 Left"), - TTRC("Joystick 4 Right"), - TTRC("Joystick 4 Up"), - TTRC("Joystick 4 Down"), -}; - -String InputEventConfigurationDialog::get_event_text(const Ref<InputEvent> &p_event, bool p_include_device) const { - ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEvent"); - - String text = p_event->as_text(); - - Ref<InputEventKey> key = p_event; - if (key.is_valid() && key->is_command_or_control_autoremap()) { -#ifdef MACOS_ENABLED - text = text.replace("Command", "Command/Ctrl"); -#else - text = text.replace("Ctrl", "Command/Ctrl"); -#endif - } - Ref<InputEventMouse> mouse = p_event; - Ref<InputEventJoypadMotion> jp_motion = p_event; - Ref<InputEventJoypadButton> jp_button = p_event; - if (jp_motion.is_valid()) { - // Joypad motion events will display slightly differently than what the event->as_text() provides. See #43660. - String desc = TTR("Unknown Joypad Axis"); - if (jp_motion->get_axis() < JoyAxis::MAX) { - desc = RTR(_joy_axis_descriptions[2 * (size_t)jp_motion->get_axis() + (jp_motion->get_axis_value() < 0 ? 0 : 1)]); - } - - text = vformat("Joypad Axis %s %s (%s)", itos((int64_t)jp_motion->get_axis()), jp_motion->get_axis_value() < 0 ? "-" : "+", desc); - } - if (p_include_device && (mouse.is_valid() || jp_button.is_valid() || jp_motion.is_valid())) { - String device_string = _get_device_string(p_event->get_device()); - text += vformat(" - %s", device_string); - } - - return text; -} - -void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, bool p_update_input_list_selection) { - if (p_event.is_valid()) { - event = p_event; - - // Update Label - event_as_text->set_text(get_event_text(event, true)); - - Ref<InputEventKey> k = p_event; - Ref<InputEventMouseButton> mb = p_event; - Ref<InputEventJoypadButton> joyb = p_event; - Ref<InputEventJoypadMotion> joym = p_event; - Ref<InputEventWithModifiers> mod = p_event; - - // Update option values and visibility - bool show_mods = false; - bool show_device = false; - bool show_phys_key = false; - - if (mod.is_valid()) { - show_mods = true; - mod_checkboxes[MOD_ALT]->set_pressed(mod->is_alt_pressed()); - mod_checkboxes[MOD_SHIFT]->set_pressed(mod->is_shift_pressed()); - mod_checkboxes[MOD_CTRL]->set_pressed(mod->is_ctrl_pressed()); - mod_checkboxes[MOD_META]->set_pressed(mod->is_meta_pressed()); - - autoremap_command_or_control_checkbox->set_pressed(mod->is_command_or_control_autoremap()); - } - - if (k.is_valid()) { - show_phys_key = true; - physical_key_checkbox->set_pressed(k->get_physical_keycode() != Key::NONE && k->get_keycode() == Key::NONE); - - } else if (joyb.is_valid() || joym.is_valid() || mb.is_valid()) { - show_device = true; - _set_current_device(event->get_device()); - } - - mod_container->set_visible(show_mods); - device_container->set_visible(show_device); - physical_key_checkbox->set_visible(show_phys_key); - additional_options_container->show(); - - // Update selected item in input list. - if (p_update_input_list_selection && (k.is_valid() || joyb.is_valid() || joym.is_valid() || mb.is_valid())) { - TreeItem *category = input_list_tree->get_root()->get_first_child(); - while (category) { - TreeItem *input_item = category->get_first_child(); - - if (input_item != nullptr) { - // input_type should always be > 0, unless the tree structure has been misconfigured. - int input_type = input_item->get_parent()->get_meta("__type", 0); - if (input_type == 0) { - return; - } - - // If event type matches input types of this category. - if ((k.is_valid() && input_type == INPUT_KEY) || (joyb.is_valid() && input_type == INPUT_JOY_BUTTON) || (joym.is_valid() && input_type == INPUT_JOY_MOTION) || (mb.is_valid() && input_type == INPUT_MOUSE_BUTTON)) { - // Loop through all items of this category until one matches. - while (input_item) { - bool key_match = k.is_valid() && (Variant(k->get_keycode()) == input_item->get_meta("__keycode") || Variant(k->get_physical_keycode()) == input_item->get_meta("__keycode")); - bool joyb_match = joyb.is_valid() && Variant(joyb->get_button_index()) == input_item->get_meta("__index"); - bool joym_match = joym.is_valid() && Variant(joym->get_axis()) == input_item->get_meta("__axis") && joym->get_axis_value() == (float)input_item->get_meta("__value"); - bool mb_match = mb.is_valid() && Variant(mb->get_button_index()) == input_item->get_meta("__index"); - if (key_match || joyb_match || joym_match || mb_match) { - category->set_collapsed(false); - input_item->select(0); - input_list_tree->ensure_cursor_is_visible(); - return; - } - input_item = input_item->get_next(); - } - } - } - - category->set_collapsed(true); // Event not in this category, so collapse; - category = category->get_next(); - } - } - } else { - // Event is not valid, reset dialog - event = p_event; - Vector<String> strings; - - // Reset message, promp for input according to which input types are allowed. - String text = TTR("Perform an Input (%s)."); - - if (allowed_input_types & INPUT_KEY) { - strings.append(TTR("Key")); - } - - if (allowed_input_types & INPUT_JOY_BUTTON) { - strings.append(TTR("Joypad Button")); - } - if (allowed_input_types & INPUT_JOY_MOTION) { - strings.append(TTR("Joypad Axis")); - } - if (allowed_input_types & INPUT_MOUSE_BUTTON) { - strings.append(TTR("Mouse Button in area below")); - } - if (strings.size() == 0) { - text = TTR("Input Event dialog has been misconfigured: No input types are allowed."); - event_as_text->set_text(text); - } else { - String insert_text = String(", ").join(strings); - event_as_text->set_text(vformat(text, insert_text)); - } - - additional_options_container->hide(); - input_list_tree->deselect_all(); - _update_input_list(); - } -} - -void InputEventConfigurationDialog::_tab_selected(int p_tab) { - Callable signal_method = callable_mp(this, &InputEventConfigurationDialog::_listen_window_input); - if (p_tab == 0) { - // Start Listening. - if (!is_connected("window_input", signal_method)) { - connect("window_input", signal_method); - } - } else { - // Stop Listening. - if (is_connected("window_input", signal_method)) { - disconnect("window_input", signal_method); - } - input_list_tree->call_deferred(SNAME("ensure_cursor_is_visible")); - if (input_list_tree->get_selected() == nullptr) { - // If nothing selected, scroll to top. - input_list_tree->scroll_to_item(input_list_tree->get_root()); - } - } -} - -void InputEventConfigurationDialog::_listen_window_input(const Ref<InputEvent> &p_event) { - // Ignore if echo or not pressed - if (p_event->is_echo() || !p_event->is_pressed()) { - return; - } - - // Ignore mouse motion - Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid()) { - return; - } - - // Ignore mouse button if not in the detection rect - Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid()) { - Rect2 r = mouse_detection_rect->get_rect(); - if (!r.has_point(mouse_detection_rect->get_local_mouse_position() + r.get_position())) { - return; - } - } - - // Create an editable reference - Ref<InputEvent> received_event = p_event; - - // Check what the type is and if it is allowed. - Ref<InputEventKey> k = received_event; - Ref<InputEventJoypadButton> joyb = received_event; - Ref<InputEventJoypadMotion> joym = received_event; - - int type = 0; - if (k.is_valid()) { - type = INPUT_KEY; - } else if (joyb.is_valid()) { - type = INPUT_JOY_BUTTON; - } else if (joym.is_valid()) { - type = INPUT_JOY_MOTION; - } else if (mb.is_valid()) { - type = INPUT_MOUSE_BUTTON; - } - - if (!(allowed_input_types & type)) { - return; - } - - if (joym.is_valid()) { - float axis_value = joym->get_axis_value(); - if (ABS(axis_value) < 0.9) { - // Ignore motion below 0.9 magnitude to avoid accidental touches - return; - } else { - // Always make the value 1 or -1 for display consistency - joym->set_axis_value(SIGN(axis_value)); - } - } - - if (k.is_valid()) { - k->set_pressed(false); // To avoid serialisation of 'pressed' property - doesn't matter for actions anyway. - // Maintain physical keycode option state - if (physical_key_checkbox->is_pressed()) { - k->set_keycode(Key::NONE); - } else { - k->set_physical_keycode(Key::NONE); - } - } - - Ref<InputEventWithModifiers> mod = received_event; - if (mod.is_valid()) { - mod->set_window_id(0); - } - - // Maintain device selection. - received_event->set_device(_get_current_device()); - - _set_event(received_event); - set_input_as_handled(); -} - -void InputEventConfigurationDialog::_search_term_updated(const String &) { - _update_input_list(); -} - -void InputEventConfigurationDialog::_update_input_list() { - input_list_tree->clear(); - - TreeItem *root = input_list_tree->create_item(); - String search_term = input_list_search->get_text(); - - bool collapse = input_list_search->get_text().is_empty(); - - if (allowed_input_types & INPUT_KEY) { - TreeItem *kb_root = input_list_tree->create_item(root); - kb_root->set_text(0, TTR("Keyboard Keys")); - kb_root->set_icon(0, icon_cache.keyboard); - kb_root->set_collapsed(collapse); - kb_root->set_meta("__type", INPUT_KEY); - - for (int i = 0; i < keycode_get_count(); i++) { - String name = keycode_get_name_by_index(i); - - if (!search_term.is_empty() && name.findn(search_term) == -1) { - continue; - } - - TreeItem *item = input_list_tree->create_item(kb_root); - item->set_text(0, name); - item->set_meta("__keycode", keycode_get_value_by_index(i)); - } - } - - if (allowed_input_types & INPUT_MOUSE_BUTTON) { - TreeItem *mouse_root = input_list_tree->create_item(root); - mouse_root->set_text(0, TTR("Mouse Buttons")); - mouse_root->set_icon(0, icon_cache.mouse); - mouse_root->set_collapsed(collapse); - mouse_root->set_meta("__type", INPUT_MOUSE_BUTTON); - - MouseButton mouse_buttons[9] = { MouseButton::LEFT, MouseButton::RIGHT, MouseButton::MIDDLE, MouseButton::WHEEL_UP, MouseButton::WHEEL_DOWN, MouseButton::WHEEL_LEFT, MouseButton::WHEEL_RIGHT, MouseButton::MB_XBUTTON1, MouseButton::MB_XBUTTON2 }; - for (int i = 0; i < 9; i++) { - Ref<InputEventMouseButton> mb; - mb.instantiate(); - mb->set_button_index(mouse_buttons[i]); - String desc = get_event_text(mb, false); - - if (!search_term.is_empty() && desc.findn(search_term) == -1) { - continue; - } - - TreeItem *item = input_list_tree->create_item(mouse_root); - item->set_text(0, desc); - item->set_meta("__index", mouse_buttons[i]); - } - } - - if (allowed_input_types & INPUT_JOY_BUTTON) { - TreeItem *joyb_root = input_list_tree->create_item(root); - joyb_root->set_text(0, TTR("Joypad Buttons")); - joyb_root->set_icon(0, icon_cache.joypad_button); - joyb_root->set_collapsed(collapse); - joyb_root->set_meta("__type", INPUT_JOY_BUTTON); - - for (int i = 0; i < (int)JoyButton::MAX; i++) { - Ref<InputEventJoypadButton> joyb; - joyb.instantiate(); - joyb->set_button_index((JoyButton)i); - String desc = get_event_text(joyb, false); - - if (!search_term.is_empty() && desc.findn(search_term) == -1) { - continue; - } - - TreeItem *item = input_list_tree->create_item(joyb_root); - item->set_text(0, desc); - item->set_meta("__index", i); - } - } - - if (allowed_input_types & INPUT_JOY_MOTION) { - TreeItem *joya_root = input_list_tree->create_item(root); - joya_root->set_text(0, TTR("Joypad Axes")); - joya_root->set_icon(0, icon_cache.joypad_axis); - joya_root->set_collapsed(collapse); - joya_root->set_meta("__type", INPUT_JOY_MOTION); - - for (int i = 0; i < (int)JoyAxis::MAX * 2; i++) { - int axis = i / 2; - int direction = (i & 1) ? 1 : -1; - Ref<InputEventJoypadMotion> joym; - joym.instantiate(); - joym->set_axis((JoyAxis)axis); - joym->set_axis_value(direction); - String desc = get_event_text(joym, false); - - if (!search_term.is_empty() && desc.findn(search_term) == -1) { - continue; - } - - TreeItem *item = input_list_tree->create_item(joya_root); - item->set_text(0, desc); - item->set_meta("__axis", i >> 1); - item->set_meta("__value", (i & 1) ? 1 : -1); - } - } -} - -void InputEventConfigurationDialog::_mod_toggled(bool p_checked, int p_index) { - Ref<InputEventWithModifiers> ie = event; - - // Not event with modifiers - if (ie.is_null()) { - return; - } - - if (p_index == 0) { - ie->set_alt_pressed(p_checked); - } else if (p_index == 1) { - ie->set_shift_pressed(p_checked); - } else if (p_index == 2) { - if (!autoremap_command_or_control_checkbox->is_pressed()) { - ie->set_ctrl_pressed(p_checked); - } - } else if (p_index == 3) { - if (!autoremap_command_or_control_checkbox->is_pressed()) { - ie->set_meta_pressed(p_checked); - } - } - - _set_event(ie); -} - -void InputEventConfigurationDialog::_autoremap_command_or_control_toggled(bool p_checked) { - Ref<InputEventWithModifiers> ie = event; - if (ie.is_valid()) { - ie->set_command_or_control_autoremap(p_checked); - _set_event(ie); - } - - if (p_checked) { - mod_checkboxes[MOD_META]->hide(); - mod_checkboxes[MOD_CTRL]->hide(); - } else { - mod_checkboxes[MOD_META]->show(); - mod_checkboxes[MOD_CTRL]->show(); - } -} - -void InputEventConfigurationDialog::_physical_keycode_toggled(bool p_checked) { - Ref<InputEventKey> k = event; - - if (k.is_null()) { - return; - } - - if (p_checked) { - k->set_physical_keycode(k->get_keycode()); - k->set_keycode(Key::NONE); - } else { - k->set_keycode((Key)k->get_physical_keycode()); - k->set_physical_keycode(Key::NONE); - } - - _set_event(k); -} - -void InputEventConfigurationDialog::_input_list_item_selected() { - TreeItem *selected = input_list_tree->get_selected(); - - // Invalid tree selection - type only exists on the "category" items, which are not a valid selection. - if (selected->has_meta("__type")) { - return; - } - - InputEventConfigurationDialog::InputType input_type = (InputEventConfigurationDialog::InputType)(int)selected->get_parent()->get_meta("__type"); - - switch (input_type) { - case InputEventConfigurationDialog::INPUT_KEY: { - Key keycode = (Key)(int)selected->get_meta("__keycode"); - Ref<InputEventKey> k; - k.instantiate(); - - if (physical_key_checkbox->is_pressed()) { - k->set_physical_keycode(keycode); - k->set_keycode(Key::NONE); - } else { - k->set_physical_keycode(Key::NONE); - k->set_keycode(keycode); - } - - // Maintain modifier state from checkboxes - k->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed()); - k->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed()); - if (autoremap_command_or_control_checkbox->is_pressed()) { - k->set_command_or_control_autoremap(true); - } else { - k->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed()); - k->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed()); - } - - _set_event(k, false); - } break; - case InputEventConfigurationDialog::INPUT_MOUSE_BUTTON: { - MouseButton idx = (MouseButton)(int)selected->get_meta("__index"); - Ref<InputEventMouseButton> mb; - mb.instantiate(); - mb->set_button_index(idx); - // Maintain modifier state from checkboxes - mb->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed()); - mb->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed()); - if (autoremap_command_or_control_checkbox->is_pressed()) { - mb->set_command_or_control_autoremap(true); - } else { - mb->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed()); - mb->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed()); - } - - // Maintain selected device - mb->set_device(_get_current_device()); - - _set_event(mb, false); - } break; - case InputEventConfigurationDialog::INPUT_JOY_BUTTON: { - JoyButton idx = (JoyButton)(int)selected->get_meta("__index"); - Ref<InputEventJoypadButton> jb = InputEventJoypadButton::create_reference(idx); - - // Maintain selected device - jb->set_device(_get_current_device()); - - _set_event(jb, false); - } break; - case InputEventConfigurationDialog::INPUT_JOY_MOTION: { - JoyAxis axis = (JoyAxis)(int)selected->get_meta("__axis"); - int value = selected->get_meta("__value"); - - Ref<InputEventJoypadMotion> jm; - jm.instantiate(); - jm->set_axis(axis); - jm->set_axis_value(value); - - // Maintain selected device - jm->set_device(_get_current_device()); - - _set_event(jm, false); - } break; - } -} - -void InputEventConfigurationDialog::_device_selection_changed(int p_option_button_index) { - // Subtract 1 as option index 0 corresponds to "All Devices" (value of -1) - // and option index 1 corresponds to device 0, etc... - event->set_device(p_option_button_index - 1); - event_as_text->set_text(get_event_text(event, true)); -} - -void InputEventConfigurationDialog::_set_current_device(int p_device) { - device_id_option->select(p_device + 1); -} - -int InputEventConfigurationDialog::_get_current_device() const { - return device_id_option->get_selected() - 1; -} - -String InputEventConfigurationDialog::_get_device_string(int p_device) const { - if (p_device == InputMap::ALL_DEVICES) { - return TTR("All Devices"); - } - return TTR("Device") + " " + itos(p_device); -} - -void InputEventConfigurationDialog::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: - case NOTIFICATION_THEME_CHANGED: { - input_list_search->set_right_icon(input_list_search->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); - - physical_key_checkbox->set_icon(get_theme_icon(SNAME("KeyboardPhysical"), SNAME("EditorIcons"))); - - icon_cache.keyboard = get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons")); - icon_cache.mouse = get_theme_icon(SNAME("Mouse"), SNAME("EditorIcons")); - icon_cache.joypad_button = get_theme_icon(SNAME("JoyButton"), SNAME("EditorIcons")); - icon_cache.joypad_axis = get_theme_icon(SNAME("JoyAxis"), SNAME("EditorIcons")); - - _update_input_list(); - } break; - } -} - -void InputEventConfigurationDialog::popup_and_configure(const Ref<InputEvent> &p_event) { - if (p_event.is_valid()) { - _set_event(p_event); - } else { - // Clear Event - _set_event(p_event); - - // Clear Checkbox Values - for (int i = 0; i < MOD_MAX; i++) { - mod_checkboxes[i]->set_pressed(false); - } - - // Enable the Physical Key checkbox by default to encourage its use. - // Physical Key should be used for most game inputs as it allows keys to work - // on non-QWERTY layouts out of the box. - // This is especially important for WASD movement layouts. - physical_key_checkbox->set_pressed(true); - - autoremap_command_or_control_checkbox->set_pressed(false); - _set_current_device(0); - - // Switch to "Listen" tab - tab_container->set_current_tab(0); - - // Select "All Devices" by default. - device_id_option->select(0); - } - - popup_centered(Size2(0, 400) * EDSCALE); -} - -Ref<InputEvent> InputEventConfigurationDialog::get_event() const { - return event; -} - -void InputEventConfigurationDialog::set_allowed_input_types(int p_type_masks) { - allowed_input_types = p_type_masks; -} - -InputEventConfigurationDialog::InputEventConfigurationDialog() { - allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION | INPUT_MOUSE_BUTTON; - - set_title(TTR("Event Configuration")); - set_min_size(Size2i(550 * EDSCALE, 0)); // Min width - - VBoxContainer *main_vbox = memnew(VBoxContainer); - add_child(main_vbox); - - tab_container = memnew(TabContainer); - tab_container->set_use_hidden_tabs_for_min_size(true); - tab_container->set_v_size_flags(Control::SIZE_EXPAND_FILL); - tab_container->set_theme_type_variation("TabContainerOdd"); - tab_container->connect("tab_selected", callable_mp(this, &InputEventConfigurationDialog::_tab_selected)); - main_vbox->add_child(tab_container); - - // Listen to input tab - VBoxContainer *vb = memnew(VBoxContainer); - vb->set_name(TTR("Listen for Input")); - event_as_text = memnew(Label); - event_as_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); - vb->add_child(event_as_text); - // Mouse button detection rect (Mouse button event outside this rect will be ignored) - mouse_detection_rect = memnew(Panel); - mouse_detection_rect->set_v_size_flags(Control::SIZE_EXPAND_FILL); - vb->add_child(mouse_detection_rect); - tab_container->add_child(vb); - - // List of all input options to manually select from. - - VBoxContainer *manual_vbox = memnew(VBoxContainer); - manual_vbox->set_name(TTR("Manual Selection")); - manual_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL); - tab_container->add_child(manual_vbox); - - input_list_search = memnew(LineEdit); - input_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL); - input_list_search->set_placeholder(TTR("Filter Inputs")); - input_list_search->set_clear_button_enabled(true); - input_list_search->connect("text_changed", callable_mp(this, &InputEventConfigurationDialog::_search_term_updated)); - manual_vbox->add_child(input_list_search); - - input_list_tree = memnew(Tree); - input_list_tree->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); // Min height for tree - input_list_tree->connect("item_selected", callable_mp(this, &InputEventConfigurationDialog::_input_list_item_selected)); - input_list_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); - manual_vbox->add_child(input_list_tree); - - input_list_tree->set_hide_root(true); - input_list_tree->set_columns(1); - - _update_input_list(); - - // Additional Options - additional_options_container = memnew(VBoxContainer); - additional_options_container->hide(); - - Label *opts_label = memnew(Label); - opts_label->set_theme_type_variation("HeaderSmall"); - opts_label->set_text(TTR("Additional Options")); - additional_options_container->add_child(opts_label); - - // Device Selection - device_container = memnew(HBoxContainer); - device_container->set_h_size_flags(Control::SIZE_EXPAND_FILL); - - Label *device_label = memnew(Label); - device_label->set_theme_type_variation("HeaderSmall"); - device_label->set_text(TTR("Device:")); - device_container->add_child(device_label); - - device_id_option = memnew(OptionButton); - device_id_option->set_h_size_flags(Control::SIZE_EXPAND_FILL); - for (int i = -1; i < 8; i++) { - device_id_option->add_item(_get_device_string(i)); - } - device_id_option->connect("item_selected", callable_mp(this, &InputEventConfigurationDialog::_device_selection_changed)); - _set_current_device(InputMap::ALL_DEVICES); - device_container->add_child(device_id_option); - - device_container->hide(); - additional_options_container->add_child(device_container); - - // Modifier Selection - mod_container = memnew(HBoxContainer); - for (int i = 0; i < MOD_MAX; i++) { - String name = mods[i]; - mod_checkboxes[i] = memnew(CheckBox); - mod_checkboxes[i]->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_mod_toggled).bind(i)); - mod_checkboxes[i]->set_text(name); - mod_checkboxes[i]->set_tooltip_text(TTR(mods_tip[i])); - mod_container->add_child(mod_checkboxes[i]); - } - - mod_container->add_child(memnew(VSeparator)); - - autoremap_command_or_control_checkbox = memnew(CheckBox); - autoremap_command_or_control_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_autoremap_command_or_control_toggled)); - autoremap_command_or_control_checkbox->set_pressed(false); - autoremap_command_or_control_checkbox->set_text(TTR("Command / Control (auto)")); - autoremap_command_or_control_checkbox->set_tooltip_text(TTR("Automatically remaps between 'Meta' ('Command') and 'Control' depending on current platform.")); - mod_container->add_child(autoremap_command_or_control_checkbox); - - mod_container->hide(); - additional_options_container->add_child(mod_container); - - // Physical Key Checkbox - - physical_key_checkbox = memnew(CheckBox); - physical_key_checkbox->set_text(TTR("Use Physical Keycode")); - physical_key_checkbox->set_tooltip_text(TTR("Stores the physical position of the key on the keyboard rather than the key's value. Used for compatibility with non-latin layouts.\nThis should generally be enabled for most game shortcuts, but not in non-game applications.")); - physical_key_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_physical_keycode_toggled)); - physical_key_checkbox->hide(); - additional_options_container->add_child(physical_key_checkbox); - - main_vbox->add_child(additional_options_container); - - // Default to first tab - tab_container->set_current_tab(0); -} - -///////////////////////////////////////// +#include "editor/event_listener_line_edit.h" +#include "editor/input_event_configuration_dialog.h" +#include "scene/gui/check_button.h" +#include "scene/gui/tree.h" static bool _is_action_name_valid(const String &p_name) { const char32_t *cstr = p_name.get_data(); @@ -944,6 +226,12 @@ void ActionMapEditor::_search_term_updated(const String &) { update_action_list(); } +void ActionMapEditor::_search_by_event(const Ref<InputEvent> &p_event) { + if (p_event.is_null() || (p_event->is_pressed() && !p_event->is_echo())) { + update_action_list(); + } +} + Variant ActionMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { TreeItem *selected = action_tree->get_selected(); if (!selected) { @@ -1084,6 +372,22 @@ InputEventConfigurationDialog *ActionMapEditor::get_configuration_dialog() { return event_config_dialog; } +bool ActionMapEditor::_should_display_action(const String &p_name, const Array &p_events) const { + const Ref<InputEvent> search_ev = action_list_search_by_event->get_event(); + bool event_match = true; + if (search_ev.is_valid()) { + event_match = false; + for (int i = 0; i < p_events.size(); ++i) { + const Ref<InputEvent> ev = p_events[i]; + if (ev.is_valid() && ev->is_match(search_ev, true)) { + event_match = true; + } + } + } + + return event_match && action_list_search->get_text().is_subsequence_ofn(p_name); +} + void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_infos) { if (!p_action_infos.is_empty()) { actions_cache = p_action_infos; @@ -1092,17 +396,11 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info action_tree->clear(); TreeItem *root = action_tree->create_item(); - int uneditable_count = 0; - for (int i = 0; i < actions_cache.size(); i++) { ActionInfo action_info = actions_cache[i]; - if (!action_info.editable) { - uneditable_count++; - } - - String search_term = action_list_search->get_text(); - if (!search_term.is_empty() && action_info.name.findn(search_term) == -1) { + const Array events = action_info.action["events"]; + if (!_should_display_action(action_info.name, events)) { continue; } @@ -1110,7 +408,6 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info continue; } - const Array events = action_info.action["events"]; const Variant deadzone = action_info.action["deadzone"]; // Update Tree... @@ -1146,7 +443,7 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info TreeItem *event_item = action_tree->create_item(action_item); // First Column - Text - event_item->set_text(0, event_config_dialog->get_event_text(event, true)); + event_item->set_text(0, EventListenerLineEdit::get_event_text(event, true)); event_item->set_meta("__event", event); event_item->set_meta("__index", evnt_idx); @@ -1206,16 +503,22 @@ ActionMapEditor::ActionMapEditor() { action_list_search = memnew(LineEdit); action_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL); - action_list_search->set_placeholder(TTR("Filter Actions")); + action_list_search->set_placeholder(TTR("Filter by name...")); action_list_search->set_clear_button_enabled(true); action_list_search->connect("text_changed", callable_mp(this, &ActionMapEditor::_search_term_updated)); top_hbox->add_child(action_list_search); - show_builtin_actions_checkbutton = memnew(CheckButton); - show_builtin_actions_checkbutton->set_pressed(false); - show_builtin_actions_checkbutton->set_text(TTR("Show Built-in Actions")); - show_builtin_actions_checkbutton->connect("toggled", callable_mp(this, &ActionMapEditor::set_show_builtin_actions)); - top_hbox->add_child(show_builtin_actions_checkbutton); + action_list_search_by_event = memnew(EventListenerLineEdit); + action_list_search_by_event->set_h_size_flags(Control::SIZE_EXPAND_FILL); + action_list_search_by_event->set_stretch_ratio(0.75); + action_list_search_by_event->connect("event_changed", callable_mp(this, &ActionMapEditor::_search_by_event)); + top_hbox->add_child(action_list_search_by_event); + + Button *clear_all_search = memnew(Button); + clear_all_search->set_text(TTR("Clear All")); + clear_all_search->connect("pressed", callable_mp(action_list_search_by_event, &EventListenerLineEdit::clear_event)); + clear_all_search->connect("pressed", callable_mp(action_list_search, &LineEdit::clear)); + top_hbox->add_child(clear_all_search); // Adding Action line edit + button add_hbox = memnew(HBoxContainer); @@ -1236,6 +539,12 @@ ActionMapEditor::ActionMapEditor() { // Disable the button and set its tooltip. _add_edit_text_changed(add_edit->get_text()); + show_builtin_actions_checkbutton = memnew(CheckButton); + show_builtin_actions_checkbutton->set_pressed(false); + show_builtin_actions_checkbutton->set_text(TTR("Show Built-in Actions")); + show_builtin_actions_checkbutton->connect("toggled", callable_mp(this, &ActionMapEditor::set_show_builtin_actions)); + add_hbox->add_child(show_builtin_actions_checkbutton); + main_vbox->add_child(add_hbox); // Action Editor Tree diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h index 36d21fe258..ad9980c4ef 100644 --- a/editor/action_map_editor.h +++ b/editor/action_map_editor.h @@ -31,117 +31,24 @@ #ifndef ACTION_MAP_EDITOR_H #define ACTION_MAP_EDITOR_H -#include "scene/gui/check_box.h" -#include "scene/gui/check_button.h" -#include "scene/gui/color_rect.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/label.h" -#include "scene/gui/option_button.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/tree.h" - -// Confirmation Dialog used when configuring an input event. -// Separate from ActionMapEditor for code cleanliness and separation of responsibilities. -class InputEventConfigurationDialog : public ConfirmationDialog { - GDCLASS(InputEventConfigurationDialog, ConfirmationDialog); +#include "scene/gui/control.h" -public: - enum InputType { - INPUT_KEY = 1, - INPUT_MOUSE_BUTTON = 2, - INPUT_JOY_BUTTON = 4, - INPUT_JOY_MOTION = 8 - }; - -private: - struct IconCache { - Ref<Texture2D> keyboard; - Ref<Texture2D> mouse; - Ref<Texture2D> joypad_button; - Ref<Texture2D> joypad_axis; - } icon_cache; - - Ref<InputEvent> event = Ref<InputEvent>(); - - TabContainer *tab_container = nullptr; - - // Listening for input - Label *event_as_text = nullptr; - Panel *mouse_detection_rect = nullptr; - - // List of All Key/Mouse/Joypad input options. - int allowed_input_types; - Tree *input_list_tree = nullptr; - LineEdit *input_list_search = nullptr; - - // Additional Options, shown depending on event selected - VBoxContainer *additional_options_container = nullptr; - - HBoxContainer *device_container = nullptr; - OptionButton *device_id_option = nullptr; - - HBoxContainer *mod_container = nullptr; // Contains the subcontainer and the store command checkbox. - - enum ModCheckbox { - MOD_ALT, - MOD_SHIFT, - MOD_CTRL, - MOD_META, - MOD_MAX - }; -#if defined(MACOS_ENABLED) - String mods[MOD_MAX] = { "Option", "Shift", "Ctrl", "Command" }; -#elif defined(WINDOWS_ENABLED) - String mods[MOD_MAX] = { "Alt", "Shift", "Ctrl", "Windows" }; -#else - String mods[MOD_MAX] = { "Alt", "Shift", "Ctrl", "Meta" }; -#endif - String mods_tip[MOD_MAX] = { "Alt or Option key", "Shift key", "Control key", "Meta/Windows or Command key" }; - - CheckBox *mod_checkboxes[MOD_MAX]; - CheckBox *autoremap_command_or_control_checkbox = nullptr; - - CheckBox *physical_key_checkbox = nullptr; - - void _set_event(const Ref<InputEvent> &p_event, bool p_update_input_list_selection = true); - - void _tab_selected(int p_tab); - void _listen_window_input(const Ref<InputEvent> &p_event); - - void _search_term_updated(const String &p_term); - void _update_input_list(); - void _input_list_item_selected(); - - void _mod_toggled(bool p_checked, int p_index); - void _autoremap_command_or_control_toggled(bool p_checked); - void _physical_keycode_toggled(bool p_checked); - - void _device_selection_changed(int p_option_button_index); - void _set_current_device(int p_device); - int _get_current_device() const; - String _get_device_string(int p_device) const; - -protected: - void _notification(int p_what); - -public: - // Pass an existing event to configure it. Alternatively, pass no event to start with a blank configuration. - void popup_and_configure(const Ref<InputEvent> &p_event = Ref<InputEvent>()); - Ref<InputEvent> get_event() const; - String get_event_text(const Ref<InputEvent> &p_event, bool p_include_device) const; - - void set_allowed_input_types(int p_type_masks); - - InputEventConfigurationDialog(); -}; +class Button; +class HBoxContainer; +class EventListenerLineEdit; +class LineEdit; +class CheckButton; +class AcceptDialog; +class InputEventConfigurationDialog; +class Tree; class ActionMapEditor : public Control { GDCLASS(ActionMapEditor, Control); public: struct ActionInfo { - String name = String(); - Dictionary action = Dictionary(); + String name; + Dictionary action; Ref<Texture2D> icon = Ref<Texture2D>(); bool editable = true; @@ -160,8 +67,8 @@ private: // Storing which action/event is currently being edited in the InputEventConfigurationDialog. - Dictionary current_action = Dictionary(); - String current_action_name = String(); + Dictionary current_action; + String current_action_name; int current_action_event_index = -1; // Popups @@ -174,6 +81,7 @@ private: bool show_builtin_actions = false; CheckButton *show_builtin_actions_checkbutton = nullptr; LineEdit *action_list_search = nullptr; + EventListenerLineEdit *action_list_search_by_event = nullptr; HBoxContainer *add_hbox = nullptr; LineEdit *add_edit = nullptr; @@ -191,6 +99,8 @@ private: void _tree_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button); void _tree_item_activated(); void _search_term_updated(const String &p_search_term); + void _search_by_event(const Ref<InputEvent> &p_event); + bool _should_display_action(const String &p_name, const Array &p_events) const; Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 219f3fdbe1..7ffec0835b 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -32,6 +32,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "scene/gui/view_panner.h" #include "scene/resources/text_line.h" @@ -211,11 +212,11 @@ void AnimationBezierTrackEdit::_draw_line_clipped(const Vector2 &p_from, const V void AnimationBezierTrackEdit::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); } break; case NOTIFICATION_ENTER_TREE: { - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { @@ -338,14 +339,14 @@ void AnimationBezierTrackEdit::_notification(int p_what) { Ref<Texture2D> unlock = get_theme_icon(SNAME("Unlock"), SNAME("EditorIcons")); float lock_hpos = remove_hpos - hsep - lock->get_width(); - Ref<Texture2D> visible = get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")); - Ref<Texture2D> hidden = get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")); - float visibility_hpos = lock_hpos - hsep - visible->get_width(); + Ref<Texture2D> visibility_visible = get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons")); + Ref<Texture2D> visibility_hidden = get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")); + float visibility_hpos = lock_hpos - hsep - visibility_visible->get_width(); Ref<Texture2D> solo = get_theme_icon(SNAME("AudioBusSolo"), SNAME("EditorIcons")); float solo_hpos = visibility_hpos - hsep - solo->get_width(); - float buttons_width = remove->get_width() + lock->get_width() + visible->get_width() + solo->get_width() + hsep * 3; + float buttons_width = remove->get_width() + lock->get_width() + visibility_visible->get_width() + solo->get_width() + hsep * 3; for (int i = 0; i < tracks.size(); ++i) { // RELATED TRACKS TITLES @@ -418,11 +419,11 @@ void AnimationBezierTrackEdit::_notification(int p_what) { draw_texture(unlock, lock_rect.position); } - Rect2 visible_rect = Rect2(visibility_hpos, icon_start_height - visible->get_height() / 2.0, visible->get_width(), visible->get_height()); + Rect2 visible_rect = Rect2(visibility_hpos, icon_start_height - visibility_visible->get_height() / 2.0, visibility_visible->get_width(), visibility_visible->get_height()); if (hidden_tracks.has(current_track)) { - draw_texture(hidden, visible_rect.position); + draw_texture(visibility_hidden, visible_rect.position); } else { - draw_texture(visible, visible_rect.position); + draw_texture(visibility_visible, visible_rect.position); } Rect2 solo_rect = Rect2(solo_hpos, icon_start_height - solo->get_height() / 2.0, solo->get_width(), solo->get_height()); @@ -655,10 +656,6 @@ Size2 AnimationBezierTrackEdit::get_minimum_size() const { return Vector2(1, 1); } -void AnimationBezierTrackEdit::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void AnimationBezierTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) { timeline = p_timeline; timeline->connect("zoom_changed", callable_mp(this, &AnimationBezierTrackEdit::_zoom_changed)); @@ -667,8 +664,8 @@ void AnimationBezierTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) { void AnimationBezierTrackEdit::set_editor(AnimationTrackEditor *p_editor) { editor = p_editor; - connect("clear_selection", Callable(editor, "_clear_selection").bind(false)); - connect("select_key", Callable(editor, "_key_selected"), CONNECT_DEFERRED); + connect("clear_selection", callable_mp(editor, &AnimationTrackEditor::_clear_selection).bind(false)); + connect("select_key", callable_mp(editor, &AnimationTrackEditor::_key_selected), CONNECT_DEFERRED); } void AnimationBezierTrackEdit::_play_position_draw() { @@ -791,6 +788,7 @@ void AnimationBezierTrackEdit::_clear_selection() { } void AnimationBezierTrackEdit::_change_selected_keys_handle_mode(Animation::HandleMode p_mode, bool p_auto) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Update Selected Key Handles")); for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { const IntPair track_key_pair = E->get(); @@ -903,11 +901,17 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } float zoom_value = timeline->get_zoom()->get_max() - zv; - timeline->get_zoom()->set_value(zoom_value); - timeline->call_deferred("set_value", minimum_time); + if (Math::is_finite(minimum_time) && Math::is_finite(maximum_time) && maximum_time - minimum_time > CMP_EPSILON) { + timeline->get_zoom()->set_value(zoom_value); + timeline->call_deferred("set_value", minimum_time); + } - v_scroll = (maximum_value + minimum_value) / 2.0; - v_zoom = (maximum_value - minimum_value) / ((get_size().height - timeline->get_size().height) * 0.9); + if (Math::is_finite(minimum_value) && Math::is_finite(maximum_value)) { + v_scroll = (maximum_value + minimum_value) / 2.0; + if (maximum_value - minimum_value > CMP_EPSILON) { + v_zoom = (maximum_value - minimum_value) / ((get_size().height - timeline->get_size().height) * 0.9); + } + } queue_redraw(); accept_event(); @@ -938,9 +942,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { Vector2 popup_pos = get_screen_position() + mb->get_position(); menu->clear(); - if (!locked_tracks.has(selected_track) || locked_tracks.has(selected_track)) { - menu->add_icon_item(bezier_icon, TTR("Insert Key Here"), MENU_KEY_INSERT); - } + menu->add_icon_item(bezier_icon, TTR("Insert Key Here"), MENU_KEY_INSERT); if (selection.size()) { menu->add_separator(); menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Duplicate Selected Key(s)"), MENU_KEY_DUPLICATE); @@ -983,6 +985,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { if (I.value.has_point(mb->get_position())) { if (I.key == REMOVE_ICON) { if (!read_only) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action("Remove Bezier Track"); undo_redo->add_do_method(this, "_update_locked_tracks_after", track); @@ -1169,6 +1172,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { time += 0.001; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Bezier Point")); undo_redo->add_do_method(animation.ptr(), "bezier_track_insert_key", selected_track, time, new_point); undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", selected_track, time); @@ -1266,6 +1270,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { if (moving_selection) { //combit it + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Move Bezier Points")); List<AnimMoveRestore> to_restore; @@ -1466,6 +1471,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { if ((moving_handle == -1 || moving_handle == 1) && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { if (!read_only) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Move Bezier Points")); if (moving_handle == -1) { real_t ratio = timeline->get_zoom_scale() * v_zoom; @@ -1537,6 +1543,7 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) { time += 0.001; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Bezier Point")); undo_redo->add_do_method(animation.ptr(), "track_insert_key", selected_track, time, new_point); undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", selected_track, time); @@ -1584,6 +1591,7 @@ void AnimationBezierTrackEdit::duplicate_selection() { } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Duplicate Keys")); List<Pair<int, real_t>> new_selection_values; @@ -1629,6 +1637,7 @@ void AnimationBezierTrackEdit::duplicate_selection() { void AnimationBezierTrackEdit::delete_selection() { if (selection.size()) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Delete Keys")); for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h index beb7a5e9c6..8f03787429 100644 --- a/editor/animation_bezier_editor.h +++ b/editor/animation_bezier_editor.h @@ -34,7 +34,6 @@ #include "animation_track_editor.h" #include "core/templates/hashfuncs.h" -class EditorUndoRedoManager; class ViewPanner; class AnimationBezierTrackEdit : public Control { @@ -53,7 +52,6 @@ class AnimationBezierTrackEdit : public Control { }; AnimationTimelineEdit *timeline = nullptr; - Ref<EditorUndoRedoManager> undo_redo; Node *root = nullptr; Control *play_position = nullptr; //separate control used to draw so updates for only position changed are much faster real_t play_position_pos = 0; @@ -197,7 +195,6 @@ public: void set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only); virtual Size2 get_minimum_size() const override; - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); void set_timeline(AnimationTimelineEdit *p_timeline); void set_editor(AnimationTrackEditor *p_editor); void set_root(Node *p_root); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 70b5501692..7c403b7523 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -35,10 +35,13 @@ #include "editor/animation_bezier_editor.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/inspector_dock.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "scene/animation/animation_player.h" #include "scene/animation/tween.h" +#include "scene/gui/grid_container.h" #include "scene/gui/separator.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" @@ -133,6 +136,7 @@ public: int existing = animation->track_find_key(track, new_time, true); setting = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Change Keyframe Time"), UndoRedo::MERGE_ENDS); Variant val = animation->track_get_key_value(track, key); @@ -160,6 +164,7 @@ public: float val = p_value; float prev_val = animation->track_get_key_transition(track, key); setting = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Change Transition"), UndoRedo::MERGE_ENDS); undo_redo->add_do_method(animation.ptr(), "track_set_key_transition", track, key, val); undo_redo->add_undo_method(animation.ptr(), "track_set_key_transition", track, key, prev_val); @@ -171,6 +176,7 @@ public: return true; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (animation->track_get_type(track)) { case Animation::TYPE_POSITION_3D: case Animation::TYPE_ROTATION_3D: @@ -685,7 +691,6 @@ public: } } - Ref<EditorUndoRedoManager> undo_redo; Ref<Animation> animation; int track = -1; float key_ofs = 0; @@ -810,6 +815,7 @@ public: int existing = animation->track_find_key(track, new_time, true); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (!setting) { setting = true; undo_redo->create_action(TTR("Anim Multi Change Keyframe Time"), UndoRedo::MERGE_ENDS); @@ -834,6 +840,7 @@ public: float val = p_value; float prev_val = animation->track_get_key_transition(track, key); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (!setting) { setting = true; undo_redo->create_action(TTR("Anim Multi Change Transition"), UndoRedo::MERGE_ENDS); @@ -843,6 +850,7 @@ public: update_obj = true; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (animation->track_get_type(track)) { case Animation::TYPE_POSITION_3D: case Animation::TYPE_ROTATION_3D: @@ -1053,6 +1061,7 @@ public: } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (setting) { if (update_obj) { undo_redo->add_do_method(this, "_update_obj", animation); @@ -1376,8 +1385,6 @@ public: bool use_fps = false; - Ref<EditorUndoRedoManager> undo_redo; - void notify_change() { notify_property_list_changed(); } @@ -1419,6 +1426,7 @@ void AnimationTimelineEdit::_anim_length_changed(double p_new_len) { } editing = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Animation Length")); undo_redo->add_do_method(animation.ptr(), "set_length", p_new_len); undo_redo->add_undo_method(animation.ptr(), "set_length", animation->get_length()); @@ -1431,6 +1439,7 @@ void AnimationTimelineEdit::_anim_length_changed(double p_new_len) { void AnimationTimelineEdit::_anim_loop_pressed() { if (!read_only) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Animation Loop")); switch (animation->get_loop_mode()) { case Animation::LOOP_NONE: { @@ -1445,7 +1454,9 @@ void AnimationTimelineEdit::_anim_loop_pressed() { default: break; } + undo_redo->add_do_method(this, "update_values"); undo_redo->add_undo_method(animation.ptr(), "set_loop_mode", animation->get_loop_mode()); + undo_redo->add_undo_method(this, "update_values"); undo_redo->commit_action(); } else { String base_path = animation->get_path(); @@ -1485,7 +1496,7 @@ void AnimationTimelineEdit::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); add_track->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); loop->set_icon(get_theme_icon(SNAME("Loop"), SNAME("EditorIcons"))); time_icon->set_texture(get_theme_icon(SNAME("Time"), SNAME("EditorIcons"))); @@ -1503,7 +1514,7 @@ void AnimationTimelineEdit::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); } break; case NOTIFICATION_RESIZED: { @@ -1676,6 +1687,7 @@ void AnimationTimelineEdit::_notification(int p_what) { } draw_line(Vector2(0, get_size().height), get_size(), linecolor, Math::round(EDSCALE)); + update_values(); } break; } } @@ -1698,7 +1710,6 @@ void AnimationTimelineEdit::set_animation(const Ref<Animation> &p_animation, boo play_position->hide(); } queue_redraw(); - update_values(); } Size2 AnimationTimelineEdit::get_minimum_size() const { @@ -1710,10 +1721,6 @@ Size2 AnimationTimelineEdit::get_minimum_size() const { return ms; } -void AnimationTimelineEdit::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void AnimationTimelineEdit::set_zoom(Range *p_zoom) { zoom = p_zoom; zoom->connect("value_changed", callable_mp(this, &AnimationTimelineEdit::_zoom_changed)); @@ -1747,6 +1754,9 @@ void AnimationTimelineEdit::update_values() { length->set_step(1); length->set_tooltip_text(TTR("Animation length (frames)")); time_icon->set_tooltip_text(TTR("Animation length (frames)")); + if (track_edit) { + track_edit->editor->_update_key_edit(); + } } else { length->set_value(animation->get_length()); length->set_step(0.001); @@ -1891,7 +1901,6 @@ void AnimationTimelineEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origi void AnimationTimelineEdit::set_use_fps(bool p_use_fps) { use_fps = p_use_fps; - update_values(); queue_redraw(); } @@ -1913,6 +1922,8 @@ void AnimationTimelineEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag"), PropertyInfo(Variant::BOOL, "timeline_only"))); ADD_SIGNAL(MethodInfo("track_added", PropertyInfo(Variant::INT, "track"))); ADD_SIGNAL(MethodInfo("length_changed", PropertyInfo(Variant::FLOAT, "size"))); + + ClassDB::bind_method(D_METHOD("update_values"), &AnimationTimelineEdit::update_values); } AnimationTimelineEdit::AnimationTimelineEdit() { @@ -2025,14 +2036,14 @@ void AnimationTrackEdit::_notification(int p_what) { draw_texture(check, check_rect.position); ofs += check->get_width() + hsep; - Ref<Texture2D> type_icon = _get_key_type_icon(); - draw_texture(type_icon, Point2(ofs, int(get_size().height - type_icon->get_height()) / 2)); - ofs += type_icon->get_width() + hsep; + Ref<Texture2D> key_type_icon = _get_key_type_icon(); + draw_texture(key_type_icon, Point2(ofs, int(get_size().height - key_type_icon->get_height()) / 2)); + ofs += key_type_icon->get_width() + hsep; - NodePath path = animation->track_get_path(track); + NodePath anim_path = animation->track_get_path(track); Node *node = nullptr; - if (root && root->has_node(path)) { - node = root->get_node(path); + if (root && root->has_node(anim_path)) { + node = root->get_node(anim_path); } String text; @@ -2049,7 +2060,7 @@ void AnimationTrackEdit::_notification(int p_what) { } else if (animation->track_get_type(track) == Animation::TYPE_ANIMATION) { text = TTR("Anim Clips:"); } else { - text += path.get_concatenated_subnames(); + text += anim_path.get_concatenated_subnames(); } text_color.a *= 0.7; } else if (node) { @@ -2058,14 +2069,14 @@ void AnimationTrackEdit::_notification(int p_what) { draw_texture(icon, Point2(ofs, int(get_size().height - icon->get_height()) / 2)); icon_cache = icon; - text = String() + node->get_name() + ":" + path.get_concatenated_subnames(); + text = String() + node->get_name() + ":" + anim_path.get_concatenated_subnames(); ofs += hsep; ofs += icon->get_width(); } else { - icon_cache = type_icon; + icon_cache = key_type_icon; - text = path; + text = anim_path; } path_cache = text; @@ -2510,14 +2521,6 @@ Size2 AnimationTrackEdit::get_minimum_size() const { return Vector2(1, max_h + separation); } -void AnimationTrackEdit::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - -Ref<EditorUndoRedoManager> AnimationTrackEdit::get_undo_redo() const { - return undo_redo; -} - void AnimationTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) { timeline = p_timeline; timeline->set_track_edit(this); @@ -2564,6 +2567,7 @@ void AnimationTrackEdit::_zoom_changed() { } void AnimationTrackEdit::_path_submitted(const String &p_text) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Track Path")); undo_redo->add_do_method(animation.ptr(), "track_set_path", track, p_text); undo_redo->add_undo_method(animation.ptr(), "track_set_path", track, animation->track_get_path(track)); @@ -2801,6 +2805,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) { if (!read_only) { if (check_rect.has_point(pos)) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Toggle Track Enabled")); undo_redo->add_do_method(animation.ptr(), "track_set_enabled", track, !animation->track_is_enabled(track)); undo_redo->add_undo_method(animation.ptr(), "track_set_enabled", track, animation->track_is_enabled(track)); @@ -2849,9 +2854,9 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) { if (ape) { AnimationPlayer *ap = ape->get_player(); if (ap) { - NodePath path = animation->track_get_path(track); - Node *nd = ap->get_node(ap->get_root())->get_node(NodePath(path.get_concatenated_names())); - StringName prop = path.get_concatenated_subnames(); + NodePath npath = animation->track_get_path(track); + Node *nd = ap->get_node(ap->get_root())->get_node(NodePath(npath.get_concatenated_names())); + StringName prop = npath.get_concatenated_subnames(); PropertyInfo prop_info; ClassDB::get_property_info(nd->get_class(), prop, &prop_info); bool is_angle = prop_info.type == Variant::FLOAT && prop_info.hint_string.find("radians") != -1; @@ -3192,6 +3197,7 @@ void AnimationTrackEdit::_menu_selected(int p_index) { case MENU_CALL_MODE_TRIGGER: case MENU_CALL_MODE_CAPTURE: { Animation::UpdateMode update_mode = Animation::UpdateMode(p_index); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Animation Update Mode")); undo_redo->add_do_method(animation.ptr(), "value_track_set_update_mode", track, update_mode); undo_redo->add_undo_method(animation.ptr(), "value_track_set_update_mode", track, animation->value_track_get_update_mode(track)); @@ -3205,6 +3211,7 @@ void AnimationTrackEdit::_menu_selected(int p_index) { case MENU_INTERPOLATION_LINEAR_ANGLE: case MENU_INTERPOLATION_CUBIC_ANGLE: { Animation::InterpolationType interp_mode = Animation::InterpolationType(p_index - MENU_INTERPOLATION_NEAREST); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Animation Interpolation Mode")); undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", track, interp_mode); undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_type", track, animation->track_get_interpolation_type(track)); @@ -3214,6 +3221,7 @@ void AnimationTrackEdit::_menu_selected(int p_index) { case MENU_LOOP_WRAP: case MENU_LOOP_CLAMP: { bool loop_wrap = p_index == MENU_LOOP_WRAP; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Animation Loop Mode")); undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_loop_wrap", track, loop_wrap); undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_loop_wrap", track, animation->track_get_interpolation_loop_wrap(track)); @@ -3420,9 +3428,6 @@ void AnimationTrackEditGroup::_zoom_changed() { queue_redraw(); } -void AnimationTrackEditGroup::_bind_methods() { -} - AnimationTrackEditGroup::AnimationTrackEditGroup() { set_mouse_filter(MOUSE_FILTER_PASS); } @@ -3445,8 +3450,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_re track_edits[_get_track_selected()]->release_focus(); } if (animation.is_valid()) { - animation->disconnect("tracks_changed", callable_mp(this, &AnimationTrackEditor::_animation_changed)); - animation->disconnect("changed", callable_mp(this, &AnimationTrackEditor::_sync_animation_change)); + animation->disconnect("changed", callable_mp(this, &AnimationTrackEditor::_animation_changed)); _clear_selection(); } animation = p_anim; @@ -3457,8 +3461,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_re _update_tracks(); if (animation.is_valid()) { - animation->connect("tracks_changed", callable_mp(this, &AnimationTrackEditor::_animation_changed), CONNECT_DEFERRED); - animation->connect("changed", callable_mp(this, &AnimationTrackEditor::_sync_animation_change), CONNECT_DEFERRED); + animation->connect("changed", callable_mp(this, &AnimationTrackEditor::_animation_changed)); hscroll->show(); edit->set_disabled(read_only); @@ -3612,7 +3615,8 @@ void AnimationTrackEditor::_animation_track_remove_request(int p_track, Ref<Anim } int idx = p_track; if (idx >= 0 && idx < p_from_animation->get_track_count()) { - undo_redo->create_action(TTR("Remove Anim Track")); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Remove Anim Track"), UndoRedo::MERGE_DISABLE, p_from_animation.ptr()); // Remove corresponding reset tracks if they are no longer needed. AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); @@ -3812,6 +3816,7 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) { } void AnimationTrackEditor::_insert_track(bool p_reset_wanted, bool p_create_beziers) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Insert")); Ref<Animation> reset_anim; @@ -3849,7 +3854,7 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_ } // Let's build a node path. - String path = root->get_path_to(p_node); + String path = root->get_path_to(p_node, true); if (!p_sub.is_empty()) { path += ":" + p_sub; } @@ -3889,7 +3894,7 @@ bool AnimationTrackEditor::has_track(Node3D *p_node, const String &p_sub, const } // Let's build a node path. - String path = root->get_path_to(p_node); + String path = root->get_path_to(p_node, true); if (!p_sub.is_empty()) { path += ":" + p_sub; } @@ -3937,11 +3942,10 @@ void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists) { ERR_FAIL_COND(!root); - // Let's build a node path. + // Let's build a node path. Node *node = p_node; - - String path = root->get_path_to(node); + String path = root->get_path_to(node, true); if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") { if (node == AnimationPlayerEditor::get_singleton()->get_player()) { @@ -4035,14 +4039,13 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history(); ERR_FAIL_COND(!root); - // Let's build a node path. ERR_FAIL_COND(history->get_path_size() == 0); Object *obj = ObjectDB::get_instance(history->get_path_object(0)); ERR_FAIL_COND(!Object::cast_to<Node>(obj)); + // Let's build a node path. Node *node = Object::cast_to<Node>(obj); - - String path = root->get_path_to(node); + String path = root->get_path_to(node, true); if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") { if (node == AnimationPlayerEditor::get_singleton()->get_player()) { @@ -4142,6 +4145,7 @@ Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() { Ref<Animation> reset_anim; reset_anim.instantiate(); reset_anim->set_length(ANIM_MIN_LENGTH); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(al.ptr(), "add_animation", SceneStringNames::get_singleton()->RESET, reset_anim); undo_redo->add_do_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player); undo_redo->add_undo_method(al.ptr(), "remove_animation", SceneStringNames::get_singleton()->RESET); @@ -4151,6 +4155,7 @@ Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() { } void AnimationTrackEditor::_confirm_insert_list() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Create & Insert")); bool create_reset = insert_confirm_reset->is_visible() && insert_confirm_reset->is_pressed(); @@ -4324,6 +4329,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (create_normal_track) { if (p_create_beziers) { bool valid; @@ -4462,24 +4468,24 @@ void AnimationTrackEditor::_update_tracks() { return; } - bool read_only = false; + bool file_read_only = false; if (!animation->get_path().is_resource_file()) { int srpos = animation->get_path().find("::"); if (srpos != -1) { String base = animation->get_path().substr(0, srpos); if (ResourceLoader::get_resource_type(base) == "PackedScene") { if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) { - read_only = true; + file_read_only = true; } } else { if (FileAccess::exists(base + ".import")) { - read_only = true; + file_read_only = true; } } } } else { if (FileAccess::exists(animation->get_path() + ".import")) { - read_only = true; + file_read_only = true; } } @@ -4608,10 +4614,9 @@ void AnimationTrackEditor::_update_tracks() { track_vbox->add_child(track_edit); } - track_edit->set_undo_redo(undo_redo); track_edit->set_timeline(timeline); track_edit->set_root(root); - track_edit->set_animation_and_track(animation, i, read_only); + track_edit->set_animation_and_track(animation, i, file_read_only); track_edit->set_play_position(timeline->get_play_position()); track_edit->set_editor(this); @@ -4649,29 +4654,25 @@ void AnimationTrackEditor::_redraw_groups() { } } -void AnimationTrackEditor::_sync_animation_change() { - bezier_edit->queue_redraw(); -} - void AnimationTrackEditor::_animation_changed() { if (animation_changing_awaiting_update) { return; // All will be updated, don't bother with anything. } if (key_edit) { - _update_key_edit(); - } - - if (key_edit && key_edit->setting) { - // If editing a key, just redraw the edited track, makes refresh less costly. - if (key_edit->track < track_edits.size()) { - if (animation->track_get_type(key_edit->track) == Animation::TYPE_BEZIER) { - bezier_edit->queue_redraw(); - } else { - track_edits[key_edit->track]->queue_redraw(); + if (key_edit->setting) { + // If editing a key, just redraw the edited track, makes refresh less costly. + if (key_edit->track < track_edits.size()) { + if (animation->track_get_type(key_edit->track) == Animation::TYPE_BEZIER) { + bezier_edit->queue_redraw(); + } else { + track_edits[key_edit->track]->queue_redraw(); + } } + return; + } else { + _update_key_edit(); } - return; } animation_changing_awaiting_update = true; @@ -4752,11 +4753,11 @@ MenuButton *AnimationTrackEditor::get_edit_menu() { void AnimationTrackEditor::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); } break; case NOTIFICATION_ENTER_TREE: { - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/animation_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { @@ -4786,12 +4787,14 @@ void AnimationTrackEditor::_update_scroll(double) { } void AnimationTrackEditor::_update_step(double p_new_step) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Animation Step")); float step_value = p_new_step; if (timeline->is_using_fps()) { if (step_value != 0.0) { step_value = 1.0 / step_value; } + timeline->queue_redraw(); } undo_redo->add_do_method(animation.ptr(), "set_step", step_value); undo_redo->add_undo_method(animation.ptr(), "set_step", animation->get_step()); @@ -4811,6 +4814,7 @@ void AnimationTrackEditor::_dropped_track(int p_from_track, int p_to_track) { } _clear_selection(true); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Rearrange Tracks")); undo_redo->add_do_method(animation.ptr(), "track_move_to", p_from_track, p_to_track); // Take into account that the position of the tracks that come after the one removed will change. @@ -4825,7 +4829,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { ERR_FAIL_COND(!root); Node *node = get_node(p_path); ERR_FAIL_COND(!node); - NodePath path_to = root->get_path_to(node); + NodePath path_to = root->get_path_to(node, true); if (adding_track_type == Animation::TYPE_BLEND_SHAPE && !node->is_class("MeshInstance3D")) { EditorNode::get_singleton()->show_warning(TTR("Blend Shape tracks only apply to MeshInstance3D nodes.")); @@ -4854,6 +4858,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { case Animation::TYPE_ROTATION_3D: case Animation::TYPE_SCALE_3D: case Animation::TYPE_METHOD: { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Track")); undo_redo->add_do_method(animation.ptr(), "add_track", adding_track_type); undo_redo->add_do_method(animation.ptr(), "track_set_path", animation->get_track_count(), path_to); @@ -4882,6 +4887,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Track")); undo_redo->add_do_method(animation.ptr(), "add_track", adding_track_type); undo_redo->add_do_method(animation.ptr(), "track_set_path", animation->get_track_count(), path_to); @@ -4900,6 +4906,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Track")); undo_redo->add_do_method(animation.ptr(), "add_track", adding_track_type); undo_redo->add_do_method(animation.ptr(), "track_set_path", animation->get_track_count(), path_to); @@ -4924,6 +4931,7 @@ void AnimationTrackEditor::_add_track(int p_type) { void AnimationTrackEditor::_new_track_property_selected(String p_name) { String full_path = String(adding_track_path) + ":" + p_name; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (adding_track_type == Animation::TYPE_VALUE) { Animation::UpdateMode update_mode = Animation::UPDATE_DISCRETE; { @@ -5018,6 +5026,7 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) { p_ofs += 0.001; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (animation->track_get_type(p_track)) { case Animation::TYPE_POSITION_3D: { if (!root->has_node(animation->track_get_path(p_track))) { @@ -5071,10 +5080,8 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) { return; } - Vector3 scale = base->get_scale(); - undo_redo->create_action(TTR("Add Scale Key")); - undo_redo->add_do_method(animation.ptr(), "scale_track_insert_key", p_track, p_ofs, scale); + undo_redo->add_do_method(animation.ptr(), "scale_track_insert_key", p_track, p_ofs, base->get_scale()); undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", p_track, p_ofs); undo_redo->commit_action(); @@ -5175,6 +5182,7 @@ void AnimationTrackEditor::_add_method_key(const String &p_method) { } d["args"] = params; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Method Track Key")); undo_redo->add_do_method(animation.ptr(), "track_insert_key", insert_key_from_track_call_track, insert_key_from_track_call_ofs, d); undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", insert_key_from_track_call_track, insert_key_from_track_call_ofs); @@ -5284,13 +5292,17 @@ void AnimationTrackEditor::_update_key_edit() { key_edit->track = selection.front()->key().track; key_edit->use_fps = timeline->is_using_fps(); - float ofs = animation->track_get_key_time(key_edit->track, selection.front()->key().key); + int key_id = selection.front()->key().key; + if (key_id >= animation->track_get_key_count(key_edit->track)) { + _clear_key_edit(); + return; // Probably in the process of rearranging the keys. + } + float ofs = animation->track_get_key_time(key_edit->track, key_id); key_edit->key_ofs = ofs; key_edit->root_path = root; NodePath np; key_edit->hint = _find_hint_for_track(key_edit->track, np); - key_edit->undo_redo = undo_redo; key_edit->base = np; EditorNode::get_singleton()->push_item(key_edit); @@ -5313,18 +5325,19 @@ void AnimationTrackEditor::_update_key_edit() { base_map[track] = NodePath(); } + int key_id = E.key.key; + if (key_id >= animation->track_get_key_count(track)) { + _clear_key_edit(); + return; // Probably in the process of rearranging the keys. + } key_ofs_map[track].push_back(animation->track_get_key_time(track, E.key.key)); } multi_key_edit->key_ofs_map = key_ofs_map; multi_key_edit->base_map = base_map; multi_key_edit->hint = _find_hint_for_track(first_track, base_map[first_track]); - multi_key_edit->use_fps = timeline->is_using_fps(); - multi_key_edit->root_path = root; - multi_key_edit->undo_redo = undo_redo; - EditorNode::get_singleton()->push_item(multi_key_edit); } } @@ -5352,9 +5365,11 @@ void AnimationTrackEditor::_select_at_anim(const Ref<Animation> &p_anim, int p_t ki.pos = p_pos; selection.insert(sk, ki); + _update_key_edit(); } void AnimationTrackEditor::_move_selection_commit() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Move Keys")); List<_AnimMoveRestore> to_restore; @@ -5427,7 +5442,6 @@ void AnimationTrackEditor::_move_selection_commit() { undo_redo->add_do_method(this, "_redraw_tracks"); undo_redo->add_undo_method(this, "_redraw_tracks"); undo_redo->commit_action(); - _update_key_edit(); } void AnimationTrackEditor::_move_selection_cancel() { @@ -5607,6 +5621,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) { int start_track = transpose ? _get_track_selected() : top_track; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Duplicate Keys")); List<Pair<int, float>> new_selection_values; @@ -5657,7 +5672,6 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) { undo_redo->add_do_method(this, "_redraw_tracks"); undo_redo->add_undo_method(this, "_redraw_tracks"); undo_redo->commit_action(); - _update_key_edit(); } } @@ -5670,18 +5684,18 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) { if (animation.is_null()) { return; } - float step = animation->get_step(); - if (step == 0) { - step = 1; + float anim_step = animation->get_step(); + if (anim_step == 0) { + anim_step = 1; } if (p_from_mouse_event && Input::get_singleton()->is_key_pressed(Key::SHIFT)) { // Use more precise snapping when holding Shift. // This is used when scrobbling the timeline using Alt + Mouse wheel. - step *= 0.25; + anim_step *= 0.25; } float pos = timeline->get_play_position(); - pos = Math::snapped(pos - step, step); + pos = Math::snapped(pos - anim_step, anim_step); if (pos < 0) { pos = 0; } @@ -5693,21 +5707,21 @@ void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event, bool p_timeli if (animation.is_null()) { return; } - float step = animation->get_step(); - if (step == 0) { - step = 1; + float anim_step = animation->get_step(); + if (anim_step == 0) { + anim_step = 1; } if (p_from_mouse_event && Input::get_singleton()->is_key_pressed(Key::SHIFT)) { // Use more precise snapping when holding Shift. // This is used when scrobbling the timeline using Alt + Mouse wheel. // Do not use precise snapping when using the menu action or keyboard shortcut, // as the default keyboard shortcut requires pressing Shift. - step *= 0.25; + anim_step *= 0.25; } float pos = timeline->get_play_position(); - pos = Math::snapped(pos + step, step); + pos = Math::snapped(pos + anim_step, anim_step); if (pos > animation->get_length()) { pos = animation->get_length(); } @@ -5800,9 +5814,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } break; case EDIT_COPY_TRACKS_CONFIRM: { track_clipboard.clear(); - TreeItem *root = track_copy_select->get_root(); - if (root) { - TreeItem *it = root->get_first_child(); + TreeItem *tree_root = track_copy_select->get_root(); + if (tree_root) { + TreeItem *it = tree_root->get_first_child(); while (it) { Dictionary md = it->get_metadata(0); int idx = md["track_idx"]; @@ -5837,6 +5851,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } int base_track = animation->get_track_count(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Paste Tracks")); for (int i = 0; i < track_clipboard.size(); i++) { undo_redo->add_do_method(animation.ptr(), "add_track", track_clipboard[i].track_type); @@ -5904,10 +5919,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } float s = scale->get_value(); - if (s == 0) { - ERR_PRINT("Can't scale to 0"); - } + ERR_FAIL_COND_MSG(s == 0, "Can't scale to 0."); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Scale Keys")); List<_AnimMoveRestore> to_restore; @@ -5981,14 +5995,13 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { undo_redo->add_do_method(this, "_redraw_tracks"); undo_redo->add_undo_method(this, "_redraw_tracks"); undo_redo->commit_action(); - _update_key_edit(); - } break; case EDIT_EASE_SELECTION: { ease_dialog->popup_centered(Size2(200, 100) * EDSCALE); } break; case EDIT_EASE_CONFIRM: { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Make Easing Keys")); Tween::TransitionType transition_type = static_cast<Tween::TransitionType>(transition_selection->get_selected_id()); @@ -6036,7 +6049,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { bool is_using_angle = animation->track_get_interpolation_type(track) == Animation::INTERPOLATION_LINEAR_ANGLE || animation->track_get_interpolation_type(track) == Animation::INTERPOLATION_CUBIC_ANGLE; // Make insert queue. - Vector<Pair<real_t, Variant>> insert_queue; + Vector<Pair<real_t, Variant>> insert_queue_new; for (int i = 0; i < len; i++) { // Check neighboring keys. if (keys[i] + 1 == keys[i + 1]) { @@ -6050,23 +6063,22 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { real_t to_diff = fmod(b - a, Math_TAU); to_v = a + fmod(2.0 * to_diff, Math_TAU) - to_diff; } - Variant delta_v; - Variant::sub(to_v, from_v, delta_v); + Variant delta_v = Animation::subtract_variant(to_v, from_v); double duration = to_t - from_t; - double fixed_duration = duration - 0.01; // Prevent to overwrap keys... + double fixed_duration = duration - UNIT_EPSILON; // Prevent to overwrap keys... for (double delta_t = dur_step; delta_t < fixed_duration; delta_t += dur_step) { Pair<real_t, Variant> keydata; keydata.first = from_t + delta_t; keydata.second = Tween::interpolate_variant(from_v, delta_v, delta_t, duration, transition_type, ease_type); - insert_queue.append(keydata); + insert_queue_new.append(keydata); } } } // Do insertion. - for (int i = 0; i < insert_queue.size(); i++) { - undo_redo->add_do_method(animation.ptr(), "track_insert_key", track, insert_queue[i].first, insert_queue[i].second); - undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", track, insert_queue[i].first); + for (int i = 0; i < insert_queue_new.size(); i++) { + undo_redo->add_do_method(animation.ptr(), "track_insert_key", track, insert_queue_new[i].first, insert_queue_new[i].second); + undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", track, insert_queue_new[i].first); } ++E; @@ -6096,6 +6108,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { _anim_duplicate_keys(true); } break; case EDIT_ADD_RESET_KEY: { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Add RESET Keys")); Ref<Animation> reset = _create_and_get_reset_animation(); @@ -6156,6 +6169,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } if (selection.size()) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Anim Delete Keys")); for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { @@ -6186,6 +6200,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { bake_dialog->popup_centered(Size2(200, 100) * EDSCALE); } break; case EDIT_BAKE_ANIMATION_CONFIRM: { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Bake Animation as Linear keys.")); int track_len = animation->get_track_count(); @@ -6206,14 +6221,14 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { if (do_bake && !animation->track_is_compressed(i)) { Animation::InterpolationType it = animation->track_get_interpolation_type(i); if (it == Animation::INTERPOLATION_NEAREST) { - continue; // Nearest and Angle interpolation cannot be baked. + continue; // Nearest interpolation cannot be baked. } // Special case for angle interpolation. bool is_using_angle = it == Animation::INTERPOLATION_LINEAR_ANGLE || it == Animation::INTERPOLATION_CUBIC_ANGLE; // Make insert queue. - Vector<Pair<real_t, Variant>> insert_queue; + Vector<Pair<real_t, Variant>> insert_queue_new; switch (type) { case Animation::TYPE_POSITION_3D: { @@ -6223,7 +6238,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { Vector3 v; animation->position_track_interpolate(i, delta_t, &v); keydata.second = v; - insert_queue.append(keydata); + insert_queue_new.append(keydata); } } break; case Animation::TYPE_ROTATION_3D: { @@ -6233,7 +6248,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { Quaternion v; animation->rotation_track_interpolate(i, delta_t, &v); keydata.second = v; - insert_queue.append(keydata); + insert_queue_new.append(keydata); } } break; case Animation::TYPE_SCALE_3D: { @@ -6243,7 +6258,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { Vector3 v; animation->scale_track_interpolate(i, delta_t, &v); keydata.second = v; - insert_queue.append(keydata); + insert_queue_new.append(keydata); } } break; case Animation::TYPE_BLEND_SHAPE: { @@ -6253,7 +6268,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { float v; animation->blend_shape_track_interpolate(i, delta_t, &v); keydata.second = v; - insert_queue.append(keydata); + insert_queue_new.append(keydata); } } break; case Animation::TYPE_VALUE: { @@ -6261,7 +6276,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { Pair<real_t, Variant> keydata; keydata.first = delta_t; keydata.second = animation->value_track_interpolate(i, delta_t); - insert_queue.append(keydata); + insert_queue_new.append(keydata); } } break; default: { @@ -6276,9 +6291,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { // Insert keys. undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", i, is_using_angle ? Animation::INTERPOLATION_LINEAR_ANGLE : Animation::INTERPOLATION_LINEAR); - for (int j = insert_queue.size() - 1; j >= 0; j--) { - undo_redo->add_do_method(animation.ptr(), "track_insert_key", i, insert_queue[j].first, insert_queue[j].second); - undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", i, insert_queue[j].first); + for (int j = insert_queue_new.size() - 1; j >= 0; j--) { + undo_redo->add_do_method(animation.ptr(), "track_insert_key", i, insert_queue_new[j].first, insert_queue_new[j].second); + undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", i, insert_queue_new[j].first); } // Undo methods. @@ -6306,6 +6321,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { animation->optimize(optimize_velocity_error->get_value(), optimize_angular_error->get_value(), optimize_precision_error->get_value()); _redraw_tracks(); _update_key_edit(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->clear_history(true, undo_redo->get_history_id_for_object(animation.ptr())); undo_redo->clear_history(true, undo_redo->get_history_id_for_object(this)); @@ -6375,6 +6391,7 @@ void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) { } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->clear_history(true, undo_redo->get_history_id_for_object(animation.ptr())); undo_redo->clear_history(true, undo_redo->get_history_id_for_object(this)); _update_tracks(); @@ -6458,16 +6475,12 @@ void AnimationTrackEditor::_select_all_tracks_for_copy() { } void AnimationTrackEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_animation_update"), &AnimationTrackEditor::_animation_update); - ClassDB::bind_method(D_METHOD("_track_grab_focus"), &AnimationTrackEditor::_track_grab_focus); - ClassDB::bind_method(D_METHOD("_update_tracks"), &AnimationTrackEditor::_update_tracks); - ClassDB::bind_method(D_METHOD("_redraw_tracks"), &AnimationTrackEditor::_redraw_tracks); - ClassDB::bind_method(D_METHOD("_clear_selection_for_anim"), &AnimationTrackEditor::_clear_selection_for_anim); - ClassDB::bind_method(D_METHOD("_select_at_anim"), &AnimationTrackEditor::_select_at_anim); - - ClassDB::bind_method(D_METHOD("_key_selected"), &AnimationTrackEditor::_key_selected); // Still used by some connect_compat. - ClassDB::bind_method(D_METHOD("_key_deselected"), &AnimationTrackEditor::_key_deselected); // Still used by some connect_compat. - ClassDB::bind_method(D_METHOD("_clear_selection"), &AnimationTrackEditor::_clear_selection); // Still used by some connect_compat. + ClassDB::bind_method("_animation_update", &AnimationTrackEditor::_animation_update); + ClassDB::bind_method("_track_grab_focus", &AnimationTrackEditor::_track_grab_focus); + ClassDB::bind_method("_redraw_tracks", &AnimationTrackEditor::_redraw_tracks); + ClassDB::bind_method("_clear_selection_for_anim", &AnimationTrackEditor::_clear_selection_for_anim); + ClassDB::bind_method("_select_at_anim", &AnimationTrackEditor::_select_at_anim); + ClassDB::bind_method("_clear_selection", &AnimationTrackEditor::_clear_selection); ClassDB::bind_method(D_METHOD("_bezier_track_set_key_handle_mode", "animation", "track_idx", "key_idx", "key_handle_mode", "key_handle_set_mode"), &AnimationTrackEditor::_bezier_track_set_key_handle_mode, DEFVAL(Animation::HANDLE_SET_MODE_NONE)); @@ -6544,8 +6557,6 @@ void AnimationTrackEditor::_pick_track_filter_input(const Ref<InputEvent> &p_ie) } AnimationTrackEditor::AnimationTrackEditor() { - undo_redo = EditorNode::get_undo_redo(); - main_panel = memnew(PanelContainer); main_panel->set_focus_mode(FOCUS_ALL); // Allow panel to have focus so that shortcuts work as expected. add_child(main_panel); @@ -6570,7 +6581,6 @@ AnimationTrackEditor::AnimationTrackEditor() { main_panel->add_child(info_message); timeline = memnew(AnimationTimelineEdit); - timeline->set_undo_redo(undo_redo); timeline_vbox->add_child(timeline); timeline->connect("timeline_changed", callable_mp(this, &AnimationTrackEditor::_timeline_changed)); timeline->connect("name_limit_changed", callable_mp(this, &AnimationTrackEditor::_name_limit_changed)); @@ -6593,7 +6603,6 @@ AnimationTrackEditor::AnimationTrackEditor() { bezier_edit = memnew(AnimationBezierTrackEdit); timeline_vbox->add_child(bezier_edit); - bezier_edit->set_undo_redo(undo_redo); bezier_edit->set_editor(this); bezier_edit->set_timeline(timeline); bezier_edit->hide(); @@ -6930,19 +6939,19 @@ AnimationTrackEditor::AnimationTrackEditor() { track_copy_dialog->set_title(TTR("Select Tracks to Copy")); track_copy_dialog->set_ok_button_text(TTR("Copy")); - VBoxContainer *track_vbox = memnew(VBoxContainer); - track_copy_dialog->add_child(track_vbox); + VBoxContainer *track_copy_vbox = memnew(VBoxContainer); + track_copy_dialog->add_child(track_copy_vbox); Button *select_all_button = memnew(Button); select_all_button->set_text(TTR("Select All/None")); select_all_button->connect("pressed", callable_mp(this, &AnimationTrackEditor::_select_all_tracks_for_copy)); - track_vbox->add_child(select_all_button); + track_copy_vbox->add_child(select_all_button); track_copy_select = memnew(Tree); track_copy_select->set_h_size_flags(SIZE_EXPAND_FILL); track_copy_select->set_v_size_flags(SIZE_EXPAND_FILL); track_copy_select->set_hide_root(true); - track_vbox->add_child(track_copy_select); + track_copy_vbox->add_child(track_copy_select); track_copy_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_COPY_TRACKS_CONFIRM)); } diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index ac69b88e99..dc0c4abe5f 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -79,7 +79,6 @@ class AnimationTimelineEdit : public Range { void _anim_loop_pressed(); void _play_position_draw(); - Ref<EditorUndoRedoManager> undo_redo; Rect2 hsize_rect; bool editing = false; @@ -113,7 +112,6 @@ public: void set_track_edit(AnimationTrackEdit *p_track_edit); void set_zoom(Range *p_zoom); Range *get_zoom() const { return zoom; } - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); void set_play_position(float p_pos); float get_play_position() const; @@ -135,6 +133,7 @@ class AnimationTrackEditor; class AnimationTrackEdit : public Control { GDCLASS(AnimationTrackEdit, Control); + friend class AnimationTimelineEdit; enum { MENU_CALL_MODE_CONTINUOUS, @@ -155,7 +154,6 @@ class AnimationTrackEdit : public Control { }; AnimationTimelineEdit *timeline = nullptr; - Ref<EditorUndoRedoManager> undo_redo; Popup *path_popup = nullptr; LineEdit *path = nullptr; Node *root = nullptr; @@ -236,12 +234,10 @@ public: Ref<Animation> get_animation() const; AnimationTimelineEdit *get_timeline() const { return timeline; } AnimationTrackEditor *get_editor() const { return editor; } - Ref<EditorUndoRedoManager> get_undo_redo() const; NodePath get_path() const; void set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only); virtual Size2 get_minimum_size() const override; - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); void set_timeline(AnimationTimelineEdit *p_timeline); void set_editor(AnimationTrackEditor *p_editor); void set_root(Node *p_root); @@ -280,7 +276,6 @@ class AnimationTrackEditGroup : public Control { void _zoom_changed(); protected: - static void _bind_methods(); void _notification(int p_what); public: @@ -294,6 +289,7 @@ public: class AnimationTrackEditor : public VBoxContainer { GDCLASS(AnimationTrackEditor, VBoxContainer); + friend class AnimationTimelineEdit; Ref<Animation> animation; bool read_only = false; @@ -327,7 +323,6 @@ class AnimationTrackEditor : public VBoxContainer { bool animation_changing_awaiting_update = false; void _animation_update(); // Updated by AnimationTrackEditor(this) int _get_track_selected(); - void _sync_animation_change(); void _animation_changed(); void _update_tracks(); void _redraw_tracks(); @@ -339,8 +334,6 @@ class AnimationTrackEditor : public VBoxContainer { void _animation_track_remove_request(int p_track, Ref<Animation> p_from_animation); void _track_grab_focus(int p_track); - Ref<EditorUndoRedoManager> undo_redo; - void _update_scroll(double); void _update_step(double p_new_step); void _update_length(double p_new_len); @@ -407,7 +400,6 @@ class AnimationTrackEditor : public VBoxContainer { void _insert_key_from_track(float p_ofs, int p_track); void _add_method_key(const String &p_method); - void _clear_selection(bool p_update = false); void _clear_selection_for_anim(const Ref<Animation> &p_anim); void _select_at_anim(const Ref<Animation> &p_anim, int p_track, float p_pos); @@ -425,9 +417,6 @@ class AnimationTrackEditor : public VBoxContainer { RBMap<SelectedKey, KeyInfo> selection; - void _key_selected(int p_key, bool p_single, int p_track); - void _key_deselected(int p_key, int p_track); - bool moving_selection = false; float moving_selection_offset = 0.0f; void _move_selection_begin(); @@ -438,7 +427,6 @@ class AnimationTrackEditor : public VBoxContainer { AnimationTrackKeyEdit *key_edit = nullptr; AnimationMultiTrackKeyEdit *multi_key_edit = nullptr; void _update_key_edit(); - void _clear_key_edit(); Control *box_selection = nullptr; @@ -531,6 +519,11 @@ protected: void _notification(int p_what); public: + // Public for use with callable_mp. + void _clear_selection(bool p_update = false); + void _key_selected(int p_key, bool p_single, int p_track); + void _key_deselected(int p_key, int p_track); + enum { EDIT_COPY_TRACKS, EDIT_COPY_TRACKS_CONFIRM, diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index 6499cf8df2..a5f6f449a6 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -31,6 +31,7 @@ #include "animation_track_editor_plugins.h" #include "editor/audio_stream_preview.h" +#include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_undo_redo_manager.h" @@ -412,9 +413,9 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se sf->get_animation_list(&animations); int frame = get_animation()->track_get_key_value(get_track(), p_index); - String animation; + String animation_name; if (animations.size() == 1) { - animation = animations.front()->get(); + animation_name = animations.front()->get(); } else { // Go through other track to find if animation is set String animation_path = get_animation()->track_get_path(get_track()); @@ -422,10 +423,10 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se int animation_track = get_animation()->find_track(animation_path, get_animation()->track_get_type(get_track())); float track_time = get_animation()->track_get_key_time(get_track(), p_index); int animaiton_index = get_animation()->track_find_key(animation_track, track_time); - animation = get_animation()->track_get_key_value(animation_track, animaiton_index); + animation_name = get_animation()->track_get_key_value(animation_track, animaiton_index); } - Ref<Texture2D> texture = sf->get_frame(animation, frame); + Ref<Texture2D> texture = sf->get_frame(animation_name, frame); if (!texture.is_valid()) { return AnimationTrackEdit::get_key_rect(p_index, p_pixels_sec); } @@ -504,9 +505,9 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in sf->get_animation_list(&animations); int frame = get_animation()->track_get_key_value(get_track(), p_index); - String animation; + String animation_name; if (animations.size() == 1) { - animation = animations.front()->get(); + animation_name = animations.front()->get(); } else { // Go through other track to find if animation is set String animation_path = get_animation()->track_get_path(get_track()); @@ -514,10 +515,10 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in int animation_track = get_animation()->find_track(animation_path, get_animation()->track_get_type(get_track())); float track_time = get_animation()->track_get_key_time(get_track(), p_index); int animaiton_index = get_animation()->track_find_key(animation_track, track_time); - animation = get_animation()->track_get_key_value(animation_track, animaiton_index); + animation_name = get_animation()->track_get_key_value(animation_track, animaiton_index); } - texture = sf->get_frame(animation, frame); + texture = sf->get_frame(animation_name, frame); if (!texture.is_valid()) { AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right); return; @@ -670,15 +671,15 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_ Vector<Vector2> lines; Vector<Color> colorv; { - Ref<Animation> animation = ap->get_animation(anim); + Ref<Animation> ap_anim = ap->get_animation(anim); - for (int i = 0; i < animation->get_track_count(); i++) { - float h = (rect.size.height - 2) / animation->get_track_count(); + for (int i = 0; i < ap_anim->get_track_count(); i++) { + float h = (rect.size.height - 2) / ap_anim->get_track_count(); int y = 2 + h * i + h / 2; - for (int j = 0; j < animation->track_get_key_count(i); j++) { - float ofs = animation->track_get_key_time(i, j); + for (int j = 0; j < ap_anim->track_get_key_count(i); j++) { + float ofs = ap_anim->track_get_key_time(i, j); int x = p_x + ofs * p_pixels_sec + 2; if (x < from_x || x >= (to_x - 4)) { @@ -1021,10 +1022,11 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant ofs += 0.001; } - get_undo_redo()->create_action(TTR("Add Audio Track Clip")); - get_undo_redo()->add_do_method(get_animation().ptr(), "audio_track_insert_key", get_track(), ofs, stream); - get_undo_redo()->add_undo_method(get_animation().ptr(), "track_remove_key_at_time", get_track(), ofs); - get_undo_redo()->commit_action(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Add Audio Track Clip")); + undo_redo->add_do_method(get_animation().ptr(), "audio_track_insert_key", get_track(), ofs, stream); + undo_redo->add_undo_method(get_animation().ptr(), "track_remove_key_at_time", get_track(), ofs); + undo_redo->commit_action(); queue_redraw(); return; @@ -1102,21 +1104,22 @@ void AnimationTrackEditTypeAudio::gui_input(const Ref<InputEvent> &p_event) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (len_resizing && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { float ofs_local = -len_resizing_rel / get_timeline()->get_zoom_scale(); if (len_resizing_start) { float prev_ofs = get_animation()->audio_track_get_key_start_offset(get_track(), len_resizing_index); - get_undo_redo()->create_action(TTR("Change Audio Track Clip Start Offset")); - get_undo_redo()->add_do_method(get_animation().ptr(), "audio_track_set_key_start_offset", get_track(), len_resizing_index, prev_ofs + ofs_local); - get_undo_redo()->add_undo_method(get_animation().ptr(), "audio_track_set_key_start_offset", get_track(), len_resizing_index, prev_ofs); - get_undo_redo()->commit_action(); + undo_redo->create_action(TTR("Change Audio Track Clip Start Offset")); + undo_redo->add_do_method(get_animation().ptr(), "audio_track_set_key_start_offset", get_track(), len_resizing_index, prev_ofs + ofs_local); + undo_redo->add_undo_method(get_animation().ptr(), "audio_track_set_key_start_offset", get_track(), len_resizing_index, prev_ofs); + undo_redo->commit_action(); } else { float prev_ofs = get_animation()->audio_track_get_key_end_offset(get_track(), len_resizing_index); - get_undo_redo()->create_action(TTR("Change Audio Track Clip End Offset")); - get_undo_redo()->add_do_method(get_animation().ptr(), "audio_track_set_key_end_offset", get_track(), len_resizing_index, prev_ofs + ofs_local); - get_undo_redo()->add_undo_method(get_animation().ptr(), "audio_track_set_key_end_offset", get_track(), len_resizing_index, prev_ofs); - get_undo_redo()->commit_action(); + undo_redo->create_action(TTR("Change Audio Track Clip End Offset")); + undo_redo->add_do_method(get_animation().ptr(), "audio_track_set_key_end_offset", get_track(), len_resizing_index, prev_ofs + ofs_local); + undo_redo->add_undo_method(get_animation().ptr(), "audio_track_set_key_end_offset", get_track(), len_resizing_index, prev_ofs); + undo_redo->commit_action(); } len_resizing_index = -1; @@ -1244,15 +1247,15 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec, Vector<Vector2> lines; Vector<Color> colorv; { - Ref<Animation> animation = ap->get_animation(anim); + Ref<Animation> ap_anim = ap->get_animation(anim); - for (int i = 0; i < animation->get_track_count(); i++) { - float h = (rect.size.height - 2) / animation->get_track_count(); + for (int i = 0; i < ap_anim->get_track_count(); i++) { + float h = (rect.size.height - 2) / ap_anim->get_track_count(); int y = 2 + h * i + h / 2; - for (int j = 0; j < animation->track_get_key_count(i); j++) { - float ofs = animation->track_get_key_time(i, j); + for (int j = 0; j < ap_anim->track_get_key_count(i); j++) { + float ofs = ap_anim->track_get_key_time(i, j); int x = p_x + ofs * p_pixels_sec + 2; if (x < from_x || x >= (to_x - 4)) { diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp index b9e52ad7ad..b84e58125e 100644 --- a/editor/audio_stream_preview.cpp +++ b/editor/audio_stream_preview.cpp @@ -42,6 +42,10 @@ float AudioStreamPreview::get_max(float p_time, float p_time_next) const { } int max = preview.size() / 2; + if (max == 0) { + return 0; + } + int time_from = p_time / length * max; int time_to = p_time_next / length * max; time_from = CLAMP(time_from, 0, max - 1); @@ -69,6 +73,10 @@ float AudioStreamPreview::get_min(float p_time, float p_time_next) const { } int max = preview.size() / 2; + if (max == 0) { + return 0; + } + int time_from = p_time / length * max; int time_to = p_time_next / length * max; time_from = CLAMP(time_from, 0, max - 1); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 11a6912aa5..65cb083ac7 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -55,6 +55,7 @@ void GotoLineDialog::ok_pressed() { if (get_line() < 1 || get_line() > text_editor->get_line_count()) { return; } + text_editor->remove_secondary_carets(); text_editor->unfold_line(get_line() - 1); text_editor->set_caret_line(get_line() - 1); hide(); @@ -90,10 +91,10 @@ void FindReplaceBar::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { find_prev->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); find_next->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); - hide_button->set_normal_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - hide_button->set_hover_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - hide_button->set_pressed_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size()); + hide_button->set_texture_normal(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); + hide_button->set_texture_hover(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); + hide_button->set_texture_pressed(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); + hide_button->set_custom_minimum_size(hide_button->get_texture_normal()->get_size()); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -149,7 +150,7 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) text_editor->unfold_line(pos.y); text_editor->set_caret_line(pos.y, false); text_editor->set_caret_column(pos.x + text.length(), false); - text_editor->center_viewport_to_caret(); + text_editor->center_viewport_to_caret(0); text_editor->select(pos.y, pos.x, pos.y, pos.x + text.length()); line_col_changed_for_result = true; @@ -176,37 +177,37 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) } void FindReplaceBar::_replace() { - bool selection_enabled = text_editor->has_selection(); + bool selection_enabled = text_editor->has_selection(0); Point2i selection_begin, selection_end; if (selection_enabled) { - selection_begin = Point2i(text_editor->get_selection_from_line(), text_editor->get_selection_from_column()); - selection_end = Point2i(text_editor->get_selection_to_line(), text_editor->get_selection_to_column()); + selection_begin = Point2i(text_editor->get_selection_from_line(0), text_editor->get_selection_from_column(0)); + selection_end = Point2i(text_editor->get_selection_to_line(0), text_editor->get_selection_to_column(0)); } - String replace_text = get_replace_text(); + String repl_text = get_replace_text(); int search_text_len = get_search_text().length(); text_editor->begin_complex_operation(); if (selection_enabled && is_selection_only()) { // To restrict search_current() to selected region - text_editor->set_caret_line(selection_begin.width); - text_editor->set_caret_column(selection_begin.height); + text_editor->set_caret_line(selection_begin.width, false, true, 0, 0); + text_editor->set_caret_column(selection_begin.height, true, 0); } if (search_current()) { text_editor->unfold_line(result_line); - text_editor->select(result_line, result_col, result_line, result_col + search_text_len); + text_editor->select(result_line, result_col, result_line, result_col + search_text_len, 0); if (selection_enabled && is_selection_only()) { Point2i match_from(result_line, result_col); Point2i match_to(result_line, result_col + search_text_len); if (!(match_from < selection_begin || match_to > selection_end)) { - text_editor->insert_text_at_caret(replace_text); + text_editor->insert_text_at_caret(repl_text, 0); if (match_to.x == selection_end.x) { // Adjust selection bounds if necessary - selection_end.y += replace_text.length() - search_text_len; + selection_end.y += repl_text.length() - search_text_len; } } } else { - text_editor->insert_text_at_caret(replace_text); + text_editor->insert_text_at_caret(repl_text, 0); } } text_editor->end_complex_operation(); @@ -216,31 +217,36 @@ void FindReplaceBar::_replace() { if (selection_enabled && is_selection_only()) { // Reselect in order to keep 'Replace' restricted to selection - text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y); + text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y, 0); } else { - text_editor->deselect(); + text_editor->deselect(0); } } void FindReplaceBar::_replace_all() { text_editor->disconnect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed)); // Line as x so it gets priority in comparison, column as y. - Point2i orig_cursor(text_editor->get_caret_line(), text_editor->get_caret_column()); + Point2i orig_cursor(text_editor->get_caret_line(0), text_editor->get_caret_column(0)); Point2i prev_match = Point2(-1, -1); - bool selection_enabled = text_editor->has_selection(); + bool selection_enabled = text_editor->has_selection(0); + if (!is_selection_only()) { + text_editor->deselect(); + selection_enabled = false; + } else { + result_line = -1; + result_col = -1; + } + Point2i selection_begin, selection_end; if (selection_enabled) { - selection_begin = Point2i(text_editor->get_selection_from_line(), text_editor->get_selection_from_column()); - selection_end = Point2i(text_editor->get_selection_to_line(), text_editor->get_selection_to_column()); + selection_begin = Point2i(text_editor->get_selection_from_line(0), text_editor->get_selection_from_column(0)); + selection_end = Point2i(text_editor->get_selection_to_line(0), text_editor->get_selection_to_column(0)); } int vsval = text_editor->get_v_scroll(); - text_editor->set_caret_line(0); - text_editor->set_caret_column(0); - - String replace_text = get_replace_text(); + String repl_text = get_replace_text(); int search_text_len = get_search_text().length(); int rc = 0; @@ -250,9 +256,13 @@ void FindReplaceBar::_replace_all() { text_editor->begin_complex_operation(); if (selection_enabled && is_selection_only()) { - text_editor->set_caret_line(selection_begin.width); - text_editor->set_caret_column(selection_begin.height); + text_editor->set_caret_line(selection_begin.width, false, true, 0, 0); + text_editor->set_caret_column(selection_begin.height, true, 0); + } else { + text_editor->set_caret_line(0, false, true, 0, 0); + text_editor->set_caret_column(0, true, 0); } + if (search_current()) { do { // replace area @@ -263,25 +273,25 @@ void FindReplaceBar::_replace_all() { break; // Done. } - prev_match = Point2i(result_line, result_col + replace_text.length()); + prev_match = Point2i(result_line, result_col + repl_text.length()); text_editor->unfold_line(result_line); - text_editor->select(result_line, result_col, result_line, match_to.y); + text_editor->select(result_line, result_col, result_line, match_to.y, 0); - if (selection_enabled && is_selection_only()) { + if (selection_enabled) { if (match_from < selection_begin || match_to > selection_end) { break; // Done. } // Replace but adjust selection bounds. - text_editor->insert_text_at_caret(replace_text); + text_editor->insert_text_at_caret(repl_text, 0); if (match_to.x == selection_end.x) { - selection_end.y += replace_text.length() - search_text_len; + selection_end.y += repl_text.length() - search_text_len; } } else { // Just replace. - text_editor->insert_text_at_caret(replace_text); + text_editor->insert_text_at_caret(repl_text, 0); } rc++; @@ -293,14 +303,12 @@ void FindReplaceBar::_replace_all() { replace_all_mode = false; // Restore editor state (selection, cursor, scroll). - text_editor->set_caret_line(orig_cursor.x); - text_editor->set_caret_column(orig_cursor.y); + text_editor->set_caret_line(orig_cursor.x, false, true, 0, 0); + text_editor->set_caret_column(orig_cursor.y, true, 0); - if (selection_enabled && is_selection_only()) { + if (selection_enabled) { // Reselect. - text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y); - } else { - text_editor->deselect(); + text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y, 0); } text_editor->set_v_scroll(vsval); @@ -313,21 +321,28 @@ void FindReplaceBar::_replace_all() { needs_to_count_results = true; } -void FindReplaceBar::_get_search_from(int &r_line, int &r_col) { - r_line = text_editor->get_caret_line(); - r_col = text_editor->get_caret_column(); +void FindReplaceBar::_get_search_from(int &r_line, int &r_col, bool p_is_searching_next) { + if (!text_editor->has_selection(0) || is_selection_only()) { + r_line = text_editor->get_caret_line(0); + r_col = text_editor->get_caret_column(0); - if (text_editor->has_selection() && is_selection_only()) { + if (!p_is_searching_next && r_line == result_line && r_col >= result_col && r_col <= result_col + get_search_text().length()) { + r_col = result_col; + } return; } - if (r_line == result_line && r_col >= result_col && r_col <= result_col + get_search_text().length()) { - r_col = result_col; + if (p_is_searching_next) { + r_line = text_editor->get_selection_to_line(); + r_col = text_editor->get_selection_to_column(); + } else { + r_line = text_editor->get_selection_from_line(); + r_col = text_editor->get_selection_from_column(); } } void FindReplaceBar::_update_results_count() { - if (!needs_to_count_results && (result_line != -1)) { + if (!needs_to_count_results && (result_line != -1) && results_count_to_current > 0) { results_count_to_current += (flags & TextEdit::SEARCH_BACKWARDS) ? -1 : 1; if (results_count_to_current > results_count) { @@ -339,9 +354,6 @@ void FindReplaceBar::_update_results_count() { return; } - results_count = 0; - results_count_to_current = 0; - String searched = get_search_text(); if (searched.is_empty()) { return; @@ -349,6 +361,8 @@ void FindReplaceBar::_update_results_count() { needs_to_count_results = false; + results_count = 0; + for (int i = 0; i < text_editor->get_line_count(); i++) { String line_text = text_editor->get_line(i); @@ -363,17 +377,24 @@ void FindReplaceBar::_update_results_count() { if (is_whole_words()) { if (col_pos > 0 && !is_symbol(line_text[col_pos - 1])) { - break; + col_pos += searched.length(); + continue; } - if (col_pos + line_text.length() < line_text.length() && !is_symbol(line_text[col_pos + searched.length()])) { - break; + if (col_pos + searched.length() < line_text.length() && !is_symbol(line_text[col_pos + searched.length()])) { + col_pos += searched.length(); + continue; } } results_count++; - if (i == result_line && col_pos == result_col) { - results_count_to_current = results_count; + if (i == result_line) { + if (col_pos == result_col) { + results_count_to_current = results_count; + } else if (col_pos < result_col && col_pos + searched.length() > result_col) { + col_pos = result_col; + results_count_to_current = results_count; + } } col_pos += searched.length(); @@ -391,10 +412,10 @@ void FindReplaceBar::_update_matches_label() { if (results_count == 0) { matches_label->set_text("No match"); - } else if (results_count == 1) { - matches_label->set_text(vformat(TTR("%d match"), results_count)); + } else if (results_count_to_current == -1) { + matches_label->set_text(vformat(TTRN("%d match", "%d matches", results_count), results_count)); } else { - matches_label->set_text(vformat(TTR("%d of %d matches"), results_count_to_current, results_count)); + matches_label->set_text(vformat(TTRN("%d of %d match", "%d of %d matches", results_count), results_count_to_current, results_count)); } } } @@ -416,6 +437,10 @@ bool FindReplaceBar::search_current() { } bool FindReplaceBar::search_prev() { + if (is_selection_only() && !replace_all_mode) { + return false; + } + if (!is_visible()) { popup_search(true); } @@ -434,9 +459,6 @@ bool FindReplaceBar::search_prev() { int line, col; _get_search_from(line, col); - if (text_editor->has_selection()) { - col--; // Skip currently selected word. - } col -= text.length(); if (col < 0) { @@ -451,17 +473,15 @@ bool FindReplaceBar::search_prev() { } bool FindReplaceBar::search_next() { + if (is_selection_only() && !replace_all_mode) { + return false; + } + if (!is_visible()) { popup_search(true); } flags = 0; - String text; - if (replace_all_mode) { - text = get_replace_text(); - } else { - text = get_search_text(); - } if (is_whole_words()) { flags |= TextEdit::SEARCH_WHOLE_WORDS; @@ -471,18 +491,7 @@ bool FindReplaceBar::search_next() { } int line, col; - _get_search_from(line, col); - - if (line == result_line && col == result_col) { - col += text.length(); - if (col > text_editor->get_line(line).length()) { - line += 1; - if (line >= text_editor->get_line_count()) { - line = 0; - } - col = 0; - } - } + _get_search_from(line, col, true); return _search(flags, line, col); } @@ -512,8 +521,10 @@ void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) { search_text->call_deferred(SNAME("grab_focus")); } - if (text_editor->has_selection() && !selection_only->is_pressed()) { - search_text->set_text(text_editor->get_selected_text()); + if (text_editor->has_selection(0) && !is_selection_only()) { + search_text->set_text(text_editor->get_selected_text(0)); + result_line = text_editor->get_selection_from_line(); + result_col = text_editor->get_selection_from_column(); } if (!get_search_text().is_empty()) { @@ -537,6 +548,7 @@ void FindReplaceBar::popup_search(bool p_show_only) { replace_text->hide(); hbc_button_replace->hide(); hbc_option_replace->hide(); + selection_only->set_pressed(false); _show_search(false, p_show_only); } @@ -548,9 +560,9 @@ void FindReplaceBar::popup_replace() { hbc_option_replace->show(); } - selection_only->set_pressed((text_editor->has_selection() && text_editor->get_selection_from_line() < text_editor->get_selection_to_line())); + selection_only->set_pressed((text_editor->has_selection(0) && text_editor->get_selection_from_line(0) < text_editor->get_selection_to_line(0))); - _show_search(is_visible() || text_editor->has_selection()); + _show_search(is_visible() || text_editor->has_selection(0)); } void FindReplaceBar::_search_options_changed(bool p_pressed) { @@ -587,7 +599,7 @@ void FindReplaceBar::_search_text_submitted(const String &p_text) { } void FindReplaceBar::_replace_text_submitted(const String &p_text) { - if (selection_only->is_pressed() && text_editor->has_selection()) { + if (selection_only->is_pressed() && text_editor->has_selection(0)) { _replace_all(); _hide_bar(); } else if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) { @@ -999,50 +1011,50 @@ void CodeTextEditor::update_editor_settings() { completion_comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color"); // Appearance: Caret - text_editor->set_caret_type((TextEdit::CaretType)EditorSettings::get_singleton()->get("text_editor/appearance/caret/type").operator int()); - text_editor->set_caret_blink_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/caret/caret_blink")); - text_editor->set_caret_blink_interval(EditorSettings::get_singleton()->get("text_editor/appearance/caret/caret_blink_interval")); - text_editor->set_highlight_current_line(EditorSettings::get_singleton()->get("text_editor/appearance/caret/highlight_current_line")); - text_editor->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/appearance/caret/highlight_all_occurrences")); + text_editor->set_caret_type((TextEdit::CaretType)EDITOR_GET("text_editor/appearance/caret/type").operator int()); + text_editor->set_caret_blink_enabled(EDITOR_GET("text_editor/appearance/caret/caret_blink")); + text_editor->set_caret_blink_interval(EDITOR_GET("text_editor/appearance/caret/caret_blink_interval")); + text_editor->set_highlight_current_line(EDITOR_GET("text_editor/appearance/caret/highlight_current_line")); + text_editor->set_highlight_all_occurrences(EDITOR_GET("text_editor/appearance/caret/highlight_all_occurrences")); // Appearance: Gutters - text_editor->set_draw_line_numbers(EditorSettings::get_singleton()->get("text_editor/appearance/gutters/show_line_numbers")); - text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/appearance/gutters/line_numbers_zero_padded")); - text_editor->set_draw_bookmarks_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/gutters/show_bookmark_gutter")); + text_editor->set_draw_line_numbers(EDITOR_GET("text_editor/appearance/gutters/show_line_numbers")); + text_editor->set_line_numbers_zero_padded(EDITOR_GET("text_editor/appearance/gutters/line_numbers_zero_padded")); + text_editor->set_draw_bookmarks_gutter(EDITOR_GET("text_editor/appearance/gutters/show_bookmark_gutter")); // Appearance: Minimap - text_editor->set_draw_minimap(EditorSettings::get_singleton()->get("text_editor/appearance/minimap/show_minimap")); - text_editor->set_minimap_width((int)EditorSettings::get_singleton()->get("text_editor/appearance/minimap/minimap_width") * EDSCALE); + text_editor->set_draw_minimap(EDITOR_GET("text_editor/appearance/minimap/show_minimap")); + text_editor->set_minimap_width((int)EDITOR_GET("text_editor/appearance/minimap/minimap_width") * EDSCALE); // Appearance: Lines - text_editor->set_line_folding_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/lines/code_folding")); - text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/lines/code_folding")); - text_editor->set_line_wrapping_mode((TextEdit::LineWrappingMode)EditorSettings::get_singleton()->get("text_editor/appearance/lines/word_wrap").operator int()); + text_editor->set_line_folding_enabled(EDITOR_GET("text_editor/appearance/lines/code_folding")); + text_editor->set_draw_fold_gutter(EDITOR_GET("text_editor/appearance/lines/code_folding")); + text_editor->set_line_wrapping_mode((TextEdit::LineWrappingMode)EDITOR_GET("text_editor/appearance/lines/word_wrap").operator int()); // Appearance: Whitespace - text_editor->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/appearance/whitespace/draw_tabs")); - text_editor->set_draw_spaces(EditorSettings::get_singleton()->get("text_editor/appearance/whitespace/draw_spaces")); + text_editor->set_draw_tabs(EDITOR_GET("text_editor/appearance/whitespace/draw_tabs")); + text_editor->set_draw_spaces(EDITOR_GET("text_editor/appearance/whitespace/draw_spaces")); // Behavior: Navigation - text_editor->set_scroll_past_end_of_file_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/scroll_past_end_of_file")); - text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/smooth_scrolling")); - text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/v_scroll_speed")); - text_editor->set_drag_and_drop_selection_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/drag_and_drop_selection")); + text_editor->set_scroll_past_end_of_file_enabled(EDITOR_GET("text_editor/behavior/navigation/scroll_past_end_of_file")); + text_editor->set_smooth_scroll_enabled(EDITOR_GET("text_editor/behavior/navigation/smooth_scrolling")); + text_editor->set_v_scroll_speed(EDITOR_GET("text_editor/behavior/navigation/v_scroll_speed")); + text_editor->set_drag_and_drop_selection_enabled(EDITOR_GET("text_editor/behavior/navigation/drag_and_drop_selection")); // Behavior: indent - text_editor->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/behavior/indent/type")); - text_editor->set_indent_size(EditorSettings::get_singleton()->get("text_editor/behavior/indent/size")); - text_editor->set_auto_indent_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/indent/auto_indent")); + text_editor->set_indent_using_spaces(EDITOR_GET("text_editor/behavior/indent/type")); + text_editor->set_indent_size(EDITOR_GET("text_editor/behavior/indent/size")); + text_editor->set_auto_indent_enabled(EDITOR_GET("text_editor/behavior/indent/auto_indent")); // Completion - text_editor->set_auto_brace_completion_enabled(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete")); + text_editor->set_auto_brace_completion_enabled(EDITOR_GET("text_editor/completion/auto_brace_complete")); // Appearance: Guidelines - if (EditorSettings::get_singleton()->get("text_editor/appearance/guidelines/show_line_length_guidelines")) { + if (EDITOR_GET("text_editor/appearance/guidelines/show_line_length_guidelines")) { TypedArray<int> guideline_cols; - guideline_cols.append(EditorSettings::get_singleton()->get("text_editor/appearance/guidelines/line_length_guideline_hard_column")); - if (EditorSettings::get_singleton()->get("text_editor/appearance/guidelines/line_length_guideline_soft_column") != guideline_cols[0]) { - guideline_cols.append(EditorSettings::get_singleton()->get("text_editor/appearance/guidelines/line_length_guideline_soft_column")); + guideline_cols.append(EDITOR_GET("text_editor/appearance/guidelines/line_length_guideline_hard_column")); + if (EDITOR_GET("text_editor/appearance/guidelines/line_length_guideline_soft_column") != guideline_cols[0]) { + guideline_cols.append(EDITOR_GET("text_editor/appearance/guidelines/line_length_guideline_soft_column")); } text_editor->set_line_length_guidelines(guideline_cols); } else { @@ -1091,6 +1103,7 @@ void CodeTextEditor::trim_trailing_whitespace() { } if (trimed_whitespace) { + text_editor->merge_overlapping_carets(); text_editor->end_complex_operation(); text_editor->queue_redraw(); } @@ -1115,15 +1128,18 @@ void CodeTextEditor::insert_final_newline() { } void CodeTextEditor::convert_indent_to_spaces() { - int indent_size = EditorSettings::get_singleton()->get("text_editor/behavior/indent/size"); + int indent_size = EDITOR_GET("text_editor/behavior/indent/size"); String indent = ""; for (int i = 0; i < indent_size; i++) { indent += " "; } - int cursor_line = text_editor->get_caret_line(); - int cursor_column = text_editor->get_caret_column(); + Vector<int> cursor_columns; + cursor_columns.resize(text_editor->get_caret_count()); + for (int c = 0; c < text_editor->get_caret_count(); c++) { + cursor_columns.write[c] = text_editor->get_caret_column(c); + } bool changed_indentation = false; for (int i = 0; i < text_editor->get_line_count(); i++) { @@ -1140,8 +1156,10 @@ void CodeTextEditor::convert_indent_to_spaces() { text_editor->begin_complex_operation(); changed_indentation = true; } - if (cursor_line == i && cursor_column > j) { - cursor_column += indent_size - 1; + for (int c = 0; c < text_editor->get_caret_count(); c++) { + if (text_editor->get_caret_line(c) == i && text_editor->get_caret_column(c) > j) { + cursor_columns.write[c] += indent_size - 1; + } } line = line.left(j) + indent + line.substr(j + 1); } @@ -1152,18 +1170,24 @@ void CodeTextEditor::convert_indent_to_spaces() { } } if (changed_indentation) { - text_editor->set_caret_column(cursor_column); + for (int c = 0; c < text_editor->get_caret_count(); c++) { + text_editor->set_caret_column(cursor_columns[c], c == 0, c); + } + text_editor->merge_overlapping_carets(); text_editor->end_complex_operation(); text_editor->queue_redraw(); } } void CodeTextEditor::convert_indent_to_tabs() { - int indent_size = EditorSettings::get_singleton()->get("text_editor/behavior/indent/size"); + int indent_size = EDITOR_GET("text_editor/behavior/indent/size"); indent_size -= 1; - int cursor_line = text_editor->get_caret_line(); - int cursor_column = text_editor->get_caret_column(); + Vector<int> cursor_columns; + cursor_columns.resize(text_editor->get_caret_count()); + for (int c = 0; c < text_editor->get_caret_count(); c++) { + cursor_columns.write[c] = text_editor->get_caret_column(c); + } bool changed_indentation = false; for (int i = 0; i < text_editor->get_line_count(); i++) { @@ -1184,8 +1208,10 @@ void CodeTextEditor::convert_indent_to_tabs() { text_editor->begin_complex_operation(); changed_indentation = true; } - if (cursor_line == i && cursor_column > j) { - cursor_column -= indent_size; + for (int c = 0; c < text_editor->get_caret_count(); c++) { + if (text_editor->get_caret_line(c) == i && text_editor->get_caret_column(c) > j) { + cursor_columns.write[c] -= indent_size; + } } line = line.left(j - indent_size) + "\t" + line.substr(j + 1); j = 0; @@ -1201,7 +1227,10 @@ void CodeTextEditor::convert_indent_to_tabs() { } } if (changed_indentation) { - text_editor->set_caret_column(cursor_column); + for (int c = 0; c < text_editor->get_caret_count(); c++) { + text_editor->set_caret_column(cursor_columns[c], c == 0, c); + } + text_editor->merge_overlapping_carets(); text_editor->end_complex_operation(); text_editor->queue_redraw(); } @@ -1211,59 +1240,128 @@ void CodeTextEditor::convert_case(CaseStyle p_case) { if (!text_editor->has_selection()) { return; } - text_editor->begin_complex_operation(); - int begin = text_editor->get_selection_from_line(); - int end = text_editor->get_selection_to_line(); - int begin_col = text_editor->get_selection_from_column(); - int end_col = text_editor->get_selection_to_column(); - - for (int i = begin; i <= end; i++) { - int len = text_editor->get_line(i).length(); - if (i == end) { - len = end_col; - } - if (i == begin) { - len -= begin_col; + Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order(); + for (const int &c : caret_edit_order) { + if (!text_editor->has_selection(c)) { + continue; } - String new_line = text_editor->get_line(i).substr(i == begin ? begin_col : 0, len); - switch (p_case) { - case UPPER: { - new_line = new_line.to_upper(); - } break; - case LOWER: { - new_line = new_line.to_lower(); - } break; - case CAPITALIZE: { - new_line = new_line.capitalize(); - } break; - } + int begin = text_editor->get_selection_from_line(c); + int end = text_editor->get_selection_to_line(c); + int begin_col = text_editor->get_selection_from_column(c); + int end_col = text_editor->get_selection_to_column(c); - if (i == begin) { - new_line = text_editor->get_line(i).left(begin_col) + new_line; - } - if (i == end) { - new_line = new_line + text_editor->get_line(i).substr(end_col); + for (int i = begin; i <= end; i++) { + int len = text_editor->get_line(i).length(); + if (i == end) { + len = end_col; + } + if (i == begin) { + len -= begin_col; + } + String new_line = text_editor->get_line(i).substr(i == begin ? begin_col : 0, len); + + switch (p_case) { + case UPPER: { + new_line = new_line.to_upper(); + } break; + case LOWER: { + new_line = new_line.to_lower(); + } break; + case CAPITALIZE: { + new_line = new_line.capitalize(); + } break; + } + + if (i == begin) { + new_line = text_editor->get_line(i).left(begin_col) + new_line; + } + if (i == end) { + new_line = new_line + text_editor->get_line(i).substr(end_col); + } + text_editor->set_line(i, new_line); } - text_editor->set_line(i, new_line); } text_editor->end_complex_operation(); } void CodeTextEditor::move_lines_up() { text_editor->begin_complex_operation(); - if (text_editor->has_selection()) { - int from_line = text_editor->get_selection_from_line(); - int from_col = text_editor->get_selection_from_column(); - int to_line = text_editor->get_selection_to_line(); - int to_column = text_editor->get_selection_to_column(); - int cursor_line = text_editor->get_caret_line(); - for (int i = from_line; i <= to_line; i++) { - int line_id = i; - int next_id = i - 1; + Vector<int> carets_to_remove; + + Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order(); + for (int i = 0; i < caret_edit_order.size(); i++) { + int c = caret_edit_order[i]; + int cl = text_editor->get_caret_line(c); + + bool swaped_caret = false; + for (int j = i + 1; j < caret_edit_order.size(); j++) { + if (text_editor->has_selection(caret_edit_order[j])) { + if (text_editor->get_selection_from_line() == cl) { + carets_to_remove.push_back(caret_edit_order[j]); + continue; + } + + if (text_editor->get_selection_to_line() == cl) { + if (text_editor->has_selection(c)) { + if (text_editor->get_selection_to_line(c) != cl) { + text_editor->select(cl + 1, 0, text_editor->get_selection_to_line(c), text_editor->get_selection_to_column(c), c); + break; + } + } + + carets_to_remove.push_back(c); + i = j - 1; + swaped_caret = true; + break; + } + break; + } + + if (text_editor->get_caret_line(caret_edit_order[j]) == cl) { + carets_to_remove.push_back(caret_edit_order[j]); + i = j; + continue; + } + break; + } + + if (swaped_caret) { + continue; + } + + if (text_editor->has_selection(c)) { + int from_line = text_editor->get_selection_from_line(c); + int from_col = text_editor->get_selection_from_column(c); + int to_line = text_editor->get_selection_to_line(c); + int to_column = text_editor->get_selection_to_column(c); + int cursor_line = text_editor->get_caret_line(c); + + for (int j = from_line; j <= to_line; j++) { + int line_id = j; + int next_id = j - 1; + + if (line_id == 0 || next_id < 0) { + return; + } + + text_editor->unfold_line(line_id); + text_editor->unfold_line(next_id); + + text_editor->swap_lines(line_id, next_id); + text_editor->set_caret_line(next_id, c == 0, true, 0, c); + } + int from_line_up = from_line > 0 ? from_line - 1 : from_line; + int to_line_up = to_line > 0 ? to_line - 1 : to_line; + int cursor_line_up = cursor_line > 0 ? cursor_line - 1 : cursor_line; + text_editor->select(from_line_up, from_col, to_line_up, to_column, c); + text_editor->set_caret_line(cursor_line_up, c == 0, true, 0, c); + } else { + int line_id = text_editor->get_caret_line(c); + int next_id = line_id - 1; if (line_id == 0 || next_id < 0) { return; @@ -1273,238 +1371,336 @@ void CodeTextEditor::move_lines_up() { text_editor->unfold_line(next_id); text_editor->swap_lines(line_id, next_id); - text_editor->set_caret_line(next_id); + text_editor->set_caret_line(next_id, c == 0, true, 0, c); } - int from_line_up = from_line > 0 ? from_line - 1 : from_line; - int to_line_up = to_line > 0 ? to_line - 1 : to_line; - int cursor_line_up = cursor_line > 0 ? cursor_line - 1 : cursor_line; - text_editor->select(from_line_up, from_col, to_line_up, to_column); - text_editor->set_caret_line(cursor_line_up); - } else { - int line_id = text_editor->get_caret_line(); - int next_id = line_id - 1; - - if (line_id == 0 || next_id < 0) { - return; - } - - text_editor->unfold_line(line_id); - text_editor->unfold_line(next_id); - - text_editor->swap_lines(line_id, next_id); - text_editor->set_caret_line(next_id); } text_editor->end_complex_operation(); + text_editor->merge_overlapping_carets(); text_editor->queue_redraw(); } void CodeTextEditor::move_lines_down() { text_editor->begin_complex_operation(); - if (text_editor->has_selection()) { - int from_line = text_editor->get_selection_from_line(); - int from_col = text_editor->get_selection_from_column(); - int to_line = text_editor->get_selection_to_line(); - int to_column = text_editor->get_selection_to_column(); - int cursor_line = text_editor->get_caret_line(); - for (int i = to_line; i >= from_line; i--) { - int line_id = i; - int next_id = i + 1; + Vector<int> carets_to_remove; + + Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order(); + for (int i = 0; i < caret_edit_order.size(); i++) { + int c = caret_edit_order[i]; + int cl = text_editor->get_caret_line(c); + + bool swaped_caret = false; + for (int j = i + 1; j < caret_edit_order.size(); j++) { + if (text_editor->has_selection(caret_edit_order[j])) { + if (text_editor->get_selection_from_line() == cl) { + carets_to_remove.push_back(caret_edit_order[j]); + continue; + } + + if (text_editor->get_selection_to_line() == cl) { + if (text_editor->has_selection(c)) { + if (text_editor->get_selection_to_line(c) != cl) { + text_editor->select(cl + 1, 0, text_editor->get_selection_to_line(c), text_editor->get_selection_to_column(c), c); + break; + } + } + + carets_to_remove.push_back(c); + i = j - 1; + swaped_caret = true; + break; + } + break; + } + + if (text_editor->get_caret_line(caret_edit_order[j]) == cl) { + carets_to_remove.push_back(caret_edit_order[j]); + i = j; + continue; + } + break; + } + + if (swaped_caret) { + continue; + } + + if (text_editor->has_selection(c)) { + int from_line = text_editor->get_selection_from_line(c); + int from_col = text_editor->get_selection_from_column(c); + int to_line = text_editor->get_selection_to_line(c); + int to_column = text_editor->get_selection_to_column(c); + int cursor_line = text_editor->get_caret_line(c); + + for (int l = to_line; l >= from_line; l--) { + int line_id = l; + int next_id = l + 1; + + if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) { + continue; + } + + text_editor->unfold_line(line_id); + text_editor->unfold_line(next_id); + + text_editor->swap_lines(line_id, next_id); + text_editor->set_caret_line(next_id, c == 0, true, 0, c); + } + int from_line_down = from_line < text_editor->get_line_count() ? from_line + 1 : from_line; + int to_line_down = to_line < text_editor->get_line_count() ? to_line + 1 : to_line; + int cursor_line_down = cursor_line < text_editor->get_line_count() ? cursor_line + 1 : cursor_line; + text_editor->select(from_line_down, from_col, to_line_down, to_column, c); + text_editor->set_caret_line(cursor_line_down, c == 0, true, 0, c); + } else { + int line_id = text_editor->get_caret_line(c); + int next_id = line_id + 1; if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) { - return; + continue; } text_editor->unfold_line(line_id); text_editor->unfold_line(next_id); text_editor->swap_lines(line_id, next_id); - text_editor->set_caret_line(next_id); + text_editor->set_caret_line(next_id, c == 0, true, 0, c); } - int from_line_down = from_line < text_editor->get_line_count() ? from_line + 1 : from_line; - int to_line_down = to_line < text_editor->get_line_count() ? to_line + 1 : to_line; - int cursor_line_down = cursor_line < text_editor->get_line_count() ? cursor_line + 1 : cursor_line; - text_editor->select(from_line_down, from_col, to_line_down, to_column); - text_editor->set_caret_line(cursor_line_down); - } else { - int line_id = text_editor->get_caret_line(); - int next_id = line_id + 1; - - if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) { - return; - } - - text_editor->unfold_line(line_id); - text_editor->unfold_line(next_id); + } - text_editor->swap_lines(line_id, next_id); - text_editor->set_caret_line(next_id); + // Sort and remove backwards to preserve indexes. + carets_to_remove.sort(); + for (int i = carets_to_remove.size() - 1; i >= 0; i--) { + text_editor->remove_caret(carets_to_remove[i]); } + + text_editor->merge_overlapping_carets(); text_editor->end_complex_operation(); text_editor->queue_redraw(); } -void CodeTextEditor::_delete_line(int p_line) { +void CodeTextEditor::_delete_line(int p_line, int p_caret) { // this is currently intended to be called within delete_lines() // so `begin_complex_operation` is omitted here text_editor->set_line(p_line, ""); if (p_line == 0 && text_editor->get_line_count() > 1) { - text_editor->set_caret_line(1); - text_editor->set_caret_column(0); + text_editor->set_caret_line(1, p_caret == 0, true, 0, p_caret); + text_editor->set_caret_column(0, p_caret == 0, p_caret); } - text_editor->backspace(); + text_editor->backspace(p_caret); if (p_line < text_editor->get_line_count()) { text_editor->unfold_line(p_line); } - text_editor->set_caret_line(p_line); + text_editor->set_caret_line(p_line, p_caret == 0, true, 0, p_caret); } void CodeTextEditor::delete_lines() { text_editor->begin_complex_operation(); - if (text_editor->has_selection()) { - int to_line = text_editor->get_selection_to_line(); - int from_line = text_editor->get_selection_from_line(); - int count = Math::abs(to_line - from_line) + 1; - text_editor->set_caret_line(from_line, false); - text_editor->deselect(); - for (int i = 0; i < count; i++) { - _delete_line(from_line); + Vector<int> carets_to_remove; + + Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order(); + for (int i = 0; i < caret_edit_order.size(); i++) { + int c = caret_edit_order[i]; + int cl = text_editor->get_caret_line(c); + + bool swaped_caret = false; + for (int j = i + 1; j < caret_edit_order.size(); j++) { + if (text_editor->has_selection(caret_edit_order[j])) { + if (text_editor->get_selection_from_line() == cl) { + carets_to_remove.push_back(caret_edit_order[j]); + continue; + } + + if (text_editor->get_selection_to_line() == cl) { + if (text_editor->has_selection(c)) { + if (text_editor->get_selection_to_line(c) != cl) { + text_editor->select(cl + 1, 0, text_editor->get_selection_to_line(c), text_editor->get_selection_to_column(c), c); + break; + } + } + + carets_to_remove.push_back(c); + i = j - 1; + swaped_caret = true; + break; + } + break; + } + + if (text_editor->get_caret_line(caret_edit_order[j]) == cl) { + carets_to_remove.push_back(caret_edit_order[j]); + i = j; + continue; + } + break; + } + + if (swaped_caret) { + continue; + } + + if (text_editor->has_selection(c)) { + int to_line = text_editor->get_selection_to_line(c); + int from_line = text_editor->get_selection_from_line(c); + int count = Math::abs(to_line - from_line) + 1; + + text_editor->set_caret_line(from_line, false, true, 0, c); + text_editor->deselect(c); + for (int j = 0; j < count; j++) { + _delete_line(from_line, c); + } + } else { + _delete_line(text_editor->get_caret_line(c), c); } - } else { - _delete_line(text_editor->get_caret_line()); } + + // Sort and remove backwards to preserve indexes. + carets_to_remove.sort(); + for (int i = carets_to_remove.size() - 1; i >= 0; i--) { + text_editor->remove_caret(carets_to_remove[i]); + } + text_editor->merge_overlapping_carets(); text_editor->end_complex_operation(); } void CodeTextEditor::duplicate_selection() { - const int cursor_column = text_editor->get_caret_column(); - int from_line = text_editor->get_caret_line(); - int to_line = text_editor->get_caret_line(); - int from_column = 0; - int to_column = 0; - int cursor_new_line = to_line + 1; - int cursor_new_column = text_editor->get_caret_column(); - String new_text = "\n" + text_editor->get_line(from_line); - bool selection_active = false; - - text_editor->set_caret_column(text_editor->get_line(from_line).length()); - if (text_editor->has_selection()) { - from_column = text_editor->get_selection_from_column(); - to_column = text_editor->get_selection_to_column(); - - from_line = text_editor->get_selection_from_line(); - to_line = text_editor->get_selection_to_line(); - cursor_new_line = to_line + text_editor->get_caret_line() - from_line; - cursor_new_column = to_column == cursor_column ? 2 * to_column - from_column : to_column; - new_text = text_editor->get_selected_text(); - selection_active = true; - - text_editor->set_caret_line(to_line); - text_editor->set_caret_column(to_column); - } - text_editor->begin_complex_operation(); - for (int i = from_line; i <= to_line; i++) { - text_editor->unfold_line(i); - } - text_editor->deselect(); - text_editor->insert_text_at_caret(new_text); - text_editor->set_caret_line(cursor_new_line); - text_editor->set_caret_column(cursor_new_column); - if (selection_active) { - text_editor->select(to_line, to_column, 2 * to_line - from_line, to_line == from_line ? 2 * to_column - from_column : to_column); - } + Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order(); + for (const int &c : caret_edit_order) { + const int cursor_column = text_editor->get_caret_column(c); + int from_line = text_editor->get_caret_line(c); + int to_line = text_editor->get_caret_line(c); + int from_column = 0; + int to_column = 0; + int cursor_new_line = to_line + 1; + int cursor_new_column = text_editor->get_caret_column(c); + String new_text = "\n" + text_editor->get_line(from_line); + bool selection_active = false; + + text_editor->set_caret_column(text_editor->get_line(from_line).length(), c == 0, c); + if (text_editor->has_selection(c)) { + from_column = text_editor->get_selection_from_column(c); + to_column = text_editor->get_selection_to_column(c); + + from_line = text_editor->get_selection_from_line(c); + to_line = text_editor->get_selection_to_line(c); + cursor_new_line = to_line + text_editor->get_caret_line(c) - from_line; + cursor_new_column = to_column == cursor_column ? 2 * to_column - from_column : to_column; + new_text = text_editor->get_selected_text(c); + selection_active = true; + + text_editor->set_caret_line(to_line, c == 0, true, 0, c); + text_editor->set_caret_column(to_column, c == 0, c); + } + for (int i = from_line; i <= to_line; i++) { + text_editor->unfold_line(i); + } + text_editor->deselect(c); + text_editor->insert_text_at_caret(new_text, c); + text_editor->set_caret_line(cursor_new_line, c == 0, true, 0, c); + text_editor->set_caret_column(cursor_new_column, c == 0, c); + if (selection_active) { + text_editor->select(to_line, to_column, 2 * to_line - from_line, to_line == from_line ? 2 * to_column - from_column : to_column, c); + } + } + text_editor->merge_overlapping_carets(); text_editor->end_complex_operation(); text_editor->queue_redraw(); } void CodeTextEditor::toggle_inline_comment(const String &delimiter) { text_editor->begin_complex_operation(); - if (text_editor->has_selection()) { - int begin = text_editor->get_selection_from_line(); - int end = text_editor->get_selection_to_line(); - // End of selection ends on the first column of the last line, ignore it. - if (text_editor->get_selection_to_column() == 0) { - end -= 1; - } + Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order(); + for (const int &c : caret_edit_order) { + if (text_editor->has_selection(c)) { + int begin = text_editor->get_selection_from_line(c); + int end = text_editor->get_selection_to_line(c); - int col_to = text_editor->get_selection_to_column(); - int cursor_pos = text_editor->get_caret_column(); + // End of selection ends on the first column of the last line, ignore it. + if (text_editor->get_selection_to_column(c) == 0) { + end -= 1; + } - // Check if all lines in the selected block are commented. - bool is_commented = true; - for (int i = begin; i <= end; i++) { - if (!text_editor->get_line(i).begins_with(delimiter)) { - is_commented = false; - break; + int col_to = text_editor->get_selection_to_column(c); + int cursor_pos = text_editor->get_caret_column(c); + + // Check if all lines in the selected block are commented. + bool is_commented = true; + for (int i = begin; i <= end; i++) { + if (!text_editor->get_line(i).begins_with(delimiter)) { + is_commented = false; + break; + } } - } - for (int i = begin; i <= end; i++) { - String line_text = text_editor->get_line(i); + for (int i = begin; i <= end; i++) { + String line_text = text_editor->get_line(i); - if (line_text.strip_edges().is_empty()) { - line_text = delimiter; - } else { - if (is_commented) { - line_text = line_text.substr(delimiter.length(), line_text.length()); + if (line_text.strip_edges().is_empty()) { + line_text = delimiter; } else { - line_text = delimiter + line_text; + if (is_commented) { + line_text = line_text.substr(delimiter.length(), line_text.length()); + } else { + line_text = delimiter + line_text; + } } + text_editor->set_line(i, line_text); } - text_editor->set_line(i, line_text); - } - // Adjust selection & cursor position. - int offset = (is_commented ? -1 : 1) * delimiter.length(); - int col_from = text_editor->get_selection_from_column() > 0 ? text_editor->get_selection_from_column() + offset : 0; + // Adjust selection & cursor position. + int offset = (is_commented ? -1 : 1) * delimiter.length(); + int col_from = text_editor->get_selection_from_column(c) > 0 ? text_editor->get_selection_from_column(c) + offset : 0; - if (is_commented && text_editor->get_caret_column() == text_editor->get_line(text_editor->get_caret_line()).length() + 1) { - cursor_pos += 1; - } + if (is_commented && text_editor->get_caret_column(c) == text_editor->get_line(text_editor->get_caret_line(c)).length() + 1) { + cursor_pos += 1; + } - if (text_editor->get_selection_to_column() != 0 && col_to != text_editor->get_line(text_editor->get_selection_to_line()).length() + 1) { - col_to += offset; - } + if (text_editor->get_selection_to_column(c) != 0 && col_to != text_editor->get_line(text_editor->get_selection_to_line(c)).length() + 1) { + col_to += offset; + } - if (text_editor->get_caret_column() != 0) { - cursor_pos += offset; - } + if (text_editor->get_caret_column(c) != 0) { + cursor_pos += offset; + } - text_editor->select(begin, col_from, text_editor->get_selection_to_line(), col_to); - text_editor->set_caret_column(cursor_pos); + text_editor->select(begin, col_from, text_editor->get_selection_to_line(c), col_to, c); + text_editor->set_caret_column(cursor_pos, c == 0, c); - } else { - int begin = text_editor->get_caret_line(); - String line_text = text_editor->get_line(begin); - int delimiter_length = delimiter.length(); - - int col = text_editor->get_caret_column(); - if (line_text.begins_with(delimiter)) { - line_text = line_text.substr(delimiter_length, line_text.length()); - col -= delimiter_length; } else { - line_text = delimiter + line_text; - col += delimiter_length; - } + int begin = text_editor->get_caret_line(c); + String line_text = text_editor->get_line(begin); + int delimiter_length = delimiter.length(); + + int col = text_editor->get_caret_column(c); + if (line_text.begins_with(delimiter)) { + line_text = line_text.substr(delimiter_length, line_text.length()); + col -= delimiter_length; + } else { + line_text = delimiter + line_text; + col += delimiter_length; + } - text_editor->set_line(begin, line_text); - text_editor->set_caret_column(col); + text_editor->set_line(begin, line_text); + text_editor->set_caret_column(col, c == 0, c); + } } + text_editor->merge_overlapping_carets(); text_editor->end_complex_operation(); text_editor->queue_redraw(); } void CodeTextEditor::goto_line(int p_line) { + text_editor->remove_secondary_carets(); text_editor->deselect(); text_editor->unfold_line(p_line); text_editor->call_deferred(SNAME("set_caret_line"), p_line); } void CodeTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) { + text_editor->remove_secondary_carets(); text_editor->unfold_line(p_line); text_editor->call_deferred(SNAME("set_caret_line"), p_line); text_editor->call_deferred(SNAME("set_caret_column"), p_begin); @@ -1526,19 +1722,7 @@ void CodeTextEditor::clear_executing_line() { Variant CodeTextEditor::get_edit_state() { Dictionary state; - - state["scroll_position"] = text_editor->get_v_scroll(); - state["h_scroll_position"] = text_editor->get_h_scroll(); - state["column"] = text_editor->get_caret_column(); - state["row"] = text_editor->get_caret_line(); - - state["selection"] = get_text_editor()->has_selection(); - if (get_text_editor()->has_selection()) { - state["selection_from_line"] = text_editor->get_selection_from_line(); - state["selection_from_column"] = text_editor->get_selection_from_column(); - state["selection_to_line"] = text_editor->get_selection_to_line(); - state["selection_to_column"] = text_editor->get_selection_to_column(); - } + state.merge(get_navigation_state()); state["folded_lines"] = text_editor->get_folded_lines(); state["breakpoints"] = text_editor->get_breakpointed_lines(); @@ -1559,8 +1743,10 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) { text_editor->set_v_scroll(state["scroll_position"]); text_editor->set_h_scroll(state["h_scroll_position"]); - if (state.has("selection")) { + if (state.get("selection", false)) { text_editor->select(state["selection_from_line"], state["selection_from_column"], state["selection_to_line"], state["selection_to_column"]); + } else { + text_editor->deselect(); } if (state.has("folded_lines")) { @@ -1585,6 +1771,25 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) { } } +Variant CodeTextEditor::get_navigation_state() { + Dictionary state; + + state["scroll_position"] = text_editor->get_v_scroll(); + state["h_scroll_position"] = text_editor->get_h_scroll(); + state["column"] = text_editor->get_caret_column(); + state["row"] = text_editor->get_caret_line(); + + state["selection"] = get_text_editor()->has_selection(); + if (get_text_editor()->has_selection()) { + state["selection_from_line"] = text_editor->get_selection_from_line(); + state["selection_from_column"] = text_editor->get_selection_from_column(); + state["selection_to_line"] = text_editor->get_selection_to_line(); + state["selection_to_column"] = text_editor->get_selection_to_column(); + } + + return state; +} + void CodeTextEditor::set_error(const String &p_error) { error->set_text(p_error); if (!p_error.is_empty()) { @@ -1608,6 +1813,7 @@ void CodeTextEditor::goto_error() { if (text_editor->get_line_count() != error_line) { text_editor->unfold_line(error_line); } + text_editor->remove_secondary_carets(); text_editor->set_caret_line(error_line); text_editor->set_caret_column(error_column); text_editor->center_viewport_to_caret(); @@ -1644,8 +1850,8 @@ void CodeTextEditor::_on_settings_change() { void CodeTextEditor::_apply_settings_change() { _update_text_editor_theme(); - font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size"); - int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures"); + font_size = EDITOR_GET("interface/editor/code_font_size"); + int ot_mode = EDITOR_GET("interface/editor/code_font_contextual_ligatures"); Ref<FontVariation> fc = text_editor->get_theme_font(SNAME("font")); if (fc.is_valid()) { @@ -1656,7 +1862,7 @@ void CodeTextEditor::_apply_settings_change() { fc->set_opentype_features(ftrs); } break; case 2: { // Custom. - Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(","); + Vector<String> subtag = String(EDITOR_GET("interface/editor/code_font_custom_opentype_features")).split(","); Dictionary ftrs; for (int i = 0; i < subtag.size(); i++) { Vector<String> subtag_a = subtag[i].split("="); @@ -1668,7 +1874,7 @@ void CodeTextEditor::_apply_settings_change() { } fc->set_opentype_features(ftrs); } break; - default: { // Default. + default: { // Enabled. Dictionary ftrs; ftrs[TS->name_to_tag("calt")] = 1; fc->set_opentype_features(ftrs); @@ -1784,8 +1990,10 @@ void CodeTextEditor::set_warning_count(int p_warning_count) { } void CodeTextEditor::toggle_bookmark() { - int line = text_editor->get_caret_line(); - text_editor->set_line_as_bookmarked(line, !text_editor->is_line_bookmarked(line)); + for (int i = 0; i < text_editor->get_caret_count(); i++) { + int line = text_editor->get_caret_line(i); + text_editor->set_line_as_bookmarked(line, !text_editor->is_line_bookmarked(line)); + } } void CodeTextEditor::goto_next_bookmark() { @@ -1794,22 +2002,14 @@ void CodeTextEditor::goto_next_bookmark() { return; } - int line = text_editor->get_caret_line(); - if (line >= (int)bmarks[bmarks.size() - 1]) { - text_editor->unfold_line(bmarks[0]); - text_editor->set_caret_line(bmarks[0]); - text_editor->center_viewport_to_caret(); - } else { - for (int i = 0; i < bmarks.size(); i++) { - int bmark_line = bmarks[i]; - if (bmark_line > line) { - text_editor->unfold_line(bmark_line); - text_editor->set_caret_line(bmark_line); - text_editor->center_viewport_to_caret(); - return; - } + int current_line = text_editor->get_caret_line(); + int bmark_idx = 0; + if (current_line < (int)bmarks[bmarks.size() - 1]) { + while (bmark_idx < bmarks.size() && bmarks[bmark_idx] <= current_line) { + bmark_idx++; } } + goto_line_centered(bmarks[bmark_idx]); } void CodeTextEditor::goto_prev_bookmark() { @@ -1818,22 +2018,14 @@ void CodeTextEditor::goto_prev_bookmark() { return; } - int line = text_editor->get_caret_line(); - if (line <= (int)bmarks[0]) { - text_editor->unfold_line(bmarks[bmarks.size() - 1]); - text_editor->set_caret_line(bmarks[bmarks.size() - 1]); - text_editor->center_viewport_to_caret(); - } else { - for (int i = bmarks.size() - 1; i >= 0; i--) { - int bmark_line = bmarks[i]; - if (bmark_line < line) { - text_editor->unfold_line(bmark_line); - text_editor->set_caret_line(bmark_line); - text_editor->center_viewport_to_caret(); - return; - } + int current_line = text_editor->get_caret_line(); + int bmark_idx = bmarks.size() - 1; + if (current_line > (int)bmarks[0]) { + while (bmark_idx >= 0 && bmarks[bmark_idx] >= current_line) { + bmark_idx--; } } + goto_line_centered(bmarks[bmark_idx]); } void CodeTextEditor::remove_all_bookmarks() { @@ -1876,7 +2068,7 @@ CodeTextEditor::CodeTextEditor() { add_child(text_editor); text_editor->set_v_size_flags(SIZE_EXPAND_FILL); - int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures"); + int ot_mode = EDITOR_GET("interface/editor/code_font_contextual_ligatures"); Ref<FontVariation> fc = text_editor->get_theme_font(SNAME("font")); if (fc.is_valid()) { switch (ot_mode) { @@ -1886,7 +2078,7 @@ CodeTextEditor::CodeTextEditor() { fc->set_opentype_features(ftrs); } break; case 2: { // Custom. - Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(","); + Vector<String> subtag = String(EDITOR_GET("interface/editor/code_font_custom_opentype_features")).split(","); Dictionary ftrs; for (int i = 0; i < subtag.size(); i++) { Vector<String> subtag_a = subtag[i].split("="); @@ -1898,7 +2090,7 @@ CodeTextEditor::CodeTextEditor() { } fc->set_opentype_features(ftrs); } break; - default: { // Default. + default: { // Enabled. Dictionary ftrs; ftrs[TS->name_to_tag("calt")] = 1; fc->set_opentype_features(ftrs); @@ -1994,7 +2186,7 @@ CodeTextEditor::CodeTextEditor() { code_complete_timer->connect("timeout", callable_mp(this, &CodeTextEditor::_code_complete_timer_timeout)); font_resize_val = 0; - font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size"); + font_size = EDITOR_GET("interface/editor/code_font_size"); font_resize_timer = memnew(Timer); add_child(font_resize_timer); font_resize_timer->set_one_shot(true); diff --git a/editor/code_editor.h b/editor/code_editor.h index 49679cc700..ded7518287 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -92,7 +92,7 @@ class FindReplaceBar : public HBoxContainer { bool replace_all_mode = false; bool preserve_cursor = false; - void _get_search_from(int &r_line, int &r_col); + void _get_search_from(int &r_line, int &r_col, bool p_is_searching_next = false); void _update_results_count(); void _update_matches_label(); @@ -197,7 +197,7 @@ class CodeTextEditor : public VBoxContainer { void _update_status_bar_theme(); - void _delete_line(int p_line); + void _delete_line(int p_line, int p_caret); void _toggle_scripts_pressed(); protected: @@ -246,6 +246,7 @@ public: Variant get_edit_state(); void set_edit_state(const Variant &p_state); + Variant get_navigation_state(); void set_error_count(int p_error_count); void set_warning_count(int p_warning_count); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 861d05f17a..2bd77bf99c 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -31,12 +31,14 @@ #include "connections_dialog.h" #include "editor/doc_tools.h" +#include "editor/editor_help.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/scene_tree_dock.h" #include "plugins/script_editor_plugin.h" +#include "scene/resources/packed_scene.h" static Node *_find_first_script(Node *p_root, Node *p_node) { if (p_node != p_root && p_node->get_owner() != p_root) { @@ -160,6 +162,9 @@ void ConnectDialog::_tree_node_selected() { } dst_path = source->get_path_to(current); + if (!edit_mode) { + set_dst_method(generate_method_callback_name(source, signal, current)); + } _update_ok_enabled(); } @@ -184,8 +189,8 @@ void ConnectDialog::_add_bind() { Variant::Type type = (Variant::Type)type_list->get_item_id(type_list->get_selected()); Variant value; - Callable::CallError error; - Variant::construct(type, value, nullptr, 0, error); + Callable::CallError err; + Variant::construct(type, value, nullptr, 0, err); cdbinds->params.push_back(value); cdbinds->notify_changed(); @@ -205,6 +210,45 @@ void ConnectDialog::_remove_bind() { cdbinds->params.remove_at(idx); cdbinds->notify_changed(); } +/* + * Automatically generates a name for the callback method. + */ +StringName ConnectDialog::generate_method_callback_name(Node *p_source, String p_signal_name, Node *p_target) { + String node_name = p_source->get_name(); + for (int i = 0; i < node_name.length(); i++) { // TODO: Regex filter may be cleaner. + char32_t c = node_name[i]; + if (!is_ascii_identifier_char(c)) { + if (c == ' ') { + // Replace spaces with underlines. + c = '_'; + } else { + // Remove any other characters. + node_name.remove_at(i); + i--; + continue; + } + } + node_name[i] = c; + } + + Dictionary subst; + subst["NodeName"] = node_name.to_pascal_case(); + subst["nodeName"] = node_name.to_camel_case(); + subst["node_name"] = node_name.to_snake_case(); + + subst["SignalName"] = p_signal_name.to_pascal_case(); + subst["signalName"] = p_signal_name.to_camel_case(); + subst["signal_name"] = p_signal_name.to_snake_case(); + + String dst_method; + if (p_source == p_target) { + dst_method = String(EDITOR_GET("interface/editors/default_signal_callback_to_self_name")).format(subst); + } else { + dst_method = String(EDITOR_GET("interface/editors/default_signal_callback_name")).format(subst); + } + + return dst_method; +} /* * Enables or disables the connect button. The connect button is enabled if a @@ -238,6 +282,12 @@ void ConnectDialog::_notification(int p_what) { String type_name = Variant::get_type_name((Variant::Type)type_list->get_item_id(i)); type_list->set_item_icon(i, get_theme_icon(type_name, SNAME("EditorIcons"))); } + + Ref<StyleBox> style = get_theme_stylebox("normal", "LineEdit")->duplicate(); + if (style.is_valid()) { + style->set_default_margin(SIDE_TOP, style->get_default_margin(SIDE_TOP) + 1.0); + from_signal->add_theme_style_override("normal", style); + } } break; } } @@ -361,6 +411,11 @@ void ConnectDialog::popup_dialog(const String &p_for_signal) { error_label->set_visible(!_find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root())); } + if (first_popup) { + first_popup = false; + _advanced_pressed(); + } + popup_centered(); } @@ -383,6 +438,7 @@ void ConnectDialog::_advanced_pressed() { } _update_ok_enabled(); + EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "use_advanced_connections", advanced->is_pressed()); popup_centered(); } @@ -465,30 +521,32 @@ ConnectDialog::ConnectDialog() { vbc_right->add_margin_child(TTR("Unbind Signal Arguments:"), unbind_count); - HBoxContainer *dstm_hb = memnew(HBoxContainer); - vbc_left->add_margin_child(TTR("Receiver Method:"), dstm_hb); - dst_method = memnew(LineEdit); dst_method->set_h_size_flags(Control::SIZE_EXPAND_FILL); dst_method->connect("text_submitted", callable_mp(this, &ConnectDialog::_text_submitted)); - dstm_hb->add_child(dst_method); + vbc_left->add_margin_child(TTR("Receiver Method:"), dst_method); advanced = memnew(CheckButton); - dstm_hb->add_child(advanced); + vbc_left->add_child(advanced); advanced->set_text(TTR("Advanced")); + advanced->set_h_size_flags(Control::SIZE_SHRINK_BEGIN | Control::SIZE_EXPAND); + advanced->set_pressed(EditorSettings::get_singleton()->get_project_metadata("editor_metadata", "use_advanced_connections", false)); advanced->connect("pressed", callable_mp(this, &ConnectDialog::_advanced_pressed)); + HBoxContainer *hbox = memnew(HBoxContainer); + vbc_right->add_child(hbox); + deferred = memnew(CheckBox); deferred->set_h_size_flags(0); deferred->set_text(TTR("Deferred")); deferred->set_tooltip_text(TTR("Defers the signal, storing it in a queue and only firing it at idle time.")); - vbc_right->add_child(deferred); + hbox->add_child(deferred); one_shot = memnew(CheckBox); one_shot->set_h_size_flags(0); - one_shot->set_text(TTR("Oneshot")); + one_shot->set_text(TTR("One Shot")); one_shot->set_tooltip_text(TTR("Disconnects the signal after its first emission.")); - vbc_right->add_child(one_shot); + hbox->add_child(one_shot); cdbinds = memnew(ConnectDialogBinds); @@ -570,19 +628,19 @@ void ConnectionsDock::_make_or_edit_connection() { // Conditions to add function: must have a script and must not have the method already // (in the class, the script itself, or inherited). bool add_script_function = false; - Ref<Script> script = target->get_script(); - if (!target->get_script().is_null() && !ClassDB::has_method(target->get_class(), cd.method)) { + Ref<Script> scr = target->get_script(); + if (!scr.is_null() && !ClassDB::has_method(target->get_class(), cd.method)) { // There is a chance that the method is inherited from another script. bool found_inherited_function = false; - Ref<Script> inherited_script = script->get_base_script(); - while (!inherited_script.is_null()) { - int line = inherited_script->get_language()->find_function(cd.method, inherited_script->get_source_code()); + Ref<Script> inherited_scr = scr->get_base_script(); + while (!inherited_scr.is_null()) { + int line = inherited_scr->get_language()->find_function(cd.method, inherited_scr->get_source_code()); if (line != -1) { found_inherited_function = true; break; } - inherited_script = inherited_script->get_base_script(); + inherited_scr = inherited_scr->get_base_script(); } add_script_function = !found_inherited_function; @@ -627,6 +685,7 @@ void ConnectionsDock::_connect(ConnectDialog::ConnectionData p_cd) { } Callable callable = p_cd.get_callable(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(p_cd.signal), String(p_cd.method))); undo_redo->add_do_method(source, "connect", p_cd.signal, callable, p_cd.flags); undo_redo->add_undo_method(source, "disconnect", p_cd.signal, callable); @@ -647,6 +706,7 @@ void ConnectionsDock::_disconnect(TreeItem &p_item) { ERR_FAIL_COND(cd.source != selected_node); // Shouldn't happen but... Bugcheck. + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Disconnect '%s' from '%s'"), cd.signal, cd.method)); Callable callable = cd.get_callable(); @@ -673,13 +733,16 @@ void ConnectionsDock::_disconnect_all() { TreeItem *child = item->get_first_child(); String signal_name = item->get_metadata(0).operator Dictionary()["name"]; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Disconnect all from signal: '%s'"), signal_name)); while (child) { Connection connection = child->get_metadata(0); - ConnectDialog::ConnectionData cd = connection; - undo_redo->add_do_method(selected_node, "disconnect", cd.signal, cd.get_callable()); - undo_redo->add_undo_method(selected_node, "connect", cd.signal, cd.get_callable(), cd.binds, cd.flags); + if (!_is_connection_inherited(connection)) { + ConnectDialog::ConnectionData cd = connection; + undo_redo->add_do_method(selected_node, "disconnect", cd.signal, cd.get_callable()); + undo_redo->add_undo_method(selected_node, "connect", cd.signal, cd.get_callable(), cd.binds, cd.flags); + } child = child->get_next(); } @@ -724,49 +787,43 @@ bool ConnectionsDock::_is_item_signal(TreeItem &p_item) { return (p_item.get_parent() == tree->get_root() || p_item.get_parent()->get_parent() == tree->get_root()); } +bool ConnectionsDock::_is_connection_inherited(Connection &p_connection) { + Node *scene_root = EditorNode::get_singleton()->get_edited_scene(); + Ref<PackedScene> scn = ResourceLoader::load(scene_root->get_scene_file_path()); + ERR_FAIL_NULL_V(scn, false); + + Ref<SceneState> state = scn->get_state(); + ERR_FAIL_NULL_V(state, false); + + Node *source = Object::cast_to<Node>(p_connection.signal.get_object()); + Node *target = Object::cast_to<Node>(p_connection.callable.get_object()); + + const NodePath source_path = scene_root->get_path_to(source); + const NodePath target_path = scene_root->get_path_to(target); + const StringName signal_name = p_connection.signal.get_name(); + const StringName method_name = p_connection.callable.get_method(); + + // If it cannot be found in PackedScene, this connection was inherited. + return !state->has_connection(source_path, signal_name, target_path, method_name, true); +} + /* * Open connection dialog with TreeItem data to CREATE a brand-new connection. */ void ConnectionsDock::_open_connection_dialog(TreeItem &p_item) { String signal_name = p_item.get_metadata(0).operator Dictionary()["name"]; const String &signal_name_ref = signal_name; - String node_name = selected_node->get_name(); - for (int i = 0; i < node_name.length(); i++) { // TODO: Regex filter may be cleaner. - char32_t c = node_name[i]; - if (!is_ascii_identifier_char(c)) { - if (c == ' ') { - // Replace spaces with underlines. - c = '_'; - } else { - // Remove any other characters. - node_name.remove_at(i); - i--; - continue; - } - } - node_name[i] = c; - } Node *dst_node = selected_node->get_owner() ? selected_node->get_owner() : selected_node; if (!dst_node || dst_node->get_script().is_null()) { dst_node = _find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root()); } - Dictionary subst; - subst["NodeName"] = node_name.to_pascal_case(); - subst["nodeName"] = node_name.to_camel_case(); - subst["node_name"] = node_name.to_snake_case(); - subst["SignalName"] = signal_name.to_pascal_case(); - subst["signalName"] = signal_name.to_camel_case(); - subst["signal_name"] = signal_name.to_snake_case(); - - String dst_method = String(EDITOR_GET("interface/editors/default_signal_callback_name")).format(subst); - ConnectDialog::ConnectionData cd; cd.source = selected_node; cd.signal = StringName(signal_name_ref); cd.target = dst_node; - cd.method = StringName(dst_method); + cd.method = ConnectDialog::generate_method_callback_name(cd.source, signal_name, cd.target); connect_dialog->popup_dialog(signal_name_ref); connect_dialog->init(cd); connect_dialog->set_title(TTR("Connect a Signal to a Method")); @@ -803,14 +860,14 @@ void ConnectionsDock::_go_to_script(TreeItem &p_item) { return; } - Ref<Script> script = cd.target->get_script(); + Ref<Script> scr = cd.target->get_script(); - if (script.is_null()) { + if (scr.is_null()) { return; } - if (script.is_valid() && ScriptEditor::get_singleton()->script_goto_method(script, cd.method)) { - EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT); + if (scr.is_valid() && ScriptEditor::get_singleton()->script_goto_method(scr, cd.method)) { + EditorNode::get_singleton()->editor_select(EditorNode::EDITOR_SCRIPT); } } @@ -836,6 +893,19 @@ void ConnectionsDock::_handle_signal_menu_option(int p_option) { } } +void ConnectionsDock::_signal_menu_about_to_popup() { + TreeItem *signal_item = tree->get_selected(); + + bool disable_disconnect_all = true; + for (int i = 0; i < signal_item->get_child_count(); i++) { + if (!signal_item->get_child(i)->has_meta("_inherited_connection")) { + disable_disconnect_all = false; + } + } + + signal_menu->set_item_disabled(slot_menu->get_item_index(DISCONNECT_ALL), disable_disconnect_all); +} + void ConnectionsDock::_handle_slot_menu_option(int p_option) { TreeItem *item = tree->get_selected(); @@ -858,6 +928,13 @@ void ConnectionsDock::_handle_slot_menu_option(int p_option) { } } +void ConnectionsDock::_slot_menu_about_to_popup() { + bool connection_is_inherited = tree->get_selected()->has_meta("_inherited_connection"); + + slot_menu->set_item_disabled(slot_menu->get_item_index(EDIT), connection_is_inherited); + slot_menu->set_item_disabled(slot_menu->get_item_index(DISCONNECT), connection_is_inherited); +} + void ConnectionsDock::_rmb_pressed(Vector2 p_position, MouseButton p_button) { if (p_button != MouseButton::RIGHT) { return; @@ -918,10 +995,6 @@ void ConnectionsDock::_bind_methods() { ClassDB::bind_method("update_tree", &ConnectionsDock::update_tree); } -void ConnectionsDock::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void ConnectionsDock::set_node(Node *p_node) { selected_node = p_node; update_tree(); @@ -971,7 +1044,7 @@ void ConnectionsDock::update_tree() { name = base; } - if (!icon.is_valid()) { + if (icon.is_null()) { icon = get_theme_icon(SNAME("Object"), SNAME("EditorIcons")); } @@ -1064,10 +1137,10 @@ void ConnectionsDock::update_tree() { } // List existing connections. - List<Object::Connection> connections; - selected_node->get_signal_connection_list(signal_name, &connections); + List<Object::Connection> existing_connections; + selected_node->get_signal_connection_list(signal_name, &existing_connections); - for (const Object::Connection &F : connections) { + for (const Object::Connection &F : existing_connections) { Connection connection = F; if (!(connection.flags & CONNECT_PERSIST)) { continue; @@ -1103,6 +1176,12 @@ void ConnectionsDock::update_tree() { connection_item->set_text(0, path); connection_item->set_metadata(0, connection); connection_item->set_icon(0, get_theme_icon(SNAME("Slot"), SNAME("EditorIcons"))); + + if (_is_connection_inherited(connection)) { + // The scene inherits this connection. + connection_item->set_custom_color(0, get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + connection_item->set_meta("_inherited_connection", true); + } } } @@ -1155,6 +1234,7 @@ ConnectionsDock::ConnectionsDock() { signal_menu = memnew(PopupMenu); add_child(signal_menu); signal_menu->connect("id_pressed", callable_mp(this, &ConnectionsDock::_handle_signal_menu_option)); + signal_menu->connect("about_to_popup", callable_mp(this, &ConnectionsDock::_signal_menu_about_to_popup)); signal_menu->add_item(TTR("Connect..."), CONNECT); signal_menu->add_item(TTR("Disconnect All"), DISCONNECT_ALL); signal_menu->add_item(TTR("Copy Name"), COPY_NAME); @@ -1162,6 +1242,7 @@ ConnectionsDock::ConnectionsDock() { slot_menu = memnew(PopupMenu); add_child(slot_menu); slot_menu->connect("id_pressed", callable_mp(this, &ConnectionsDock::_handle_slot_menu_option)); + slot_menu->connect("about_to_popup", callable_mp(this, &ConnectionsDock::_slot_menu_about_to_popup)); slot_menu->add_item(TTR("Edit..."), EDIT); slot_menu->add_item(TTR("Go to Method"), GO_TO_SCRIPT); slot_menu->add_item(TTR("Disconnect"), DISCONNECT); @@ -1174,6 +1255,7 @@ ConnectionsDock::ConnectionsDock() { add_theme_constant_override("separation", 3 * EDSCALE); EDITOR_DEF("interface/editors/default_signal_callback_name", "_on_{node_name}_{signal_name}"); + EDITOR_DEF("interface/editors/default_signal_callback_to_self_name", "_on_{signal_name}"); } ConnectionsDock::~ConnectionsDock() { diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index e37246e7a0..fcfc501386 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -47,7 +47,6 @@ #include "scene/gui/tree.h" class ConnectDialogBinds; -class EditorUndoRedoManager; class ConnectDialog : public ConfirmationDialog { GDCLASS(ConnectDialog, ConfirmationDialog); @@ -112,6 +111,7 @@ private: LineEdit *dst_method = nullptr; ConnectDialogBinds *cdbinds = nullptr; bool edit_mode = false; + bool first_popup = true; NodePath dst_path; VBoxContainer *vbc_right = nullptr; @@ -143,6 +143,7 @@ protected: static void _bind_methods(); public: + static StringName generate_method_callback_name(Node *p_source, String p_signal_name, Node *p_target); Node *get_source() const; StringName get_signal_name() const; NodePath get_dst_path() const; @@ -195,7 +196,6 @@ class ConnectionsDock : public VBoxContainer { Button *connect_button = nullptr; PopupMenu *signal_menu = nullptr; PopupMenu *slot_menu = nullptr; - Ref<EditorUndoRedoManager> undo_redo; LineEdit *search_box = nullptr; HashMap<StringName, HashMap<StringName, String>> descr_cache; @@ -210,13 +210,16 @@ class ConnectionsDock : public VBoxContainer { void _tree_item_selected(); void _tree_item_activated(); bool _is_item_signal(TreeItem &p_item); + bool _is_connection_inherited(Connection &p_connection); void _open_connection_dialog(TreeItem &p_item); void _open_connection_dialog(ConnectDialog::ConnectionData p_cd); void _go_to_script(TreeItem &p_item); void _handle_signal_menu_option(int p_option); + void _signal_menu_about_to_popup(); void _handle_slot_menu_option(int p_option); + void _slot_menu_about_to_popup(); void _rmb_pressed(Vector2 p_position, MouseButton p_button); void _close(); @@ -226,7 +229,6 @@ protected: static void _bind_methods(); public: - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); void set_node(Node *p_node); void update_tree(); diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 3e72c6211d..785476d75b 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -126,10 +126,6 @@ bool CreateDialog::_should_hide_type(const String &p_type) const { return true; // Do not show editor nodes. } - if (p_type == base_type && !EditorNode::get_editor_data().get_custom_types().has(p_type)) { - return true; // Root is already added. - } - if (ClassDB::class_exists(p_type)) { if (!ClassDB::can_instantiate(p_type) || ClassDB::is_virtual(p_type)) { return true; // Can't create abstract or virtual class. @@ -217,18 +213,18 @@ void CreateDialog::_add_type(const String &p_type, const TypeCategory p_type_cat inherited_type = TypeCategory::CPP_TYPE; } else if (p_type_category == TypeCategory::PATH_TYPE) { ERR_FAIL_COND(!ResourceLoader::exists(p_type, "Script")); - Ref<Script> script = ResourceLoader::load(p_type, "Script"); - ERR_FAIL_COND(script.is_null()); + Ref<Script> scr = ResourceLoader::load(p_type, "Script"); + ERR_FAIL_COND(scr.is_null()); - Ref<Script> base = script->get_base_script(); + Ref<Script> base = scr->get_base_script(); if (base.is_null()) { String extends; - script->get_language()->get_global_class_name(script->get_path(), &extends); + scr->get_language()->get_global_class_name(scr->get_path(), &extends); inherits = extends; inherited_type = TypeCategory::CPP_TYPE; } else { - inherits = script->get_language()->get_global_class_name(base->get_path()); + inherits = scr->get_language()->get_global_class_name(base->get_path()); if (inherits.is_empty()) { inherits = base->get_path(); inherited_type = TypeCategory::PATH_TYPE; @@ -236,18 +232,18 @@ void CreateDialog::_add_type(const String &p_type, const TypeCategory p_type_cat } } else { if (ScriptServer::is_global_class(p_type)) { - Ref<Script> script = EditorNode::get_editor_data().script_class_load_script(p_type); - ERR_FAIL_COND(script.is_null()); + Ref<Script> scr = EditorNode::get_editor_data().script_class_load_script(p_type); + ERR_FAIL_COND(scr.is_null()); - Ref<Script> base = script->get_base_script(); + Ref<Script> base = scr->get_base_script(); if (base.is_null()) { String extends; - script->get_language()->get_global_class_name(script->get_path(), &extends); + scr->get_language()->get_global_class_name(scr->get_path(), &extends); inherits = extends; inherited_type = TypeCategory::CPP_TYPE; } else { - inherits = script->get_language()->get_global_class_name(base->get_path()); + inherits = scr->get_language()->get_global_class_name(base->get_path()); if (inherits.is_empty()) { inherits = base->get_path(); inherited_type = TypeCategory::PATH_TYPE; @@ -288,12 +284,12 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String bool can_instantiate = (p_type_category == TypeCategory::CPP_TYPE && ClassDB::can_instantiate(p_type)) || p_type_category == TypeCategory::OTHER_TYPE; - if (!can_instantiate) { - r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + if (can_instantiate && !ClassDB::is_virtual(p_type)) { + r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback)); + } else { r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, "NodeDisabled")); + r_item->set_custom_color(0, search_options->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); r_item->set_selectable(0, false); - } else { - r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback)); } bool is_deprecated = EditorHelp::get_doc_data()->class_list[p_type].is_deprecated; @@ -311,7 +307,7 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String // Don't collapse the root node or an abstract node on the first tree level. bool should_collapse = p_type != base_type && (r_item->get_parent()->get_text(0) != base_type || can_instantiate); - if (should_collapse && bool(EditorSettings::get_singleton()->get("docks/scene_tree/start_create_dialog_fully_expanded"))) { + if (should_collapse && bool(EDITOR_GET("docks/scene_tree/start_create_dialog_fully_expanded"))) { should_collapse = false; // Collapse all nodes anyway. } r_item->set_collapsed(should_collapse); @@ -343,6 +339,11 @@ String CreateDialog::_top_result(const Vector<String> p_candidates, const String } float CreateDialog::_score_type(const String &p_type, const String &p_search) const { + if (p_type == p_search) { + // Always favor an exact match (case-sensitive), since clicking a favorite will set the search text to the type. + return 1.0f; + } + float inverse_length = 1.f / float(p_type.length()); // Favor types where search term is a substring close to the start of the type. @@ -351,13 +352,13 @@ float CreateDialog::_score_type(const String &p_type, const String &p_search) co float score = (pos > -1) ? 1.0f - w * MIN(1, 3 * pos * inverse_length) : MAX(0.f, .9f - w); // Favor shorter items: they resemble the search term more. - w = 0.1f; - score *= (1 - w) + w * (p_search.length() * inverse_length); + w = 0.9f; + score *= (1 - w) + w * MIN(1.0f, p_search.length() * inverse_length); - score *= _is_type_preferred(p_type) ? 1.0f : 0.8f; + score *= _is_type_preferred(p_type) ? 1.0f : 0.9f; // Add score for being a favorite type. - score *= (favorite_list.find(p_type) > -1) ? 1.0f : 0.7f; + score *= (favorite_list.find(p_type) > -1) ? 1.0f : 0.8f; // Look through at most 5 recent items bool in_recent = false; @@ -367,7 +368,7 @@ float CreateDialog::_score_type(const String &p_type, const String &p_search) co break; } } - score *= in_recent ? 1.0f : 0.8f; + score *= in_recent ? 1.0f : 0.9f; return score; } @@ -500,7 +501,7 @@ String CreateDialog::get_selected_type() { return selected->get_text(0); } -Variant CreateDialog::instance_selected() { +Variant CreateDialog::instantiate_selected() { TreeItem *selected = search_options->get_selected(); if (!selected) { @@ -518,7 +519,7 @@ Variant CreateDialog::instance_selected() { n->set_name(custom); } } else { - obj = EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom); + obj = EditorNode::get_editor_data().instantiate_custom_type(selected->get_text(0), custom); } } else { obj = ClassDB::instantiate(selected->get_text(0)); @@ -751,10 +752,7 @@ CreateDialog::CreateDialog() { favorites->connect("cell_selected", callable_mp(this, &CreateDialog::_favorite_selected)); favorites->connect("item_activated", callable_mp(this, &CreateDialog::_favorite_activated)); favorites->add_theme_constant_override("draw_guides", 1); -#ifndef _MSC_VER -#warning cannot forward drag data to a non control, must be fixed -#endif - //favorites->set_drag_forwarding(this); + favorites->set_drag_forwarding(this); fav_vb->add_margin_child(TTR("Favorites:"), favorites, true); VBoxContainer *rec_vb = memnew(VBoxContainer); diff --git a/editor/create_dialog.h b/editor/create_dialog.h index f2e741624f..961538d8b7 100644 --- a/editor/create_dialog.h +++ b/editor/create_dialog.h @@ -110,7 +110,7 @@ protected: void _save_and_update_favorite_list(); public: - Variant instance_selected(); + Variant instantiate_selected(); String get_selected_type(); void set_base_type(const String &p_base) { base_type = p_base; } diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp index 4c445eb766..ae8752eb6d 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp @@ -656,7 +656,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { bool DebugAdapterProtocol::process_message(const String &p_text) { JSON json; - ERR_FAIL_COND_V_MSG(json.parse(p_text) != OK, true, "Mal-formed message!"); + ERR_FAIL_COND_V_MSG(json.parse(p_text) != OK, true, "Malformed message!"); Dictionary params = json.get_data(); bool completed = true; @@ -921,11 +921,11 @@ void DebugAdapterProtocol::on_debug_stack_frame_vars(const int &p_size) { ERR_FAIL_COND(!stackframe_list.has(frame)); List<int> scope_ids = stackframe_list.find(frame)->value; for (List<int>::Element *E = scope_ids.front(); E; E = E->next()) { - int variable_id = E->get(); - if (variable_list.has(variable_id)) { - variable_list.find(variable_id)->value.clear(); + int var_id = E->get(); + if (variable_list.has(var_id)) { + variable_list.find(var_id)->value.clear(); } else { - variable_list.insert(variable_id, Array()); + variable_list.insert(var_id, Array()); } } } @@ -941,7 +941,7 @@ void DebugAdapterProtocol::on_debug_stack_frame_var(const Array &p_data) { List<int> scope_ids = stackframe_list.find(frame)->value; ERR_FAIL_COND(scope_ids.size() != 3); ERR_FAIL_INDEX(stack_var.type, 3); - int variable_id = scope_ids[stack_var.type]; + int var_id = scope_ids[stack_var.type]; DAP::Variable variable; @@ -950,7 +950,7 @@ void DebugAdapterProtocol::on_debug_stack_frame_var(const Array &p_data) { variable.type = Variant::get_type_name(stack_var.value.get_type()); variable.variablesReference = parse_variant(stack_var.value); - variable_list.find(variable_id)->value.push_back(variable.to_json()); + variable_list.find(var_id)->value.push_back(variable.to_json()); _remaining_vars--; } diff --git a/editor/debugger/debug_adapter/debug_adapter_server.cpp b/editor/debugger/debug_adapter/debug_adapter_server.cpp index 41e6b1f308..2e2361889d 100644 --- a/editor/debugger/debug_adapter/debug_adapter_server.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_server.cpp @@ -62,12 +62,12 @@ void DebugAdapterServer::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - protocol._request_timeout = EditorSettings::get_singleton()->get("network/debug_adapter/request_timeout"); - protocol._sync_breakpoints = EditorSettings::get_singleton()->get("network/debug_adapter/sync_breakpoints"); - int remote_port = (int)_EDITOR_GET("network/debug_adapter/remote_port"); - if (remote_port != this->remote_port) { - this->stop(); - this->start(); + protocol._request_timeout = EDITOR_GET("network/debug_adapter/request_timeout"); + protocol._sync_breakpoints = EDITOR_GET("network/debug_adapter/sync_breakpoints"); + int port = (int)_EDITOR_GET("network/debug_adapter/remote_port"); + if (port != remote_port) { + stop(); + start(); } } break; } diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp index 7ea6cedd2b..c64f23aba0 100644 --- a/editor/debugger/editor_debugger_inspector.cpp +++ b/editor/debugger/editor_debugger_inspector.cpp @@ -166,11 +166,11 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) { if (pinfo.hint_string == "Script") { if (debug_obj->get_script() != var) { debug_obj->set_script(Ref<RefCounted>()); - Ref<Script> script(var); - if (!script.is_null()) { - ScriptInstance *script_instance = script->placeholder_instance_create(debug_obj); - if (script_instance) { - debug_obj->set_script_and_instance(var, script_instance); + Ref<Script> scr(var); + if (!scr.is_null()) { + ScriptInstance *scr_instance = scr->placeholder_instance_create(debug_obj); + if (scr_instance) { + debug_obj->set_script_and_instance(var, scr_instance); } } } @@ -230,7 +230,7 @@ void EditorDebuggerInspector::add_stack_variable(const Array &p_array) { Variant v = var.value; PropertyHint h = PROPERTY_HINT_NONE; - String hs = String(); + String hs; if (v.get_type() == Variant::OBJECT) { v = Object::cast_to<EncodedObjectAsID>(v)->get_object_id(); diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 9fd7fa578f..610f467faa 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -35,6 +35,8 @@ #include "editor/debugger/script_editor_debugger.h" #include "editor/editor_log.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" +#include "editor/inspector_dock.h" #include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/scene_tree_dock.h" @@ -77,6 +79,7 @@ EditorDebuggerNode::EditorDebuggerNode() { remote_scene_tree = memnew(EditorDebuggerTree); remote_scene_tree->connect("object_selected", callable_mp(this, &EditorDebuggerNode::_remote_object_requested)); remote_scene_tree->connect("save_node", callable_mp(this, &EditorDebuggerNode::_save_node_requested)); + remote_scene_tree->connect("button_clicked", callable_mp(this, &EditorDebuggerNode::_remote_tree_button_pressed)); SceneTreeDock::get_singleton()->add_remote_tree_editor(remote_scene_tree); SceneTreeDock::get_singleton()->connect("remote_tree_selected", callable_mp(this, &EditorDebuggerNode::request_remote_tree)); @@ -118,8 +121,8 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { } if (!debugger_plugins.is_empty()) { - for (const Ref<Script> &i : debugger_plugins) { - node->add_debugger_plugin(i); + for (Ref<EditorDebuggerPlugin> plugin : debugger_plugins) { + plugin->create_session(node); } } @@ -166,7 +169,7 @@ void EditorDebuggerNode::_text_editor_stack_goto(const ScriptEditorDebugger *p_d void EditorDebuggerNode::_bind_methods() { // LiveDebug. ClassDB::bind_method("live_debug_create_node", &EditorDebuggerNode::live_debug_create_node); - ClassDB::bind_method("live_debug_instance_node", &EditorDebuggerNode::live_debug_instance_node); + ClassDB::bind_method("live_debug_instantiate_node", &EditorDebuggerNode::live_debug_instantiate_node); ClassDB::bind_method("live_debug_remove_node", &EditorDebuggerNode::live_debug_remove_node); ClassDB::bind_method("live_debug_remove_and_keep_node", &EditorDebuggerNode::live_debug_remove_and_keep_node); ClassDB::bind_method("live_debug_restore_node", &EditorDebuggerNode::live_debug_restore_node); @@ -206,9 +209,32 @@ String EditorDebuggerNode::get_server_uri() const { return server->get_uri(); } +void EditorDebuggerNode::set_keep_open(bool p_keep_open) { + keep_open = p_keep_open; + if (keep_open) { + if (server.is_null() || !server->is_active()) { + start(); + } + } else { + bool found = false; + _for_all(tabs, [&](ScriptEditorDebugger *p_debugger) { + if (p_debugger->is_session_active()) { + found = true; + } + }); + if (!found) { + stop(); + } + } +} + Error EditorDebuggerNode::start(const String &p_uri) { - stop(); ERR_FAIL_COND_V(p_uri.find("://") < 0, ERR_INVALID_PARAMETER); + if (keep_open && current_uri == p_uri && server.is_valid()) { + return OK; + } + stop(true); + current_uri = p_uri; if (EDITOR_GET("run/output/always_open_output_on_play")) { EditorNode::get_singleton()->make_bottom_panel_item_visible(EditorNode::get_log()); } else { @@ -224,10 +250,20 @@ Error EditorDebuggerNode::start(const String &p_uri) { return OK; } -void EditorDebuggerNode::stop() { +void EditorDebuggerNode::stop(bool p_force) { + if (keep_open && !p_force) { + return; + } + current_uri.clear(); if (server.is_valid()) { server->stop(); EditorNode::get_log()->add_message("--- Debugging process stopped ---", EditorLog::MSG_TYPE_EDITOR); + + if (EditorNode::get_singleton()->is_movie_maker_enabled()) { + // Request attention in case the user was doing something else when movie recording is finished. + DisplayServer::get_singleton()->window_request_attention(); + } + server.unref(); } // Also close all debugging sessions. @@ -237,11 +273,6 @@ void EditorDebuggerNode::stop() { } }); _break_state_changed(); - if (hide_on_stop) { - if (is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); - } - } breakpoints.clear(); set_process(false); } @@ -277,7 +308,7 @@ void EditorDebuggerNode::_notification(int p_what) { // Remote scene tree update remote_scene_tree_timeout -= get_process_delta_time(); if (remote_scene_tree_timeout < 0) { - remote_scene_tree_timeout = EditorSettings::get_singleton()->get("debugger/remote_scene_tree_refresh_interval"); + remote_scene_tree_timeout = EDITOR_GET("debugger/remote_scene_tree_refresh_interval"); if (remote_scene_tree->is_visible_in_tree()) { get_current_debugger()->request_remote_tree(); } @@ -286,7 +317,7 @@ void EditorDebuggerNode::_notification(int p_what) { // Remote inspector update inspect_edited_object_timeout -= get_process_delta_time(); if (inspect_edited_object_timeout < 0) { - inspect_edited_object_timeout = EditorSettings::get_singleton()->get("debugger/remote_inspect_refresh_interval"); + inspect_edited_object_timeout = EDITOR_GET("debugger/remote_inspect_refresh_interval"); if (EditorDebuggerRemoteObject *obj = get_inspected_remote_object()) { get_current_debugger()->request_remote_object(obj->remote_object_id); } @@ -313,7 +344,7 @@ void EditorDebuggerNode::_notification(int p_what) { EditorNode::get_singleton()->get_pause_button()->set_disabled(false); // Switch to remote tree view if so desired. - auto_switch_remote_scene_tree = (bool)EditorSettings::get_singleton()->get("debugger/auto_switch_to_remote_scene_tree"); + auto_switch_remote_scene_tree = (bool)EDITOR_GET("debugger/auto_switch_to_remote_scene_tree"); if (auto_switch_remote_scene_tree) { SceneTreeDock::get_singleton()->show_remote_tree(); } @@ -421,7 +452,6 @@ void EditorDebuggerNode::set_script_debug_button(MenuButton *p_button) { p->add_shortcut(ED_GET_SHORTCUT("debugger/break"), DEBUG_BREAK); p->add_shortcut(ED_GET_SHORTCUT("debugger/continue"), DEBUG_CONTINUE); p->add_separator(); - p->add_check_shortcut(ED_GET_SHORTCUT("debugger/keep_debugger_open"), DEBUG_KEEP_DEBUGGER_OPEN); p->add_check_shortcut(ED_GET_SHORTCUT("debugger/debug_with_external_editor"), DEBUG_WITH_EXTERNAL_EDITOR); p->connect("id_pressed", callable_mp(this, &EditorDebuggerNode::_menu_option)); @@ -461,12 +491,6 @@ void EditorDebuggerNode::_menu_option(int p_id) { case DEBUG_CONTINUE: { debug_continue(); } break; - case DEBUG_KEEP_DEBUGGER_OPEN: { - bool ischecked = script_menu->get_popup()->is_item_checked(script_menu->get_popup()->get_item_index(DEBUG_KEEP_DEBUGGER_OPEN)); - hide_on_stop = ischecked; - script_menu->get_popup()->set_item_checked(script_menu->get_popup()->get_item_index(DEBUG_KEEP_DEBUGGER_OPEN), !ischecked); - EditorSettings::get_singleton()->set_project_metadata("debug_options", "keep_debugger_open", !ischecked); - } break; case DEBUG_WITH_EXTERNAL_EDITOR: { bool ischecked = script_menu->get_popup()->is_item_checked(script_menu->get_popup()->get_item_index(DEBUG_WITH_EXTERNAL_EDITOR)); debug_with_external_editor = !ischecked; @@ -477,13 +501,7 @@ void EditorDebuggerNode::_menu_option(int p_id) { } void EditorDebuggerNode::_update_debug_options() { - bool keep_debugger_open = EditorSettings::get_singleton()->get_project_metadata("debug_options", "keep_debugger_open", false); - bool debug_with_external_editor = EditorSettings::get_singleton()->get_project_metadata("debug_options", "debug_with_external_editor", false); - - if (keep_debugger_open) { - _menu_option(DEBUG_KEEP_DEBUGGER_OPEN); - } - if (debug_with_external_editor) { + if (EditorSettings::get_singleton()->get_project_metadata("debug_options", "debug_with_external_editor", false).operator bool()) { _menu_option(DEBUG_WITH_EXTERNAL_EDITOR); } } @@ -576,6 +594,24 @@ void EditorDebuggerNode::_remote_tree_updated(int p_debugger) { remote_scene_tree->update_scene_tree(get_current_debugger()->get_remote_tree(), p_debugger); } +void EditorDebuggerNode::_remote_tree_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button) { + if (p_button != MouseButton::LEFT) { + return; + } + + TreeItem *item = Object::cast_to<TreeItem>(p_item); + ERR_FAIL_COND(!item); + + if (p_id == EditorDebuggerTree::BUTTON_SUBSCENE) { + remote_scene_tree->emit_signal(SNAME("open"), item->get_meta("scene_file_path")); + } else if (p_id == EditorDebuggerTree::BUTTON_VISIBILITY) { + ObjectID obj_id = item->get_metadata(0); + ERR_FAIL_COND(obj_id.is_null()); + get_current_debugger()->update_remote_object(obj_id, "visible", !item->get_meta("visible")); + get_current_debugger()->request_remote_tree(); + } +} + void EditorDebuggerNode::_remote_object_updated(ObjectID p_id, int p_debugger) { if (p_debugger != tabs->get_current_tab()) { return; @@ -654,9 +690,9 @@ void EditorDebuggerNode::live_debug_create_node(const NodePath &p_parent, const }); } -void EditorDebuggerNode::live_debug_instance_node(const NodePath &p_parent, const String &p_path, const String &p_name) { +void EditorDebuggerNode::live_debug_instantiate_node(const NodePath &p_parent, const String &p_path, const String &p_name) { _for_all(tabs, [&](ScriptEditorDebugger *dbg) { - dbg->live_debug_instance_node(p_parent, p_path, p_name); + dbg->live_debug_instantiate_node(p_parent, p_path, p_name); }); } @@ -701,22 +737,36 @@ EditorDebuggerNode::CameraOverride EditorDebuggerNode::get_camera_override() { return camera_override; } -void EditorDebuggerNode::add_debugger_plugin(const Ref<Script> &p_script) { - ERR_FAIL_COND_MSG(debugger_plugins.has(p_script), "Debugger plugin already exists."); - ERR_FAIL_COND_MSG(p_script.is_null(), "Debugger plugin script is null"); - ERR_FAIL_COND_MSG(p_script->get_instance_base_type() == StringName(), "Debugger plugin script has error."); - ERR_FAIL_COND_MSG(String(p_script->get_instance_base_type()) != "EditorDebuggerPlugin", "Base type of debugger plugin is not 'EditorDebuggerPlugin'."); - ERR_FAIL_COND_MSG(!p_script->is_tool(), "Debugger plugin script is not in tool mode."); - debugger_plugins.insert(p_script); +void EditorDebuggerNode::add_debugger_plugin(const Ref<EditorDebuggerPlugin> &p_plugin) { + ERR_FAIL_COND_MSG(p_plugin.is_null(), "Debugger plugin is null."); + ERR_FAIL_COND_MSG(debugger_plugins.has(p_plugin), "Debugger plugin already exists."); + debugger_plugins.insert(p_plugin); + + Ref<EditorDebuggerPlugin> plugin = p_plugin; for (int i = 0; get_debugger(i); i++) { - get_debugger(i)->add_debugger_plugin(p_script); + plugin->create_session(get_debugger(i)); } } -void EditorDebuggerNode::remove_debugger_plugin(const Ref<Script> &p_script) { - ERR_FAIL_COND_MSG(!debugger_plugins.has(p_script), "Debugger plugin doesn't exists."); - debugger_plugins.erase(p_script); - for (int i = 0; get_debugger(i); i++) { - get_debugger(i)->remove_debugger_plugin(p_script); +void EditorDebuggerNode::remove_debugger_plugin(const Ref<EditorDebuggerPlugin> &p_plugin) { + ERR_FAIL_COND_MSG(p_plugin.is_null(), "Debugger plugin is null."); + ERR_FAIL_COND_MSG(!debugger_plugins.has(p_plugin), "Debugger plugin doesn't exists."); + debugger_plugins.erase(p_plugin); + Ref<EditorDebuggerPlugin>(p_plugin)->clear(); +} + +bool EditorDebuggerNode::plugins_capture(ScriptEditorDebugger *p_debugger, const String &p_message, const Array &p_data) { + int session_index = tabs->get_tab_idx_from_control(p_debugger); + ERR_FAIL_COND_V(session_index < 0, false); + int colon_index = p_message.find_char(':'); + ERR_FAIL_COND_V_MSG(colon_index < 1, false, "Invalid message received."); + + const String cap = p_message.substr(0, colon_index); + bool parsed = false; + for (Ref<EditorDebuggerPlugin> plugin : debugger_plugins) { + if (plugin->has_capture(cap)) { + parsed |= plugin->capture(p_message, p_data, session_index); + } } + return parsed; } diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h index e79e60b180..030f4c7d12 100644 --- a/editor/debugger/editor_debugger_node.h +++ b/editor/debugger/editor_debugger_node.h @@ -36,6 +36,7 @@ class Button; class DebugAdapterParser; +class EditorDebuggerPlugin; class EditorDebuggerTree; class EditorDebuggerRemoteObject; class MenuButton; @@ -62,7 +63,6 @@ private: DEBUG_STEP, DEBUG_BREAK, DEBUG_CONTINUE, - DEBUG_KEEP_DEBUGGER_OPEN, DEBUG_WITH_EXTERNAL_EDITOR, }; @@ -109,11 +109,13 @@ private: float remote_scene_tree_timeout = 0.0; bool auto_switch_remote_scene_tree = false; bool debug_with_external_editor = false; - bool hide_on_stop = true; + bool keep_open = false; + String current_uri; + CameraOverride camera_override = OVERRIDE_NONE; HashMap<Breakpoint, bool, Breakpoint> breakpoints; - HashSet<Ref<Script>> debugger_plugins; + HashSet<Ref<EditorDebuggerPlugin>> debugger_plugins; ScriptEditorDebugger *_add_debugger(); EditorDebuggerRemoteObject *get_inspected_remote_object(); @@ -129,6 +131,7 @@ protected: void _debugger_wants_stop(int p_id); void _debugger_changed(int p_tab); void _remote_tree_updated(int p_debugger); + void _remote_tree_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button); void _remote_object_updated(ObjectID p_id, int p_debugger); void _remote_object_property_updated(ObjectID p_id, const String &p_property, int p_debugger); void _remote_object_requested(ObjectID p_id, int p_debugger); @@ -189,7 +192,7 @@ public: void set_live_debugging(bool p_enabled); void update_live_edit_root(); void live_debug_create_node(const NodePath &p_parent, const String &p_type, const String &p_name); - void live_debug_instance_node(const NodePath &p_parent, const String &p_path, const String &p_name); + void live_debug_instantiate_node(const NodePath &p_parent, const String &p_path, const String &p_name); void live_debug_remove_node(const NodePath &p_at); void live_debug_remove_and_keep_node(const NodePath &p_at, ObjectID p_keep_id); void live_debug_restore_node(ObjectID p_id, const NodePath &p_at, int p_at_pos); @@ -201,11 +204,13 @@ public: String get_server_uri() const; + void set_keep_open(bool p_keep_open); Error start(const String &p_uri = "tcp://"); - void stop(); + void stop(bool p_force = false); - void add_debugger_plugin(const Ref<Script> &p_script); - void remove_debugger_plugin(const Ref<Script> &p_script); + bool plugins_capture(ScriptEditorDebugger *p_debugger, const String &p_message, const Array &p_data); + void add_debugger_plugin(const Ref<EditorDebuggerPlugin> &p_plugin); + void remove_debugger_plugin(const Ref<EditorDebuggerPlugin> &p_plugin); }; #endif // EDITOR_DEBUGGER_NODE_H diff --git a/editor/debugger/editor_debugger_server.cpp b/editor/debugger/editor_debugger_server.cpp index 63390825c6..dba0491cfc 100644 --- a/editor/debugger/editor_debugger_server.cpp +++ b/editor/debugger/editor_debugger_server.cpp @@ -72,8 +72,8 @@ String EditorDebuggerServerTCP::get_uri() const { Error EditorDebuggerServerTCP::start(const String &p_uri) { // Default host and port - String bind_host = (String)EditorSettings::get_singleton()->get("network/debug/remote_host"); - int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); + String bind_host = (String)EDITOR_GET("network/debug/remote_host"); + int bind_port = (int)EDITOR_GET("network/debug/remote_port"); // Optionally override if (!p_uri.is_empty() && p_uri != "tcp://") { diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index 76efcd7190..8b31781c5e 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -34,6 +34,7 @@ #include "editor/editor_node.h" #include "editor/scene_tree_dock.h" #include "scene/debugger/scene_debugger.h" +#include "scene/gui/texture_rect.h" #include "scene/resources/packed_scene.h" #include "servers/display_server.h" @@ -65,6 +66,7 @@ void EditorDebuggerTree::_notification(int p_what) { void EditorDebuggerTree::_bind_methods() { ADD_SIGNAL(MethodInfo("object_selected", PropertyInfo(Variant::INT, "object_id"), PropertyInfo(Variant::INT, "debugger"))); ADD_SIGNAL(MethodInfo("save_node", PropertyInfo(Variant::INT, "object_id"), PropertyInfo(Variant::STRING, "filename"), PropertyInfo(Variant::INT, "debugger"))); + ADD_SIGNAL(MethodInfo("open")); } void EditorDebuggerTree::_scene_tree_selected() { @@ -162,7 +164,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int } item->set_metadata(0, node.id); - // Set current item as collapsed if necessary (root is never collapsed) + // Set current item as collapsed if necessary (root is never collapsed). if (parent) { if (!unfold_cache.has(node.id)) { item->set_collapsed(true); @@ -178,7 +180,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int } } else { // Must use path if (last_path == _get_path(item)) { - updating_scene_tree = false; // Force emission of new selection + updating_scene_tree = false; // Force emission of new selection. item->select(0); if (filter_changed) { scroll_item = item; @@ -187,6 +189,33 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int } } + // Add buttons. + const Color remote_button_color = Color(1, 1, 1, 0.8); + if (!node.scene_file_path.is_empty()) { + String node_scene_file_path = node.scene_file_path; + Ref<Texture2D> button_icon = get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")); + String tooltip = vformat(TTR("This node has been instantiated from a PackedScene file:\n%s\nClick to open the original file in the Editor."), node_scene_file_path); + + item->set_meta("scene_file_path", node_scene_file_path); + item->add_button(0, button_icon, BUTTON_SUBSCENE, false, tooltip); + item->set_button_color(0, item->get_button_count(0) - 1, remote_button_color); + } + + if (node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_HAS_VISIBLE_METHOD) { + bool node_visible = node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_VISIBLE; + bool node_visible_in_tree = node.view_flags & SceneDebuggerTree::RemoteNode::VIEW_VISIBLE_IN_TREE; + Ref<Texture2D> button_icon = get_theme_icon(node_visible ? SNAME("GuiVisibilityVisible") : SNAME("GuiVisibilityHidden"), SNAME("EditorIcons")); + String tooltip = TTR("Toggle Visibility"); + + item->set_meta("visible", node_visible); + item->add_button(0, button_icon, BUTTON_VISIBILITY, false, tooltip); + if (ClassDB::is_parent_class(node.type_name, "CanvasItem") || ClassDB::is_parent_class(node.type_name, "Node3D")) { + item->set_button_color(0, item->get_button_count(0) - 1, node_visible_in_tree ? remote_button_color : Color(1, 1, 1, 0.6)); + } else { + item->set_button_color(0, item->get_button_count(0) - 1, remote_button_color); + } + } + // Add in front of the parents stack if children are expected. if (node.child_count) { parents.push_front(Pair<TreeItem *, int>(item, node.child_count)); diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h index 5b2df8abd5..6d590cdb7a 100644 --- a/editor/debugger/editor_debugger_tree.h +++ b/editor/debugger/editor_debugger_tree.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene/gui/tree.h" - #ifndef EDITOR_DEBUGGER_TREE_H #define EDITOR_DEBUGGER_TREE_H +#include "scene/gui/tree.h" + class SceneDebuggerTree; class EditorFileDialog; @@ -65,6 +65,11 @@ protected: void _notification(int p_what); public: + enum Button { + BUTTON_SUBSCENE = 0, + BUTTON_VISIBILITY = 1, + }; + virtual Variant get_drag_data(const Point2 &p_point) override; String get_selected_path(); diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp deleted file mode 100644 index 8c18eba71d..0000000000 --- a/editor/debugger/editor_network_profiler.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/*************************************************************************/ -/* editor_network_profiler.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "editor_network_profiler.h" - -#include "core/os/os.h" -#include "editor/editor_scale.h" -#include "editor/editor_settings.h" - -void EditorNetworkProfiler::_bind_methods() { - ADD_SIGNAL(MethodInfo("enable_profiling", PropertyInfo(Variant::BOOL, "enable"))); -} - -void EditorNetworkProfiler::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: - case NOTIFICATION_THEME_CHANGED: { - activate->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons"))); - clear_button->set_icon(get_theme_icon(SNAME("Clear"), SNAME("EditorIcons"))); - incoming_bandwidth_text->set_right_icon(get_theme_icon(SNAME("ArrowDown"), SNAME("EditorIcons"))); - outgoing_bandwidth_text->set_right_icon(get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); - - // This needs to be done here to set the faded color when the profiler is first opened - incoming_bandwidth_text->add_theme_color_override("font_uneditable_color", get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5)); - outgoing_bandwidth_text->add_theme_color_override("font_uneditable_color", get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5)); - } break; - } -} - -void EditorNetworkProfiler::_update_frame() { - counters_display->clear(); - - TreeItem *root = counters_display->create_item(); - - for (const KeyValue<ObjectID, SceneDebugger::RPCNodeInfo> &E : nodes_data) { - TreeItem *node = counters_display->create_item(root); - - for (int j = 0; j < counters_display->get_columns(); ++j) { - node->set_text_alignment(j, j > 0 ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT); - } - - node->set_text(0, E.value.node_path); - node->set_text(1, E.value.incoming_rpc == 0 ? "-" : itos(E.value.incoming_rpc)); - node->set_text(2, E.value.outgoing_rpc == 0 ? "-" : itos(E.value.outgoing_rpc)); - } -} - -void EditorNetworkProfiler::_activate_pressed() { - if (activate->is_pressed()) { - activate->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); - activate->set_text(TTR("Stop")); - } else { - activate->set_icon(get_theme_icon(SNAME("Play"), SNAME("EditorIcons"))); - activate->set_text(TTR("Start")); - } - emit_signal(SNAME("enable_profiling"), activate->is_pressed()); -} - -void EditorNetworkProfiler::_clear_pressed() { - nodes_data.clear(); - set_bandwidth(0, 0); - if (frame_delay->is_stopped()) { - frame_delay->set_wait_time(0.1); - frame_delay->start(); - } -} - -void EditorNetworkProfiler::add_node_frame_data(const SceneDebugger::RPCNodeInfo p_frame) { - if (!nodes_data.has(p_frame.node)) { - nodes_data.insert(p_frame.node, p_frame); - } else { - nodes_data[p_frame.node].incoming_rpc += p_frame.incoming_rpc; - nodes_data[p_frame.node].outgoing_rpc += p_frame.outgoing_rpc; - } - - if (frame_delay->is_stopped()) { - frame_delay->set_wait_time(0.1); - frame_delay->start(); - } -} - -void EditorNetworkProfiler::set_bandwidth(int p_incoming, int p_outgoing) { - incoming_bandwidth_text->set_text(vformat(TTR("%s/s"), String::humanize_size(p_incoming))); - outgoing_bandwidth_text->set_text(vformat(TTR("%s/s"), String::humanize_size(p_outgoing))); - - // Make labels more prominent when the bandwidth is greater than 0 to attract user attention - incoming_bandwidth_text->add_theme_color_override( - "font_uneditable_color", - get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, p_incoming > 0 ? 1 : 0.5)); - outgoing_bandwidth_text->add_theme_color_override( - "font_uneditable_color", - get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, p_outgoing > 0 ? 1 : 0.5)); -} - -bool EditorNetworkProfiler::is_profiling() { - return activate->is_pressed(); -} - -EditorNetworkProfiler::EditorNetworkProfiler() { - HBoxContainer *hb = memnew(HBoxContainer); - hb->add_theme_constant_override("separation", 8 * EDSCALE); - add_child(hb); - - activate = memnew(Button); - activate->set_toggle_mode(true); - activate->set_text(TTR("Start")); - activate->connect("pressed", callable_mp(this, &EditorNetworkProfiler::_activate_pressed)); - hb->add_child(activate); - - clear_button = memnew(Button); - clear_button->set_text(TTR("Clear")); - clear_button->connect("pressed", callable_mp(this, &EditorNetworkProfiler::_clear_pressed)); - hb->add_child(clear_button); - - hb->add_spacer(); - - Label *lb = memnew(Label); - lb->set_text(TTR("Down")); - hb->add_child(lb); - - incoming_bandwidth_text = memnew(LineEdit); - incoming_bandwidth_text->set_editable(false); - incoming_bandwidth_text->set_custom_minimum_size(Size2(120, 0) * EDSCALE); - incoming_bandwidth_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); - hb->add_child(incoming_bandwidth_text); - - Control *down_up_spacer = memnew(Control); - down_up_spacer->set_custom_minimum_size(Size2(30, 0) * EDSCALE); - hb->add_child(down_up_spacer); - - lb = memnew(Label); - lb->set_text(TTR("Up")); - hb->add_child(lb); - - outgoing_bandwidth_text = memnew(LineEdit); - outgoing_bandwidth_text->set_editable(false); - outgoing_bandwidth_text->set_custom_minimum_size(Size2(120, 0) * EDSCALE); - outgoing_bandwidth_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); - hb->add_child(outgoing_bandwidth_text); - - // Set initial texts in the incoming/outgoing bandwidth labels - set_bandwidth(0, 0); - - counters_display = memnew(Tree); - counters_display->set_custom_minimum_size(Size2(300, 0) * EDSCALE); - counters_display->set_v_size_flags(SIZE_EXPAND_FILL); - counters_display->set_hide_folding(true); - counters_display->set_hide_root(true); - counters_display->set_columns(3); - counters_display->set_column_titles_visible(true); - counters_display->set_column_title(0, TTR("Node")); - counters_display->set_column_expand(0, true); - counters_display->set_column_clip_content(0, true); - counters_display->set_column_custom_minimum_width(0, 60 * EDSCALE); - counters_display->set_column_title(1, TTR("Incoming RPC")); - counters_display->set_column_expand(1, false); - counters_display->set_column_clip_content(1, true); - counters_display->set_column_custom_minimum_width(1, 120 * EDSCALE); - counters_display->set_column_title(2, TTR("Outgoing RPC")); - counters_display->set_column_expand(2, false); - counters_display->set_column_clip_content(2, true); - counters_display->set_column_custom_minimum_width(2, 120 * EDSCALE); - add_child(counters_display); - - frame_delay = memnew(Timer); - frame_delay->set_wait_time(0.1); - frame_delay->set_one_shot(true); - add_child(frame_delay); - frame_delay->connect("timeout", callable_mp(this, &EditorNetworkProfiler::_update_frame)); -} diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp index 10b50a81e4..071eb583c0 100644 --- a/editor/debugger/editor_performance_profiler.cpp +++ b/editor/debugger/editor_performance_profiler.cpp @@ -234,6 +234,7 @@ TreeItem *EditorPerformanceProfiler::_get_monitor_base(const StringName &p_base_ base->set_editable(0, false); base->set_selectable(0, false); base->set_expand_right(0, true); + base->set_custom_font(0, get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); base_map.insert(p_base_name, base); return base; } @@ -349,12 +350,12 @@ void EditorPerformanceProfiler::update_monitors(const Vector<StringName> &p_name void EditorPerformanceProfiler::add_profile_frame(const Vector<float> &p_values) { for (KeyValue<StringName, Monitor> &E : monitors) { - float data = 0.0f; + float value = 0.0f; if (E.value.frame_index >= 0 && E.value.frame_index < p_values.size()) { - data = p_values[E.value.frame_index]; + value = p_values[E.value.frame_index]; } - E.value.history.push_front(data); - E.value.update_value(data); + E.value.history.push_front(value); + E.value.update_value(value); } marker_frame++; monitor_draw->queue_redraw(); diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index a882275375..35666a5566 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -85,7 +85,7 @@ void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) { } void EditorProfiler::clear() { - int metric_size = EditorSettings::get_singleton()->get("debugger/profiler_frame_history_size"); + int metric_size = EDITOR_GET("debugger/profiler_frame_history_size"); metric_size = CLAMP(metric_size, 60, 10000); frame_metrics.clear(); frame_metrics.resize(metric_size); @@ -308,9 +308,7 @@ void EditorProfiler::_update_plot() { } } - Ref<Image> img; - img.instantiate(); - img->create(w, h, false, Image::FORMAT_RGBA8, graph_image); + Ref<Image> img = Image::create_from_data(w, h, false, Image::FORMAT_RGBA8, graph_image); if (reset_texture) { if (graph_texture.is_null()) { diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 8e7135f1c5..b8bc712ba6 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -92,7 +92,7 @@ void EditorVisualProfiler::add_frame_metric(const Metric &p_metric) { } void EditorVisualProfiler::clear() { - int metric_size = EditorSettings::get_singleton()->get("debugger/profiler_frame_history_size"); + int metric_size = EDITOR_GET("debugger/profiler_frame_history_size"); metric_size = CLAMP(metric_size, 60, 10000); frame_metrics.clear(); frame_metrics.resize(metric_size); @@ -298,9 +298,7 @@ void EditorVisualProfiler::_update_plot() { } } - Ref<Image> img; - img.instantiate(); - img->create(w, h, false, Image::FORMAT_RGBA8, graph_image); + Ref<Image> img = Image::create_from_data(w, h, false, Image::FORMAT_RGBA8, graph_image); if (reset_texture) { if (graph_texture.is_null()) { diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 6bc1536cb9..deca638f3b 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -37,7 +37,6 @@ #include "core/string/ustring.h" #include "core/version.h" #include "editor/debugger/debug_adapter/debug_adapter_protocol.h" -#include "editor/debugger/editor_network_profiler.h" #include "editor/debugger/editor_performance_profiler.h" #include "editor/debugger/editor_profiler.h" #include "editor/debugger/editor_visual_profiler.h" @@ -47,12 +46,15 @@ #include "editor/editor_property_name_processor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/inspector_dock.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "main/performance.h" #include "scene/3d/camera_3d.h" +#include "scene/debugger/scene_debugger.h" #include "scene/gui/dialogs.h" +#include "scene/gui/grid_container.h" #include "scene/gui/label.h" #include "scene/gui/line_edit.h" #include "scene/gui/margin_container.h" @@ -713,17 +715,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da profiler->add_frame_metric(metric, true); } - } else if (p_msg == "multiplayer:rpc") { - SceneDebugger::RPCProfilerFrame frame; - frame.deserialize(p_data); - for (int i = 0; i < frame.infos.size(); i++) { - network_profiler->add_node_frame_data(frame.infos[i]); - } - - } else if (p_msg == "multiplayer:bandwidth") { - ERR_FAIL_COND(p_data.size() < 2); - network_profiler->set_bandwidth(p_data[0], p_data[1]); - } else if (p_msg == "request_quit") { emit_signal(SNAME("stop_requested")); _stop_and_notify(); @@ -741,22 +732,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da int colon_index = p_msg.find_char(':'); ERR_FAIL_COND_MSG(colon_index < 1, "Invalid message received"); - bool parsed = false; - const String cap = p_msg.substr(0, colon_index); - HashMap<StringName, Callable>::Iterator element = captures.find(cap); - if (element) { - Callable &c = element->value; - ERR_FAIL_COND_MSG(c.is_null(), "Invalid callable registered: " + cap); - Variant cmd = p_msg.substr(colon_index + 1), data = p_data; - const Variant *args[2] = { &cmd, &data }; - Variant retval; - Callable::CallError err; - c.callp(args, 2, retval, err); - ERR_FAIL_COND_MSG(err.error != Callable::CallError::CALL_OK, "Error calling 'capture' to callable: " + Variant::get_callable_error_text(c, args, 2, err)); - ERR_FAIL_COND_MSG(retval.get_type() != Variant::BOOL, "Error calling 'capture' to callable: " + String(c) + ". Return type is not bool."); - parsed = retval; - } - + bool parsed = EditorDebuggerNode::get_singleton()->plugins_capture(this, p_msg, p_data); if (!parsed) { WARN_PRINT("unknown message " + p_msg); } @@ -895,9 +871,9 @@ void ScriptEditorDebugger::_clear_execution() { } void ScriptEditorDebugger::_set_breakpoint(const String &p_file, const int &p_line, const bool &p_enabled) { - Ref<Script> script = ResourceLoader::load(p_file); - emit_signal(SNAME("set_breakpoint"), script, p_line - 1, p_enabled); - script.unref(); + Ref<Script> scr = ResourceLoader::load(p_file); + emit_signal(SNAME("set_breakpoint"), scr, p_line - 1, p_enabled); + scr.unref(); } void ScriptEditorDebugger::_clear_breakpoints() { @@ -979,15 +955,11 @@ void ScriptEditorDebugger::stop() { } void ScriptEditorDebugger::_profiler_activate(bool p_enable, int p_type) { - Array data; - data.push_back(p_enable); + Array msg_data; + msg_data.push_back(p_enable); switch (p_type) { - case PROFILER_NETWORK: - _put_msg("profiler:multiplayer", data); - _put_msg("profiler:rpc", data); - break; case PROFILER_VISUAL: - _put_msg("profiler:visual", data); + _put_msg("profiler:visual", msg_data); break; case PROFILER_SCRIPTS_SERVERS: if (p_enable) { @@ -995,11 +967,11 @@ void ScriptEditorDebugger::_profiler_activate(bool p_enable, int p_type) { profiler_signature.clear(); // Add max funcs options to request. Array opts; - int max_funcs = EditorSettings::get_singleton()->get("debugger/profiler_frame_max_functions"); + int max_funcs = EDITOR_GET("debugger/profiler_frame_max_functions"); opts.push_back(CLAMP(max_funcs, 16, 512)); - data.push_back(opts); + msg_data.push_back(opts); } - _put_msg("profiler:servers", data); + _put_msg("profiler:servers", msg_data); break; default: ERR_FAIL_MSG("Invalid profiler type"); @@ -1283,13 +1255,13 @@ void ScriptEditorDebugger::live_debug_create_node(const NodePath &p_parent, cons } } -void ScriptEditorDebugger::live_debug_instance_node(const NodePath &p_parent, const String &p_path, const String &p_name) { +void ScriptEditorDebugger::live_debug_instantiate_node(const NodePath &p_parent, const String &p_path, const String &p_name) { if (live_debug) { Array msg; msg.push_back(p_parent); msg.push_back(p_path); msg.push_back(p_name); - _put_msg("scene:live_instance_node", msg); + _put_msg("scene:live_instantiate_node", msg); } } @@ -1563,8 +1535,22 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { ti = ti->get_parent(); } - // We only need the first child here (C++ source stack trace). + // Find the child with the "C++ Source". + // It's not at a fixed position as "C++ Error" may come first. TreeItem *ci = ti->get_first_child(); + const String cpp_source = "<" + TTR("C++ Source") + ">"; + while (ci) { + if (ci->get_text(0) == cpp_source) { + break; + } + ci = ci->get_next(); + } + + if (!ci) { + WARN_PRINT_ED("No C++ source reference is available for this error."); + return; + } + // Parse back the `file:line @ method()` string. const Vector<String> file_line_number = ci->get_text(1).split("@")[0].strip_edges().split(":"); ERR_FAIL_COND_MSG(file_line_number.size() < 2, "Incorrect C++ source stack trace file:line format (please report)."); @@ -1612,7 +1598,7 @@ void ScriptEditorDebugger::_tab_changed(int p_tab) { void ScriptEditorDebugger::_bind_methods() { ClassDB::bind_method(D_METHOD("live_debug_create_node"), &ScriptEditorDebugger::live_debug_create_node); - ClassDB::bind_method(D_METHOD("live_debug_instance_node"), &ScriptEditorDebugger::live_debug_instance_node); + ClassDB::bind_method(D_METHOD("live_debug_instantiate_node"), &ScriptEditorDebugger::live_debug_instantiate_node); ClassDB::bind_method(D_METHOD("live_debug_remove_node"), &ScriptEditorDebugger::live_debug_remove_node); ClassDB::bind_method(D_METHOD("live_debug_remove_and_keep_node"), &ScriptEditorDebugger::live_debug_remove_and_keep_node); ClassDB::bind_method(D_METHOD("live_debug_restore_node"), &ScriptEditorDebugger::live_debug_restore_node); @@ -1644,41 +1630,25 @@ void ScriptEditorDebugger::_bind_methods() { ADD_SIGNAL(MethodInfo("errors_cleared")); } -void ScriptEditorDebugger::add_debugger_plugin(const Ref<Script> &p_script) { - if (!debugger_plugins.has(p_script)) { - EditorDebuggerPlugin *plugin = memnew(EditorDebuggerPlugin()); - plugin->attach_debugger(this); - plugin->set_script(p_script); - tabs->add_child(plugin); - debugger_plugins.insert(p_script, plugin); - } +void ScriptEditorDebugger::add_debugger_tab(Control *p_control) { + tabs->add_child(p_control); } -void ScriptEditorDebugger::remove_debugger_plugin(const Ref<Script> &p_script) { - if (debugger_plugins.has(p_script)) { - tabs->remove_child(debugger_plugins[p_script]); - debugger_plugins[p_script]->detach_debugger(false); - memdelete(debugger_plugins[p_script]); - debugger_plugins.erase(p_script); - } +void ScriptEditorDebugger::remove_debugger_tab(Control *p_control) { + int idx = tabs->get_tab_idx_from_control(p_control); + ERR_FAIL_COND(idx < 0); + p_control->queue_free(); } void ScriptEditorDebugger::send_message(const String &p_message, const Array &p_args) { _put_msg(p_message, p_args); } -void ScriptEditorDebugger::register_message_capture(const StringName &p_name, const Callable &p_callable) { - ERR_FAIL_COND_MSG(has_capture(p_name), "Capture already registered: " + p_name); - captures.insert(p_name, p_callable); -} - -void ScriptEditorDebugger::unregister_message_capture(const StringName &p_name) { - ERR_FAIL_COND_MSG(!has_capture(p_name), "Capture not registered: " + p_name); - captures.erase(p_name); -} - -bool ScriptEditorDebugger::has_capture(const StringName &p_name) { - return captures.has(p_name); +void ScriptEditorDebugger::toggle_profiler(const String &p_profiler, bool p_enable, const Array &p_data) { + Array msg_data; + msg_data.push_back(p_enable); + msg_data.append_array(p_data); + _put_msg("profiler:" + p_profiler, msg_data); } ScriptEditorDebugger::ScriptEditorDebugger() { @@ -1688,6 +1658,8 @@ ScriptEditorDebugger::ScriptEditorDebugger() { add_child(tabs); + InspectorDock::get_inspector_singleton()->connect("object_id_selected", callable_mp(this, &ScriptEditorDebugger::_remote_object_selected)); + { //debugger VBoxContainer *vbc = memnew(VBoxContainer); vbc->set_name(TTR("Debugger")); @@ -1890,13 +1862,6 @@ ScriptEditorDebugger::ScriptEditorDebugger() { visual_profiler->connect("enable_profiling", callable_mp(this, &ScriptEditorDebugger::_profiler_activate).bind(PROFILER_VISUAL)); } - { //network profiler - network_profiler = memnew(EditorNetworkProfiler); - network_profiler->set_name(TTR("Network Profiler")); - tabs->add_child(network_profiler); - network_profiler->connect("enable_profiling", callable_mp(this, &ScriptEditorDebugger::_profiler_activate).bind(PROFILER_NETWORK)); - } - { //monitors performance_profiler = memnew(EditorPerformanceProfiler); tabs->add_child(performance_profiler); diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h index aa0a50ff03..06bff39053 100644 --- a/editor/debugger/script_editor_debugger.h +++ b/editor/debugger/script_editor_debugger.h @@ -50,7 +50,6 @@ class ItemList; class EditorProfiler; class EditorFileDialog; class EditorVisualProfiler; -class EditorNetworkProfiler; class EditorPerformanceProfiler; class SceneDebuggerTree; class EditorDebuggerPlugin; @@ -72,7 +71,6 @@ private: }; enum ProfilerType { - PROFILER_NETWORK, PROFILER_VISUAL, PROFILER_SCRIPTS_SERVERS }; @@ -151,7 +149,6 @@ private: EditorProfiler *profiler = nullptr; EditorVisualProfiler *visual_profiler = nullptr; - EditorNetworkProfiler *network_profiler = nullptr; EditorPerformanceProfiler *performance_profiler = nullptr; OS::ProcessID remote_pid = 0; @@ -163,10 +160,6 @@ private: EditorDebuggerNode::CameraOverride camera_override; - HashMap<Ref<Script>, EditorDebuggerPlugin *> debugger_plugins; - - HashMap<StringName, Callable> captures; - void _stack_dump_frame_selected(); void _file_selected(const String &p_file); @@ -266,7 +259,7 @@ public: void set_live_debugging(bool p_enable); void live_debug_create_node(const NodePath &p_parent, const String &p_type, const String &p_name); - void live_debug_instance_node(const NodePath &p_parent, const String &p_path, const String &p_name); + void live_debug_instantiate_node(const NodePath &p_parent, const String &p_path, const String &p_name); void live_debug_remove_node(const NodePath &p_at); void live_debug_remove_and_keep_node(const NodePath &p_at, ObjectID p_keep_id); void live_debug_restore_node(ObjectID p_id, const NodePath &p_at, int p_at_pos); @@ -286,14 +279,11 @@ public: virtual Size2 get_minimum_size() const override; - void add_debugger_plugin(const Ref<Script> &p_script); - void remove_debugger_plugin(const Ref<Script> &p_script); + void add_debugger_tab(Control *p_control); + void remove_debugger_tab(Control *p_control); void send_message(const String &p_message, const Array &p_args); - - void register_message_capture(const StringName &p_name, const Callable &p_callable); - void unregister_message_capture(const StringName &p_name); - bool has_capture(const StringName &p_name); + void toggle_profiler(const String &p_profiler, bool p_enable, const Array &p_data); ScriptEditorDebugger(); ~ScriptEditorDebugger(); diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 43961a7ceb..959c4ab92c 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -286,7 +286,11 @@ void DependencyEditorOwners::_list_rmb_clicked(int p_item, const Vector2 &p_pos, file_options->clear(); file_options->reset_size(); if (p_item >= 0) { - file_options->add_item(TTR("Open"), FILE_OPEN); + if (owners->get_selected_items().size() == 1) { + file_options->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open Scene"), FILE_OPEN); + } else { + file_options->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open Scenes"), FILE_OPEN); + } } file_options->set_position(owners->get_screen_position() + p_pos); @@ -307,11 +311,14 @@ void DependencyEditorOwners::_select_file(int p_idx) { void DependencyEditorOwners::_file_option(int p_option) { switch (p_option) { case FILE_OPEN: { - int idx = owners->get_current(); - if (idx < 0 || idx >= owners->get_item_count()) { - break; + PackedInt32Array selected_items = owners->get_selected_items(); + for (int i = 0; i < selected_items.size(); i++) { + int item_idx = selected_items[i]; + if (item_idx < 0 || item_idx >= owners->get_item_count()) { + break; + } + _select_file(item_idx); } - _select_file(idx); } break; } } @@ -362,7 +369,7 @@ DependencyEditorOwners::DependencyEditorOwners() { file_options->connect("id_pressed", callable_mp(this, &DependencyEditorOwners::_file_option)); owners = memnew(ItemList); - owners->set_select_mode(ItemList::SELECT_SINGLE); + owners->set_select_mode(ItemList::SELECT_MULTI); owners->connect("item_clicked", callable_mp(this, &DependencyEditorOwners::_list_rmb_clicked)); owners->connect("item_activated", callable_mp(this, &DependencyEditorOwners::_select_file)); owners->set_allow_rmb_select(true); @@ -423,7 +430,7 @@ void DependencyRemoveDialog::_find_localization_remaps_of_removed_files(Vector<R // Look for dependencies in the translation remaps. if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { - Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); if (remaps.has(path)) { RemovedDependency dep; @@ -537,28 +544,28 @@ void DependencyRemoveDialog::ok_pressed() { // If the file we are deleting for e.g. the main scene, default environment, // or audio bus layout, we must clear its definition in Project Settings. - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("application/config/icon"))) { + if (files_to_delete[i] == String(GLOBAL_GET("application/config/icon"))) { ProjectSettings::get_singleton()->set("application/config/icon", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("application/run/main_scene"))) { + if (files_to_delete[i] == String(GLOBAL_GET("application/run/main_scene"))) { ProjectSettings::get_singleton()->set("application/run/main_scene", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("application/boot_splash/image"))) { + if (files_to_delete[i] == String(GLOBAL_GET("application/boot_splash/image"))) { ProjectSettings::get_singleton()->set("application/boot_splash/image", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("rendering/environment/defaults/default_environment"))) { + if (files_to_delete[i] == String(GLOBAL_GET("rendering/environment/defaults/default_environment"))) { ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"))) { + if (files_to_delete[i] == String(GLOBAL_GET("display/mouse_cursor/custom_image"))) { ProjectSettings::get_singleton()->set("display/mouse_cursor/custom_image", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("gui/theme/custom"))) { + if (files_to_delete[i] == String(GLOBAL_GET("gui/theme/custom"))) { ProjectSettings::get_singleton()->set("gui/theme/custom", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("gui/theme/custom_font"))) { + if (files_to_delete[i] == String(GLOBAL_GET("gui/theme/custom_font"))) { ProjectSettings::get_singleton()->set("gui/theme/custom_font", ""); } - if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"))) { + if (files_to_delete[i] == String(GLOBAL_GET("audio/buses/default_bus_layout"))) { ProjectSettings::get_singleton()->set("audio/buses/default_bus_layout", ""); } @@ -785,14 +792,14 @@ void OrphanResourcesDialog::show() { popup_centered_ratio(0.4); } -void OrphanResourcesDialog::_find_to_delete(TreeItem *p_item, List<String> &paths) { +void OrphanResourcesDialog::_find_to_delete(TreeItem *p_item, List<String> &r_paths) { while (p_item) { if (p_item->get_cell_mode(0) == TreeItem::CELL_MODE_CHECK && p_item->is_checked(0)) { - paths.push_back(p_item->get_metadata(0)); + r_paths.push_back(p_item->get_metadata(0)); } if (p_item->get_first_child()) { - _find_to_delete(p_item->get_first_child(), paths); + _find_to_delete(p_item->get_first_child(), r_paths); } p_item = p_item->get_next(); diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h index 6e39015ec3..7a523457ef 100644 --- a/editor/dependency_editor.h +++ b/editor/dependency_editor.h @@ -165,7 +165,7 @@ class OrphanResourcesDialog : public ConfirmationDialog { bool _fill_owners(EditorFileSystemDirectory *efsd, HashMap<String, int> &refs, TreeItem *p_parent); List<String> paths; - void _find_to_delete(TreeItem *p_item, List<String> &paths); + void _find_to_delete(TreeItem *p_item, List<String> &r_paths); void _delete_confirm(); void _button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button); diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 7d6eb186dc..14a2640e63 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -335,7 +335,7 @@ static Variant get_documentation_default_value(const StringName &p_class_name, c Variant default_value = Variant(); r_default_value_valid = false; - if (ClassDB::can_instantiate(p_class_name)) { + if (ClassDB::can_instantiate(p_class_name) && !ClassDB::is_virtual(p_class_name)) { // Keep this condition in sync with ClassDB::class_get_default_property_value. default_value = ClassDB::class_get_default_property_value(p_class_name, p_property_name, &r_default_value_valid); } else { // Cannot get default value of classes that can't be instantiated diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index aaa5956c17..77697f4de1 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -183,16 +183,16 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { int pp = path.rfind("/"); - TreeItem *parent; + TreeItem *parent_item; if (pp == -1) { - parent = root; + parent_item = root; } else { String ppath = path.substr(0, pp); ERR_CONTINUE(!dir_map.has(ppath)); - parent = dir_map[ppath]; + parent_item = dir_map[ppath]; } - TreeItem *ti = tree->create_item(parent); + TreeItem *ti = tree->create_item(parent_item); ti->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); ti->set_checked(0, true); ti->set_editable(0, true); @@ -284,17 +284,17 @@ void EditorAssetInstaller::ok_pressed() { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); da->make_dir(dirpath); } else { - Vector<uint8_t> data; - data.resize(info.uncompressed_size); + Vector<uint8_t> uncomp_data; + uncomp_data.resize(info.uncompressed_size); //read unzOpenCurrentFile(pkg); - unzReadCurrentFile(pkg, data.ptrw(), data.size()); + unzReadCurrentFile(pkg, uncomp_data.ptrw(), uncomp_data.size()); unzCloseCurrentFile(pkg); Ref<FileAccess> f = FileAccess::open(path, FileAccess::WRITE); if (f.is_valid()) { - f->store_buffer(data.ptr(), data.size()); + f->store_buffer(uncomp_data.ptr(), uncomp_data.size()); } else { failed_files.push_back(path); } diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 09dce869c9..a040d918df 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -40,6 +40,7 @@ #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "filesystem_dock.h" +#include "scene/gui/separator.h" #include "scene/resources/font.h" #include "servers/audio_server.h" @@ -338,7 +339,7 @@ float EditorAudioBus::_normalized_volume_to_scaled_db(float normalized) { * values to relative decibal values. * One formula is an exponential graph which intends to counteract * the logarithmic nature of human hearing. This is an approximation - * of the behaviour of a 'logarithmic potentiometer' found on most + * of the behavior of a 'logarithmic potentiometer' found on most * musical instruments and also emulated in popular software. * The other two equations are hand-tuned linear tapers that intend to * try to ease the exponential equation in areas where it makes sense.*/ @@ -919,10 +920,10 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { effect_options = memnew(PopupMenu); effect_options->connect("index_pressed", callable_mp(this, &EditorAudioBus::_effect_add)); add_child(effect_options); - List<StringName> effects; - ClassDB::get_inheriters_from_class("AudioEffect", &effects); - effects.sort_custom<StringName::AlphCompare>(); - for (const StringName &E : effects) { + List<StringName> effect_list; + ClassDB::get_inheriters_from_class("AudioEffect", &effect_list); + effect_list.sort_custom<StringName::AlphCompare>(); + for (const StringName &E : effect_list) { if (!ClassDB::can_instantiate(E) || ClassDB::is_virtual(E)) { continue; } @@ -1036,7 +1037,7 @@ void EditorAudioBuses::_notification(int p_what) { case NOTIFICATION_DRAG_END: { if (drop_end) { - drop_end->queue_delete(); + drop_end->queue_free(); drop_end = nullptr; } } break; @@ -1208,7 +1209,7 @@ void EditorAudioBuses::_load_layout() { } void EditorAudioBuses::_load_default_layout() { - String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"); + String layout_path = GLOBAL_GET("audio/buses/default_bus_layout"); Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); if (state.is_null()) { @@ -1273,7 +1274,7 @@ EditorAudioBuses::EditorAudioBuses() { add_child(top_hb); file = memnew(Label); - String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"); + String layout_path = GLOBAL_GET("audio/buses/default_bus_layout"); file->set_text(String(TTR("Layout:")) + " " + layout_path.get_file()); file->set_clip_text(true); file->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1328,7 +1329,7 @@ EditorAudioBuses::EditorAudioBuses() { set_v_size_flags(SIZE_EXPAND_FILL); - edited_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"); + edited_path = GLOBAL_GET("audio/buses/default_bus_layout"); file_dialog = memnew(EditorFileDialog); List<String> ext; diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h index 436b391ccd..97e94089cc 100644 --- a/editor/editor_audio_buses.h +++ b/editor/editor_audio_buses.h @@ -47,6 +47,7 @@ #include "scene/gui/tree.h" class EditorAudioBuses; +class EditorFileDialog; class EditorAudioBus : public PanelContainer { GDCLASS(EditorAudioBus, PanelContainer); diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 544b6c7141..41b3d45a1f 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -194,7 +194,7 @@ void EditorAutoloadSettings::_autoload_edited() { TreeItem *ti = tree->get_edited(); int column = tree->get_edited_column(); - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (column == 0) { String name = ti->get_text(0); @@ -222,15 +222,15 @@ void EditorAutoloadSettings::_autoload_edited() { name = "autoload/" + name; int order = ProjectSettings::get_singleton()->get_order(selected_autoload); - String path = ProjectSettings::get_singleton()->get(selected_autoload); + String scr_path = GLOBAL_GET(selected_autoload); undo_redo->create_action(TTR("Rename Autoload")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), name, path); + undo_redo->add_do_property(ProjectSettings::get_singleton(), name, scr_path); undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", name, order); undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", selected_autoload); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), selected_autoload, path); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), selected_autoload, scr_path); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", selected_autoload, order); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name); @@ -250,21 +250,21 @@ void EditorAutoloadSettings::_autoload_edited() { String base = "autoload/" + ti->get_text(0); int order = ProjectSettings::get_singleton()->get_order(base); - String path = ProjectSettings::get_singleton()->get(base); + String scr_path = GLOBAL_GET(base); - if (path.begins_with("*")) { - path = path.substr(1, path.length()); + if (scr_path.begins_with("*")) { + scr_path = scr_path.substr(1, scr_path.length()); } // Singleton autoloads are represented with a leading "*" in their path. if (checked) { - path = "*" + path; + scr_path = "*" + scr_path; } undo_redo->create_action(TTR("Toggle Autoload Globals")); - undo_redo->add_do_property(ProjectSettings::get_singleton(), base, path); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), base, ProjectSettings::get_singleton()->get(base)); + undo_redo->add_do_property(ProjectSettings::get_singleton(), base, scr_path); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), base, GLOBAL_GET(base)); undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", base, order); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", base, order); @@ -289,7 +289,7 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu String name = "autoload/" + ti->get_text(0); - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (p_button) { case BUTTON_OPEN: { @@ -337,7 +337,7 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu undo_redo->add_do_property(ProjectSettings::get_singleton(), name, Variant()); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, ProjectSettings::get_singleton()->get(name)); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, GLOBAL_GET(name)); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_persisting", name, true); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", order); @@ -400,27 +400,38 @@ void EditorAutoloadSettings::_autoload_text_changed(const String p_name) { } Node *EditorAutoloadSettings::_create_autoload(const String &p_path) { - Ref<Resource> res = ResourceLoader::load(p_path); - ERR_FAIL_COND_V_MSG(res.is_null(), nullptr, "Can't autoload: " + p_path + "."); Node *n = nullptr; - Ref<PackedScene> scn = res; - Ref<Script> script = res; - if (scn.is_valid()) { - n = scn->instantiate(); - } else if (script.is_valid()) { - StringName ibt = script->get_instance_base_type(); - bool valid_type = ClassDB::is_parent_class(ibt, "Node"); - ERR_FAIL_COND_V_MSG(!valid_type, nullptr, "Script does not inherit from Node: " + p_path + "."); + if (ResourceLoader::get_resource_type(p_path) == "PackedScene") { + // Cache the scene reference before loading it (for cyclic references) + Ref<PackedScene> scn; + scn.instantiate(); + scn->set_path(p_path); + scn->reload_from_file(); + ERR_FAIL_COND_V_MSG(!scn.is_valid(), nullptr, vformat("Can't autoload: %s.", p_path)); - Object *obj = ClassDB::instantiate(ibt); + if (scn.is_valid()) { + n = scn->instantiate(); + } + } else { + Ref<Resource> res = ResourceLoader::load(p_path); + ERR_FAIL_COND_V_MSG(res.is_null(), nullptr, vformat("Can't autoload: %s.", p_path)); + + Ref<Script> scr = res; + if (scr.is_valid()) { + StringName ibt = scr->get_instance_base_type(); + bool valid_type = ClassDB::is_parent_class(ibt, "Node"); + ERR_FAIL_COND_V_MSG(!valid_type, nullptr, vformat("Script does not inherit from Node: %s.", p_path)); + + Object *obj = ClassDB::instantiate(ibt); - ERR_FAIL_COND_V_MSG(!obj, nullptr, "Cannot instance script for Autoload, expected 'Node' inheritance, got: " + String(ibt) + "."); + ERR_FAIL_COND_V_MSG(!obj, nullptr, vformat("Cannot instance script for Autoload, expected 'Node' inheritance, got: %s.", ibt)); - n = Object::cast_to<Node>(obj); - n->set_script(script); + n = Object::cast_to<Node>(obj); + n->set_script(scr); + } } - ERR_FAIL_COND_V_MSG(!n, nullptr, "Path in Autoload not a node or script: " + p_path + "."); + ERR_FAIL_COND_V_MSG(!n, nullptr, vformat("Path in Autoload not a node or script: %s.", p_path)); return n; } @@ -453,21 +464,21 @@ void EditorAutoloadSettings::update_autoload() { } String name = pi.name.get_slice("/", 1); - String path = ProjectSettings::get_singleton()->get(pi.name); + String scr_path = GLOBAL_GET(pi.name); if (name.is_empty()) { continue; } AutoloadInfo info; - info.is_singleton = path.begins_with("*"); + info.is_singleton = scr_path.begins_with("*"); if (info.is_singleton) { - path = path.substr(1, path.length()); + scr_path = scr_path.substr(1, scr_path.length()); } info.name = name; - info.path = path; + info.path = scr_path; info.order = ProjectSettings::get_singleton()->get_order(pi.name); bool need_to_add = true; @@ -499,7 +510,7 @@ void EditorAutoloadSettings::update_autoload() { item->set_text(0, name); item->set_editable(0, true); - item->set_text(1, path); + item->set_text(1, scr_path); item->set_selectable(1, true); item->set_cell_mode(2, TreeItem::CELL_MODE_CHECK); @@ -527,11 +538,9 @@ void EditorAutoloadSettings::update_autoload() { } if (info.node) { - info.node->queue_delete(); + info.node->queue_free(); info.node = nullptr; } - - ProjectSettings::get_singleton()->remove_autoload(info.name); } // Load new/changed autoloads @@ -556,12 +565,6 @@ void EditorAutoloadSettings::update_autoload() { } } - ProjectSettings::AutoloadInfo prop_info; - prop_info.name = info->name; - prop_info.path = info->path; - prop_info.is_singleton = info->is_singleton; - ProjectSettings::get_singleton()->add_autoload(prop_info); - if (!info->in_editor && !info->is_singleton) { // No reason to keep this node memdelete(info->node); @@ -714,7 +717,7 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant & orders.sort(); - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Rearrange Autoloads")); @@ -745,27 +748,26 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_ return false; } - const String &path = p_path; - if (!FileAccess::exists(path)) { + if (!FileAccess::exists(p_path)) { EditorNode::get_singleton()->show_warning(TTR("Can't add Autoload:") + "\n" + vformat(TTR("%s is an invalid path. File does not exist."), path)); return false; } - if (!path.begins_with("res://")) { + if (!p_path.begins_with("res://")) { EditorNode::get_singleton()->show_warning(TTR("Can't add Autoload:") + "\n" + vformat(TTR("%s is an invalid path. Not in resource path (res://)."), path)); return false; } name = "autoload/" + name; - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Autoload")); // Singleton autoloads are represented with a leading "*" in their path. - undo_redo->add_do_property(ProjectSettings::get_singleton(), name, "*" + path); + undo_redo->add_do_property(ProjectSettings::get_singleton(), name, "*" + p_path); if (ProjectSettings::get_singleton()->has_setting(name)) { - undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, ProjectSettings::get_singleton()->get(name)); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, GLOBAL_GET(name)); } else { undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, Variant()); } @@ -784,7 +786,7 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_ void EditorAutoloadSettings::autoload_remove(const String &p_name) { String name = "autoload/" + p_name; - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); int order = ProjectSettings::get_singleton()->get_order(name); @@ -792,7 +794,7 @@ void EditorAutoloadSettings::autoload_remove(const String &p_name) { undo_redo->add_do_property(ProjectSettings::get_singleton(), name, Variant()); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, ProjectSettings::get_singleton()->get(name)); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), name, GLOBAL_GET(name)); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_persisting", name, true); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", order); @@ -829,21 +831,21 @@ EditorAutoloadSettings::EditorAutoloadSettings() { } String name = pi.name.get_slice("/", 1); - String path = ProjectSettings::get_singleton()->get(pi.name); + String scr_path = GLOBAL_GET(pi.name); if (name.is_empty()) { continue; } AutoloadInfo info; - info.is_singleton = path.begins_with("*"); + info.is_singleton = scr_path.begins_with("*"); if (info.is_singleton) { - path = path.substr(1, path.length()); + scr_path = scr_path.substr(1, scr_path.length()); } info.name = name; - info.path = path; + info.path = scr_path; info.order = ProjectSettings::get_singleton()->get_order(pi.name); if (info.is_singleton) { diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp index 0f0ab4a339..96c69c0bd1 100644 --- a/editor/editor_build_profile.cpp +++ b/editor/editor_build_profile.cpp @@ -255,8 +255,7 @@ Error EditorBuildProfile::save_to_file(const String &p_path) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE); ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_CREATE, "Cannot create file '" + p_path + "'."); - JSON json; - String text = json.stringify(data, "\t"); + String text = JSON::stringify(data, "\t"); f->store_string(text); return OK; } @@ -876,7 +875,7 @@ EditorBuildProfileManager::EditorBuildProfileManager() { import_profile = memnew(EditorFileDialog); add_child(import_profile); import_profile->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - import_profile->add_filter("*.build", TTR("Egine Build Profile")); + import_profile->add_filter("*.build", TTR("Engine Build Profile")); import_profile->connect("files_selected", callable_mp(this, &EditorBuildProfileManager::_import_profile)); import_profile->set_title(TTR("Load Profile")); import_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM); @@ -884,7 +883,7 @@ EditorBuildProfileManager::EditorBuildProfileManager() { export_profile = memnew(EditorFileDialog); add_child(export_profile); export_profile->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); - export_profile->add_filter("*.build", TTR("Egine Build Profile")); + export_profile->add_filter("*.build", TTR("Engine Build Profile")); export_profile->connect("file_selected", callable_mp(this, &EditorBuildProfileManager::_export_profile)); export_profile->set_title(TTR("Export Profile")); export_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM); diff --git a/editor/editor_build_profile.h b/editor/editor_build_profile.h index 606c415429..9624f7e44b 100644 --- a/editor/editor_build_profile.h +++ b/editor/editor_build_profile.h @@ -117,6 +117,7 @@ public: VARIANT_ENUM_CAST(EditorBuildProfile::BuildOption) VARIANT_ENUM_CAST(EditorBuildProfile::BuildOptionCategory) +class EditorFileDialog; class EditorFileSystemDirectory; class EditorBuildProfileManager : public AcceptDialog { diff --git a/editor/editor_builders.py b/editor/editor_builders.py index e73fbc6107..696e3b64ec 100644 --- a/editor/editor_builders.py +++ b/editor/editor_builders.py @@ -9,6 +9,7 @@ import shutil import subprocess import tempfile import uuid +import zlib from platform_methods import subprocess_main @@ -28,7 +29,6 @@ def make_doc_header(target, source, env): buf = (docbegin + buf + docend).encode("utf-8") decomp_size = len(buf) - import zlib # Use maximum zlib compression level to further reduce file size # (at the cost of initial build times). @@ -88,9 +88,6 @@ def make_translations_header(target, source, env, category): g.write("#ifndef _{}_TRANSLATIONS_H\n".format(category.upper())) g.write("#define _{}_TRANSLATIONS_H\n".format(category.upper())) - import zlib - import os.path - sorted_paths = sorted(source, key=lambda path: os.path.splitext(os.path.basename(path))[0]) msgfmt_available = shutil.which("msgfmt") is not None diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp index ba1f2fd6af..b92b0fca59 100644 --- a/editor/editor_command_palette.cpp +++ b/editor/editor_command_palette.cpp @@ -130,7 +130,7 @@ void EditorCommandPalette::_update_command_search(const String &search_text) { ti->set_metadata(0, entries[i].key_name); ti->set_text_alignment(1, HORIZONTAL_ALIGNMENT_RIGHT); ti->set_text(1, shortcut_text); - Color c = Color(1, 1, 1, 0.5); + Color c = get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5); ti->set_custom_color(1, c); } @@ -171,7 +171,13 @@ void EditorCommandPalette::_confirmed() { } void EditorCommandPalette::open_popup() { - popup_centered_clamped(Size2i(600, 440), 0.8f); + static bool was_showed = false; + if (!was_showed) { + was_showed = true; + popup_centered_clamped(Size2(600, 440) * EDSCALE, 0.8f); + } else { + show(); + } command_search_box->clear(); command_search_box->grab_focus(); @@ -226,7 +232,7 @@ void EditorCommandPalette::_add_command(String p_command_name, String p_key_name void EditorCommandPalette::execute_command(String &p_command_key) { ERR_FAIL_COND_MSG(!commands.has(p_command_key), p_command_key + " not found."); commands[p_command_key].last_used = OS::get_singleton()->get_unix_time(); - commands[p_command_key].callable.call_deferredp(nullptr, 0); + commands[p_command_key].callable.call_deferred(); _save_history(); } diff --git a/editor/editor_command_palette.h b/editor/editor_command_palette.h index b3e84771d0..15200552b4 100644 --- a/editor/editor_command_palette.h +++ b/editor/editor_command_palette.h @@ -66,7 +66,11 @@ class EditorCommandPalette : public ConfirmationDialog { struct CommandHistoryComparator { _FORCE_INLINE_ bool operator()(const CommandEntry &A, const CommandEntry &B) const { - return A.last_used > B.last_used; + if (A.last_used == B.last_used) { + return A.display_name < B.display_name; + } else { + return A.last_used > B.last_used; + } } }; diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index d1ea0f2814..f15b874c45 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -457,12 +457,10 @@ Callable EditorData::get_move_array_element_function(const StringName &p_class) } void EditorData::remove_editor_plugin(EditorPlugin *p_plugin) { - p_plugin->undo_redo = Ref<EditorUndoRedoManager>(); editor_plugins.erase(p_plugin); } void EditorData::add_editor_plugin(EditorPlugin *p_plugin) { - p_plugin->undo_redo = undo_redo_manager; editor_plugins.push_back(p_plugin); } @@ -488,7 +486,7 @@ void EditorData::add_custom_type(const String &p_type, const String &p_inherits, custom_types[p_inherits].push_back(ct); } -Variant EditorData::instance_custom_type(const String &p_type, const String &p_inherits) { +Variant EditorData::instantiate_custom_type(const String &p_type, const String &p_inherits) { if (get_custom_types().has(p_inherits)) { for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) { if (get_custom_types()[p_inherits][i].name == p_type) { @@ -947,11 +945,11 @@ StringName EditorData::script_class_get_base(const String &p_class) const { Variant EditorData::script_class_instance(const String &p_class) { if (ScriptServer::is_global_class(p_class)) { - Variant obj = ClassDB::instantiate(ScriptServer::get_global_class_native_base(p_class)); - if (obj) { - Ref<Script> script = script_class_load_script(p_class); - if (script.is_valid()) { - ((Object *)obj)->set_script(script); + Ref<Script> script = script_class_load_script(p_class); + if (script.is_valid()) { + Object *obj = ClassDB::instantiate(script->get_instance_base_type()); + if (obj) { + obj->set_script(script); } return obj; } @@ -1008,7 +1006,7 @@ void EditorData::script_class_save_icon_paths() { Dictionary old; if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) { - old = ProjectSettings::get_singleton()->get("_global_script_class_icons"); + old = GLOBAL_GET("_global_script_class_icons"); } if ((!old.is_empty() || d.is_empty()) && d.hash() == old.hash()) { return; @@ -1028,7 +1026,7 @@ void EditorData::script_class_load_icon_paths() { script_class_clear_icon_paths(); if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) { - Dictionary d = ProjectSettings::get_singleton()->get("_global_script_class_icons"); + Dictionary d = GLOBAL_GET("_global_script_class_icons"); List<Variant> keys; d.get_key_list(&keys); diff --git a/editor/editor_data.h b/editor/editor_data.h index 4f1740d4f0..aad00f3ff8 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -181,7 +181,7 @@ public: void restore_editor_global_states(); void add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon); - Variant instance_custom_type(const String &p_type, const String &p_inherits); + Variant instantiate_custom_type(const String &p_type, const String &p_inherits); void remove_custom_type(const String &p_type); const HashMap<String, Vector<CustomType>> &get_custom_types() const { return custom_types; } const CustomType *get_custom_type_by_name(const String &p_name) const; diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp index f464ca3b3c..0c5c15a0ed 100644 --- a/editor/editor_dir_dialog.cpp +++ b/editor/editor_dir_dialog.cpp @@ -57,7 +57,7 @@ void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p } //this should be handled by EditorFileSystem already - //bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"); + //bool show_hidden = EDITOR_GET("filesystem/file_dialog/show_hidden_files"); updating = false; for (int i = 0; i < p_dir->get_subdir_count(); i++) { TreeItem *ti = tree->create_item(p_item); diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 708173ea26..7080cdbdd5 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -47,6 +47,7 @@ const char *EditorFeatureProfile::feature_names[FEATURE_MAX] = { TTRC("Node Dock"), TTRC("FileSystem Dock"), TTRC("Import Dock"), + TTRC("History Dock"), }; const char *EditorFeatureProfile::feature_descriptions[FEATURE_MAX] = { @@ -57,6 +58,7 @@ const char *EditorFeatureProfile::feature_descriptions[FEATURE_MAX] = { TTRC("Allows to work with signals and groups of the node selected in the Scene dock."), TTRC("Allows to browse the local file system via a dedicated dock."), TTRC("Allows to configure import settings for individual assets. Requires the FileSystem dock to function."), + TTRC("Provides an overview of the editor's and each scene's undo history."), }; const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = { @@ -67,6 +69,7 @@ const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = { "node_dock", "filesystem_dock", "import_dock", + "history_dock", }; void EditorFeatureProfile::set_disable_class(const StringName &p_class, bool p_disabled) { @@ -302,10 +305,15 @@ void EditorFeatureProfile::_bind_methods() { BIND_ENUM_CONSTANT(FEATURE_NODE_DOCK); BIND_ENUM_CONSTANT(FEATURE_FILESYSTEM_DOCK); BIND_ENUM_CONSTANT(FEATURE_IMPORT_DOCK); + BIND_ENUM_CONSTANT(FEATURE_HISTORY_DOCK); BIND_ENUM_CONSTANT(FEATURE_MAX); } -EditorFeatureProfile::EditorFeatureProfile() {} +EditorFeatureProfile::EditorFeatureProfile() { + for (int i = 0; i < FEATURE_MAX; i++) { + features_disabled[i] = false; + } +} ////////////////////////// @@ -742,6 +750,8 @@ void EditorFeatureProfileManager::_update_selected_profile() { class_list->clear(); String profile = _get_selected_profile(); + profile_actions[PROFILE_SET]->set_disabled(profile == current_profile); + if (profile.is_empty()) { //nothing selected, nothing edited property_list->clear(); edited.unref(); @@ -763,7 +773,7 @@ void EditorFeatureProfileManager::_update_selected_profile() { TreeItem *root = class_list->create_item(); TreeItem *features = class_list->create_item(root); - TreeItem *last_feature; + TreeItem *last_feature = nullptr; features->set_text(0, TTR("Main Features:")); for (int i = 0; i < EditorFeatureProfile::FEATURE_MAX; i++) { TreeItem *feature; diff --git a/editor/editor_feature_profile.h b/editor/editor_feature_profile.h index dab6c951e4..1d79844913 100644 --- a/editor/editor_feature_profile.h +++ b/editor/editor_feature_profile.h @@ -40,6 +40,8 @@ #include "scene/gui/split_container.h" #include "scene/gui/tree.h" +class EditorFileDialog; + class EditorFeatureProfile : public RefCounted { GDCLASS(EditorFeatureProfile, RefCounted); @@ -52,6 +54,7 @@ public: FEATURE_NODE_DOCK, FEATURE_FILESYSTEM_DOCK, FEATURE_IMPORT_DOCK, + FEATURE_HISTORY_DOCK, FEATURE_MAX }; diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 9fa08a0adb..55c512f77d 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -34,7 +34,6 @@ #include "core/io/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" -#include "core/string/print_string.h" #include "dependency_editor.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" @@ -44,6 +43,10 @@ #include "scene/gui/center_container.h" #include "scene/gui/label.h" #include "scene/gui/margin_container.h" +#include "scene/gui/option_button.h" +#include "scene/gui/separator.h" +#include "scene/gui/split_container.h" +#include "scene/gui/texture_rect.h" #include "servers/display_server.h" EditorFileDialog::GetIconFunc EditorFileDialog::get_icon_func = nullptr; @@ -131,11 +134,11 @@ void EditorFileDialog::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - bool is_showing_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"); + bool is_showing_hidden = EDITOR_GET("filesystem/file_dialog/show_hidden_files"); if (show_hidden_files != is_showing_hidden) { set_show_hidden_files(is_showing_hidden); } - set_display_mode((DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int()); + set_display_mode((DisplayMode)EDITOR_GET("filesystem/file_dialog/display_mode").operator int()); // DO NOT CALL UPDATE FILE LIST HERE, ALL HUNDREDS OF HIDDEN DIALOGS WILL RESPOND, CALL INVALIDATE INSTEAD invalidate(); @@ -740,7 +743,7 @@ void EditorFileDialog::update_file_name() { // DO NOT USE THIS FUNCTION UNLESS NEEDED, CALL INVALIDATE() INSTEAD. void EditorFileDialog::update_file_list() { - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + int thumbnail_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); thumbnail_size *= EDSCALE; Ref<Texture2D> folder_thumbnail; Ref<Texture2D> file_thumbnail; @@ -1023,10 +1026,10 @@ void EditorFileDialog::set_current_path(const String &p_path) { if (pos == -1) { set_current_file(p_path); } else { - String dir = p_path.substr(0, pos); - String file = p_path.substr(pos + 1, p_path.length()); - set_current_dir(dir); - set_current_file(file); + String path_dir = p_path.substr(0, pos); + String path_file = p_path.substr(pos + 1, p_path.length()); + set_current_dir(path_dir); + set_current_file(path_file); } } @@ -1614,26 +1617,26 @@ void EditorFileDialog::set_default_display_mode(DisplayMode p_mode) { } void EditorFileDialog::_save_to_recent() { - String dir = get_current_dir(); - Vector<String> recent = EditorSettings::get_singleton()->get_recent_dirs(); + String cur_dir = get_current_dir(); + Vector<String> recent_new = EditorSettings::get_singleton()->get_recent_dirs(); const int max = 20; int count = 0; - bool res = dir.begins_with("res://"); + bool res = cur_dir.begins_with("res://"); - for (int i = 0; i < recent.size(); i++) { - bool cres = recent[i].begins_with("res://"); - if (recent[i] == dir || (res == cres && count > max)) { - recent.remove_at(i); + for (int i = 0; i < recent_new.size(); i++) { + bool cres = recent_new[i].begins_with("res://"); + if (recent_new[i] == cur_dir || (res == cres && count > max)) { + recent_new.remove_at(i); i--; } else { count++; } } - recent.insert(0, dir); + recent_new.insert(0, cur_dir); - EditorSettings::get_singleton()->set_recent_dirs(recent); + EditorSettings::get_singleton()->set_recent_dirs(recent_new); } void EditorFileDialog::set_disable_overwrite_warning(bool p_disable) { diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h index 6d11cb10ed..40073326a1 100644 --- a/editor/editor_file_dialog.h +++ b/editor/editor_file_dialog.h @@ -32,17 +32,14 @@ #define EDITOR_FILE_DIALOG_H #include "core/io/dir_access.h" -#include "editor/plugins/editor_preview_plugins.h" -#include "scene/gui/box_container.h" #include "scene/gui/dialogs.h" -#include "scene/gui/item_list.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/option_button.h" -#include "scene/gui/separator.h" -#include "scene/gui/split_container.h" -#include "scene/gui/texture_rect.h" class DependencyRemoveDialog; +class HSplitContainer; +class ItemList; +class OptionButton; +class PopupMenu; +class TextureRect; class EditorFileDialog : public ConfirmationDialog { GDCLASS(EditorFileDialog, ConfirmationDialog); @@ -202,7 +199,6 @@ private: void _select_drive(int p_idx); void _dir_submitted(String p_dir); - void _file_submitted(const String &p_file); void _action_pressed(); void _save_confirm_pressed(); void _cancel_pressed(); @@ -240,6 +236,9 @@ protected: static void _bind_methods(); public: + // Public for use with callable_mp. + void _file_submitted(const String &p_file); + void popup_file_dialog(); void clear_filters(); void add_filter(const String &p_filter, const String &p_description = ""); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 177bc6d2b2..5d137ce290 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -39,6 +39,7 @@ #include "core/object/worker_thread_pool.h" #include "core/os/os.h" #include "core/variant/variant_parser.h" +#include "editor/editor_help.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_resource_preview.h" @@ -619,7 +620,12 @@ bool EditorFileSystem::_update_scan_actions() { if (_test_for_reimport(full_path, false)) { //must reimport reimports.push_back(full_path); - reimports.append_array(_get_dependencies(full_path)); + Vector<String> dependencies = _get_dependencies(full_path); + for (const String &dependency_path : dependencies) { + if (import_extensions.has(dependency_path.get_extension())) { + reimports.push_back(dependency_path); + } + } } else { //must not reimport, all was good //update modified times, to avoid reimport @@ -690,7 +696,6 @@ void EditorFileSystem::scan() { _update_extensions(); - abort_scan = false; if (!use_threads) { scanning = true; scan_total = 0; @@ -920,11 +925,11 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc for (int i = 0; i < ScriptServer::get_language_count(); i++) { ScriptLanguage *lang = ScriptServer::get_language(i); if (lang->supports_documentation() && fi->type == lang->get_type()) { - Ref<Script> script = ResourceLoader::load(path); - if (script == nullptr) { + Ref<Script> scr = ResourceLoader::load(path); + if (scr == nullptr) { continue; } - Vector<DocData::ClassDoc> docs = script->get_documentation(); + Vector<DocData::ClassDoc> docs = scr->get_documentation(); for (int j = 0; j < docs.size(); j++) { EditorHelp::get_doc_data()->add_doc(docs[j]); } @@ -1162,8 +1167,6 @@ void EditorFileSystem::scan_changes() { scanning_changes = true; scanning_changes_done = false; - abort_scan = false; - if (!use_threads) { if (filesystem) { EditorProgressBG pr("sources", TTR("ScanSources"), 1000); @@ -1195,8 +1198,6 @@ void EditorFileSystem::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { Thread &active_thread = thread.is_started() ? thread : thread_sources; if (use_threads && active_thread.is_started()) { - //abort thread if in progress - abort_scan = true; while (scanning) { OS::get_singleton()->delay_usec(1000); } @@ -1893,7 +1894,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap<String if (load_default && ProjectSettings::get_singleton()->has_setting("importer_defaults/" + importer->get_importer_name())) { //use defaults if exist - Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); + Dictionary d = GLOBAL_GET("importer_defaults/" + importer->get_importer_name()); List<Variant> v; d.get_key_list(&v); @@ -1907,8 +1908,8 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap<String List<String> import_variants; List<String> gen_files; - Variant metadata; - Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files, &metadata); + Variant meta; + Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files, &meta); if (err != OK) { ERR_PRINT("Error importing '" + p_file + "'."); @@ -1960,8 +1961,8 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap<String f->store_line("valid=false"); } - if (metadata != Variant()) { - f->store_line("metadata=" + metadata.get_construct_string()); + if (meta != Variant()) { + f->store_line("metadata=" + meta.get_construct_string()); } f->store_line(""); @@ -2090,7 +2091,7 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { if (group_file_cache.has(file)) { //maybe the file itself is a group! groups_to_reimport.insert(file); - //groups do not belong to grups + //groups do not belong to groups group_file = String(); } else if (!group_file.is_empty()) { //it's a group file, add group to import and skip this file @@ -2113,11 +2114,11 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { reimport_files.sort(); - bool use_threads = GLOBAL_GET("editor/import/use_multiple_threads"); + bool use_multiple_threads = GLOBAL_GET("editor/import/use_multiple_threads"); int from = 0; for (int i = 0; i < reimport_files.size(); i++) { - if (use_threads && reimport_files[i].threaded) { + if (use_multiple_threads && reimport_files[i].threaded) { if (i + 1 == reimport_files.size() || reimport_files[i + 1].importer != reimport_files[from].importer) { if (from - i == 0) { //single file, do not use threads @@ -2129,16 +2130,16 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { importer->import_threaded_begin(); - ImportThreadData data; - data.max_index = from; - data.reimport_from = from; - data.reimport_files = reimport_files.ptr(); + ImportThreadData tdata; + tdata.max_index = from; + tdata.reimport_from = from; + tdata.reimport_files = reimport_files.ptr(); - WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &EditorFileSystem::_reimport_thread, &data, i - from + 1, -1, false, vformat(TTR("Import resources of type: %s"), reimport_files[from].importer)); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &EditorFileSystem::_reimport_thread, &tdata, i - from + 1, -1, false, vformat(TTR("Import resources of type: %s"), reimport_files[from].importer)); int current_index = from - 1; do { - if (current_index < data.max_index) { - current_index = data.max_index; + if (current_index < tdata.max_index) { + current_index = tdata.max_index; pr.step(reimport_files[current_index].path.get_file(), current_index); } OS::get_singleton()->delay_usec(1); @@ -2264,7 +2265,7 @@ void EditorFileSystem::move_group_file(const String &p_path, const String &p_new ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const String &p_path, bool p_generate) { if (!p_path.is_resource_file() || p_path.begins_with(ProjectSettings::get_singleton()->get_project_data_path())) { - //saved externally (configuration file) or internal file, do not assign an ID. + // Saved externally (configuration file) or internal file, do not assign an ID. return ResourceUID::INVALID_ID; } @@ -2272,15 +2273,21 @@ ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const int cpos = -1; if (!singleton->_find_file(p_path, &fs, cpos)) { + // Fallback to ResourceLoader if filesystem cache fails (can happen during scanning etc.). + ResourceUID::ID fallback = ResourceLoader::get_resource_uid(p_path); + if (fallback != ResourceUID::INVALID_ID) { + return fallback; + } + if (p_generate) { - return ResourceUID::get_singleton()->create_id(); //just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple. + return ResourceUID::get_singleton()->create_id(); // Just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple. } else { return ResourceUID::INVALID_ID; } } else if (fs->files[cpos]->uid != ResourceUID::INVALID_ID) { return fs->files[cpos]->uid; } else if (p_generate) { - return ResourceUID::get_singleton()->create_id(); //just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple. + return ResourceUID::get_singleton()->create_id(); // Just create a new one, we will be notified of save anyway and fetch the right UUID at that time, to keep things simple. } else { return ResourceUID::INVALID_ID; } @@ -2387,7 +2394,7 @@ void EditorFileSystem::_update_extensions() { valid_extensions.insert(E); } - const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); for (const String &E : textfile_ext) { if (valid_extensions.has(E)) { continue; @@ -2427,7 +2434,7 @@ EditorFileSystem::EditorFileSystem() { scan_total = 0; update_script_classes_queued.clear(); - ResourceUID::get_singleton()->clear(); //will be updated on scan + MessageQueue::get_singleton()->push_callable(callable_mp(ResourceUID::get_singleton(), &ResourceUID::clear)); // Will be updated on scan. ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path); } diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index f4e69b95e7..e06c6e4593 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -168,7 +168,6 @@ class EditorFileSystem : public Node { EditorFileSystemDirectory *new_filesystem = nullptr; - bool abort_scan = false; bool scanning = false; bool importing = false; bool first_scan = true; diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index c31d13d122..e7d4636ad9 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -57,6 +57,24 @@ Ref<FontFile> load_external_font(const String &p_path, TextServer::Hinting p_hin return font; } +Ref<SystemFont> load_system_font(const PackedStringArray &p_names, TextServer::Hinting p_hinting, TextServer::FontAntialiasing p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) { + Ref<SystemFont> font; + font.instantiate(); + + font->set_font_names(p_names); + font->set_multichannel_signed_distance_field(p_msdf); + font->set_antialiasing(p_aa); + font->set_hinting(p_hinting); + font->set_force_autohinter(p_autohint); + font->set_subpixel_positioning(p_font_subpixel_positioning); + + if (r_fallbacks != nullptr) { + r_fallbacks->push_back(font); + } + + return font; +} + Ref<FontFile> load_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, TextServer::FontAntialiasing p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) { Ref<FontFile> font; font.instantiate(); @@ -91,9 +109,9 @@ Ref<FontVariation> make_bold_font(const Ref<Font> &p_font, double p_embolden, Ty void editor_register_fonts(Ref<Theme> p_theme) { Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - TextServer::FontAntialiasing font_antialiasing = (TextServer::FontAntialiasing)(int)EditorSettings::get_singleton()->get("interface/editor/font_antialiasing"); - int font_hinting_setting = (int)EditorSettings::get_singleton()->get("interface/editor/font_hinting"); - TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)EditorSettings::get_singleton()->get("interface/editor/font_subpixel_positioning"); + TextServer::FontAntialiasing font_antialiasing = (TextServer::FontAntialiasing)(int)EDITOR_GET("interface/editor/font_antialiasing"); + int font_hinting_setting = (int)EDITOR_GET("interface/editor/font_hinting"); + TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)EDITOR_GET("interface/editor/font_subpixel_positioning"); TextServer::Hinting font_hinting; TextServer::Hinting font_mono_hinting; @@ -166,6 +184,20 @@ void editor_register_fonts(Ref<Theme> p_theme) { Ref<FontFile> thai_font_bold = load_internal_font(_font_NotoSansThaiUI_Bold, _font_NotoSansThaiUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold); Ref<FontVariation> fallback_font_bold = make_bold_font(fallback_font, embolden_strength, &fallbacks_bold); Ref<FontVariation> japanese_font_bold = make_bold_font(japanese_font, embolden_strength, &fallbacks_bold); + + if (OS::get_singleton()->has_feature("system_fonts")) { + PackedStringArray emoji_font_names; + emoji_font_names.push_back("Apple Color Emoji"); + emoji_font_names.push_back("Segoe UI Emoji"); + emoji_font_names.push_back("Noto Color Emoji"); + emoji_font_names.push_back("Twitter Color Emoji"); + emoji_font_names.push_back("OpenMoji"); + emoji_font_names.push_back("EmojiOne Color"); + Ref<SystemFont> emoji_font = load_system_font(emoji_font_names, font_hinting, font_antialiasing, true, font_subpixel_positioning, false); + fallbacks.push_back(emoji_font); + fallbacks_bold.push_back(emoji_font); + } + default_font_bold->set_fallbacks(fallbacks_bold); default_font_bold_msdf->set_fallbacks(fallbacks_bold); @@ -173,9 +205,9 @@ void editor_register_fonts(Ref<Theme> p_theme) { default_font_mono->set_fallbacks(fallbacks); // Init base font configs and load custom fonts. - String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font"); - String custom_font_path_bold = EditorSettings::get_singleton()->get("interface/editor/main_font_bold"); - String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); + String custom_font_path = EDITOR_GET("interface/editor/main_font"); + String custom_font_path_bold = EDITOR_GET("interface/editor/main_font_bold"); + String custom_font_path_source = EDITOR_GET("interface/editor/code_font"); Ref<FontVariation> default_fc; default_fc.instantiate(); @@ -283,7 +315,7 @@ void editor_register_fonts(Ref<Theme> p_theme) { Ref<FontVariation> mono_other_fc = mono_fc->duplicate(); // Enable contextual alternates (coding ligatures) and custom features for the source editor font. - int ot_mode = EditorSettings::get_singleton()->get("interface/editor/code_font_contextual_ligatures"); + int ot_mode = EDITOR_GET("interface/editor/code_font_contextual_ligatures"); switch (ot_mode) { case 1: { // Disable ligatures. Dictionary ftrs; @@ -291,7 +323,7 @@ void editor_register_fonts(Ref<Theme> p_theme) { mono_fc->set_opentype_features(ftrs); } break; case 2: { // Custom. - Vector<String> subtag = String(EditorSettings::get_singleton()->get("interface/editor/code_font_custom_opentype_features")).split(","); + Vector<String> subtag = String(EDITOR_GET("interface/editor/code_font_custom_opentype_features")).split(","); Dictionary ftrs; for (int i = 0; i < subtag.size(); i++) { Vector<String> subtag_a = subtag[i].split("="); @@ -303,7 +335,7 @@ void editor_register_fonts(Ref<Theme> p_theme) { } mono_fc->set_opentype_features(ftrs); } break; - default: { // Default. + default: { // Enabled. Dictionary ftrs; ftrs[TS->name_to_tag("calt")] = 1; mono_fc->set_opentype_features(ftrs); @@ -317,6 +349,24 @@ void editor_register_fonts(Ref<Theme> p_theme) { mono_other_fc->set_opentype_features(ftrs); } + // Use fake bold/italics to style the editor log's `print_rich()` output. + // Use stronger embolden strength to make bold easier to distinguish from regular text. + Ref<FontVariation> mono_other_fc_bold = mono_other_fc->duplicate(); + mono_other_fc_bold->set_variation_embolden(0.8); + + Ref<FontVariation> mono_other_fc_italic = mono_other_fc->duplicate(); + mono_other_fc_italic->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0)); + + Ref<FontVariation> mono_other_fc_bold_italic = mono_other_fc->duplicate(); + mono_other_fc_bold_italic->set_variation_embolden(0.8); + mono_other_fc_bold_italic->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0)); + + Ref<FontVariation> mono_other_fc_mono = mono_other_fc->duplicate(); + // Use a different font style to distinguish `[code]` in rich prints. + // This emulates the "faint" styling used in ANSI escape codes by using a slightly thinner font. + mono_other_fc_mono->set_variation_embolden(-0.25); + mono_other_fc_mono->set_variation_transform(Transform2D(1.0, 0.1, 0.0, 1.0, 0.0, 0.0)); + Ref<FontVariation> italic_fc = default_fc->duplicate(); italic_fc->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0)); @@ -386,6 +436,10 @@ void editor_register_fonts(Ref<Theme> p_theme) { p_theme->set_font_size("output_source_size", "EditorFonts", int(EDITOR_GET("run/output/font_size")) * EDSCALE); p_theme->set_font("output_source", "EditorFonts", mono_other_fc); + p_theme->set_font("output_source_bold", "EditorFonts", mono_other_fc_bold); + p_theme->set_font("output_source_italic", "EditorFonts", mono_other_fc_italic); + p_theme->set_font("output_source_bold_italic", "EditorFonts", mono_other_fc_bold_italic); + p_theme->set_font("output_source_mono", "EditorFonts", mono_other_fc_mono); p_theme->set_font_size("status_source_size", "EditorFonts", default_font_size); p_theme->set_font("status_source", "EditorFonts", mono_other_fc); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 745dcdd04c..6bd67fbcb9 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -39,6 +39,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/script_editor_plugin.h" +#include "scene/gui/line_edit.h" #define CONTRIBUTE_URL vformat("%s/community/contributing/updating_the_class_reference.html", VERSION_DOCS_URL) @@ -54,10 +55,14 @@ void EditorHelp::_update_theme() { qualifier_color = get_theme_color(SNAME("qualifier_color"), SNAME("EditorHelp")); type_color = get_theme_color(SNAME("type_color"), SNAME("EditorHelp")); + class_desc->add_theme_style_override("normal", get_theme_stylebox(SNAME("background"), SNAME("EditorHelp"))); + class_desc->add_theme_style_override("focus", get_theme_stylebox(SNAME("background"), SNAME("EditorHelp"))); class_desc->add_theme_color_override("selection_color", get_theme_color(SNAME("selection_color"), SNAME("EditorHelp"))); class_desc->add_theme_constant_override("line_separation", get_theme_constant(SNAME("line_separation"), SNAME("EditorHelp"))); class_desc->add_theme_constant_override("table_h_separation", get_theme_constant(SNAME("table_h_separation"), SNAME("EditorHelp"))); class_desc->add_theme_constant_override("table_v_separation", get_theme_constant(SNAME("table_v_separation"), SNAME("EditorHelp"))); + class_desc->add_theme_constant_override("text_highlight_h_padding", get_theme_constant(SNAME("text_highlight_h_padding"), SNAME("EditorHelp"))); + class_desc->add_theme_constant_override("text_highlight_v_padding", get_theme_constant(SNAME("text_highlight_v_padding"), SNAME("EditorHelp"))); doc_font = get_theme_font(SNAME("doc"), SNAME("EditorFonts")); doc_bold_font = get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")); @@ -184,9 +189,9 @@ void EditorHelp::_class_desc_input(const Ref<InputEvent> &p_input) { void EditorHelp::_class_desc_resized(bool p_force_update_theme) { // Add extra horizontal margins for better readability. // The margins increase as the width of the editor help container increases. - Ref<Font> doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); + Ref<Font> font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("doc_source_size"), SNAME("EditorFonts")); - real_t char_width = doc_code_font->get_char_size('x', font_size).width; + real_t char_width = font->get_char_size('x', font_size).width; const int new_display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - char_width * 120 * EDSCALE) * 0.5; if (display_margin != new_display_margin || p_force_update_theme) { display_margin = new_display_margin; @@ -199,13 +204,20 @@ void EditorHelp::_class_desc_resized(bool p_force_update_theme) { } void EditorHelp::_add_type(const String &p_type, const String &p_enum) { - String t = p_type; - if (t.is_empty()) { - t = "void"; + if (p_type.is_empty() || p_type == "void") { + class_desc->push_color(Color(type_color, 0.5)); + class_desc->push_hint(TTR("No return value.")); + class_desc->add_text("void"); + class_desc->pop(); + class_desc->pop(); + return; } - bool can_ref = (t != "void" && !t.contains("*")) || !p_enum.is_empty(); - if (!p_enum.is_empty()) { + bool is_enum_type = !p_enum.is_empty(); + bool can_ref = !p_type.contains("*") || is_enum_type; + + String t = p_type; + if (is_enum_type) { if (p_enum.get_slice_count(".") > 1) { t = p_enum.get_slice(".", 1); } else { @@ -219,21 +231,24 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) { if (t.ends_with("[]")) { add_array = true; t = t.replace("[]", ""); + + class_desc->push_meta("#Array"); //class + class_desc->add_text("Array"); + class_desc->pop(); + class_desc->add_text("["); } - if (p_enum.is_empty()) { - class_desc->push_meta("#" + t); //class - } else { + + if (is_enum_type) { class_desc->push_meta("$" + p_enum); //class + } else { + class_desc->push_meta("#" + t); //class } } class_desc->add_text(t); if (can_ref) { - class_desc->pop(); + class_desc->pop(); // Pushed meta above. if (add_array) { - class_desc->add_text(" "); - class_desc->push_meta("#Array"); //class - class_desc->add_text("[]"); - class_desc->pop(); + class_desc->add_text("]"); } } class_desc->pop(); @@ -368,8 +383,29 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview class_desc->pop(); if (!p_method.qualifiers.is_empty()) { class_desc->push_color(qualifier_color); - class_desc->add_text(" "); - _add_text(p_method.qualifiers); + + PackedStringArray qualifiers = p_method.qualifiers.split_spaces(); + for (const String &qualifier : qualifiers) { + String hint; + if (qualifier == "vararg") { + hint = TTR("This method supports a variable number of arguments."); + } else if (qualifier == "virtual") { + hint = TTR("This method is called by the engine.\nIt can be overridden to customize built-in behavior."); + } else if (qualifier == "const") { + hint = TTR("This method has no side effects.\nIt does not modify the object in any way."); + } else if (qualifier == "static") { + hint = TTR("This method does not need an instance to be called.\nIt can be called directly using the class name."); + } + + class_desc->add_text(" "); + if (!hint.is_empty()) { + class_desc->push_hint(hint); + class_desc->add_text(qualifier); + class_desc->pop(); + } else { + class_desc->add_text(qualifier); + } + } class_desc->pop(); } @@ -411,14 +447,14 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { return OK; } -void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods, bool &r_method_descrpitons) { - Ref<Font> doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); +void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods) { + Ref<Font> font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); class_desc->pop(); // title font size class_desc->pop(); // title font class_desc->pop(); // title color class_desc->add_newline(); - class_desc->push_font(doc_code_font); + class_desc->push_font(font); class_desc->push_indent(1); class_desc->push_table(2); class_desc->set_table_column_expand(1, true); @@ -461,10 +497,6 @@ void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods, class_desc->pop(); //cell } - if (!m[i].description.strip_edges().is_empty() || m[i].errors_returned.size() > 0) { - r_method_descrpitons = true; - } - _add_method(m[i], true); } @@ -479,9 +511,8 @@ void EditorHelp::_update_method_list(const Vector<DocData::MethodDoc> p_methods, } void EditorHelp::_update_method_descriptions(const DocData::ClassDoc p_classdoc, const Vector<DocData::MethodDoc> p_methods, const String &p_method_type) { - Ref<Font> doc_font = get_theme_font(SNAME("doc"), SNAME("EditorFonts")); - Ref<Font> doc_bold_font = get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")); - Ref<Font> doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); + Ref<Font> font = get_theme_font(SNAME("doc"), SNAME("EditorFonts")); + Ref<Font> code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); String link_color_text = title_color.to_html(false); class_desc->pop(); // title font size class_desc->pop(); // title font @@ -501,7 +532,7 @@ void EditorHelp::_update_method_descriptions(const DocData::ClassDoc p_classdoc, } for (int i = 0; i < methods_filtered.size(); i++) { - class_desc->push_font(doc_code_font); + class_desc->push_font(code_font); _add_method(methods_filtered[i], false); class_desc->pop(); @@ -509,7 +540,7 @@ void EditorHelp::_update_method_descriptions(const DocData::ClassDoc p_classdoc, class_desc->add_newline(); class_desc->push_color(text_color); - class_desc->push_font(doc_font); + class_desc->push_font(font); class_desc->push_indent(1); if (methods_filtered[i].errors_returned.size()) { class_desc->append_text(TTR("Error codes returned:")); @@ -683,11 +714,15 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + bool has_description = false; + class_desc->add_newline(); class_desc->add_newline(); // Brief description if (!cd.brief_description.strip_edges().is_empty()) { + has_description = true; + class_desc->push_color(text_color); class_desc->push_font(doc_bold_font); class_desc->push_indent(1); @@ -702,6 +737,8 @@ void EditorHelp::_update_doc() { // Class description if (!cd.description.strip_edges().is_empty()) { + has_description = true; + section_line.push_back(Pair<String, int>(TTR("Description"), class_desc->get_paragraph_count() - 2)); description_line = class_desc->get_paragraph_count() - 2; class_desc->push_color(title_color); @@ -726,6 +763,22 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); } + if (!has_description) { + class_desc->add_image(get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); + class_desc->add_text(" "); + class_desc->push_color(comment_color); + + if (cd.is_script_doc) { + class_desc->append_text(TTR("There is currently no description for this class.")); + } else { + class_desc->append_text(TTR("There is currently no description for this class. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + } + + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + } + // Online tutorials if (cd.tutorials.size()) { class_desc->push_color(title_color); @@ -762,7 +815,6 @@ void EditorHelp::_update_doc() { // Properties overview HashSet<String> skip_methods; - bool property_descr = false; bool has_properties = cd.properties.size() != 0; if (cd.is_script_doc) { @@ -840,7 +892,6 @@ void EditorHelp::_update_doc() { if (describe) { class_desc->pop(); - property_descr = true; } class_desc->pop(); @@ -925,10 +976,7 @@ void EditorHelp::_update_doc() { } // Methods overview - bool constructor_descriptions = false; - bool method_descriptions = false; - bool operator_descriptions = false; - bool sort_methods = EditorSettings::get_singleton()->get("text_editor/help/sort_functions_alphabetically"); + bool sort_methods = EDITOR_GET("text_editor/help/sort_functions_alphabetically"); Vector<DocData::MethodDoc> methods; @@ -955,19 +1003,20 @@ void EditorHelp::_update_doc() { class_desc->push_font(doc_title_font); class_desc->push_font_size(doc_title_font_size); class_desc->add_text(TTR("Constructors")); - _update_method_list(cd.constructors, constructor_descriptions); + _update_method_list(cd.constructors); } if (!methods.is_empty()) { if (sort_methods) { methods.sort(); } + section_line.push_back(Pair<String, int>(TTR("Methods"), class_desc->get_paragraph_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); class_desc->push_font_size(doc_title_font_size); class_desc->add_text(TTR("Methods")); - _update_method_list(methods, method_descriptions); + _update_method_list(methods); } if (!cd.operators.is_empty()) { @@ -980,7 +1029,7 @@ void EditorHelp::_update_doc() { class_desc->push_font(doc_title_font); class_desc->push_font_size(doc_title_font_size); class_desc->add_text(TTR("Operators")); - _update_method_list(cd.operators, operator_descriptions); + _update_method_list(cd.operators); } // Theme properties @@ -1315,7 +1364,7 @@ void EditorHelp::_update_doc() { if (constants[i].value.begins_with("Color(") && constants[i].value.ends_with(")")) { String stripped = constants[i].value.replace(" ", "").replace("Color(", "").replace(")", ""); - Vector<float> color = stripped.split_floats(","); + PackedFloat64Array color = stripped.split_floats(","); if (color.size() >= 3) { class_desc->push_color(Color(color[0], color[1], color[2])); _add_bulletpoint(); @@ -1473,7 +1522,7 @@ void EditorHelp::_update_doc() { } // Property descriptions - if (property_descr) { + if (has_properties) { section_line.push_back(Pair<String, int>(TTR("Property Descriptions"), class_desc->get_paragraph_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); @@ -1648,7 +1697,7 @@ void EditorHelp::_update_doc() { } // Constructor descriptions - if (constructor_descriptions) { + if (!cd.constructors.is_empty()) { section_line.push_back(Pair<String, int>(TTR("Constructor Descriptions"), class_desc->get_paragraph_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); @@ -1658,7 +1707,7 @@ void EditorHelp::_update_doc() { } // Method descriptions - if (method_descriptions) { + if (!methods.is_empty()) { section_line.push_back(Pair<String, int>(TTR("Method Descriptions"), class_desc->get_paragraph_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); @@ -1668,7 +1717,7 @@ void EditorHelp::_update_doc() { } // Operator descriptions - if (operator_descriptions) { + if (!cd.operators.is_empty()) { section_line.push_back(Pair<String, int>(TTR("Operator Descriptions"), class_desc->get_paragraph_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); @@ -1676,6 +1725,8 @@ void EditorHelp::_update_doc() { class_desc->add_text(TTR("Operator Descriptions")); _update_method_descriptions(cd, cd.operators, "operator"); } + + // Free the scroll. scroll_locked = false; } @@ -1766,9 +1817,19 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control Ref<Font> doc_code_font = p_owner_node->get_theme_font(SNAME("doc_source"), SNAME("EditorFonts")); Ref<Font> doc_kbd_font = p_owner_node->get_theme_font(SNAME("doc_keyboard"), SNAME("EditorFonts")); - Color link_color = p_owner_node->get_theme_color(SNAME("link_color"), SNAME("EditorHelp")); - Color code_color = p_owner_node->get_theme_color(SNAME("code_color"), SNAME("EditorHelp")); - Color kbd_color = p_owner_node->get_theme_color(SNAME("kbd_color"), SNAME("EditorHelp")); + const Color type_color = p_owner_node->get_theme_color(SNAME("type_color"), SNAME("EditorHelp")); + const Color code_color = p_owner_node->get_theme_color(SNAME("code_color"), SNAME("EditorHelp")); + const Color kbd_color = p_owner_node->get_theme_color(SNAME("kbd_color"), SNAME("EditorHelp")); + const Color code_dark_color = Color(code_color, 0.8); + + const Color link_color = p_owner_node->get_theme_color(SNAME("link_color"), SNAME("EditorHelp")); + const Color link_method_color = p_owner_node->get_theme_color(SNAME("accent_color"), SNAME("Editor")); + const Color link_property_color = link_color.lerp(p_owner_node->get_theme_color(SNAME("accent_color"), SNAME("Editor")), 0.25); + const Color link_annotation_color = link_color.lerp(p_owner_node->get_theme_color(SNAME("accent_color"), SNAME("Editor")), 0.5); + + const Color code_bg_color = p_owner_node->get_theme_color(SNAME("code_bg_color"), SNAME("EditorHelp")); + const Color kbd_bg_color = p_owner_node->get_theme_color(SNAME("kbd_bg_color"), SNAME("EditorHelp")); + const Color param_bg_color = p_owner_node->get_theme_color(SNAME("param_bg_color"), SNAME("EditorHelp")); String bbcode = p_bbcode.dedent().replace("\t", "").replace("\r", "").strip_edges(); @@ -1901,14 +1962,21 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control const String link_tag = tag.substr(0, tag_end); const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" "); - // Use monospace font with translucent colored background color to make clickable references + // Use monospace font to make clickable references // easier to distinguish from inline code and other text. p_rt->push_font(doc_code_font); - p_rt->push_color(link_color); - p_rt->push_bgcolor(code_color * Color(1, 1, 1, 0.15)); + + Color target_color = link_color; + if (link_tag == "method") { + target_color = link_method_color; + } else if (link_tag == "member" || link_tag == "signal" || link_tag == "theme property") { + target_color = link_property_color; + } else if (link_tag == "annotation") { + target_color = link_annotation_color; + } + p_rt->push_color(target_color); p_rt->push_meta("@" + link_tag + " " + link_target); - p_rt->add_text(link_target + (tag.begins_with("method ") ? "()" : "")); - p_rt->pop(); + p_rt->add_text(link_target + (link_tag == "method" ? "()" : "")); p_rt->pop(); p_rt->pop(); p_rt->pop(); @@ -1920,7 +1988,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control // Use monospace font with translucent background color to make code easier to distinguish from other text. p_rt->push_font(doc_code_font); - p_rt->push_bgcolor(Color(0.5, 0.5, 0.5, 0.15)); + p_rt->push_bgcolor(param_bg_color); p_rt->push_color(code_color); p_rt->add_text(param_name); p_rt->pop(); @@ -1931,17 +1999,15 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control } else if (doc->class_list.has(tag)) { // Class reference tag such as [Node2D] or [SceneTree]. - // Use monospace font with translucent colored background color to make clickable references + // Use monospace font to make clickable references // easier to distinguish from inline code and other text. p_rt->push_font(doc_code_font); - p_rt->push_color(link_color); - p_rt->push_bgcolor(code_color * Color(1, 1, 1, 0.15)); + p_rt->push_color(type_color); p_rt->push_meta("#" + tag); p_rt->add_text(tag); p_rt->pop(); p_rt->pop(); p_rt->pop(); - p_rt->pop(); pos = brk_end + 1; } else if (tag == "b") { @@ -1955,30 +2021,30 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, Control pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "code") { - // Use monospace font with translucent background color to make code easier to distinguish from other text. + // Use monospace font with darkened background color to make code easier to distinguish from other text. p_rt->push_font(doc_code_font); - p_rt->push_bgcolor(Color(0.5, 0.5, 0.5, 0.15)); - p_rt->push_color(code_color); + p_rt->push_bgcolor(code_bg_color); + p_rt->push_color(code_color.lerp(p_owner_node->get_theme_color(SNAME("error_color"), SNAME("Editor")), 0.6)); code_tag = true; pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "codeblock") { - // Use monospace font with translucent background color to make code easier to distinguish from other text. + // Use monospace font with darkened background color to make code easier to distinguish from other text. // Use a single-column table with cell row background color instead of `[bgcolor]`. // This makes the background color highlight cover the entire block, rather than individual lines. p_rt->push_font(doc_code_font); p_rt->push_table(1); p_rt->push_cell(); - p_rt->set_cell_row_background_color(Color(0.5, 0.5, 0.5, 0.15), Color(0.5, 0.5, 0.5, 0.15)); + p_rt->set_cell_row_background_color(code_bg_color, Color(code_bg_color, 0.99)); p_rt->set_cell_padding(Rect2(10 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE)); - p_rt->push_color(code_color); + p_rt->push_color(code_dark_color); codeblock_tag = true; pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "kbd") { // Use keyboard font with custom color and background color. p_rt->push_font(doc_kbd_font); - p_rt->push_bgcolor(Color(0.5, 0.5, 0.5, 0.15)); + p_rt->push_bgcolor(kbd_bg_color); p_rt->push_color(kbd_color); code_tag = true; // Though not strictly a code tag, logic is similar. pos = brk_end + 1; @@ -2305,7 +2371,6 @@ EditorHelpBit::EditorHelpBit() { rich_text = memnew(RichTextLabel); add_child(rich_text); rich_text->connect("meta_clicked", callable_mp(this, &EditorHelpBit::_meta_clicked)); - rich_text->set_override_selected_font_color(false); rich_text->set_fit_content_height(true); set_custom_minimum_size(Size2(0, 50 * EDSCALE)); } @@ -2371,10 +2436,10 @@ void FindBar::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { find_prev->set_icon(get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); find_next->set_icon(get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); - hide_button->set_normal_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - hide_button->set_hover_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - hide_button->set_pressed_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size()); + hide_button->set_texture_normal(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); + hide_button->set_texture_hover(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); + hide_button->set_texture_pressed(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); + hide_button->set_custom_minimum_size(hide_button->get_texture_normal()->get_size()); matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); } break; diff --git a/editor/editor_help.h b/editor/editor_help.h index c9c1afb51b..15bfdc7c91 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -167,7 +167,7 @@ class EditorHelp : public VBoxContainer { Error _goto_desc(const String &p_class, int p_vscr = -1); //void _update_history_buttons(); - void _update_method_list(const Vector<DocData::MethodDoc> p_methods, bool &r_method_descrpitons); + void _update_method_list(const Vector<DocData::MethodDoc> p_methods); void _update_method_descriptions(const DocData::ClassDoc p_classdoc, const Vector<DocData::MethodDoc> p_methods, const String &p_method_type); void _update_doc(); diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index 7e7d7ca418..286dcf4b8e 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -320,15 +320,25 @@ bool EditorHelpSearch::Runner::_phase_match_classes_init() { matched_item = nullptr; match_highest_score = 0; + terms = term.split_spaces(); + if (terms.is_empty()) { + terms.append(term); + } + return true; } bool EditorHelpSearch::Runner::_phase_match_classes() { + if (!iterator_doc) { + return true; + } + DocData::ClassDoc &class_doc = iterator_doc->value; if (class_doc.name.is_empty()) { ++iterator_doc; return false; } + if (!_is_class_disabled_by_feature_profile(class_doc.name)) { ClassMatch match; match.doc = &class_doc; @@ -345,62 +355,38 @@ bool EditorHelpSearch::Runner::_phase_match_classes() { // Make an exception for annotations, since there are not that many of them. if (term.length() > 1 || term == "@") { if (search_flags & SEARCH_CONSTRUCTORS) { - for (int i = 0; i < class_doc.constructors.size(); i++) { - String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.constructors[i].name : class_doc.constructors[i].name.to_lower(); - if (method_name.find(term) > -1 || - (term.begins_with(".") && method_name.begins_with(term.substr(1))) || - (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || - (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { - match.constructors.push_back(const_cast<DocData::MethodDoc *>(&class_doc.constructors[i])); - } - } + _match_method_name_and_push_back(class_doc.constructors, &match.constructors); } if (search_flags & SEARCH_METHODS) { - for (int i = 0; i < class_doc.methods.size(); i++) { - String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower(); - if (method_name.find(term) > -1 || - (term.begins_with(".") && method_name.begins_with(term.substr(1))) || - (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || - (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { - match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i])); - } - } + _match_method_name_and_push_back(class_doc.methods, &match.methods); } if (search_flags & SEARCH_OPERATORS) { - for (int i = 0; i < class_doc.operators.size(); i++) { - String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.operators[i].name : class_doc.operators[i].name.to_lower(); - if (method_name.find(term) > -1 || - (term.begins_with(".") && method_name.begins_with(term.substr(1))) || - (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || - (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { - match.operators.push_back(const_cast<DocData::MethodDoc *>(&class_doc.operators[i])); - } - } + _match_method_name_and_push_back(class_doc.operators, &match.operators); } if (search_flags & SEARCH_SIGNALS) { for (int i = 0; i < class_doc.signals.size(); i++) { - if (_match_string(term, class_doc.signals[i].name)) { + if (_all_terms_in_name(class_doc.signals[i].name)) { match.signals.push_back(const_cast<DocData::MethodDoc *>(&class_doc.signals[i])); } } } if (search_flags & SEARCH_CONSTANTS) { for (int i = 0; i < class_doc.constants.size(); i++) { - if (_match_string(term, class_doc.constants[i].name)) { + if (_all_terms_in_name(class_doc.constants[i].name)) { match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc.constants[i])); } } } if (search_flags & SEARCH_PROPERTIES) { for (int i = 0; i < class_doc.properties.size(); i++) { - if (_match_string(term, class_doc.properties[i].name) || _match_string(term, class_doc.properties[i].getter) || _match_string(term, class_doc.properties[i].setter)) { + if (_all_terms_in_name(class_doc.properties[i].name)) { match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.properties[i])); } } } if (search_flags & SEARCH_THEME_ITEMS) { for (int i = 0; i < class_doc.theme_properties.size(); i++) { - if (_match_string(term, class_doc.theme_properties[i].name)) { + if (_all_terms_in_name(class_doc.theme_properties[i].name)) { match.theme_properties.push_back(const_cast<DocData::ThemeItemDoc *>(&class_doc.theme_properties[i])); } } @@ -412,7 +398,6 @@ bool EditorHelpSearch::Runner::_phase_match_classes() { } } } - matches[class_doc.name] = match; } matches[class_doc.name] = match; } @@ -465,7 +450,7 @@ bool EditorHelpSearch::Runner::_phase_member_items() { return false; } - TreeItem *parent = (search_flags & SEARCH_SHOW_HIERARCHY) ? class_items[match.doc->name] : root_item; + TreeItem *parent_item = (search_flags & SEARCH_SHOW_HIERARCHY) ? class_items[match.doc->name] : root_item; bool constructor_created = false; for (int i = 0; i < match.methods.size(); i++) { String text = match.methods[i]->name; @@ -479,23 +464,23 @@ bool EditorHelpSearch::Runner::_phase_member_items() { continue; } } - _create_method_item(parent, match.doc, text, match.methods[i]); + _create_method_item(parent_item, match.doc, text, match.methods[i]); } for (int i = 0; i < match.signals.size(); i++) { - _create_signal_item(parent, match.doc, match.signals[i]); + _create_signal_item(parent_item, match.doc, match.signals[i]); } for (int i = 0; i < match.constants.size(); i++) { - _create_constant_item(parent, match.doc, match.constants[i]); + _create_constant_item(parent_item, match.doc, match.constants[i]); } for (int i = 0; i < match.properties.size(); i++) { - _create_property_item(parent, match.doc, match.properties[i]); + _create_property_item(parent_item, match.doc, match.properties[i]); } for (int i = 0; i < match.theme_properties.size(); i++) { - _create_theme_property_item(parent, match.doc, match.theme_properties[i]); + _create_theme_property_item(parent_item, match.doc, match.theme_properties[i]); } for (int i = 0; i < match.annotations.size(); i++) { // Hide the redundant leading @ symbol. - _create_annotation_item(parent, match.doc, match.annotations[i]->name.substr(1), match.annotations[i]); + _create_annotation_item(parent_item, match.doc, match.annotations[i]->name.substr(1), match.annotations[i]); } ++iterator_match; @@ -509,6 +494,28 @@ bool EditorHelpSearch::Runner::_phase_select_match() { return true; } +void EditorHelpSearch::Runner::_match_method_name_and_push_back(Vector<DocData::MethodDoc> &p_methods, Vector<DocData::MethodDoc *> *r_match_methods) { + // Constructors, Methods, Operators... + for (int i = 0; i < p_methods.size(); i++) { + String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? p_methods[i].name : p_methods[i].name.to_lower(); + if (_all_terms_in_name(method_name) || + (term.begins_with(".") && method_name.begins_with(term.substr(1))) || + (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || + (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { + r_match_methods->push_back(const_cast<DocData::MethodDoc *>(&p_methods[i])); + } + } +} + +bool EditorHelpSearch::Runner::_all_terms_in_name(String name) { + for (int i = 0; i < terms.size(); i++) { + if (!_match_string(terms[i], name)) { + return false; + } + } + return true; +} + bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String &p_string) const { if (search_flags & SEARCH_CASE_SENSITIVE) { return p_string.find(p_term) > -1; @@ -560,19 +567,19 @@ TreeItem *EditorHelpSearch::Runner::_create_class_hierarchy(const ClassMatch &p_ } // Ensure parent nodes are created first. - TreeItem *parent = root_item; + TreeItem *parent_item = root_item; if (!p_match.doc->inherits.is_empty()) { if (class_items.has(p_match.doc->inherits)) { - parent = class_items[p_match.doc->inherits]; + parent_item = class_items[p_match.doc->inherits]; } else { ClassMatch &base_match = matches[p_match.doc->inherits]; if (base_match.doc) { - parent = _create_class_hierarchy(base_match); + parent_item = _create_class_hierarchy(base_match); } } } - TreeItem *class_item = _create_class_item(parent, p_match.doc, !p_match.name); + TreeItem *class_item = _create_class_item(parent_item, p_match.doc, !p_match.name); class_items[p_match.doc->name] = class_item; return class_item; } diff --git a/editor/editor_help_search.h b/editor/editor_help_search.h index efd8645cd7..a8bd219b89 100644 --- a/editor/editor_help_search.h +++ b/editor/editor_help_search.h @@ -119,6 +119,7 @@ class EditorHelpSearch::Runner : public RefCounted { Control *ui_service = nullptr; Tree *results_tree = nullptr; String term; + Vector<String> terms; int search_flags; Ref<Texture2D> empty_icon; @@ -145,6 +146,8 @@ class EditorHelpSearch::Runner : public RefCounted { String _build_method_tooltip(const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc) const; + void _match_method_name_and_push_back(Vector<DocData::MethodDoc> &p_methods, Vector<DocData::MethodDoc *> *r_match_methods); + bool _all_terms_in_name(String name); bool _match_string(const String &p_term, const String &p_string) const; void _match_item(TreeItem *p_item, const String &p_text); TreeItem *_create_class_hierarchy(const ClassMatch &p_match); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 9e7314bf50..a5397a8e6a 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -30,18 +30,19 @@ #include "editor_inspector.h" -#include "array_property_edit.h" #include "core/os/keyboard.h" -#include "dictionary_property_edit.h" #include "editor/doc_tools.h" #include "editor/editor_feature_profile.h" #include "editor/editor_node.h" #include "editor/editor_property_name_processor.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" +#include "editor/inspector_dock.h" #include "editor/plugins/script_editor_plugin.h" #include "multi_node_edit.h" -#include "scene/gui/center_container.h" +#include "scene/gui/spin_box.h" +#include "scene/gui/texture_rect.h" #include "scene/property_utils.h" #include "scene/resources/packed_scene.h" @@ -426,6 +427,9 @@ void EditorProperty::_set_read_only(bool p_read_only) { void EditorProperty::set_read_only(bool p_read_only) { read_only = p_read_only; + if (GDVIRTUAL_CALL(_set_read_only, p_read_only)) { + return; + } _set_read_only(p_read_only); } @@ -458,7 +462,7 @@ StringName EditorProperty::_get_revert_property() const { return property; } -void EditorProperty::update_revert_and_pin_status() { +void EditorProperty::update_editor_property_status() { if (property == StringName()) { return; //no property, so nothing to do } @@ -469,15 +473,26 @@ void EditorProperty::update_revert_and_pin_status() { CRASH_COND(!node); new_pinned = node->is_property_pinned(property); } + Variant current = object->get(_get_revert_property()); bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property, ¤t) && !is_read_only(); - if (new_can_revert != can_revert || new_pinned != pinned) { + bool new_checked = checked; + if (checkable) { // for properties like theme overrides. + bool valid = false; + Variant value = object->get(property, &valid); + if (valid) { + new_checked = value.get_type() != Variant::NIL; + } + } + + if (new_can_revert != can_revert || new_pinned != pinned || new_checked != checked) { if (new_can_revert != can_revert) { emit_signal(SNAME("property_can_revert_changed"), property, new_can_revert); } can_revert = new_can_revert; pinned = new_pinned; + checked = new_checked; queue_redraw(); } } @@ -645,6 +660,7 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) { } if (keying_rect.has_point(mpos)) { + accept_event(); emit_signal(SNAME("property_keyed"), property, use_keying_next()); if (use_keying_next()) { @@ -668,10 +684,12 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) { } } if (delete_rect.has_point(mpos)) { + accept_event(); emit_signal(SNAME("property_deleted"), property); } if (revert_rect.has_point(mpos)) { + accept_event(); bool is_valid_revert = false; Variant revert_value = EditorPropertyRevert::get_property_revert_value(object, property, &is_valid_revert); ERR_FAIL_COND(!is_valid_revert); @@ -680,11 +698,13 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) { } if (check_rect.has_point(mpos)) { + accept_event(); checked = !checked; queue_redraw(); emit_signal(SNAME("property_checked"), property, checked); } } else if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { + accept_event(); _update_popup(); menu->set_position(get_screen_position() + get_local_mouse_position()); menu->reset_size(); @@ -702,11 +722,11 @@ void EditorProperty::shortcut_input(const Ref<InputEvent> &p_event) { const Ref<InputEventKey> k = p_event; if (k.is_valid() && k->is_pressed()) { - if (ED_IS_SHORTCUT("property_editor/copy_property", p_event)) { - menu_option(MENU_COPY_PROPERTY); + if (ED_IS_SHORTCUT("property_editor/copy_value", p_event)) { + menu_option(MENU_COPY_VALUE); accept_event(); - } else if (ED_IS_SHORTCUT("property_editor/paste_property", p_event) && !is_read_only()) { - menu_option(MENU_PASTE_PROPERTY); + } else if (ED_IS_SHORTCUT("property_editor/paste_value", p_event) && !is_read_only()) { + menu_option(MENU_PASTE_VALUE); accept_event(); } else if (ED_IS_SHORTCUT("property_editor/copy_property_path", p_event)) { menu_option(MENU_COPY_PROPERTY_PATH); @@ -769,9 +789,9 @@ Variant EditorProperty::get_drag_data(const Point2 &p_point) { dp["property"] = property; dp["value"] = object->get(property); - Label *label = memnew(Label); - label->set_text(property); - set_drag_preview(label); + Label *drag_label = memnew(Label); + drag_label->set_text(property); + set_drag_preview(drag_label); return dp; } @@ -901,10 +921,10 @@ Control *EditorProperty::make_custom_tooltip(const String &p_text) const { void EditorProperty::menu_option(int p_option) { switch (p_option) { - case MENU_COPY_PROPERTY: { + case MENU_COPY_VALUE: { InspectorDock::get_inspector_singleton()->set_property_clipboard(object->get(property)); } break; - case MENU_PASTE_PROPERTY: { + case MENU_PASTE_VALUE: { emit_changed(property, InspectorDock::get_inspector_singleton()->get_property_clipboard()); } break; case MENU_COPY_PROPERTY_PATH: { @@ -974,7 +994,9 @@ void EditorProperty::_bind_methods() { ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "focusable_idx"))); GDVIRTUAL_BIND(_update_property) - ClassDB::bind_method(D_METHOD("_update_revert_and_pin_status"), &EditorProperty::update_revert_and_pin_status); + GDVIRTUAL_BIND(_set_read_only, "read_only") + + ClassDB::bind_method(D_METHOD("_update_editor_property_status"), &EditorProperty::update_editor_property_status); } EditorProperty::EditorProperty() { @@ -997,10 +1019,10 @@ void EditorProperty::_update_popup() { add_child(menu); menu->connect("id_pressed", callable_mp(this, &EditorProperty::menu_option)); } - menu->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/copy_property"), MENU_COPY_PROPERTY); - menu->add_icon_shortcut(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/paste_property"), MENU_PASTE_PROPERTY); + menu->add_icon_shortcut(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/copy_value"), MENU_COPY_VALUE); + menu->add_icon_shortcut(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/paste_value"), MENU_PASTE_VALUE); menu->add_icon_shortcut(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH); - menu->set_item_disabled(MENU_PASTE_PROPERTY, is_read_only()); + menu->set_item_disabled(MENU_PASTE_VALUE, is_read_only()); if (!pin_hidden) { menu->add_separator(); if (can_pin) { @@ -1045,11 +1067,9 @@ void EditorInspectorPlugin::add_property_editor_for_multiple_properties(const St } bool EditorInspectorPlugin::can_handle(Object *p_object) { - bool success; - if (GDVIRTUAL_CALL(_can_handle, p_object, success)) { - return success; - } - return false; + bool success = false; + GDVIRTUAL_CALL(_can_handle, p_object, success); + return success; } void EditorInspectorPlugin::parse_begin(Object *p_object) { @@ -1065,11 +1085,9 @@ void EditorInspectorPlugin::parse_group(Object *p_object, const String &p_group) } bool EditorInspectorPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) { - bool ret; - if (GDVIRTUAL_CALL(_parse_property, p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_parse_property, p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide, ret); + return ret; } void EditorInspectorPlugin::parse_end(Object *p_object) { @@ -1127,11 +1145,10 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons } Size2 EditorInspectorCategory::get_minimum_size() const { - Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Tree")); - int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); + Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); Size2 ms; - ms.width = 1; ms.height = font->get_height(font_size); if (icon.is_valid()) { ms.height = MAX(icon->get_height(), ms.height); @@ -1470,6 +1487,8 @@ void EditorInspectorSection::gui_input(const Ref<InputEvent> &p_event) { return; } + accept_event(); + bool should_unfold = !object->editor_is_section_unfolded(section); if (should_unfold) { unfold(); @@ -1560,9 +1579,9 @@ int EditorInspectorArray::_get_array_count() { return _extract_properties_as_array(object_property_list).size(); } else if (mode == MODE_USE_COUNT_PROPERTY) { bool valid; - int count = object->get(count_property, &valid); + int count_val = object->get(count_property, &valid); ERR_FAIL_COND_V_MSG(!valid, 0, vformat("%s is not a valid property to be used as array count.", count_property)); - return count; + return count_val; } return 0; } @@ -1668,6 +1687,7 @@ void EditorInspectorArray::_panel_gui_input(Ref<InputEvent> p_event, int p_index Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { if (movable && mb->get_button_index() == MouseButton::RIGHT) { + array_elements[p_index].panel->accept_event(); popup_array_index_pressed = begin_array_index + p_index; rmb_popup->set_item_disabled(OPTION_MOVE_UP, popup_array_index_pressed == 0); rmb_popup->set_item_disabled(OPTION_MOVE_DOWN, popup_array_index_pressed == count - 1); @@ -1687,6 +1707,7 @@ void EditorInspectorArray::_move_element(int p_element_index, int p_to_pos) { } else { action_name = vformat("Move element %d to position %d in property array with prefix %s.", p_element_index, p_to_pos, array_element_prefix); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(action_name); if (mode == MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION) { // Call the function. @@ -1830,6 +1851,7 @@ void EditorInspectorArray::_move_element(int p_element_index, int p_to_pos) { } void EditorInspectorArray::_clear_array() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat("Clear property array with prefix %s.", array_element_prefix)); if (mode == MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION) { for (int i = count - 1; i >= 0; i--) { @@ -1882,6 +1904,7 @@ void EditorInspectorArray::_resize_array(int p_size) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat("Resize property array with prefix %s.", array_element_prefix)); if (p_size > count) { if (mode == MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION) { @@ -2231,10 +2254,6 @@ void EditorInspectorArray::_bind_methods() { ADD_SIGNAL(MethodInfo("page_change_request")); } -void EditorInspectorArray::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void EditorInspectorArray::setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable, bool p_numbered, int p_page_length, const String &p_add_item_text) { count_property = ""; mode = MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION; @@ -2497,10 +2516,6 @@ Button *EditorInspector::create_inspector_action_button(const String &p_text) { return button; } -void EditorInspector::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - String EditorInspector::get_selected_path() const { return property_selected; } @@ -2512,7 +2527,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, EditorIn if (ep) { ep->object = object; - ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed)); + ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed).bind(false)); ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); @@ -2552,7 +2567,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, EditorIn ep->set_read_only(read_only); ep->update_property(); ep->_update_pin_flags(); - ep->update_revert_and_pin_status(); + ep->update_editor_property_status(); ep->set_deletable(deletable_properties); ep->update_cache(); } @@ -2753,13 +2768,13 @@ void EditorInspector::update_tree() { // Set the category icon. if (!EditorNode::get_editor_data().is_type_recognized(type) && p.hint_string.length() && FileAccess::exists(p.hint_string)) { // If we have a category inside a script, search for the first script with a valid icon. - Ref<Script> script = ResourceLoader::load(p.hint_string, "Script"); + Ref<Script> scr = ResourceLoader::load(p.hint_string, "Script"); StringName base_type; StringName name; - if (script.is_valid()) { - base_type = script->get_instance_base_type(); - name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); - Vector<DocData::ClassDoc> docs = script->get_documentation(); + if (scr.is_valid()) { + base_type = scr->get_instance_base_type(); + name = EditorNode::get_editor_data().script_class_get_name(scr->get_path()); + Vector<DocData::ClassDoc> docs = scr->get_documentation(); if (!docs.is_empty()) { doc_name = docs[0].name; } @@ -2767,20 +2782,20 @@ void EditorInspector::update_tree() { label = name; } } - while (script.is_valid()) { - name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); + while (scr.is_valid()) { + name = EditorNode::get_editor_data().script_class_get_name(scr->get_path()); String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name); if (name != StringName() && !icon_path.is_empty()) { category->icon = ResourceLoader::load(icon_path, "Texture"); break; } - const EditorData::CustomType *ctype = EditorNode::get_editor_data().get_custom_type_by_path(script->get_path()); + const EditorData::CustomType *ctype = EditorNode::get_editor_data().get_custom_type_by_path(scr->get_path()); if (ctype) { category->icon = ctype->icon; break; } - script = script->get_base_script(); + scr = scr->get_base_script(); } if (category->icon.is_null() && has_theme_icon(base_type, SNAME("EditorIcons"))) { category->icon = get_theme_icon(base_type, SNAME("EditorIcons")); @@ -3038,7 +3053,7 @@ void EditorInspector::update_tree() { bool movable = true; bool numbered = false; bool foldable = use_folding; - String add_button_text; + String add_button_text = TTR("Add Element"); String swap_method; for (int i = (p.type == Variant::NIL ? 1 : 2); i < class_name_components.size(); i++) { if (class_name_components[i].begins_with("page_size") && class_name_components[i].get_slice_count("=") == 2) { @@ -3066,7 +3081,6 @@ void EditorInspector::update_tree() { int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0; editor_inspector_array->setup_with_move_element_function(object, array_label, array_element_prefix, page, c, use_folding); editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request).bind(array_element_prefix)); - editor_inspector_array->set_undo_redo(undo_redo); } else if (p.type == Variant::INT) { // Setup the array to use the count property and built-in functions to create/move/delete elements. if (class_name_components.size() >= 2) { @@ -3076,8 +3090,6 @@ void EditorInspector::update_tree() { editor_inspector_array->setup_with_count_property(object, class_name_components[0], p.name, array_element_prefix, page, c, foldable, movable, numbered, page_size, add_button_text, swap_method); editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request).bind(array_element_prefix)); - - editor_inspector_array->set_undo_redo(undo_redo); } } @@ -3110,11 +3122,24 @@ void EditorInspector::update_tree() { // Build the doc hint, to use as tooltip. // Get the class name. - StringName classname = doc_name == "" ? object->get_class_name() : doc_name; + StringName classname = doc_name; if (!object_class.is_empty()) { classname = object_class; } else if (Object::cast_to<MultiNodeEdit>(object)) { classname = Object::cast_to<MultiNodeEdit>(object)->get_edited_class_name(); + } else if (classname == "") { + classname = object->get_class_name(); + Resource *res = Object::cast_to<Resource>(object); + if (res && !res->get_script().is_null()) { + // Grab the script of this resource to get the evaluated script class. + Ref<Script> scr = res->get_script(); + if (scr.is_valid()) { + Vector<DocData::ClassDoc> docs = scr->get_documentation(); + if (!docs.is_empty()) { + classname = docs[0].name; + } + } + } } StringName propname = property_prefix + p.name; @@ -3211,6 +3236,7 @@ void EditorInspector::update_tree() { // Use the existing one. ep->set_label(property_label_string); } + for (int j = 0; j < properties.size(); j++) { String prop = properties[j]; @@ -3258,7 +3284,7 @@ void EditorInspector::update_tree() { ep->set_doc_path(doc_info.path); ep->update_property(); ep->_update_pin_flags(); - ep->update_revert_and_pin_status(); + ep->update_editor_property_status(); ep->update_cache(); if (current_selected && ep->property == current_selected) { @@ -3297,7 +3323,7 @@ void EditorInspector::update_property(const String &p_prop) { for (EditorProperty *E : editor_property_map[p_prop]) { E->update_property(); - E->update_revert_and_pin_status(); + E->update_editor_property_status(); E->update_cache(); } } @@ -3447,7 +3473,7 @@ void EditorInspector::expand_revertable() { } } - // Climb up the hierachy doing double buffering with the sets. + // Climb up the hierarchy doing double buffering with the sets. int a = 0; int b = 1; while (sections_to_unfold[a].size()) { @@ -3553,6 +3579,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (!undo_redo.is_valid() || bool(object->call("_dont_undo_redo"))) { object->set(p_name, p_value); if (p_refresh_all) { @@ -3640,7 +3667,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo if (editor_property_map.has(p_name)) { for (EditorProperty *E : editor_property_map[p_name]) { - E->update_revert_and_pin_status(); + E->update_editor_property_status(); } } } @@ -3673,6 +3700,7 @@ void EditorInspector::_multiple_properties_changed(Vector<String> p_paths, Array } names += p_paths[i]; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Multiple:") + " " + names, UndoRedo::MERGE_ENDS); for (int i = 0; i < p_paths.size(); i++) { _edit_set(p_paths[i], p_values[i], false, ""); @@ -3707,6 +3735,7 @@ void EditorInspector::_property_deleted(const String &p_path) { if (p_path.begins_with("metadata/")) { String name = p_path.replace_first("metadata/", ""); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Remove metadata %s"), name)); undo_redo->add_do_method(object, "remove_meta", name); undo_redo->add_undo_method(object, "set_meta", name, object->get_meta(name)); @@ -3754,7 +3783,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { for (EditorProperty *E : editor_property_map[p_path]) { E->set_checked(p_checked); E->update_property(); - E->update_revert_and_pin_status(); + E->update_editor_property_status(); E->update_cache(); } } @@ -3772,14 +3801,15 @@ void EditorInspector::_property_pinned(const String &p_path, bool p_pinned) { Node *node = Object::cast_to<Node>(object); ERR_FAIL_COND(!node); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (undo_redo.is_valid()) { undo_redo->create_action(vformat(p_pinned ? TTR("Pinned %s") : TTR("Unpinned %s"), p_path)); undo_redo->add_do_method(node, "_set_property_pinned", p_path, p_pinned); undo_redo->add_undo_method(node, "_set_property_pinned", p_path, !p_pinned); if (editor_property_map.has(p_path)) { for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) { - undo_redo->add_do_method(E->get(), "_update_revert_and_pin_status"); - undo_redo->add_undo_method(E->get(), "_update_revert_and_pin_status"); + undo_redo->add_do_method(E->get(), "_update_editor_property_status"); + undo_redo->add_undo_method(E->get(), "_update_editor_property_status"); } } undo_redo->commit_action(); @@ -3787,7 +3817,7 @@ void EditorInspector::_property_pinned(const String &p_path, bool p_pinned) { node->set_property_pinned(p_path, p_pinned); if (editor_property_map.has(p_path)) { for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) { - E->get()->update_revert_and_pin_status(); + E->get()->update_editor_property_status(); } } } @@ -3860,7 +3890,7 @@ void EditorInspector::_notification(int p_what) { update_scroll_request = -1; } if (update_tree_pending) { - refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval")); + refresh_countdown = float(EDITOR_GET("docks/property_editor/auto_refresh_interval")); } else if (refresh_countdown > 0) { refresh_countdown -= get_process_delta_time(); if (refresh_countdown <= 0) { @@ -3868,12 +3898,12 @@ void EditorInspector::_notification(int p_what) { for (EditorProperty *E : F.value) { if (E && !E->is_cache_valid()) { E->update_property(); - E->update_revert_and_pin_status(); + E->update_editor_property_status(); E->update_cache(); } } } - refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval")); + refresh_countdown = float(EDITOR_GET("docks/property_editor/auto_refresh_interval")); } } @@ -3890,7 +3920,7 @@ void EditorInspector::_notification(int p_what) { if (editor_property_map.has(prop)) { for (EditorProperty *E : editor_property_map[prop]) { E->update_property(); - E->update_revert_and_pin_status(); + E->update_editor_property_status(); E->update_cache(); } } @@ -3969,6 +3999,7 @@ void EditorInspector::_add_meta_confirm() { Variant defval; Callable::CallError ce; Variant::construct(Variant::Type(add_meta_type->get_selected_id()), defval, nullptr, 0, ce); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Add metadata %s"), name)); undo_redo->add_do_method(object, "set_meta", name, defval); undo_redo->add_undo_method(object, "remove_meta", name); @@ -3983,13 +4014,7 @@ void EditorInspector::_check_meta_name(const String &p_name) { } else if (!p_name.is_valid_identifier()) { error = TTR("Metadata name must be a valid identifier."); } else if (object->has_meta(p_name)) { - Node *node = Object::cast_to<Node>(object); - if (node) { - error = vformat(TTR("Metadata with name \"%s\" already exists on \"%s\"."), p_name, node->get_name()); - } else { - // This should normally never be reached, but the error is set just in case. - error = vformat(TTR("Metadata with name \"%s\" already exists."), p_name, node->get_name()); - } + error = vformat(TTR("Metadata with name \"%s\" already exists."), p_name); } else if (p_name[0] == '_') { error = TTR("Names starting with _ are reserved for editor-only metadata."); } @@ -4009,14 +4034,6 @@ void EditorInspector::_show_add_meta_dialog() { if (!add_meta_dialog) { add_meta_dialog = memnew(ConfirmationDialog); - Node *node = Object::cast_to<Node>(object); - if (node) { - add_meta_dialog->set_title(vformat(TTR("Add Metadata Property for \"%s\""), node->get_name())); - } else { - // This should normally never be reached, but the title is set just in case. - add_meta_dialog->set_title(vformat(TTR("Add Metadata Property"), node->get_name())); - } - VBoxContainer *vbc = memnew(VBoxContainer); add_meta_dialog->add_child(vbc); HBoxContainer *hbc = memnew(HBoxContainer); @@ -4046,6 +4063,14 @@ void EditorInspector::_show_add_meta_dialog() { add_meta_name->connect("text_changed", callable_mp(this, &EditorInspector::_check_meta_name)); } + Node *node = Object::cast_to<Node>(object); + if (node) { + add_meta_dialog->set_title(vformat(TTR("Add Metadata Property for \"%s\""), node->get_name())); + } else { + // This should normally be reached when the object is derived from Resource. + add_meta_dialog->set_title(vformat(TTR("Add Metadata Property for \"%s\""), object->get_class())); + } + add_meta_dialog->popup_centered(); add_meta_name->set_text(""); _check_meta_name(""); @@ -4054,6 +4079,7 @@ void EditorInspector::_show_add_meta_dialog() { void EditorInspector::_bind_methods() { ClassDB::bind_method("_edit_request_change", &EditorInspector::_edit_request_change); + ClassDB::bind_method("get_selected_path", &EditorInspector::get_selected_path); ADD_SIGNAL(MethodInfo("property_selected", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::BOOL, "advance"))); @@ -4084,13 +4110,13 @@ EditorInspector::EditorInspector() { get_v_scroll_bar()->connect("value_changed", callable_mp(this, &EditorInspector::_vscroll_changed)); update_scroll_request = -1; if (EditorSettings::get_singleton()) { - refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval")); + refresh_countdown = float(EDITOR_GET("docks/property_editor/auto_refresh_interval")); } else { //used when class is created by the docgen to dump default values of everything bindable, editorsettings may not be created refresh_countdown = 0.33; } - ED_SHORTCUT("property_editor/copy_property", TTR("Copy Property"), KeyModifierMask::CMD_OR_CTRL | Key::C); - ED_SHORTCUT("property_editor/paste_property", TTR("Paste Property"), KeyModifierMask::CMD_OR_CTRL | Key::V); + ED_SHORTCUT("property_editor/copy_value", TTR("Copy Value"), KeyModifierMask::CMD_OR_CTRL | Key::C); + ED_SHORTCUT("property_editor/paste_value", TTR("Paste Value"), KeyModifierMask::CMD_OR_CTRL | Key::V); ED_SHORTCUT("property_editor/copy_property_path", TTR("Copy Property Path"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::C); } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 70378d8cf2..41651494ce 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -31,17 +31,19 @@ #ifndef EDITOR_INSPECTOR_H #define EDITOR_INSPECTOR_H -#include "editor/editor_undo_redo_manager.h" #include "editor_property_name_processor.h" #include "scene/gui/box_container.h" -#include "scene/gui/button.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/option_button.h" -#include "scene/gui/panel_container.h" #include "scene/gui/scroll_container.h" -#include "scene/gui/spin_box.h" -#include "scene/gui/texture_rect.h" + +class AcceptDialog; +class Button; +class ConfirmationDialog; +class LineEdit; +class OptionButton; +class PanelContainer; +class PopupMenu; +class SpinBox; +class TextureRect; class EditorPropertyRevert { public: @@ -58,8 +60,8 @@ class EditorProperty : public Container { public: enum MenuItems { - MENU_COPY_PROPERTY, - MENU_PASTE_PROPERTY, + MENU_COPY_VALUE, + MENU_PASTE_VALUE, MENU_COPY_PROPERTY_PATH, MENU_PIN_VALUE, MENU_OPEN_DOCUMENTATION, @@ -120,6 +122,8 @@ private: HashMap<StringName, Variant> cache; GDVIRTUAL0(_update_property) + GDVIRTUAL1(_set_read_only, bool) + void _update_pin_flags(); protected: @@ -151,7 +155,7 @@ public: void set_doc_path(const String &p_doc_path); virtual void update_property(); - void update_revert_and_pin_status(); + void update_editor_property_status(); virtual bool use_keying_next() const; @@ -303,8 +307,6 @@ public: class EditorInspectorArray : public EditorInspectorSection { GDCLASS(EditorInspectorArray, EditorInspectorSection); - Ref<EditorUndoRedoManager> undo_redo; - enum Mode { MODE_NONE, MODE_USE_COUNT_PROPERTY, @@ -399,8 +401,6 @@ protected: static void _bind_methods(); public: - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); - void setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable = true, bool p_numbered = false, int p_page_length = 5, const String &p_add_item_text = ""); void setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable = true, bool p_numbered = false, int p_page_length = 5, const String &p_add_item_text = "", const String &p_swap_method = ""); VBoxContainer *get_vbox(int p_index); @@ -439,7 +439,6 @@ public: class EditorInspector : public ScrollContainer { GDCLASS(EditorInspector, ScrollContainer); - Ref<EditorUndoRedoManager> undo_redo; enum { MAX_PLUGINS = 1024 }; @@ -553,8 +552,6 @@ public: static EditorProperty *instantiate_property_editor(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false); - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); - String get_selected_path() const; void update_tree(); diff --git a/editor/editor_locale_dialog.cpp b/editor/editor_locale_dialog.cpp index 87da67fb05..a913fb2fd9 100644 --- a/editor/editor_locale_dialog.cpp +++ b/editor/editor_locale_dialog.cpp @@ -123,7 +123,7 @@ void EditorLocaleDialog::_filter_lang_option_changed() { Array f_lang_all; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/language_filter")) { - f_lang_all = ProjectSettings::get_singleton()->get("internationalization/locale/language_filter"); + f_lang_all = GLOBAL_GET("internationalization/locale/language_filter"); prev = f_lang_all; } @@ -141,6 +141,7 @@ void EditorLocaleDialog::_filter_lang_option_changed() { f_lang_all.sort(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Changed Locale Language Filter")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", f_lang_all); undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", prev); @@ -149,22 +150,22 @@ void EditorLocaleDialog::_filter_lang_option_changed() { void EditorLocaleDialog::_filter_script_option_changed() { TreeItem *t = script_list->get_edited(); - String script = t->get_metadata(0); + String scr_code = t->get_metadata(0); bool checked = t->is_checked(0); Variant prev; Array f_script_all; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/script_filter")) { - f_script_all = ProjectSettings::get_singleton()->get("internationalization/locale/script_filter"); + f_script_all = GLOBAL_GET("internationalization/locale/script_filter"); prev = f_script_all; } - int l_idx = f_script_all.find(script); + int l_idx = f_script_all.find(scr_code); if (checked) { if (l_idx == -1) { - f_script_all.append(script); + f_script_all.append(scr_code); } } else { if (l_idx != -1) { @@ -174,6 +175,7 @@ void EditorLocaleDialog::_filter_script_option_changed() { f_script_all.sort(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Changed Locale Script Filter")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", f_script_all); undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", prev); @@ -189,7 +191,7 @@ void EditorLocaleDialog::_filter_cnt_option_changed() { Array f_cnt_all; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/country_filter")) { - f_cnt_all = ProjectSettings::get_singleton()->get("internationalization/locale/country_filter"); + f_cnt_all = GLOBAL_GET("internationalization/locale/country_filter"); prev = f_cnt_all; } @@ -207,6 +209,7 @@ void EditorLocaleDialog::_filter_cnt_option_changed() { f_cnt_all.sort(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Changed Locale Country Filter")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", f_cnt_all); undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", prev); @@ -218,9 +221,10 @@ void EditorLocaleDialog::_filter_mode_changed(int p_mode) { Variant prev; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter_mode")) { - prev = ProjectSettings::get_singleton()->get("internationalization/locale/locale_filter_mode"); + prev = GLOBAL_GET("internationalization/locale/locale_filter_mode"); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Changed Locale Filter Mode")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", f_mode); undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", prev); @@ -238,19 +242,19 @@ void EditorLocaleDialog::_update_tree() { int filter = SHOW_ALL_LOCALES; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter_mode")) { - filter = ProjectSettings::get_singleton()->get("internationalization/locale/locale_filter_mode"); + filter = GLOBAL_GET("internationalization/locale/locale_filter_mode"); } Array f_lang_all; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/language_filter")) { - f_lang_all = ProjectSettings::get_singleton()->get("internationalization/locale/language_filter"); + f_lang_all = GLOBAL_GET("internationalization/locale/language_filter"); } Array f_cnt_all; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/country_filter")) { - f_cnt_all = ProjectSettings::get_singleton()->get("internationalization/locale/country_filter"); + f_cnt_all = GLOBAL_GET("internationalization/locale/country_filter"); } Array f_script_all; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/script_filter")) { - f_script_all = ProjectSettings::get_singleton()->get("internationalization/locale/script_filter"); + f_script_all = GLOBAL_GET("internationalization/locale/script_filter"); } bool is_edit_mode = edit_filters->is_pressed(); @@ -298,7 +302,7 @@ void EditorLocaleDialog::_update_tree() { Vector<String> scripts = TranslationServer::get_singleton()->get_all_scripts(); for (const String &E : scripts) { if (is_edit_mode || (filter == SHOW_ALL_LOCALES) || f_script_all.has(E) || f_script_all.is_empty()) { - const String &script = TranslationServer::get_singleton()->get_script_name(E); + const String &scr_code = TranslationServer::get_singleton()->get_script_name(E); TreeItem *t = script_list->create_item(s_root); if (is_edit_mode) { t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); @@ -307,7 +311,7 @@ void EditorLocaleDialog::_update_tree() { } else if (script_code->get_text() == E) { t->select(0); } - t->set_text(0, vformat("%s [%s]", script, E)); + t->set_text(0, vformat("%s [%s]", scr_code, E)); t->set_metadata(0, E); } } @@ -385,8 +389,6 @@ void EditorLocaleDialog::popup_locale_dialog() { } EditorLocaleDialog::EditorLocaleDialog() { - undo_redo = EditorNode::get_undo_redo(); - set_title(TTR("Select a Locale")); VBoxContainer *vb = memnew(VBoxContainer); diff --git a/editor/editor_locale_dialog.h b/editor/editor_locale_dialog.h index 8ac642a038..48f9edd4b0 100644 --- a/editor/editor_locale_dialog.h +++ b/editor/editor_locale_dialog.h @@ -40,7 +40,6 @@ class VBoxContainer; class LineEdit; class Tree; class OptionButton; -class EditorUndoRedoManager; class EditorLocaleDialog : public ConfirmationDialog { GDCLASS(EditorLocaleDialog, ConfirmationDialog); @@ -63,8 +62,6 @@ class EditorLocaleDialog : public ConfirmationDialog { Tree *script_list = nullptr; Tree *cnt_list = nullptr; - Ref<EditorUndoRedoManager> undo_redo; - bool locale_set = false; bool updating_lists = false; diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 6e6a898757..84284a7f31 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -30,6 +30,7 @@ #include "editor_log.h" +#include "core/object/undo_redo.h" #include "core/os/keyboard.h" #include "core/version.h" #include "editor/editor_node.h" @@ -65,19 +66,34 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f } void EditorLog::_update_theme() { - Ref<Font> normal_font = get_theme_font(SNAME("output_source"), SNAME("EditorFonts")); + const Ref<Font> normal_font = get_theme_font(SNAME("output_source"), SNAME("EditorFonts")); if (normal_font.is_valid()) { log->add_theme_font_override("normal_font", normal_font); } - log->add_theme_font_size_override("normal_font_size", get_theme_font_size(SNAME("output_source_size"), SNAME("EditorFonts"))); - log->add_theme_color_override("selection_color", get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); - - Ref<Font> bold_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); + const Ref<Font> bold_font = get_theme_font(SNAME("output_source_bold"), SNAME("EditorFonts")); if (bold_font.is_valid()) { log->add_theme_font_override("bold_font", bold_font); } + const Ref<Font> italics_font = get_theme_font(SNAME("output_source_italic"), SNAME("EditorFonts")); + if (italics_font.is_valid()) { + log->add_theme_font_override("italics_font", italics_font); + } + + const Ref<Font> bold_italics_font = get_theme_font(SNAME("output_source_bold_italic"), SNAME("EditorFonts")); + if (bold_italics_font.is_valid()) { + log->add_theme_font_override("bold_italics_font", bold_italics_font); + } + + const Ref<Font> mono_font = get_theme_font(SNAME("output_source_mono"), SNAME("EditorFonts")); + if (mono_font.is_valid()) { + log->add_theme_font_override("mono_font", mono_font); + } + + log->add_theme_font_size_override("normal_font_size", get_theme_font_size(SNAME("output_source_size"), SNAME("EditorFonts"))); + log->add_theme_color_override("selection_color", get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); + type_filter_map[MSG_TYPE_STD]->toggle_button->set_icon(get_theme_icon(SNAME("Popup"), SNAME("EditorIcons"))); type_filter_map[MSG_TYPE_ERROR]->toggle_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"))); type_filter_map[MSG_TYPE_WARNING]->toggle_button->set_icon(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); @@ -211,7 +227,7 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) { // Make text split by new lines their own message. // See #41321 for reasoning. At time of writing, multiple print()'s in running projects // get grouped together and sent to the editor log as one message. This can mess with the - // search functionality (see the comments on the PR above for more details). This behaviour + // search functionality (see the comments on the PR above for more details). This behavior // also matches that of other IDE's. Vector<String> lines = p_msg.split("\n", true); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 8eaddcb7e1..d00a64f796 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -37,7 +37,6 @@ #include "core/io/image_loader.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/io/stream_peer_tls.h" #include "core/object/class_db.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" @@ -47,10 +46,7 @@ #include "core/string/translation.h" #include "core/version.h" #include "main/main.h" -#include "scene/3d/importer_mesh_instance_3d.h" -#include "scene/gui/center_container.h" #include "scene/gui/color_picker.h" -#include "scene/gui/control.h" #include "scene/gui/dialogs.h" #include "scene/gui/file_dialog.h" #include "scene/gui/link_button.h" @@ -61,18 +57,13 @@ #include "scene/gui/split_container.h" #include "scene/gui/tab_bar.h" #include "scene/gui/tab_container.h" -#include "scene/gui/texture_progress_bar.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "servers/display_server.h" -#include "servers/navigation_server_2d.h" #include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" -#include "servers/rendering/rendering_device.h" -#include "editor/animation_track_editor.h" #include "editor/audio_stream_preview.h" -#include "editor/debugger/debug_adapter/debug_adapter_server.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/dependency_editor.h" #include "editor/editor_about.h" @@ -82,7 +73,6 @@ #include "editor/editor_data.h" #include "editor/editor_feature_profile.h" #include "editor/editor_file_dialog.h" -#include "editor/editor_file_system.h" #include "editor/editor_folding.h" #include "editor/editor_help.h" #include "editor/editor_inspector.h" @@ -93,15 +83,12 @@ #include "editor/editor_properties.h" #include "editor/editor_property_name_processor.h" #include "editor/editor_quick_open.h" -#include "editor/editor_resource_picker.h" #include "editor/editor_resource_preview.h" #include "editor/editor_run.h" #include "editor/editor_run_native.h" -#include "editor/editor_run_script.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_settings_dialog.h" -#include "editor/editor_spin_slider.h" #include "editor/editor_themes.h" #include "editor/editor_toaster.h" #include "editor/editor_translation_parser.h" @@ -110,6 +97,7 @@ #include "editor/export/export_template_manager.h" #include "editor/export/project_export.h" #include "editor/filesystem_dock.h" +#include "editor/history_dock.h" #include "editor/import/audio_stream_import_settings.h" #include "editor/import/dynamic_font_import_settings.h" #include "editor/import/editor_import_collada.h" @@ -121,88 +109,32 @@ #include "editor/import/resource_importer_imagefont.h" #include "editor/import/resource_importer_layered_texture.h" #include "editor/import/resource_importer_obj.h" -#include "editor/import/resource_importer_scene.h" #include "editor/import/resource_importer_shader_file.h" #include "editor/import/resource_importer_texture.h" #include "editor/import/resource_importer_texture_atlas.h" #include "editor/import/resource_importer_wav.h" #include "editor/import/scene_import_settings.h" #include "editor/import_dock.h" +#include "editor/inspector_dock.h" #include "editor/multi_node_edit.h" #include "editor/node_dock.h" #include "editor/plugin_config_dialog.h" -#include "editor/plugins/animation_blend_space_1d_editor.h" -#include "editor/plugins/animation_blend_space_2d_editor.h" -#include "editor/plugins/animation_blend_tree_editor_plugin.h" #include "editor/plugins/animation_player_editor_plugin.h" -#include "editor/plugins/animation_state_machine_editor.h" -#include "editor/plugins/animation_tree_editor_plugin.h" #include "editor/plugins/asset_library_editor_plugin.h" -#include "editor/plugins/audio_stream_randomizer_editor_plugin.h" -#include "editor/plugins/bit_map_editor_plugin.h" -#include "editor/plugins/bone_map_editor_plugin.h" -#include "editor/plugins/camera_3d_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h" -#include "editor/plugins/cast_2d_editor_plugin.h" -#include "editor/plugins/collision_polygon_2d_editor_plugin.h" -#include "editor/plugins/collision_shape_2d_editor_plugin.h" -#include "editor/plugins/control_editor_plugin.h" -#include "editor/plugins/cpu_particles_2d_editor_plugin.h" -#include "editor/plugins/cpu_particles_3d_editor_plugin.h" -#include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/debugger_editor_plugin.h" -#include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/editor_preview_plugins.h" #include "editor/plugins/editor_resource_conversion_plugin.h" -#include "editor/plugins/font_config_plugin.h" #include "editor/plugins/gdextension_export_plugin.h" -#include "editor/plugins/gpu_particles_2d_editor_plugin.h" -#include "editor/plugins/gpu_particles_3d_editor_plugin.h" -#include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h" -#include "editor/plugins/gradient_editor_plugin.h" -#include "editor/plugins/gradient_texture_2d_editor_plugin.h" -#include "editor/plugins/input_event_editor_plugin.h" -#include "editor/plugins/light_occluder_2d_editor_plugin.h" -#include "editor/plugins/lightmap_gi_editor_plugin.h" -#include "editor/plugins/line_2d_editor_plugin.h" #include "editor/plugins/material_editor_plugin.h" -#include "editor/plugins/mesh_editor_plugin.h" -#include "editor/plugins/mesh_instance_3d_editor_plugin.h" #include "editor/plugins/mesh_library_editor_plugin.h" -#include "editor/plugins/multimesh_editor_plugin.h" -#include "editor/plugins/navigation_link_2d_editor_plugin.h" -#include "editor/plugins/navigation_polygon_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" -#include "editor/plugins/occluder_instance_3d_editor_plugin.h" #include "editor/plugins/packed_scene_translation_parser_plugin.h" -#include "editor/plugins/path_2d_editor_plugin.h" -#include "editor/plugins/path_3d_editor_plugin.h" -#include "editor/plugins/physical_bone_3d_editor_plugin.h" -#include "editor/plugins/polygon_2d_editor_plugin.h" -#include "editor/plugins/polygon_3d_editor_plugin.h" -#include "editor/plugins/resource_preloader_editor_plugin.h" #include "editor/plugins/root_motion_editor_plugin.h" -#include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_text_editor.h" -#include "editor/plugins/shader_editor_plugin.h" -#include "editor/plugins/shader_file_editor_plugin.h" -#include "editor/plugins/skeleton_2d_editor_plugin.h" -#include "editor/plugins/skeleton_3d_editor_plugin.h" -#include "editor/plugins/skeleton_ik_3d_editor_plugin.h" -#include "editor/plugins/sprite_2d_editor_plugin.h" -#include "editor/plugins/sprite_frames_editor_plugin.h" -#include "editor/plugins/style_box_editor_plugin.h" -#include "editor/plugins/sub_viewport_preview_editor_plugin.h" #include "editor/plugins/text_editor.h" -#include "editor/plugins/texture_3d_editor_plugin.h" -#include "editor/plugins/texture_editor_plugin.h" -#include "editor/plugins/texture_layered_editor_plugin.h" -#include "editor/plugins/texture_region_editor_plugin.h" -#include "editor/plugins/theme_editor_plugin.h" -#include "editor/plugins/tiles/tiles_editor_plugin.h" #include "editor/plugins/version_control_editor_plugin.h" #include "editor/plugins/visual_shader_editor_plugin.h" -#include "editor/plugins/voxel_gi_editor_plugin.h" #include "editor/progress_dialog.h" #include "editor/project_settings_editor.h" #include "editor/register_exporters.h" @@ -243,15 +175,11 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto String full_path = p_full_paths[set_idx]; // Get rid of file extensions and res:// prefixes. - if (scene_name.rfind(".") >= 0) { - scene_name = scene_name.substr(0, scene_name.rfind(".")); - } + scene_name = scene_name.get_basename(); if (full_path.begins_with("res://")) { full_path = full_path.substr(6); } - if (full_path.rfind(".") >= 0) { - full_path = full_path.substr(0, full_path.rfind(".")); - } + full_path = full_path.get_basename(); // Normalize trailing slashes when normalizing directory names. scene_name = scene_name.trim_suffix("/"); @@ -269,7 +197,7 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto String parent = full_path.substr(0, difference); int slash_idx = parent.rfind("/"); slash_idx = parent.rfind("/", slash_idx - 1); - parent = slash_idx >= 0 ? parent.substr(slash_idx + 1) : parent; + parent = (slash_idx >= 0 && parent.length() > 1) ? parent.substr(slash_idx + 1) : parent; r_filenames.write[set_idx] = parent + r_filenames[set_idx]; } } @@ -301,15 +229,11 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto String path = p_full_paths[E->get()]; // Get rid of file extensions and res:// prefixes. - if (scene_name.rfind(".") >= 0) { - scene_name = scene_name.substr(0, scene_name.rfind(".")); - } + scene_name = scene_name.get_basename(); if (path.begins_with("res://")) { path = path.substr(6); } - if (path.rfind(".") >= 0) { - path = path.substr(0, path.rfind(".")); - } + path = path.get_basename(); // Normalize trailing slashes when normalizing directory names. scene_name = scene_name.trim_suffix("/"); @@ -335,7 +259,7 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto // TODO: This REALLY should be done in a better way than replacing all tabs after almost EVERY action. void EditorNode::_update_scene_tabs() { - bool show_rb = EditorSettings::get_singleton()->get("interface/scene_tabs/show_script_button"); + bool show_rb = EDITOR_GET("interface/scene_tabs/show_script_button"); if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) { DisplayServer::get_singleton()->global_menu_clear("_dock"); @@ -428,8 +352,8 @@ void EditorNode::_version_control_menu_option(int p_idx) { } void EditorNode::_update_title() { - const String appname = ProjectSettings::get_singleton()->get("application/config/name"); - String title = (appname.is_empty() ? TTR("Unnamed Project") : appname) + String(" - ") + VERSION_NAME; + const String appname = GLOBAL_GET("application/config/name"); + String title = (appname.is_empty() ? TTR("Unnamed Project") : appname); const String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_scene_file_path() : String(); if (!edited.is_empty()) { // Display the edited scene name before the program name so that it can be seen in the OS task bar. @@ -439,8 +363,10 @@ void EditorNode::_update_title() { // Display the "modified" mark before anything else so that it can always be seen in the OS task bar. title = vformat("(*) %s", title); } - - DisplayServer::get_singleton()->window_set_title(title); + DisplayServer::get_singleton()->window_set_title(title + String(" - ") + VERSION_NAME); + if (project_title) { + project_title->set_text(title); + } } void EditorNode::shortcut_input(const Ref<InputEvent> &p_event) { @@ -465,15 +391,15 @@ void EditorNode::shortcut_input(const Ref<InputEvent> &p_event) { } if (ED_IS_SHORTCUT("editor/editor_2d", p_event)) { - _editor_select(EDITOR_2D); + editor_select(EDITOR_2D); } else if (ED_IS_SHORTCUT("editor/editor_3d", p_event)) { - _editor_select(EDITOR_3D); + editor_select(EDITOR_3D); } else if (ED_IS_SHORTCUT("editor/editor_script", p_event)) { - _editor_select(EDITOR_SCRIPT); + editor_select(EDITOR_SCRIPT); } else if (ED_IS_SHORTCUT("editor/editor_help", p_event)) { emit_signal(SNAME("request_help_search"), ""); } else if (ED_IS_SHORTCUT("editor/editor_assetlib", p_event) && AssetLibraryEditorPlugin::is_available()) { - _editor_select(EDITOR_ASSETLIB); + editor_select(EDITOR_ASSETLIB); } else if (ED_IS_SHORTCUT("editor/editor_next", p_event)) { _editor_select_next(); } else if (ED_IS_SHORTCUT("editor/editor_prev", p_event)) { @@ -541,7 +467,7 @@ void EditorNode::_update_from_settings() { RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter"))); RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/2d/shadow_atlas/size")); - bool use_half_res_gi = GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false); + bool use_half_res_gi = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution"); RS::get_singleton()->gi_set_use_half_resolution(use_half_res_gi); bool snap_2d_transforms = GLOBAL_GET("rendering/2d/snap/snap_2d_transforms_to_pixel"); @@ -584,7 +510,7 @@ void EditorNode::_update_from_settings() { void EditorNode::_select_default_main_screen_plugin() { if (EDITOR_3D < main_editor_buttons.size() && main_editor_buttons[EDITOR_3D]->is_visible()) { // If the 3D editor is enabled, use this as the default. - _editor_select(EDITOR_3D); + editor_select(EDITOR_3D); return; } @@ -593,12 +519,12 @@ void EditorNode::_select_default_main_screen_plugin() { for (int i = 0; i < main_editor_buttons.size(); i++) { Button *editor_button = main_editor_buttons[i]; if (editor_button->is_visible()) { - _editor_select(i); + editor_select(i); return; } } - _editor_select(-1); + editor_select(-1); } void EditorNode::_notification(int p_what) { @@ -633,7 +559,7 @@ void EditorNode::_notification(int p_what) { update_spinner_step_frame = frame + 1; // Update the icon itself only when the spinner is visible. - if (EditorSettings::get_singleton()->get("interface/editor/show_update_spinner")) { + if (EDITOR_GET("interface/editor/show_update_spinner")) { update_spinner->set_icon(gui_base->get_theme_icon("Progress" + itos(update_spinner_step + 1), SNAME("EditorIcons"))); } } @@ -659,6 +585,12 @@ void EditorNode::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { Engine::get_singleton()->set_editor_hint(true); + Window *window = static_cast<Window *>(get_tree()->get_root()); + if (window) { + // Handle macOS fullscreen and extend-to-title changes. + window->connect("titlebar_changed", callable_mp(this, &EditorNode::_titlebar_resized)); + } + OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); get_tree()->get_root()->set_as_audio_listener_3d(false); get_tree()->get_root()->set_as_audio_listener_2d(false); @@ -692,7 +624,7 @@ void EditorNode::_notification(int p_what) { _initializing_plugins = true; Vector<String> addons; if (ProjectSettings::get_singleton()->has_setting("editor_plugins/enabled")) { - addons = ProjectSettings::get_singleton()->get("editor_plugins/enabled"); + addons = GLOBAL_GET("editor_plugins/enabled"); } for (int i = 0; i < addons.size(); i++) { @@ -713,6 +645,8 @@ void EditorNode::_notification(int p_what) { ProjectSettings::get_singleton()->save(); } + _titlebar_resized(); + /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } break; @@ -750,7 +684,8 @@ void EditorNode::_notification(int p_what) { EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/theme") || EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/font") || EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/main_font") || - EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/code_font"); + EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/code_font") || + EditorSettings::get_singleton()->check_changed_settings_in_group("filesystem/file_dialog/thumbnail_size"); if (theme_changed) { theme = create_custom_theme(theme_base->get_theme()); @@ -836,7 +771,7 @@ void EditorNode::_notification(int p_what) { HashSet<String> updated_textfile_extensions; bool extensions_match = true; - const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); for (const String &E : textfile_ext) { updated_textfile_extensions.insert(E); if (extensions_match && !textfile_extensions.has(E)) { @@ -855,9 +790,9 @@ void EditorNode::_notification(int p_what) { } void EditorNode::_update_update_spinner() { - update_spinner->set_visible(EditorSettings::get_singleton()->get("interface/editor/show_update_spinner")); + update_spinner->set_visible(EDITOR_GET("interface/editor/show_update_spinner")); - const bool update_continuously = EditorSettings::get_singleton()->get("interface/editor/update_continuously"); + const bool update_continuously = EDITOR_GET("interface/editor/update_continuously"); PopupMenu *update_popup = update_spinner->get_popup(); update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_CONTINUOUSLY), update_continuously); update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_WHEN_CHANGED), !update_continuously); @@ -881,8 +816,8 @@ void EditorNode::_update_update_spinner() { } void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_name) { - Ref<Script> script = Object::cast_to<Script>(p_script); - if (script.is_null()) { + Ref<Script> scr = Object::cast_to<Script>(p_script); + if (scr.is_null()) { return; } if (p_activate_name.length()) { @@ -890,7 +825,7 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam } project_settings_editor->update_plugins(); project_settings_editor->hide(); - push_item(script.operator->()); + push_item(scr.operator->()); } void EditorNode::_remove_plugin_from_enabled(const String &p_name) { @@ -1169,6 +1104,22 @@ void EditorNode::_reload_project_settings() { void EditorNode::_vp_resized() { } +void EditorNode::_titlebar_resized() { + DisplayServer::get_singleton()->window_set_window_buttons_offset(Vector2i(menu_hb->get_global_position().y + menu_hb->get_size().y / 2, menu_hb->get_global_position().y + menu_hb->get_size().y / 2), DisplayServer::MAIN_WINDOW_ID); + const Vector3i &margin = DisplayServer::get_singleton()->window_get_safe_title_margins(DisplayServer::MAIN_WINDOW_ID); + if (left_menu_spacer) { + int w = (gui_base->is_layout_rtl()) ? margin.y : margin.x; + left_menu_spacer->set_custom_minimum_size(Size2(w, 0)); + } + if (right_menu_spacer) { + int w = (gui_base->is_layout_rtl()) ? margin.x : margin.y; + right_menu_spacer->set_custom_minimum_size(Size2(w, 0)); + } + if (menu_hb) { + menu_hb->set_custom_minimum_size(Size2(0, margin.z - menu_hb->get_global_position().y)); + } +} + void EditorNode::_version_button_pressed() { DisplayServer::get_singleton()->clipboard_set(version_btn->get_meta(META_TEXT_TO_COPY)); } @@ -1190,7 +1141,7 @@ void EditorNode::_editor_select_next() { } } while (!main_editor_buttons[editor]->is_visible()); - _editor_select(editor); + editor_select(editor); } void EditorNode::_open_command_palette() { @@ -1208,7 +1159,7 @@ void EditorNode::_editor_select_prev() { } } while (!main_editor_buttons[editor]->is_visible()); - _editor_select(editor); + editor_select(editor); } Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_deps) { @@ -1243,10 +1194,14 @@ void EditorNode::edit_node(Node *p_node) { push_item(p_node); } +void EditorNode::edit_resource(const Ref<Resource> &p_resource) { + InspectorDock::get_singleton()->edit_resource(p_resource); +} + void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) { editor_data.apply_changes_in_editors(); int flg = 0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) { + if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; } @@ -1591,7 +1546,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { // which would result in an invalid texture. if (c3d == 0 && c2d == 0) { img.instantiate(); - img->create(1, 1, false, Image::FORMAT_RGB8); + img->initialize_data(1, 1, false, Image::FORMAT_RGB8); } else if (c3d < c2d) { Ref<ViewportTexture> viewport_texture = scene_root->get_texture(); if (viewport_texture->get_width() > 0 && viewport_texture->get_height() > 0) { @@ -1613,7 +1568,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { save.step(TTR("Creating Thumbnail"), 2); save.step(TTR("Creating Thumbnail"), 3); - int preview_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + int preview_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); preview_size *= EDSCALE; // Consider a square region. @@ -1642,10 +1597,8 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { cache_base = temp_path.path_join("resthumb-" + cache_base); // Does not have it, try to load a cached thumbnail. - String file = cache_base + ".png"; - post_process_preview(img); - img->save_png(file); + img->save_png(cache_base + ".png"); } } @@ -1676,7 +1629,7 @@ int EditorNode::_save_external_resources() { // Save external resources and its subresources if any was modified. int flg = 0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) { + if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; } flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; @@ -1745,7 +1698,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } if (!scene->get_scene_file_path().is_empty() && _validate_scene_recursive(scene->get_scene_file_path(), scene)) { - show_accept(TTR("This scene can't be saved because there is a cyclic instancing inclusion.\nPlease resolve it and then attempt to save again."), TTR("OK")); + show_accept(TTR("This scene can't be saved because there is a cyclic instance inclusion.\nPlease resolve it and then attempt to save again."), TTR("OK")); return; } @@ -1782,7 +1735,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } int flg = 0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) { + if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; } flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; @@ -2015,8 +1968,8 @@ void EditorNode::_dialog_action(String p_file) { ERR_FAIL_COND(saving_resource.is_null()); save_resource_in_path(saving_resource, p_file); saving_resource = Ref<Resource>(); - ObjectID current = editor_history.get_current(); - Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; + ObjectID current_id = editor_history.get_current(); + Object *current_obj = current_id.is_valid() ? ObjectDB::get_instance(current_id) : nullptr; ERR_FAIL_COND(!current_obj); current_obj->notify_property_list_changed(); } break; @@ -2217,8 +2170,8 @@ static bool overrides_external_editor(Object *p_object) { } void EditorNode::_edit_current(bool p_skip_foreign) { - ObjectID current = editor_history.get_current(); - Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; + ObjectID current_id = editor_history.get_current(); + Object *current_obj = current_id.is_valid() ? ObjectDB::get_instance(current_id) : nullptr; Ref<Resource> res = Object::cast_to<Resource>(current_obj); if (p_skip_foreign && res.is_valid()) { @@ -2313,7 +2266,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { if (get_edited_scene() && !get_edited_scene()->get_scene_file_path().is_empty()) { String source_scene = get_edited_scene()->get_scene_file_path(); if (FileAccess::exists(source_scene + ".import")) { - editable_info = TTR("This scene was imported, so changes to it won't be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); + editable_info = TTR("This scene was imported, so changes to it won't be kept.\nInstantiating or inheriting it will allow you to make changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); info_is_warning = true; } } @@ -2382,7 +2335,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { if (main_plugin && !skip_main_plugin) { // Special case if use of external editor is true. Resource *current_res = Object::cast_to<Resource>(current_obj); - if (main_plugin->get_name() == "Script" && !current_obj->is_class("VisualScript") && current_res && !current_res->is_built_in() && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { + if (main_plugin->get_name() == "Script" && !current_obj->is_class("VisualScript") && current_res && !current_res->is_built_in() && (bool(EDITOR_GET("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { if (!changing_scene) { main_plugin->edit(current_obj); } @@ -2390,7 +2343,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { else if (main_plugin != editor_plugin_screen && (!ScriptEditor::get_singleton() || !ScriptEditor::get_singleton()->is_visible_in_tree() || ScriptEditor::get_singleton()->can_take_away_focus())) { // Update screen main_plugin. - _editor_select(plugin_index); + editor_select(plugin_index); main_plugin->edit(current_obj); } else { editor_plugin_screen->edit(current_obj); @@ -2450,7 +2403,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { write_movie_file = GLOBAL_GET("editor/movie_writer/movie_file"); } if (write_movie_file == String()) { - show_accept(TTR("Movie Maker mode is enabled, but no movie file path has been specified.\nA default movie file path can be specified in the project settings under the 'Editor/Movie Writer' category.\nAlternatively, for running single scenes, a 'movie_path' metadata can be added to the root node,\nspecifying the path to a movie file that will be used when recording that scene."), TTR("OK")); + show_accept(TTR("Movie Maker mode is enabled, but no movie file path has been specified.\nA default movie file path can be specified in the project settings under the Editor > Movie Writer category.\nAlternatively, for running single scenes, a `movie_file` string metadata can be added to the root node,\nspecifying the path to a movie file that will be used when recording that scene."), TTR("OK")); return; } } @@ -2668,9 +2621,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { save_confirmation->set_text(TTR("Save modified resources before closing?")); } } else { - Node *scene_root = editor_data.get_edited_scene_root(tab_closing_idx); - if (scene_root) { - String scene_filename = scene_root->get_scene_file_path(); + Node *ed_scene_root = editor_data.get_edited_scene_root(tab_closing_idx); + if (ed_scene_root) { + String scene_filename = ed_scene_root->get_scene_file_path(); if (p_option == FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT) { save_confirmation->set_ok_button_text(TTR("Save & Reload")); save_confirmation->set_text(vformat(TTR("Save changes to '%s' before reloading?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene")); @@ -2763,18 +2716,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } } else if (extensions.size()) { String root_name = scene->get_name(); - // Very similar to node naming logic. - switch (ProjectSettings::get_singleton()->get("editor/scene/scene_naming").operator int()) { - case SCENE_NAME_CASING_AUTO: - // Use casing of the root node. - break; - case SCENE_NAME_CASING_PASCAL_CASE: { - root_name = root_name.to_pascal_case(); - } break; - case SCENE_NAME_CASING_SNAKE_CASE: - root_name = root_name.replace("-", "_").to_snake_case(); - break; - } + root_name = EditorNode::adjust_scene_name_casing(root_name); file->set_current_path(root_name + "." + extensions.front()->get().to_lower()); } file->popup_file_dialog(); @@ -3080,8 +3022,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case HELP_SUPPORT_GODOT_DEVELOPMENT: { OS::get_singleton()->shell_open("https://godotengine.org/donate"); } break; - case SET_RENDERING_DRIVER_SAVE_AND_RESTART: { - ProjectSettings::get_singleton()->set("rendering/driver/driver_name", rendering_driver_request); + case SET_RENDERER_NAME_SAVE_AND_RESTART: { + ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method", renderer_request); ProjectSettings::get_singleton()->save(); save_all_scenes(); @@ -3090,6 +3032,19 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } } +String EditorNode::adjust_scene_name_casing(const String &root_name) { + switch (GLOBAL_GET("editor/scene/scene_naming").operator int()) { + case SCENE_NAME_CASING_AUTO: + // Use casing of the root node. + break; + case SCENE_NAME_CASING_PASCAL_CASE: + return root_name.to_pascal_case(); + case SCENE_NAME_CASING_SNAKE_CASE: + return root_name.replace("-", "_").to_snake_case(); + } + return root_name; +} + void EditorNode::_request_screenshot() { _screenshot(); } @@ -3098,7 +3053,7 @@ void EditorNode::_screenshot(bool p_use_utc) { String name = "editor_screenshot_" + Time::get_singleton()->get_datetime_string_from_system(p_use_utc).replace(":", "") + ".png"; NodePath path = String("user://") + name; _save_screenshot(path); - if (EditorSettings::get_singleton()->get("interface/editor/automatically_open_screenshots")) { + if (EDITOR_GET("interface/editor/automatically_open_screenshots")) { OS::get_singleton()->shell_open(String("file://") + ProjectSettings::get_singleton()->globalize_path(path)); } } @@ -3303,7 +3258,7 @@ VBoxContainer *EditorNode::get_main_screen_control() { return main_screen_vbox; } -void EditorNode::_editor_select(int p_which) { +void EditorNode::editor_select(int p_which) { static bool selecting = false; if (selecting || changing_scene) { return; @@ -3343,7 +3298,7 @@ void EditorNode::_editor_select(int p_which) { editor_data.get_editor_plugin(i)->notify_main_screen_changed(editor_plugin_screen->get_name()); } - if (EditorSettings::get_singleton()->get("interface/editor/separate_distraction_mode")) { + if (EDITOR_GET("interface/editor/separate_distraction_mode")) { if (p_which == EDITOR_SCRIPT) { set_distraction_free_mode(script_distraction_free); } else { @@ -3357,7 +3312,7 @@ void EditorNode::select_editor_by_name(const String &p_name) { for (int i = 0; i < main_editor_buttons.size(); i++) { if (main_editor_buttons[i]->get_text() == p_name) { - _editor_select(i); + editor_select(i); return; } } @@ -3370,7 +3325,7 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed Button *tb = memnew(Button); tb->set_flat(true); tb->set_toggle_mode(true); - tb->connect("pressed", callable_mp(singleton, &EditorNode::_editor_select).bind(singleton->main_editor_buttons.size())); + tb->connect("pressed", callable_mp(singleton, &EditorNode::editor_select).bind(singleton->main_editor_buttons.size())); tb->set_name(p_editor->get_name()); tb->set_text(p_editor->get_name()); @@ -3387,7 +3342,7 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed tb->add_theme_font_size_override("font_size", singleton->gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts"))); singleton->main_editor_buttons.push_back(tb); - singleton->main_editor_button_vb->add_child(tb); + singleton->main_editor_button_hb->add_child(tb); singleton->editor_table.push_back(p_editor); singleton->distraction_free->move_to_front(); @@ -3401,16 +3356,21 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_changed) { if (p_editor->has_main_screen()) { - for (int i = 0; i < singleton->main_editor_buttons.size(); i++) { + // Remove the main editor button and update the bindings of + // all buttons behind it to point to the correct main window. + for (int i = singleton->main_editor_buttons.size() - 1; i >= 0; i--) { if (p_editor->get_name() == singleton->main_editor_buttons[i]->get_text()) { if (singleton->main_editor_buttons[i]->is_pressed()) { - singleton->_editor_select(EDITOR_SCRIPT); + singleton->editor_select(EDITOR_SCRIPT); } memdelete(singleton->main_editor_buttons[i]); singleton->main_editor_buttons.remove_at(i); break; + } else { + singleton->main_editor_buttons[i]->disconnect("pressed", callable_mp(singleton, &EditorNode::editor_select)); + singleton->main_editor_buttons[i]->connect("pressed", callable_mp(singleton, &EditorNode::editor_select).bind(i - 1)); } } @@ -3486,39 +3446,39 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, } String script_path = cf->get_value("plugin", "script"); - Ref<Script> script; // We need to save it for creating "ep" below. + Ref<Script> scr; // We need to save it for creating "ep" below. // Only try to load the script if it has a name. Else, the plugin has no init script. if (script_path.length() > 0) { script_path = addon_path.get_base_dir().path_join(script_path); - script = ResourceLoader::load(script_path); + scr = ResourceLoader::load(script_path); - if (script.is_null()) { + if (scr.is_null()) { show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), script_path)); return; } // Errors in the script cause the base_type to be an empty StringName. - if (script->get_instance_base_type() == StringName()) { + if (scr->get_instance_base_type() == StringName()) { show_warning(vformat(TTR("Unable to load addon script from path: '%s'. This might be due to a code error in that script.\nDisabling the addon at '%s' to prevent further errors."), script_path, addon_path)); _remove_plugin_from_enabled(addon_path); return; } // Plugin init scripts must inherit from EditorPlugin and be tools. - if (String(script->get_instance_base_type()) != "EditorPlugin") { + if (String(scr->get_instance_base_type()) != "EditorPlugin") { show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), script_path)); return; } - if (!script->is_tool()) { + if (!scr->is_tool()) { show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), script_path)); return; } } EditorPlugin *ep = memnew(EditorPlugin); - ep->set_script(script); + ep->set_script(scr); addon_name_to_plugin[addon_path] = ep; add_editor_plugin(ep, p_config_changed); @@ -3533,6 +3493,14 @@ bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const { return addon_name_to_plugin.has("res://addons/" + p_addon + "/plugin.cfg"); } +void EditorNode::set_movie_maker_enabled(bool p_enabled) { + write_movie_button->set_pressed(p_enabled); +} + +bool EditorNode::is_movie_maker_enabled() const { + return write_movie_button->is_pressed(); +} + void EditorNode::_remove_edited_scene(bool p_change_tab) { int new_index = editor_data.get_edited_scene(); int old_index = new_index; @@ -3616,32 +3584,32 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { changing_scene = false; - int current = -1; + int current_tab = -1; for (int i = 0; i < editor_table.size(); i++) { if (editor_plugin_screen == editor_table[i]) { - current = i; + current_tab = i; break; } } if (p_state.has("editor_index")) { int index = p_state["editor_index"]; - if (current < 2) { // If currently in spatial/2d, only switch to spatial/2d. If currently in script, stay there. + if (current_tab < 2) { // If currently in spatial/2d, only switch to spatial/2d. If currently in script, stay there. if (index < 2 || !get_edited_scene()) { - _editor_select(index); + editor_select(index); } } } if (get_edited_scene()) { - if (current < 2) { + if (current_tab < 2) { // Use heuristic instead. int n2d = 0, n3d = 0; _find_node_types(get_edited_scene(), n2d, n3d); if (n2d > n3d) { - _editor_select(EDITOR_2D); + editor_select(EDITOR_2D); } else if (n3d > n2d) { - _editor_select(EDITOR_3D); + editor_select(EDITOR_3D); } } } @@ -3662,16 +3630,13 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { EditorDebuggerNode::get_singleton()->update_live_edit_root(); ScriptEditor::get_singleton()->set_scene_root_script(editor_data.get_scene_root_script(editor_data.get_edited_scene())); editor_data.notify_edited_scene_changed(); + emit_signal(SNAME("scene_changed")); } bool EditorNode::is_changing_scene() const { return changing_scene; } -void EditorNode::_clear_undo_history() { - get_undo_redo()->clear_history(false); -} - void EditorNode::set_current_scene(int p_idx) { // Save the folding in case the scene gets reloaded. if (editor_data.get_scene_path(p_idx) != "" && editor_data.get_edited_scene_root(p_idx)) { @@ -3751,7 +3716,7 @@ int EditorNode::new_scene() { if (editor_data.get_edited_scene_count() > 1) { for (int i = 0; i < editor_data.get_edited_scene_count() - 1; i++) { bool unsaved = get_undo_redo()->is_history_unsaved(editor_data.get_scene_history_id(i)); - if (!unsaved && editor_data.get_scene_path(i).is_empty()) { + if (!unsaved && editor_data.get_scene_path(i).is_empty() && editor_data.get_edited_scene_root(i) == nullptr) { editor_data.remove_scene(i); idx--; } @@ -3918,9 +3883,9 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b void EditorNode::open_request(const String &p_path) { if (!opening_prev) { - List<String>::Element *prev_scene = previous_scenes.find(p_path); - if (prev_scene != nullptr) { - prev_scene->erase(); + List<String>::Element *prev_scene_item = previous_scenes.find(p_path); + if (prev_scene_item != nullptr) { + prev_scene_item->erase(); } } @@ -3967,7 +3932,7 @@ bool EditorNode::is_resource_read_only(Ref<Resource> p_resource, bool p_foreign_ return false; } -void EditorNode::request_instance_scene(const String &p_path) { +void EditorNode::request_instantiate_scene(const String &p_path) { SceneTreeDock::get_singleton()->instantiate(p_path); } @@ -4052,7 +4017,7 @@ void EditorNode::_quick_opened() { List<String> scene_extensions; ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); - if (open_scene_dialog || scene_extensions.find(files[i].get_extension())) { + if (open_scene_dialog || scene_extensions.find(files[i].get_extension().to_lower())) { open_request(res_path); } else { load_resource(res_path); @@ -4103,62 +4068,6 @@ bool EditorNode::is_scene_in_use(const String &p_path) { return false; } -void EditorNode::register_editor_types() { - ResourceLoader::set_timestamp_on_load(true); - ResourceSaver::set_timestamp_on_save(true); - - GDREGISTER_CLASS(EditorPaths); - GDREGISTER_CLASS(EditorPlugin); - GDREGISTER_CLASS(EditorTranslationParserPlugin); - GDREGISTER_CLASS(EditorImportPlugin); - GDREGISTER_CLASS(EditorScript); - GDREGISTER_CLASS(EditorSelection); - GDREGISTER_CLASS(EditorFileDialog); - GDREGISTER_ABSTRACT_CLASS(EditorSettings); - GDREGISTER_CLASS(EditorNode3DGizmo); - GDREGISTER_CLASS(EditorNode3DGizmoPlugin); - GDREGISTER_ABSTRACT_CLASS(EditorResourcePreview); - GDREGISTER_CLASS(EditorResourcePreviewGenerator); - GDREGISTER_ABSTRACT_CLASS(EditorFileSystem); - GDREGISTER_CLASS(EditorFileSystemDirectory); - GDREGISTER_CLASS(EditorVCSInterface); - GDREGISTER_ABSTRACT_CLASS(ScriptEditor); - GDREGISTER_ABSTRACT_CLASS(ScriptEditorBase); - GDREGISTER_CLASS(EditorSyntaxHighlighter); - GDREGISTER_ABSTRACT_CLASS(EditorInterface); - GDREGISTER_CLASS(EditorExportPlugin); - GDREGISTER_ABSTRACT_CLASS(EditorExportPlatform); - GDREGISTER_CLASS(EditorResourceConversionPlugin); - GDREGISTER_CLASS(EditorSceneFormatImporter); - GDREGISTER_CLASS(EditorScenePostImportPlugin); - GDREGISTER_CLASS(EditorInspector); - GDREGISTER_CLASS(EditorInspectorPlugin); - GDREGISTER_CLASS(EditorProperty); - GDREGISTER_CLASS(AnimationTrackEditPlugin); - GDREGISTER_CLASS(ScriptCreateDialog); - GDREGISTER_CLASS(EditorFeatureProfile); - GDREGISTER_CLASS(EditorSpinSlider); - GDREGISTER_CLASS(EditorResourcePicker); - GDREGISTER_CLASS(EditorScriptPicker); - GDREGISTER_ABSTRACT_CLASS(EditorUndoRedoManager); - - GDREGISTER_ABSTRACT_CLASS(FileSystemDock); - GDREGISTER_VIRTUAL_CLASS(EditorFileSystemImportFormatSupportQuery); - - GDREGISTER_CLASS(EditorScenePostImport); - GDREGISTER_CLASS(EditorCommandPalette); - GDREGISTER_CLASS(EditorDebuggerPlugin); -} - -void EditorNode::unregister_editor_types() { - _init_callbacks.clear(); - if (EditorPaths::get_singleton()) { - EditorPaths::free(); - } - - EditorResourcePicker::clear_caches(); -} - void EditorNode::stop_child_process(OS::ProcessID p_pid) { if (has_child_process(p_pid)) { editor_run.stop_child_process(p_pid); @@ -4171,9 +4080,9 @@ void EditorNode::stop_child_process(OS::ProcessID p_pid) { Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) const { ERR_FAIL_COND_V(!p_object, nullptr); - Ref<Script> script = p_object->get_script(); + Ref<Script> scr = p_object->get_script(); - if (script.is_valid()) { + if (scr.is_valid()) { // Uncommenting would break things! Consider adding a parameter if you need it. // StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); // if (name != StringName()) { @@ -4181,18 +4090,18 @@ Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) cons // } // TODO: Should probably be deprecated in 4.x - StringName base = script->get_instance_base_type(); + StringName base = scr->get_instance_base_type(); if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; - Ref<Script> base_script = script; - while (base_script.is_valid()) { + Ref<Script> base_scr = scr; + while (base_scr.is_valid()) { for (int i = 0; i < types.size(); ++i) { - if (types[i].script == base_script) { + if (types[i].script == base_scr) { return types[i].script; } } - base_script = base_script->get_base_script(); + base_scr = base_scr->get_base_script(); } } } @@ -4203,30 +4112,30 @@ Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) cons StringName EditorNode::get_object_custom_type_name(const Object *p_object) const { ERR_FAIL_COND_V(!p_object, StringName()); - Ref<Script> script = p_object->get_script(); - if (script.is_null() && Object::cast_to<Script>(p_object)) { - script = p_object; + Ref<Script> scr = p_object->get_script(); + if (scr.is_null() && Object::cast_to<Script>(p_object)) { + scr = p_object; } - if (script.is_valid()) { - Ref<Script> base_script = script; - while (base_script.is_valid()) { - StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + if (scr.is_valid()) { + Ref<Script> base_scr = scr; + while (base_scr.is_valid()) { + StringName name = EditorNode::get_editor_data().script_class_get_name(base_scr->get_path()); if (name != StringName()) { return name; } // TODO: Should probably be deprecated in 4.x. - StringName base = base_script->get_instance_base_type(); + StringName base = base_scr->get_instance_base_type(); if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; for (int i = 0; i < types.size(); ++i) { - if (types[i].script == base_script) { + if (types[i].script == base_scr) { return types[i].name; } } } - base_script = base_script->get_base_script(); + base_scr = base_scr->get_base_script(); } } @@ -4270,40 +4179,40 @@ void EditorNode::_pick_main_scene_custom_action(const String &p_custom_action_na Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) { ERR_FAIL_COND_V(!p_object || !gui_base, nullptr); - Ref<Script> script = p_object->get_script(); - if (script.is_null() && p_object->is_class("Script")) { - script = p_object; + Ref<Script> scr = p_object->get_script(); + if (scr.is_null() && p_object->is_class("Script")) { + scr = p_object; } - if (script.is_valid() && !script_icon_cache.has(script)) { - Ref<Script> base_script = script; - while (base_script.is_valid()) { - StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + if (scr.is_valid() && !script_icon_cache.has(scr)) { + Ref<Script> base_scr = scr; + while (base_scr.is_valid()) { + StringName name = EditorNode::get_editor_data().script_class_get_name(base_scr->get_path()); String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name); Ref<ImageTexture> icon = _load_custom_class_icon(icon_path); if (icon.is_valid()) { - script_icon_cache[script] = icon; + script_icon_cache[scr] = icon; return icon; } // TODO: should probably be deprecated in 4.x - StringName base = base_script->get_instance_base_type(); + StringName base = base_scr->get_instance_base_type(); if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; for (int i = 0; i < types.size(); ++i) { - if (types[i].script == base_script && types[i].icon.is_valid()) { - script_icon_cache[script] = types[i].icon; + if (types[i].script == base_scr && types[i].icon.is_valid()) { + script_icon_cache[scr] = types[i].icon; return types[i].icon; } } } - base_script = base_script->get_base_script(); + base_scr = base_scr->get_base_script(); } // If no icon found, cache it as null. - script_icon_cache[script] = Ref<Texture>(); - } else if (script.is_valid() && script_icon_cache.has(script) && script_icon_cache[script].is_valid()) { - return script_icon_cache[script]; + script_icon_cache[scr] = Ref<Texture>(); + } else if (scr.is_valid() && script_icon_cache.has(scr) && script_icon_cache[scr].is_valid()) { + return script_icon_cache[scr]; } // TODO: Should probably be deprecated in 4.x. @@ -4327,7 +4236,7 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p if (ScriptServer::is_global_class(p_class)) { String class_name = p_class; - Ref<Script> script = EditorNode::get_editor_data().script_class_load_script(class_name); + Ref<Script> scr = EditorNode::get_editor_data().script_class_load_script(class_name); while (true) { String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(class_name); @@ -4338,18 +4247,18 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p // Find next global class along the inheritance chain. do { - Ref<Script> base_script = script->get_base_script(); - if (base_script.is_null()) { + Ref<Script> base_scr = scr->get_base_script(); + if (base_scr.is_null()) { // We've reached a native class, use its icon. String base_type; - script->get_language()->get_global_class_name(script->get_path(), &base_type); + scr->get_language()->get_global_class_name(scr->get_path(), &base_type); if (gui_base->has_theme_icon(base_type, "EditorIcons")) { return gui_base->get_theme_icon(base_type, "EditorIcons"); } return gui_base->get_theme_icon(p_fallback, "EditorIcons"); } - script = base_script; - class_name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); + scr = base_scr; + class_name = EditorNode::get_editor_data().script_class_get_name(scr->get_path()); } while (class_name.is_empty()); } } @@ -4369,6 +4278,27 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p return nullptr; } +bool EditorNode::is_object_of_custom_type(const Object *p_object, const StringName &p_class) { + ERR_FAIL_COND_V(!p_object, false); + + Ref<Script> scr = p_object->get_script(); + if (scr.is_null() && Object::cast_to<Script>(p_object)) { + scr = p_object; + } + + if (scr.is_valid()) { + Ref<Script> base_script = scr; + while (base_script.is_valid()) { + StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + if (name == p_class) { + return true; + } + base_script = base_script->get_base_script(); + } + } + return false; +} + void EditorNode::progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) { if (singleton->cmdline_export_mode) { print_line(p_task + ": begin: " + p_label + " steps: " + itos(p_steps)); @@ -4510,8 +4440,9 @@ void EditorNode::_dock_floating_close_request(Control *p_control) { dock_slot[window_slot]->add_child(p_control); dock_slot[window_slot]->move_child(p_control, MIN((int)window->get_meta("dock_index"), dock_slot[window_slot]->get_tab_count())); dock_slot[window_slot]->set_current_tab(window->get_meta("dock_index")); + dock_slot[window_slot]->set_tab_title(dock_slot[window_slot]->get_tab_idx_from_control(p_control), TTRGET(p_control->get_name())); - window->queue_delete(); + window->queue_free(); _update_dock_containers(); @@ -4533,7 +4464,7 @@ void EditorNode::_dock_make_float() { dock_slot[dock_popup_selected_idx]->remove_child(dock); Window *window = memnew(Window); - window->set_title(dock->get_name()); + window->set_title(TTRGET(dock->get_name())); Panel *p = memnew(Panel); p->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("PanelForeground"), SNAME("EditorStyles"))); p->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); @@ -4654,26 +4585,24 @@ void EditorNode::_dock_move_left() { if (dock_popup_selected_idx < 0 || dock_popup_selected_idx >= DOCK_SLOT_MAX) { return; } - Control *current = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab()); - Control *prev = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab() - 1); - if (!current || !prev) { + Control *current_ctl = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab()); + Control *prev_ctl = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab() - 1); + if (!current_ctl || !prev_ctl) { return; } - dock_slot[dock_popup_selected_idx]->move_child(current, prev->get_index()); - dock_slot[dock_popup_selected_idx]->set_current_tab(dock_slot[dock_popup_selected_idx]->get_current_tab() - 1); + dock_slot[dock_popup_selected_idx]->move_child(current_ctl, prev_ctl->get_index(false)); dock_select->queue_redraw(); _edit_current(); _save_docks(); } void EditorNode::_dock_move_right() { - Control *current = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab()); - Control *next = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab() + 1); - if (!current || !next) { + Control *current_ctl = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab()); + Control *next_ctl = dock_slot[dock_popup_selected_idx]->get_tab_control(dock_slot[dock_popup_selected_idx]->get_current_tab() + 1); + if (!current_ctl || !next_ctl) { return; } - dock_slot[dock_popup_selected_idx]->move_child(next, current->get_index()); - dock_slot[dock_popup_selected_idx]->set_current_tab(dock_slot[dock_popup_selected_idx]->get_current_tab() + 1); + dock_slot[dock_popup_selected_idx]->move_child(next_ctl, current_ctl->get_index(false)); dock_select->queue_redraw(); _edit_current(); _save_docks(); @@ -4857,7 +4786,7 @@ void EditorNode::_load_docks() { editor_data.set_plugin_window_layout(config); } -void EditorNode::_update_dock_slots_visibility() { +void EditorNode::_update_dock_slots_visibility(bool p_keep_selected_tabs) { if (!docks_visible) { for (int i = 0; i < DOCK_SLOT_MAX; i++) { dock_slot[i]->hide(); @@ -4892,9 +4821,11 @@ void EditorNode::_update_dock_slots_visibility() { } } - for (int i = 0; i < DOCK_SLOT_MAX; i++) { - if (dock_slot[i]->is_visible() && dock_slot[i]->get_tab_count()) { - dock_slot[i]->set_current_tab(0); + if (!p_keep_selected_tabs) { + for (int i = 0; i < DOCK_SLOT_MAX; i++) { + if (dock_slot[i]->is_visible() && dock_slot[i]->get_tab_count()) { + dock_slot[i]->set_current_tab(0); + } } } @@ -4955,7 +4886,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String Vector<String> names = String(p_layout->get_value(p_section, "dock_" + itos(i + 1))).split(","); - for (int j = 0; j < names.size(); j++) { + for (int j = names.size() - 1; j >= 0; j--) { String name = names[j]; // FIXME: Find it, in a horribly inefficient way. int atidx = -1; @@ -4976,7 +4907,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String } if (atidx == i) { - node->move_to_front(); + dock_slot[i]->move_child(node, 0); continue; } @@ -4986,6 +4917,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String dock_slot[atidx]->hide(); } dock_slot[i]->add_child(node); + dock_slot[i]->move_child(node, 0); dock_slot[i]->show(); } } @@ -5088,7 +5020,7 @@ bool EditorNode::has_scenes_in_session() { bool EditorNode::ensure_main_scene(bool p_from_native) { pick_main_scene->set_meta("from_native", p_from_native); // Whether from play button or native run. - String main_scene = GLOBAL_DEF_BASIC("application/run/main_scene", ""); + String main_scene = GLOBAL_GET("application/run/main_scene"); if (main_scene.is_empty()) { current_menu_option = -1; @@ -5155,7 +5087,7 @@ bool EditorNode::is_run_playing() const { String EditorNode::get_run_playing_scene() const { String run_filename = editor_run.get_running_scene(); if (run_filename.is_empty() && is_run_playing()) { - run_filename = GLOBAL_DEF_BASIC("application/run/main_scene", ""); // Must be the main scene then. + run_filename = GLOBAL_GET("application/run/main_scene"); // Must be the main scene then. } return run_filename; @@ -5187,6 +5119,10 @@ bool EditorNode::immediate_confirmation_dialog(const String &p_text, const Strin return singleton->immediate_dialog_confirmed; } +void EditorNode::cleanup() { + _init_callbacks.clear(); +} + int EditorNode::get_current_tab() { return scene_tabs->get_current_tab(); } @@ -5260,9 +5196,9 @@ void EditorNode::_layout_menu_option(int p_id) { } void EditorNode::_scene_tab_script_edited(int p_tab) { - Ref<Script> script = editor_data.get_scene_root_script(p_tab); - if (script.is_valid()) { - InspectorDock::get_singleton()->edit_resource(script); + Ref<Script> scr = editor_data.get_scene_root_script(p_tab); + if (scr.is_valid()) { + InspectorDock::get_singleton()->edit_resource(scr); } } @@ -5507,7 +5443,7 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) { void EditorNode::set_docks_visible(bool p_show) { docks_visible = p_show; - _update_dock_slots_visibility(); + _update_dock_slots_visibility(true); } bool EditorNode::get_docks_visible() const { @@ -5515,7 +5451,7 @@ bool EditorNode::get_docks_visible() const { } void EditorNode::_toggle_distraction_free_mode() { - if (EditorSettings::get_singleton()->get("interface/editor/separate_distraction_mode")) { + if (EDITOR_GET("interface/editor/separate_distraction_mode")) { int screen = -1; for (int i = 0; i < editor_table.size(); i++) { if (editor_plugin_screen == editor_table[i]) { @@ -5715,7 +5651,7 @@ void EditorNode::_global_menu_new_window(const Variant &p_tag) { } void EditorNode::_dropped_files(const Vector<String> &p_files) { - String to_path = ProjectSettings::get_singleton()->globalize_path(FileSystemDock::get_singleton()->get_selected_path()); + String to_path = ProjectSettings::get_singleton()->globalize_path(FileSystemDock::get_singleton()->get_current_directory()); _add_dropped_files_recursive(p_files, to_path); @@ -5882,27 +5818,27 @@ void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) { top_split->set_visible(!p_pressed); } -void EditorNode::_update_rendering_driver_color() { - if (rendering_driver->get_text() == "opengl3") { - rendering_driver->add_theme_color_override("font_color", Color::hex(0x5586a4ff)); - } else if (rendering_driver->get_text() == "vulkan") { - rendering_driver->add_theme_color_override("font_color", theme_base->get_theme_color(SNAME("vulkan_color"), SNAME("Editor"))); +void EditorNode::_update_renderer_color() { + if (renderer->get_text() == "gl_compatibility") { + renderer->add_theme_color_override("font_color", Color::hex(0x5586a4ff)); + } else if (renderer->get_text() == "forward_plus" || renderer->get_text() == "mobile") { + renderer->add_theme_color_override("font_color", theme_base->get_theme_color(SNAME("highend_color"), SNAME("Editor"))); } } -void EditorNode::_rendering_driver_selected(int p_which) { - String driver = rendering_driver->get_item_metadata(p_which); +void EditorNode::_renderer_selected(int p_which) { + String rendering_method = renderer->get_item_metadata(p_which); - String current_driver = OS::get_singleton()->get_current_rendering_driver_name(); + String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method"); - if (driver == current_driver) { + if (rendering_method == current_renderer) { return; } - rendering_driver_request = driver; + renderer_request = rendering_method; video_restart_dialog->popup_centered(); - rendering_driver->select(rendering_driver_current); - _update_rendering_driver_color(); + renderer->select(renderer_current); + _update_renderer_color(); } void EditorNode::_resource_saved(Ref<Resource> p_resource, const String &p_path) { @@ -5922,12 +5858,14 @@ void EditorNode::_feature_profile_changed() { TabContainer *import_tabs = cast_to<TabContainer>(ImportDock::get_singleton()->get_parent()); TabContainer *node_tabs = cast_to<TabContainer>(NodeDock::get_singleton()->get_parent()); TabContainer *fs_tabs = cast_to<TabContainer>(FileSystemDock::get_singleton()->get_parent()); + TabContainer *history_tabs = cast_to<TabContainer>(history_dock->get_parent()); if (profile.is_valid()) { node_tabs->set_tab_hidden(node_tabs->get_tab_idx_from_control(NodeDock::get_singleton()), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK)); // The Import dock is useless without the FileSystem dock. Ensure the configuration is valid. bool fs_dock_disabled = profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK); fs_tabs->set_tab_hidden(fs_tabs->get_tab_idx_from_control(FileSystemDock::get_singleton()), fs_dock_disabled); import_tabs->set_tab_hidden(import_tabs->get_tab_idx_from_control(ImportDock::get_singleton()), fs_dock_disabled || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK)); + history_tabs->set_tab_hidden(history_tabs->get_tab_idx_from_control(history_dock), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_HISTORY_DOCK)); main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D)); main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT)); @@ -5937,15 +5875,13 @@ void EditorNode::_feature_profile_changed() { if ((profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D) && singleton->main_editor_buttons[EDITOR_3D]->is_pressed()) || (profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT) && singleton->main_editor_buttons[EDITOR_SCRIPT]->is_pressed()) || (AssetLibraryEditorPlugin::is_available() && profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB) && singleton->main_editor_buttons[EDITOR_ASSETLIB]->is_pressed())) { - _editor_select(EDITOR_2D); + editor_select(EDITOR_2D); } } else { import_tabs->set_tab_hidden(import_tabs->get_tab_idx_from_control(ImportDock::get_singleton()), false); node_tabs->set_tab_hidden(node_tabs->get_tab_idx_from_control(NodeDock::get_singleton()), false); fs_tabs->set_tab_hidden(fs_tabs->get_tab_idx_from_control(FileSystemDock::get_singleton()), false); - ImportDock::get_singleton()->set_visible(true); - NodeDock::get_singleton()->set_visible(true); - FileSystemDock::get_singleton()->set_visible(true); + history_tabs->set_tab_hidden(history_tabs->get_tab_idx_from_control(history_dock), false); main_editor_buttons[EDITOR_3D]->set_visible(true); main_editor_buttons[EDITOR_SCRIPT]->set_visible(true); if (AssetLibraryEditorPlugin::is_available()) { @@ -5960,19 +5896,14 @@ void EditorNode::_bind_methods() { GLOBAL_DEF("editor/scene/scene_naming", SCENE_NAME_CASING_SNAKE_CASE); ProjectSettings::get_singleton()->set_custom_property_info("editor/scene/scene_naming", PropertyInfo(Variant::INT, "editor/scene/scene_naming", PROPERTY_HINT_ENUM, "Auto,PascalCase,snake_case")); ClassDB::bind_method("edit_current", &EditorNode::edit_current); - ClassDB::bind_method("_editor_select", &EditorNode::_editor_select); - ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed); ClassDB::bind_method("edit_node", &EditorNode::edit_node); ClassDB::bind_method(D_METHOD("push_item", "object", "property", "inspector_only"), &EditorNode::push_item, DEFVAL(""), DEFVAL(false)); - ClassDB::bind_method("_get_scene_metadata", &EditorNode::_get_scene_metadata); ClassDB::bind_method("set_edited_scene", &EditorNode::set_edited_scene); ClassDB::bind_method("open_request", &EditorNode::open_request); ClassDB::bind_method("edit_foreign_resource", &EditorNode::edit_foreign_resource); ClassDB::bind_method("is_resource_read_only", &EditorNode::is_resource_read_only); - ClassDB::bind_method("_close_messages", &EditorNode::_close_messages); - ClassDB::bind_method("_show_messages", &EditorNode::_show_messages); ClassDB::bind_method("stop_child_process", &EditorNode::stop_child_process); @@ -5981,19 +5912,10 @@ void EditorNode::_bind_methods() { ClassDB::bind_method("_set_main_scene_state", &EditorNode::_set_main_scene_state); ClassDB::bind_method("_update_recent_scenes", &EditorNode::_update_recent_scenes); - ClassDB::bind_method("_clear_undo_history", &EditorNode::_clear_undo_history); - ClassDB::bind_method("edit_item_resource", &EditorNode::edit_item_resource); ClassDB::bind_method(D_METHOD("get_gui_base"), &EditorNode::get_gui_base); - ClassDB::bind_method(D_METHOD("_on_plugin_ready"), &EditorNode::_on_plugin_ready); // Still used by some connect_compat. - - ClassDB::bind_method("_screenshot", &EditorNode::_screenshot); - ClassDB::bind_method("_save_screenshot", &EditorNode::_save_screenshot); - - ClassDB::bind_method("_version_button_pressed", &EditorNode::_version_button_pressed); - ADD_SIGNAL(MethodInfo("play_pressed")); ADD_SIGNAL(MethodInfo("pause_pressed")); ADD_SIGNAL(MethodInfo("stop_pressed")); @@ -6002,6 +5924,7 @@ void EditorNode::_bind_methods() { ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj"))); ADD_SIGNAL(MethodInfo("scene_saved", PropertyInfo(Variant::STRING, "path"))); ADD_SIGNAL(MethodInfo("project_settings_changed")); + ADD_SIGNAL(MethodInfo("scene_changed")); } static Node *_resource_get_edited_scene() { @@ -6138,7 +6061,7 @@ EditorNode::EditorNode() { FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename")); { - int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale"); + int display_scale = EDITOR_GET("interface/editor/display_scale"); switch (display_scale) { case 0: @@ -6164,7 +6087,7 @@ EditorNode::EditorNode() { editor_set_scale(2.0); break; default: - editor_set_scale(EditorSettings::get_singleton()->get("interface/editor/custom_display_scale")); + editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale")); break; } } @@ -6172,10 +6095,17 @@ EditorNode::EditorNode() { // Define a minimum window size to prevent UI elements from overlapping or being cut off. DisplayServer::get_singleton()->window_set_min_size(Size2(1024, 600) * EDSCALE); + FileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files")); + EditorFileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files")); + EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EDITOR_GET("filesystem/file_dialog/display_mode").operator int()); + + int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons"); + if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on DisplayServer. + // Swap on means OK first. + AcceptDialog::set_swap_cancel_ok(swap_cancel_ok == 2); + } + ResourceLoader::set_abort_on_missing_resources(false); - FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); - EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); - EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int()); ResourceLoader::set_error_notify_func(this, _load_error_notify); ResourceLoader::set_dependency_error_notify_func(this, _dependency_error_report); @@ -6336,7 +6266,7 @@ EditorNode::EditorNode() { ED_SHORTCUT("canvas_item_editor/pan_view", TTR("Pan View"), Key::SPACE); - const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); for (const String &E : textfile_ext) { textfile_extensions.insert(E); } @@ -6605,14 +6535,14 @@ EditorNode::EditorNode() { if (can_expand) { // Add spacer to avoid other controls under window minimize/maximize/close buttons (left side). - Control *menu_spacer = memnew(Control); - menu_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); - menu_spacer->set_custom_minimum_size(Size2(DisplayServer::get_singleton()->window_get_safe_title_margins(DisplayServer::MAIN_WINDOW_ID).x, 0)); - menu_hb->add_child(menu_spacer); + left_menu_spacer = memnew(Control); + left_menu_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); + menu_hb->add_child(left_menu_spacer); } main_menu = memnew(MenuBar); menu_hb->add_child(main_menu); + main_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); main_menu->set_flat(true); main_menu->set_start_index(0); // Main menu, add to the start of global menu. @@ -6781,22 +6711,30 @@ EditorNode::EditorNode() { project_menu->add_shortcut(ED_GET_SHORTCUT("editor/quit_to_project_list"), RUN_PROJECT_MANAGER, true); // Spacer to center 2D / 3D / Script buttons. - Control *left_spacer = memnew(Control); + HBoxContainer *left_spacer = memnew(HBoxContainer); left_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); + left_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); menu_hb->add_child(left_spacer); - menu_hb->add_spacer(); + if (can_expand && global_menu) { + project_title = memnew(Label); + project_title->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); + project_title->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"))); + project_title->set_focus_mode(Control::FOCUS_NONE); + project_title->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); + project_title->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); + project_title->set_h_size_flags(Control::SIZE_EXPAND_FILL); + left_spacer->add_child(project_title); + } - main_editor_button_vb = memnew(HBoxContainer); - menu_hb->add_child(main_editor_button_vb); + main_editor_button_hb = memnew(HBoxContainer); + menu_hb->add_child(main_editor_button_hb); // Options are added and handled by DebuggerEditorPlugin. debug_menu = memnew(PopupMenu); debug_menu->set_name(TTR("Debug")); main_menu->add_child(debug_menu); - menu_hb->add_spacer(); - settings_menu = memnew(PopupMenu); settings_menu->set_name(TTR("Editor")); main_menu->add_child(settings_menu); @@ -6870,6 +6808,7 @@ EditorNode::EditorNode() { // Spacer to center 2D / 3D / Script buttons. Control *right_spacer = memnew(Control); right_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); + right_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); menu_hb->add_child(right_spacer); launch_pad = memnew(PanelContainer); @@ -6885,23 +6824,24 @@ EditorNode::EditorNode() { play_button->set_toggle_mode(true); play_button->set_focus_mode(Control::FOCUS_NONE); play_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY)); + play_button->set_tooltip_text(TTR("Run the project's default scene.")); - ED_SHORTCUT_AND_COMMAND("editor/play", TTR("Play"), Key::F5); - ED_SHORTCUT_OVERRIDE("editor/play", "macos", KeyModifierMask::META | Key::B); - play_button->set_shortcut(ED_GET_SHORTCUT("editor/play")); + ED_SHORTCUT_AND_COMMAND("editor/run_project", TTR("Run Project"), Key::F5); + ED_SHORTCUT_OVERRIDE("editor/run_project", "macos", KeyModifierMask::META | Key::B); + play_button->set_shortcut(ED_GET_SHORTCUT("editor/run_project")); pause_button = memnew(Button); pause_button->set_flat(true); pause_button->set_toggle_mode(true); pause_button->set_icon(gui_base->get_theme_icon(SNAME("Pause"), SNAME("EditorIcons"))); pause_button->set_focus_mode(Control::FOCUS_NONE); - pause_button->set_tooltip_text(TTR("Pause the scene execution for debugging.")); + pause_button->set_tooltip_text(TTR("Pause the running project's execution for debugging.")); pause_button->set_disabled(true); launch_pad_hb->add_child(pause_button); - ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), Key::F7); - ED_SHORTCUT_OVERRIDE("editor/pause_scene", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::Y); - pause_button->set_shortcut(ED_GET_SHORTCUT("editor/pause_scene")); + ED_SHORTCUT("editor/pause_running_project", TTR("Pause Running Project"), Key::F7); + ED_SHORTCUT_OVERRIDE("editor/pause_running_project", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::Y); + pause_button->set_shortcut(ED_GET_SHORTCUT("editor/pause_running_project")); stop_button = memnew(Button); stop_button->set_flat(true); @@ -6909,12 +6849,12 @@ EditorNode::EditorNode() { stop_button->set_focus_mode(Control::FOCUS_NONE); stop_button->set_icon(gui_base->get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); stop_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_STOP)); - stop_button->set_tooltip_text(TTR("Stop the scene.")); + stop_button->set_tooltip_text(TTR("Stop the currently running project.")); stop_button->set_disabled(true); - ED_SHORTCUT("editor/stop", TTR("Stop"), Key::F8); - ED_SHORTCUT_OVERRIDE("editor/stop", "macos", KeyModifierMask::META | Key::PERIOD); - stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop")); + ED_SHORTCUT("editor/stop_running_project", TTR("Stop Running Project"), Key::F8); + ED_SHORTCUT_OVERRIDE("editor/stop_running_project", "macos", KeyModifierMask::META | Key::PERIOD); + stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop_running_project")); run_native = memnew(EditorRunNative); launch_pad_hb->add_child(run_native); @@ -6926,10 +6866,11 @@ EditorNode::EditorNode() { play_scene_button->set_toggle_mode(true); play_scene_button->set_focus_mode(Control::FOCUS_NONE); play_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_SCENE)); + play_scene_button->set_tooltip_text(TTR("Run the currently edited scene.")); - ED_SHORTCUT_AND_COMMAND("editor/play_scene", TTR("Play Scene"), Key::F6); - ED_SHORTCUT_OVERRIDE("editor/play_scene", "macos", KeyModifierMask::META | Key::R); - play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_scene")); + ED_SHORTCUT_AND_COMMAND("editor/run_current_scene", TTR("Run Current Scene"), Key::F6); + ED_SHORTCUT_OVERRIDE("editor/run_current_scene", "macos", KeyModifierMask::META | Key::R); + play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_current_scene")); play_custom_scene_button = memnew(Button); play_custom_scene_button->set_flat(true); @@ -6937,12 +6878,13 @@ EditorNode::EditorNode() { play_custom_scene_button->set_toggle_mode(true); play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE); play_custom_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_CUSTOM_SCENE)); + play_custom_scene_button->set_tooltip_text(TTR("Run a specific scene.")); _reset_play_buttons(); - ED_SHORTCUT_AND_COMMAND("editor/play_custom_scene", TTR("Play Custom Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5); - ED_SHORTCUT_OVERRIDE("editor/play_custom_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R); - play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_custom_scene")); + ED_SHORTCUT_AND_COMMAND("editor/run_specific_scene", TTR("Run Specific Scene"), KeyModifierMask::META | KeyModifierMask::SHIFT | Key::F5); + ED_SHORTCUT_OVERRIDE("editor/run_specific_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R); + play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_specific_scene")); write_movie_panel = memnew(PanelContainer); write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); @@ -6966,58 +6908,54 @@ EditorNode::EditorNode() { HBoxContainer *right_menu_hb = memnew(HBoxContainer); menu_hb->add_child(right_menu_hb); - rendering_driver = memnew(OptionButton); - + renderer = memnew(OptionButton); // Hide the renderer selection dropdown until OpenGL support is more mature. // The renderer can still be changed in the project settings or using `--rendering-driver opengl3`. - rendering_driver->set_visible(false); - - rendering_driver->set_flat(true); - rendering_driver->set_focus_mode(Control::FOCUS_NONE); - rendering_driver->connect("item_selected", callable_mp(this, &EditorNode::_rendering_driver_selected)); - rendering_driver->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); - rendering_driver->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"))); + renderer->set_visible(false); + renderer->set_flat(true); + renderer->set_focus_mode(Control::FOCUS_NONE); + renderer->connect("item_selected", callable_mp(this, &EditorNode::_renderer_selected)); + renderer->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); + renderer->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"))); - right_menu_hb->add_child(rendering_driver); + right_menu_hb->add_child(renderer); if (can_expand) { // Add spacer to avoid other controls under the window minimize/maximize/close buttons (right side). - Control *menu_spacer = memnew(Control); - menu_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); - menu_spacer->set_custom_minimum_size(Size2(DisplayServer::get_singleton()->window_get_safe_title_margins(DisplayServer::MAIN_WINDOW_ID).y, 0)); - menu_hb->add_child(menu_spacer); + right_menu_spacer = memnew(Control); + right_menu_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); + menu_hb->add_child(right_menu_spacer); } - // Only display the render drivers that are available for this display driver. - int display_driver_idx = OS::get_singleton()->get_display_driver_id(); - Vector<String> render_drivers = DisplayServer::get_create_function_rendering_drivers(display_driver_idx); - String current_rendering_driver = OS::get_singleton()->get_current_rendering_driver_name(); + String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method"); + + PackedStringArray renderers = ProjectSettings::get_singleton()->get_custom_property_info().get(StringName("rendering/renderer/rendering_method")).hint_string.split(",", false); // As we are doing string comparisons, keep in standard case to prevent problems with capitals // "vulkan" in particular uses lowercase "v" in the code, and uppercase in the UI. - current_rendering_driver = current_rendering_driver.to_lower(); + current_renderer = current_renderer.to_lower(); - for (int i = 0; i < render_drivers.size(); i++) { - String driver = render_drivers[i]; + for (int i = 0; i < renderers.size(); i++) { + String rendering_method = renderers[i]; - // Add the driver to the UI. - rendering_driver->add_item(driver); - rendering_driver->set_item_metadata(i, driver); + // Add the renderers name to the UI. + renderer->add_item(rendering_method); + renderer->set_item_metadata(i, rendering_method); // Lowercase for standard comparison. - driver = driver.to_lower(); + rendering_method = rendering_method.to_lower(); - if (current_rendering_driver == driver) { - rendering_driver->select(i); - rendering_driver_current = i; + if (current_renderer == rendering_method) { + renderer->select(i); + renderer_current = i; } } - _update_rendering_driver_color(); + _update_renderer_color(); video_restart_dialog = memnew(ConfirmationDialog); - video_restart_dialog->set_text(TTR("Changing the video driver requires restarting the editor.")); + video_restart_dialog->set_text(TTR("Changing the renderer requires restarting the editor.")); video_restart_dialog->set_ok_button_text(TTR("Save & Restart")); - video_restart_dialog->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind(SET_RENDERING_DRIVER_SAVE_AND_RESTART)); + video_restart_dialog->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind(SET_RENDERER_NAME_SAVE_AND_RESTART)); gui_base->add_child(video_restart_dialog); progress_hb = memnew(BackgroundProgress); @@ -7048,10 +6986,12 @@ EditorNode::EditorNode() { FileSystemDock *filesystem_dock = memnew(FileSystemDock); filesystem_dock->connect("inherit", callable_mp(this, &EditorNode::_inherit_request)); - filesystem_dock->connect("instance", callable_mp(this, &EditorNode::_instantiate_request)); + filesystem_dock->connect("instantiate", callable_mp(this, &EditorNode::_instantiate_request)); filesystem_dock->connect("display_mode_changed", callable_mp(this, &EditorNode::_save_docks)); get_project_settings()->connect_filesystem_dock_signals(filesystem_dock); + history_dock = memnew(HistoryDock); + // Scene: Top left. dock_slot[DOCK_SLOT_LEFT_UR]->add_child(SceneTreeDock::get_singleton()); dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(dock_slot[DOCK_SLOT_LEFT_UR]->get_tab_idx_from_control(SceneTreeDock::get_singleton()), TTR("Scene")); @@ -7072,6 +7012,10 @@ EditorNode::EditorNode() { dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(NodeDock::get_singleton()); dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(dock_slot[DOCK_SLOT_RIGHT_UL]->get_tab_idx_from_control(NodeDock::get_singleton()), TTR("Node")); + // History: Full height right, behind Node. + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(history_dock); + dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(dock_slot[DOCK_SLOT_RIGHT_UL]->get_tab_idx_from_control(history_dock), TTR("History")); + // Hide unused dock slots and vsplits. dock_slot[DOCK_SLOT_LEFT_UL]->hide(); dock_slot[DOCK_SLOT_LEFT_BL]->hide(); @@ -7092,7 +7036,7 @@ EditorNode::EditorNode() { // Dock numbers are based on DockSlot enum value + 1. default_layout->set_value(docks_section, "dock_3", "Scene,Import"); default_layout->set_value(docks_section, "dock_4", "FileSystem"); - default_layout->set_value(docks_section, "dock_5", "Inspector,Node"); + default_layout->set_value(docks_section, "dock_5", "Inspector,Node,History"); for (int i = 0; i < vsplits.size(); i++) { default_layout->set_value(docks_section, "dock_split_" + itos(i + 1), 0); @@ -7265,7 +7209,6 @@ EditorNode::EditorNode() { add_child(audio_preview_gen); add_editor_plugin(memnew(DebuggerEditorPlugin(debug_menu))); - add_editor_plugin(memnew(DebugAdapterServer())); disk_changed = memnew(ConfirmationDialog); { @@ -7315,63 +7258,7 @@ EditorNode::EditorNode() { raise_bottom_panel_item(AnimationPlayerEditor::get_singleton()); add_editor_plugin(VersionControlEditorPlugin::get_singleton()); - - // This list is alphabetized, and plugins that depend on Node2D are in their own section below. - add_editor_plugin(memnew(AnimationTreeEditorPlugin)); add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); - add_editor_plugin(memnew(AudioStreamRandomizerEditorPlugin)); - add_editor_plugin(memnew(BitMapEditorPlugin)); - add_editor_plugin(memnew(BoneMapEditorPlugin)); - add_editor_plugin(memnew(Camera3DEditorPlugin)); - add_editor_plugin(memnew(ControlEditorPlugin)); - add_editor_plugin(memnew(CPUParticles3DEditorPlugin)); - add_editor_plugin(memnew(CurveEditorPlugin)); - add_editor_plugin(memnew(FontEditorPlugin)); - add_editor_plugin(memnew(GPUParticles3DEditorPlugin)); - add_editor_plugin(memnew(GPUParticlesCollisionSDF3DEditorPlugin)); - add_editor_plugin(memnew(GradientEditorPlugin)); - add_editor_plugin(memnew(GradientTexture2DEditorPlugin)); - add_editor_plugin(memnew(InputEventEditorPlugin)); - add_editor_plugin(memnew(LightmapGIEditorPlugin)); - add_editor_plugin(memnew(MaterialEditorPlugin)); - add_editor_plugin(memnew(MeshEditorPlugin)); - add_editor_plugin(memnew(MeshInstance3DEditorPlugin)); - add_editor_plugin(memnew(MeshLibraryEditorPlugin)); - add_editor_plugin(memnew(MultiMeshEditorPlugin)); - add_editor_plugin(memnew(OccluderInstance3DEditorPlugin)); - add_editor_plugin(memnew(Path3DEditorPlugin)); - add_editor_plugin(memnew(PhysicalBone3DEditorPlugin)); - add_editor_plugin(memnew(Polygon3DEditorPlugin)); - add_editor_plugin(memnew(ResourcePreloaderEditorPlugin)); - add_editor_plugin(memnew(ShaderEditorPlugin)); - add_editor_plugin(memnew(ShaderFileEditorPlugin)); - add_editor_plugin(memnew(Skeleton3DEditorPlugin)); - add_editor_plugin(memnew(SkeletonIK3DEditorPlugin)); - add_editor_plugin(memnew(SpriteFramesEditorPlugin)); - add_editor_plugin(memnew(StyleBoxEditorPlugin)); - add_editor_plugin(memnew(SubViewportPreviewEditorPlugin)); - add_editor_plugin(memnew(Texture3DEditorPlugin)); - add_editor_plugin(memnew(TextureEditorPlugin)); - add_editor_plugin(memnew(TextureLayeredEditorPlugin)); - add_editor_plugin(memnew(TextureRegionEditorPlugin)); - add_editor_plugin(memnew(ThemeEditorPlugin)); - add_editor_plugin(memnew(VoxelGIEditorPlugin)); - - // 2D - add_editor_plugin(memnew(CollisionPolygon2DEditorPlugin)); - add_editor_plugin(memnew(CollisionShape2DEditorPlugin)); - add_editor_plugin(memnew(CPUParticles2DEditorPlugin)); - add_editor_plugin(memnew(GPUParticles2DEditorPlugin)); - add_editor_plugin(memnew(LightOccluder2DEditorPlugin)); - add_editor_plugin(memnew(Line2DEditorPlugin)); - add_editor_plugin(memnew(NavigationLink2DEditorPlugin)); - add_editor_plugin(memnew(NavigationPolygonEditorPlugin)); - add_editor_plugin(memnew(Path2DEditorPlugin)); - add_editor_plugin(memnew(Polygon2DEditorPlugin)); - add_editor_plugin(memnew(Cast2DEditorPlugin)); - add_editor_plugin(memnew(Skeleton2DEditorPlugin)); - add_editor_plugin(memnew(Sprite2DEditorPlugin)); - add_editor_plugin(memnew(TilesEditorPlugin)); for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) { add_editor_plugin(EditorPlugins::create(i)); @@ -7541,9 +7428,9 @@ EditorNode::EditorNode() { screenshot_timer->set_owner(get_owner()); // Adjust spacers to center 2D / 3D / Script buttons. - int max_w = MAX(launch_pad_hb->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu->get_minimum_size().x); + int max_w = MAX(launch_pad->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu->get_minimum_size().x); left_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - main_menu->get_minimum_size().x), 0)); - right_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - launch_pad_hb->get_minimum_size().x - right_menu_hb->get_minimum_size().x), 0)); + right_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - launch_pad->get_minimum_size().x - right_menu_hb->get_minimum_size().x), 0)); // Extend menu bar to window title. if (can_expand) { @@ -7600,7 +7487,7 @@ bool EditorPluginList::forward_gui_input(const Ref<InputEvent> &p_event) { return discard; } -EditorPlugin::AfterGUIInput EditorPluginList::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled) { +EditorPlugin::AfterGUIInput EditorPluginList::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled) { EditorPlugin::AfterGUIInput after = EditorPlugin::AFTER_GUI_INPUT_PASS; for (int i = 0; i < plugins_list.size(); i++) { @@ -7608,7 +7495,7 @@ EditorPlugin::AfterGUIInput EditorPluginList::forward_spatial_gui_input(Camera3D continue; } - EditorPlugin::AfterGUIInput current_after = plugins_list[i]->forward_spatial_gui_input(p_camera, p_event); + EditorPlugin::AfterGUIInput current_after = plugins_list[i]->forward_3d_gui_input(p_camera, p_event); if (current_after == EditorPlugin::AFTER_GUI_INPUT_STOP) { after = EditorPlugin::AFTER_GUI_INPUT_STOP; } @@ -7632,15 +7519,15 @@ void EditorPluginList::forward_canvas_force_draw_over_viewport(Control *p_overla } } -void EditorPluginList::forward_spatial_draw_over_viewport(Control *p_overlay) { +void EditorPluginList::forward_3d_draw_over_viewport(Control *p_overlay) { for (int i = 0; i < plugins_list.size(); i++) { - plugins_list[i]->forward_spatial_draw_over_viewport(p_overlay); + plugins_list[i]->forward_3d_draw_over_viewport(p_overlay); } } -void EditorPluginList::forward_spatial_force_draw_over_viewport(Control *p_overlay) { +void EditorPluginList::forward_3d_force_draw_over_viewport(Control *p_overlay) { for (int i = 0; i < plugins_list.size(); i++) { - plugins_list[i]->forward_spatial_force_draw_over_viewport(p_overlay); + plugins_list[i]->forward_3d_force_draw_over_viewport(p_overlay); } } diff --git a/editor/editor_node.h b/editor/editor_node.h index 200d68908c..c430662c7f 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -32,12 +32,13 @@ #define EDITOR_NODE_H #include "core/templates/safe_refcount.h" +#include "editor/editor_data.h" #include "editor/editor_folding.h" #include "editor/editor_native_shader_source_visualizer.h" +#include "editor/editor_plugin.h" #include "editor/editor_run.h" #include "editor/editor_title_bar.h" #include "editor/export/editor_export.h" -#include "editor/inspector_dock.h" typedef void (*EditorNodeInitCallback)(); typedef void (*EditorPluginInitializeCallback)(); @@ -46,8 +47,8 @@ typedef bool (*EditorBuildCallback)(); class AcceptDialog; class AudioStreamPreviewGenerator; class BackgroundProgress; -class Button; class CenterContainer; +class CheckBox; class ColorPicker; class ConfirmationDialog; class Control; @@ -59,30 +60,33 @@ class EditorCommandPalette; class EditorExport; class EditorExtensionManager; class EditorFeatureProfileManager; +class EditorFileDialog; class EditorFileServer; class EditorFolding; class EditorInspector; class EditorLayoutsDialog; class EditorLog; -class EditorPlugin; class EditorPluginList; class EditorQuickOpen; class EditorResourcePreview; class EditorResourceConversionPlugin; class EditorRun; class EditorRunNative; +class EditorSelectionHistory; class EditorSettingsDialog; class EditorToaster; class EditorUndoRedoManager; class ExportTemplateManager; class FileDialog; class FileSystemDock; +class HistoryDock; class HSplitContainer; class ImportDock; class LinkButton; class MenuBar; class MenuButton; class NodeDock; +class OptionButton; class OrphanResourcesDialog; class Panel; class PanelContainer; @@ -97,7 +101,9 @@ class ScriptCreateDialog; class SubViewport; class TabBar; class TabContainer; +class TextureRect; class TextureProgressBar; +class Tree; class VSplitContainer; class Window; class EditorBuildProfileManager; @@ -125,6 +131,12 @@ public: EDITOR_ASSETLIB }; + enum SceneNameCasing { + SCENE_NAME_CASING_AUTO, + SCENE_NAME_CASING_PASCAL_CASE, + SCENE_NAME_CASING_SNAKE_CASE + }; + struct ExecuteThreadArgs { String path; List<String> args; @@ -218,7 +230,7 @@ private: HELP_ABOUT, HELP_SUPPORT_GODOT_DEVELOPMENT, - SET_RENDERING_DRIVER_SAVE_AND_RESTART, + SET_RENDERER_NAME_SAVE_AND_RESTART, GLOBAL_NEW_WINDOW, GLOBAL_SCENE, @@ -233,12 +245,6 @@ private: MAX_BUILD_CALLBACKS = 128 }; - enum ScriptNameCasing { - SCENE_NAME_CASING_AUTO, - SCENE_NAME_CASING_PASCAL_CASE, - SCENE_NAME_CASING_SNAKE_CASE - }; - struct BottomPanelItem { String name; Control *control = nullptr; @@ -274,6 +280,7 @@ private: EditorRunNative *run_native = nullptr; EditorSelection *editor_selection = nullptr; EditorSettingsDialog *editor_settings_dialog = nullptr; + HistoryDock *history_dock = nullptr; ProjectExportDialog *project_export = nullptr; ProjectSettingsEditor *project_settings_editor = nullptr; @@ -286,12 +293,12 @@ private: Control *theme_base = nullptr; Control *gui_base = nullptr; VBoxContainer *main_vbox = nullptr; - OptionButton *rendering_driver = nullptr; + OptionButton *renderer = nullptr; ConfirmationDialog *video_restart_dialog = nullptr; - int rendering_driver_current = 0; - String rendering_driver_request; + int renderer_current = 0; + String renderer_request; // Split containers. HSplitContainer *left_l_hsplit = nullptr; @@ -322,6 +329,9 @@ private: HBoxContainer *bottom_hb = nullptr; Control *vp_base = nullptr; + Label *project_title = nullptr; + Control *left_menu_spacer = nullptr; + Control *right_menu_spacer = nullptr; EditorTitleBar *menu_hb = nullptr; VBoxContainer *main_screen_vbox = nullptr; MenuBar *main_menu = nullptr; @@ -397,7 +407,7 @@ private: String current_path; MenuButton *update_spinner = nullptr; - HBoxContainer *main_editor_button_vb = nullptr; + HBoxContainer *main_editor_button_hb = nullptr; Vector<Button *> main_editor_buttons; Vector<EditorPlugin *> editor_table; @@ -543,7 +553,6 @@ private: void _update_file_menu_opened(); void _update_file_menu_closed(); - void _on_plugin_ready(Object *p_script, const String &p_activate_name); void _remove_plugin_from_enabled(const String &p_name); void _fs_changed(); @@ -553,7 +562,6 @@ private: void _node_renamed(); void _editor_select_next(); void _editor_select_prev(); - void _editor_select(int p_which); void _set_scene_metadata(const String &p_file, int p_idx = -1); void _get_scene_metadata(const String &p_file); void _update_title(); @@ -562,6 +570,7 @@ private: void _close_messages(); void _show_messages(); void _vp_resized(); + void _titlebar_resized(); void _version_button_pressed(); int _save_external_resources(); @@ -599,8 +608,8 @@ private: void _update_from_settings(); - void _rendering_driver_selected(int); - void _update_rendering_driver_color(); + void _renderer_selected(int); + void _update_renderer_color(); void _exit_editor(int p_exit_code); @@ -649,7 +658,7 @@ private: void _load_docks(); void _save_docks_to_config(Ref<ConfigFile> p_layout, const String &p_section); void _load_docks_from_config(Ref<ConfigFile> p_layout, const String &p_section); - void _update_dock_slots_visibility(); + void _update_dock_slots_visibility(bool p_keep_selected_tabs = false); void _dock_tab_changed(int p_tab); void _save_open_scenes_to_config(Ref<ConfigFile> p_layout, const String &p_section); @@ -658,8 +667,6 @@ private: void _update_layouts_menu(); void _layout_menu_option(int p_id); - void _clear_undo_history(); - void _update_addon_config(); void _toggle_distraction_free_mode(); @@ -703,12 +710,13 @@ protected: void set_current_tab(int p_tab); public: - void set_visible_editor(EditorTable p_table) { _editor_select(p_table); } + // Public for use with callable_mp. + void _on_plugin_ready(Object *p_script, const String &p_activate_name); - bool call_build(); + void editor_select(int p_which); + void set_visible_editor(EditorTable p_table) { editor_select(p_table); } - static void register_editor_types(); - static void unregister_editor_types(); + bool call_build(); static EditorNode *get_singleton() { return singleton; } @@ -720,6 +728,8 @@ public: static HBoxContainer *get_menu_hb() { return singleton->menu_hb; } static VSplitContainer *get_top_split() { return singleton->top_split; } + static String adjust_scene_name_casing(const String &root_name); + static bool has_unsaved_changes() { return singleton->unsaved_cache; } static void disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames); static void add_io_error(const String &p_error); @@ -741,6 +751,8 @@ public: static bool immediate_confirmation_dialog(const String &p_text, const String &p_ok_text = TTR("Ok"), const String &p_cancel_text = TTR("Cancel")); + static void cleanup(); + EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; } EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; } EditorPluginList *get_editor_plugins_force_over() { return editor_plugins_force_over; } @@ -764,8 +776,11 @@ public: void set_addon_plugin_enabled(const String &p_addon, bool p_enabled, bool p_config_changed = false); bool is_addon_plugin_enabled(const String &p_addon) const; + void set_movie_maker_enabled(bool p_enabled); + bool is_movie_maker_enabled() const; + void edit_node(Node *p_node); - void edit_resource(const Ref<Resource> &p_resource) { InspectorDock::get_singleton()->edit_resource(p_resource); }; + void edit_resource(const Ref<Resource> &p_resource); void save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path); void save_resource(const Ref<Resource> &p_resource); @@ -805,7 +820,7 @@ public: void setup_color_picker(ColorPicker *picker); - void request_instance_scene(const String &p_path); + void request_instantiate_scene(const String &p_path); void request_instantiate_scenes(const Vector<String> &p_files); void set_convert_old_scene(bool p_old) { convert_old = p_old; } @@ -821,6 +836,8 @@ public: Ref<Texture2D> get_object_icon(const Object *p_object, const String &p_fallback = "Object"); Ref<Texture2D> get_class_icon(const String &p_class, const String &p_fallback = "Object") const; + bool is_object_of_custom_type(const Object *p_object, const StringName &p_class); + void show_accept(const String &p_text, const String &p_title); void show_save_accept(const String &p_text, const String &p_title); void show_warning(const String &p_text, const String &p_title = TTR("Warning!")); @@ -929,9 +946,9 @@ public: bool forward_gui_input(const Ref<InputEvent> &p_event); void forward_canvas_draw_over_viewport(Control *p_overlay); void forward_canvas_force_draw_over_viewport(Control *p_overlay); - EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled); - void forward_spatial_draw_over_viewport(Control *p_overlay); - void forward_spatial_force_draw_over_viewport(Control *p_overlay); + EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled); + void forward_3d_draw_over_viewport(Control *p_overlay); + void forward_3d_force_draw_over_viewport(Control *p_overlay); void add_plugin(EditorPlugin *p_plugin); void remove_plugin(EditorPlugin *p_plugin); void clear(); diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp index d1f41dad84..a8fd9d0eb0 100644 --- a/editor/editor_path.cpp +++ b/editor/editor_path.cpp @@ -59,7 +59,7 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { continue; } - Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(obj); + Ref<Texture2D> obj_icon = EditorNode::get_singleton()->get_object_icon(obj); String proper_name = ""; Vector<String> name_parts = E.name.split("/"); @@ -72,7 +72,7 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { } int index = sub_objects_menu->get_item_count(); - sub_objects_menu->add_icon_item(icon, proper_name, objects.size()); + sub_objects_menu->add_icon_item(obj_icon, proper_name, objects.size()); sub_objects_menu->set_item_indent(index, p_depth); objects.push_back(obj->get_instance_id()); @@ -122,15 +122,15 @@ void EditorPath::update_path() { continue; } - Ref<Texture2D> icon; + Ref<Texture2D> obj_icon; if (Object::cast_to<MultiNodeEdit>(obj)) { - icon = EditorNode::get_singleton()->get_class_icon(Object::cast_to<MultiNodeEdit>(obj)->get_edited_class_name()); + obj_icon = EditorNode::get_singleton()->get_class_icon(Object::cast_to<MultiNodeEdit>(obj)->get_edited_class_name()); } else { - icon = EditorNode::get_singleton()->get_object_icon(obj); + obj_icon = EditorNode::get_singleton()->get_object_icon(obj); } - if (icon.is_valid()) { - current_object_icon->set_texture(icon); + if (obj_icon.is_valid()) { + current_object_icon->set_texture(obj_icon); } if (i == history->get_path_size() - 1) { diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp index 54d4660cb6..f55c530ffb 100644 --- a/editor/editor_paths.cpp +++ b/editor/editor_paths.cpp @@ -83,7 +83,7 @@ String EditorPaths::get_script_templates_dir() const { } String EditorPaths::get_project_script_templates_dir() const { - return ProjectSettings::get_singleton()->get("editor/script/templates_search_path"); + return GLOBAL_GET("editor/script/templates_search_path"); } String EditorPaths::get_feature_profiles_dir() const { diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 981dad2d2a..f9c8b722c4 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -30,15 +30,21 @@ #include "editor_plugin.h" +#include "editor/debugger/editor_debugger_node.h" #include "editor/editor_command_palette.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_resource_preview.h" #include "editor/editor_settings.h" +#include "editor/editor_translation_parser.h" #include "editor/editor_undo_redo_manager.h" #include "editor/export/editor_export.h" #include "editor/filesystem_dock.h" +#include "editor/import/editor_import_plugin.h" +#include "editor/import/resource_importer_scene.h" +#include "editor/inspector_dock.h" #include "editor/plugins/canvas_item_editor_plugin.h" +#include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/project_settings_editor.h" @@ -238,14 +244,18 @@ void EditorInterface::select_file(const String &p_file) { FileSystemDock::get_singleton()->select_file(p_file); } -String EditorInterface::get_selected_path() const { - return FileSystemDock::get_singleton()->get_selected_path(); +Vector<String> EditorInterface::get_selected_paths() const { + return FileSystemDock::get_singleton()->get_selected_paths(); } String EditorInterface::get_current_path() const { return FileSystemDock::get_singleton()->get_current_path(); } +String EditorInterface::get_current_directory() const { + return FileSystemDock::get_singleton()->get_current_directory(); +} + void EditorInterface::inspect_object(Object *p_obj, const String &p_for_property, bool p_inspector_only) { EditorNode::get_singleton()->push_item(p_obj, p_for_property, p_inspector_only); } @@ -289,6 +299,14 @@ bool EditorInterface::is_plugin_enabled(const String &p_plugin) const { return EditorNode::get_singleton()->is_addon_plugin_enabled(p_plugin); } +void EditorInterface::set_movie_maker_enabled(bool p_enabled) { + EditorNode::get_singleton()->set_movie_maker_enabled(p_enabled); +} + +bool EditorInterface::is_movie_maker_enabled() const { + return EditorNode::get_singleton()->is_movie_maker_enabled(); +} + EditorInspector *EditorInterface::get_inspector() const { return InspectorDock::get_inspector_singleton(); } @@ -355,8 +373,9 @@ void EditorInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("get_editor_main_screen"), &EditorInterface::get_editor_main_screen); ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews); ClassDB::bind_method(D_METHOD("select_file", "file"), &EditorInterface::select_file); - ClassDB::bind_method(D_METHOD("get_selected_path"), &EditorInterface::get_selected_path); + ClassDB::bind_method(D_METHOD("get_selected_paths"), &EditorInterface::get_selected_paths); ClassDB::bind_method(D_METHOD("get_current_path"), &EditorInterface::get_current_path); + ClassDB::bind_method(D_METHOD("get_current_directory"), &EditorInterface::get_current_directory); ClassDB::bind_method(D_METHOD("get_file_system_dock"), &EditorInterface::get_file_system_dock); ClassDB::bind_method(D_METHOD("get_editor_paths"), &EditorInterface::get_editor_paths); ClassDB::bind_method(D_METHOD("get_command_palette"), &EditorInterface::get_command_palette); @@ -364,6 +383,9 @@ void EditorInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("set_plugin_enabled", "plugin", "enabled"), &EditorInterface::set_plugin_enabled); ClassDB::bind_method(D_METHOD("is_plugin_enabled", "plugin"), &EditorInterface::is_plugin_enabled); + ClassDB::bind_method(D_METHOD("set_movie_maker_enabled", "enabled"), &EditorInterface::set_movie_maker_enabled); + ClassDB::bind_method(D_METHOD("is_movie_maker_enabled"), &EditorInterface::is_movie_maker_enabled); + ClassDB::bind_method(D_METHOD("get_inspector"), &EditorInterface::get_inspector); ClassDB::bind_method(D_METHOD("save_scene"), &EditorInterface::save_scene); @@ -570,11 +592,9 @@ void EditorPlugin::notify_resource_saved(const Ref<Resource> &p_resource) { } bool EditorPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { - bool success; - if (GDVIRTUAL_CALL(_forward_canvas_gui_input, p_event, success)) { - return success; - } - return false; + bool success = false; + GDVIRTUAL_CALL(_forward_canvas_gui_input, p_event, success); + return success; } void EditorPlugin::forward_canvas_draw_over_viewport(Control *p_overlay) { @@ -604,49 +624,36 @@ int EditorPlugin::update_overlays() const { } } -EditorPlugin::AfterGUIInput EditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { - int success; - - if (GDVIRTUAL_CALL(_forward_3d_gui_input, p_camera, p_event, success)) { - return static_cast<EditorPlugin::AfterGUIInput>(success); - } - - return EditorPlugin::AFTER_GUI_INPUT_PASS; +EditorPlugin::AfterGUIInput EditorPlugin::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { + int success = EditorPlugin::AFTER_GUI_INPUT_PASS; + GDVIRTUAL_CALL(_forward_3d_gui_input, p_camera, p_event, success); + return static_cast<EditorPlugin::AfterGUIInput>(success); } -void EditorPlugin::forward_spatial_draw_over_viewport(Control *p_overlay) { +void EditorPlugin::forward_3d_draw_over_viewport(Control *p_overlay) { GDVIRTUAL_CALL(_forward_3d_draw_over_viewport, p_overlay); } -void EditorPlugin::forward_spatial_force_draw_over_viewport(Control *p_overlay) { +void EditorPlugin::forward_3d_force_draw_over_viewport(Control *p_overlay) { GDVIRTUAL_CALL(_forward_3d_force_draw_over_viewport, p_overlay); } String EditorPlugin::get_name() const { String name; - if (GDVIRTUAL_CALL(_get_plugin_name, name)) { - return name; - } - - return String(); + GDVIRTUAL_CALL(_get_plugin_name, name); + return name; } const Ref<Texture2D> EditorPlugin::get_icon() const { Ref<Texture2D> icon; - if (GDVIRTUAL_CALL(_get_plugin_icon, icon)) { - return icon; - } - - return Ref<Texture2D>(); + GDVIRTUAL_CALL(_get_plugin_icon, icon); + return icon; } bool EditorPlugin::has_main_screen() const { - bool success; - if (GDVIRTUAL_CALL(_has_main_screen, success)) { - return success; - } - - return false; + bool success = false; + GDVIRTUAL_CALL(_has_main_screen, success); + return success; } void EditorPlugin::make_visible(bool p_visible) { @@ -662,21 +669,15 @@ void EditorPlugin::edit(Object *p_object) { } bool EditorPlugin::handles(Object *p_object) const { - bool success; - if (GDVIRTUAL_CALL(_handles, p_object, success)) { - return success; - } - - return false; + bool success = false; + GDVIRTUAL_CALL(_handles, p_object, success); + return success; } Dictionary EditorPlugin::get_state() const { Dictionary state; - if (GDVIRTUAL_CALL(_get_state, state)) { - return state; - } - - return Dictionary(); + GDVIRTUAL_CALL(_get_state, state); + return state; } void EditorPlugin::set_state(const Dictionary &p_state) { @@ -753,12 +754,12 @@ void EditorPlugin::remove_export_plugin(const Ref<EditorExportPlugin> &p_exporte EditorExport::get_singleton()->remove_export_plugin(p_exporter); } -void EditorPlugin::add_spatial_gizmo_plugin(const Ref<EditorNode3DGizmoPlugin> &p_gizmo_plugin) { +void EditorPlugin::add_node_3d_gizmo_plugin(const Ref<EditorNode3DGizmoPlugin> &p_gizmo_plugin) { ERR_FAIL_COND(!p_gizmo_plugin.is_valid()); Node3DEditor::get_singleton()->add_gizmo_plugin(p_gizmo_plugin); } -void EditorPlugin::remove_spatial_gizmo_plugin(const Ref<EditorNode3DGizmoPlugin> &p_gizmo_plugin) { +void EditorPlugin::remove_node_3d_gizmo_plugin(const Ref<EditorNode3DGizmoPlugin> &p_gizmo_plugin) { ERR_FAIL_COND(!p_gizmo_plugin.is_valid()); Node3DEditor::get_singleton()->remove_gizmo_plugin(p_gizmo_plugin); } @@ -822,11 +823,9 @@ void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout) { } bool EditorPlugin::build() { - bool success; - if (GDVIRTUAL_CALL(_build, success)) { - return success; - } - return true; + bool success = true; + GDVIRTUAL_CALL(_build, success); + return success; } void EditorPlugin::queue_save_layout() { @@ -849,12 +848,12 @@ ScriptCreateDialog *EditorPlugin::get_script_create_dialog() { return SceneTreeDock::get_singleton()->get_script_create_dialog(); } -void EditorPlugin::add_debugger_plugin(const Ref<Script> &p_script) { - EditorDebuggerNode::get_singleton()->add_debugger_plugin(p_script); +void EditorPlugin::add_debugger_plugin(const Ref<EditorDebuggerPlugin> &p_plugin) { + EditorDebuggerNode::get_singleton()->add_debugger_plugin(p_plugin); } -void EditorPlugin::remove_debugger_plugin(const Ref<Script> &p_script) { - EditorDebuggerNode::get_singleton()->remove_debugger_plugin(p_script); +void EditorPlugin::remove_debugger_plugin(const Ref<EditorDebuggerPlugin> &p_plugin) { + EditorDebuggerNode::get_singleton()->remove_debugger_plugin(p_plugin); } void EditorPlugin::_editor_project_settings_changed() { @@ -908,8 +907,8 @@ void EditorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_scene_post_import_plugin", "scene_import_plugin"), &EditorPlugin::remove_scene_post_import_plugin); ClassDB::bind_method(D_METHOD("add_export_plugin", "plugin"), &EditorPlugin::add_export_plugin); ClassDB::bind_method(D_METHOD("remove_export_plugin", "plugin"), &EditorPlugin::remove_export_plugin); - ClassDB::bind_method(D_METHOD("add_spatial_gizmo_plugin", "plugin"), &EditorPlugin::add_spatial_gizmo_plugin); - ClassDB::bind_method(D_METHOD("remove_spatial_gizmo_plugin", "plugin"), &EditorPlugin::remove_spatial_gizmo_plugin); + ClassDB::bind_method(D_METHOD("add_node_3d_gizmo_plugin", "plugin"), &EditorPlugin::add_node_3d_gizmo_plugin); + ClassDB::bind_method(D_METHOD("remove_node_3d_gizmo_plugin", "plugin"), &EditorPlugin::remove_node_3d_gizmo_plugin); ClassDB::bind_method(D_METHOD("add_inspector_plugin", "plugin"), &EditorPlugin::add_inspector_plugin); ClassDB::bind_method(D_METHOD("remove_inspector_plugin", "plugin"), &EditorPlugin::remove_inspector_plugin); ClassDB::bind_method(D_METHOD("set_input_event_forwarding_always_enabled"), &EditorPlugin::set_input_event_forwarding_always_enabled); @@ -979,7 +978,7 @@ void EditorPlugin::_bind_methods() { } Ref<EditorUndoRedoManager> EditorPlugin::get_undo_redo() { - return undo_redo; + return EditorNode::get_undo_redo(); } EditorPluginCreateFunc EditorPlugins::creation_funcs[MAX_CREATE_FUNCS]; diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index a048b174e4..d736675faf 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -32,33 +32,34 @@ #define EDITOR_PLUGIN_H #include "core/io/config_file.h" -#include "core/object/undo_redo.h" -#include "editor/debugger/editor_debugger_node.h" -#include "editor/editor_inspector.h" -#include "editor/editor_translation_parser.h" -#include "editor/import/editor_import_plugin.h" -#include "editor/import/resource_importer_scene.h" -#include "editor/script_create_dialog.h" #include "scene/3d/camera_3d.h" -#include "scene/main/node.h" -#include "scene/resources/texture.h" +#include "scene/gui/control.h" class Node3D; -class Camera3D; +class Button; +class PopupMenu; class EditorCommandPalette; -class EditorSelection; +class EditorDebuggerPlugin; class EditorExport; -class EditorSettings; -class EditorImportPlugin; class EditorExportPlugin; +class EditorFileSystem; +class EditorImportPlugin; +class EditorInspector; +class EditorInspectorPlugin; class EditorNode3DGizmoPlugin; +class EditorPaths; class EditorResourcePreview; -class EditorUndoRedoManager; -class EditorFileSystem; +class EditorSceneFormatImporter; +class EditorScenePostImportPlugin; +class EditorSelection; +class EditorSettings; class EditorToolAddons; -class EditorPaths; +class EditorTranslationParserPlugin; +class EditorUndoRedoManager; class FileSystemDock; +class ScriptCreateDialog; class ScriptEditor; +class VBoxContainer; class EditorInterface : public Node { GDCLASS(EditorInterface, Node); @@ -93,8 +94,9 @@ public: EditorCommandPalette *get_command_palette() const; void select_file(const String &p_file); - String get_selected_path() const; + Vector<String> get_selected_paths() const; String get_current_path() const; + String get_current_directory() const; void inspect_object(Object *p_obj, const String &p_for_property = String(), bool p_inspector_only = false); @@ -113,6 +115,9 @@ public: void set_plugin_enabled(const String &p_plugin, bool p_enabled); bool is_plugin_enabled(const String &p_plugin) const; + void set_movie_maker_enabled(bool p_enabled); + bool is_movie_maker_enabled() const; + EditorInspector *get_inspector() const; Error save_scene(); @@ -131,7 +136,6 @@ public: class EditorPlugin : public Node { GDCLASS(EditorPlugin, Node); friend class EditorData; - Ref<EditorUndoRedoManager> undo_redo; bool input_event_forwarding_always_enabled = false; bool force_draw_over_forwarding_enabled = false; @@ -237,9 +241,9 @@ public: virtual void forward_canvas_draw_over_viewport(Control *p_overlay); virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay); - virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event); - virtual void forward_spatial_draw_over_viewport(Control *p_overlay); - virtual void forward_spatial_force_draw_over_viewport(Control *p_overlay); + virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event); + virtual void forward_3d_draw_over_viewport(Control *p_overlay); + virtual void forward_3d_force_draw_over_viewport(Control *p_overlay); virtual String get_name() const; virtual const Ref<Texture2D> get_icon() const; @@ -285,8 +289,8 @@ public: void add_export_plugin(const Ref<EditorExportPlugin> &p_exporter); void remove_export_plugin(const Ref<EditorExportPlugin> &p_exporter); - void add_spatial_gizmo_plugin(const Ref<EditorNode3DGizmoPlugin> &p_gizmo_plugin); - void remove_spatial_gizmo_plugin(const Ref<EditorNode3DGizmoPlugin> &p_gizmo_plugin); + void add_node_3d_gizmo_plugin(const Ref<EditorNode3DGizmoPlugin> &p_gizmo_plugin); + void remove_node_3d_gizmo_plugin(const Ref<EditorNode3DGizmoPlugin> &p_gizmo_plugin); void add_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); void remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); @@ -300,8 +304,8 @@ public: void add_autoload_singleton(const String &p_name, const String &p_path); void remove_autoload_singleton(const String &p_name); - void add_debugger_plugin(const Ref<Script> &p_script); - void remove_debugger_plugin(const Ref<Script> &p_script); + void add_debugger_plugin(const Ref<EditorDebuggerPlugin> &p_plugin); + void remove_debugger_plugin(const Ref<EditorDebuggerPlugin> &p_plugin); void enable_plugin(); void disable_plugin(); @@ -318,7 +322,7 @@ typedef EditorPlugin *(*EditorPluginCreateFunc)(); class EditorPlugins { enum { - MAX_CREATE_FUNCS = 64 + MAX_CREATE_FUNCS = 128 }; static EditorPluginCreateFunc creation_funcs[MAX_CREATE_FUNCS]; diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index a8df486381..dd647c944d 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -46,7 +46,7 @@ void EditorPluginSettings::_notification(int p_what) { } break; case Node::NOTIFICATION_READY: { - plugin_config_dialog->connect("plugin_ready", Callable(EditorNode::get_singleton(), "_on_plugin_ready")); + plugin_config_dialog->connect("plugin_ready", callable_mp(EditorNode::get_singleton(), &EditorNode::_on_plugin_ready)); plugin_list->connect("button_clicked", callable_mp(this, &EditorPluginSettings::_cell_button_pressed)); } break; } @@ -98,14 +98,14 @@ void EditorPluginSettings::update_plugins() { String author = cf->get_value("plugin", "author"); String version = cf->get_value("plugin", "version"); String description = cf->get_value("plugin", "description"); - String script = cf->get_value("plugin", "script"); + String scr = cf->get_value("plugin", "script"); TreeItem *item = plugin_list->create_item(root); item->set_text(0, name); - item->set_tooltip_text(0, TTR("Name:") + " " + name + "\n" + TTR("Path:") + " " + path + "\n" + TTR("Main Script:") + " " + script + "\n" + TTR("Description:") + " " + description); + item->set_tooltip_text(0, TTR("Name:") + " " + name + "\n" + TTR("Path:") + " " + path + "\n" + TTR("Main Script:") + " " + scr + "\n" + TTR("Description:") + " " + description); item->set_metadata(0, path); item->set_text(1, version); - item->set_metadata(1, script); + item->set_metadata(1, scr); item->set_text(2, author); item->set_metadata(2, description); item->set_cell_mode(3, TreeItem::CELL_MODE_CHECK); diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h index 9c619066f2..829135b544 100644 --- a/editor/editor_plugin_settings.h +++ b/editor/editor_plugin_settings.h @@ -31,7 +31,6 @@ #ifndef EDITOR_PLUGIN_SETTINGS_H #define EDITOR_PLUGIN_SETTINGS_H -#include "core/object/undo_redo.h" #include "editor/editor_data.h" #include "editor/plugin_config_dialog.h" diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 3b99962435..fb3bf46c05 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -31,15 +31,23 @@ #include "editor_properties.h" #include "core/config/project_settings.h" +#include "core/core_string_names.h" +#include "editor/create_dialog.h" #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_properties_array_dict.h" -#include "editor/editor_resource_preview.h" +#include "editor/editor_resource_picker.h" #include "editor/editor_scale.h" -#include "editor/filesystem_dock.h" +#include "editor/editor_settings.h" +#include "editor/inspector_dock.h" +#include "editor/plugins/script_editor_plugin.h" +#include "editor/project_settings_editor.h" +#include "editor/property_selector.h" +#include "editor/scene_tree_editor.h" #include "scene/2d/gpu_particles_2d.h" #include "scene/3d/fog_volume.h" #include "scene/3d/gpu_particles_3d.h" +#include "scene/gui/color_picker.h" #include "scene/main/window.h" #include "scene/resources/font.h" #include "scene/resources/mesh.h" @@ -51,9 +59,9 @@ void EditorPropertyNil::update_property() { } EditorPropertyNil::EditorPropertyNil() { - Label *label = memnew(Label); - label->set_text("<null>"); - add_child(label); + Label *prop_label = memnew(Label); + prop_label->set_text("<null>"); + add_child(prop_label); } ///////////////////// TEXT ///////////////////////// @@ -89,7 +97,9 @@ void EditorPropertyText::update_property() { String s = get_edited_object()->get(get_edited_property()); updating = true; if (text->get_text() != s) { + int caret = text->get_caret_column(); text->set_text(s); + text->set_caret_column(caret); } text->set_editable(!is_read_only()); updating = false; @@ -759,8 +769,13 @@ void EditorPropertyEnum::_option_selected(int p_which) { } void EditorPropertyEnum::update_property() { - int64_t which = get_edited_object()->get(get_edited_property()); + Variant current = get_edited_object()->get(get_edited_property()); + if (current.get_type() == Variant::NIL) { + options->select(-1); + return; + } + int64_t which = current; for (int i = 0; i < options->get_item_count(); i++) { if (which == (int64_t)options->get_item_metadata(i)) { options->select(i); @@ -1037,7 +1052,6 @@ void EditorPropertyLayersGrid::_notification(int p_what) { const int vofs = (grid_size.height - h) / 2; int layer_index = 0; - int block_index = 0; Point2 arrow_pos; @@ -1104,8 +1118,6 @@ void EditorPropertyLayersGrid::_notification(int p_what) { break; } } - - ++block_index; } if ((expansion_rows != prev_expansion_rows) && expanded) { @@ -1164,9 +1176,9 @@ void EditorPropertyLayers::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - button->set_normal_texture(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); - button->set_pressed_texture(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); - button->set_disabled_texture(get_theme_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons"))); + button->set_texture_normal(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); + button->set_texture_pressed(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); + button->set_texture_disabled(get_theme_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons"))); } break; } } @@ -1234,7 +1246,7 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) { String name; if (ProjectSettings::get_singleton()->has_setting(basename + vformat("/layer_%d", i + 1))) { - name = ProjectSettings::get_singleton()->get(basename + vformat("/layer_%d", i + 1)); + name = GLOBAL_GET(basename + vformat("/layer_%d", i + 1)); } if (name.is_empty()) { @@ -1252,26 +1264,41 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) { } void EditorPropertyLayers::set_layer_name(int p_index, const String &p_name) { - if (ProjectSettings::get_singleton()->has_setting(basename + vformat("/layer_%d", p_index + 1))) { - ProjectSettings::get_singleton()->set(basename + vformat("/layer_%d", p_index + 1), p_name); + const String property_name = basename + vformat("/layer_%d", p_index + 1); + if (ProjectSettings::get_singleton()->has_setting(property_name)) { + ProjectSettings::get_singleton()->set(property_name, p_name); ProjectSettings::get_singleton()->save(); } } +String EditorPropertyLayers::get_layer_name(int p_index) const { + const String property_name = basename + vformat("/layer_%d", p_index + 1); + if (ProjectSettings::get_singleton()->has_setting(property_name)) { + return GLOBAL_GET(property_name); + } + return String(); +} + void EditorPropertyLayers::_button_pressed() { int layer_count = grid->layer_count; - int layer_group_size = grid->layer_group_size; - layers->clear(); for (int i = 0; i < layer_count; i++) { - if ((i != 0) && ((i % layer_group_size) == 0)) { - layers->add_separator(); + const String name = get_layer_name(i); + if (name.is_empty()) { + continue; } - layers->add_check_item(grid->names[i], i); + layers->add_check_item(name, i); int idx = layers->get_item_index(i); layers->set_item_checked(idx, grid->value & (1 << i)); } + if (layers->get_item_count() == 0) { + layers->add_item(TTR("No Named Layers")); + layers->set_item_disabled(0, true); + } + layers->add_separator(); + layers->add_icon_item(get_theme_icon("Edit", "EditorIcons"), TTR("Edit Layer Names"), grid->layer_count); + Rect2 gp = button->get_screen_rect(); layers->reset_size(); Vector2 popup_pos = gp.position - Vector2(layers->get_contents_minimum_size().x, 0); @@ -1280,14 +1307,19 @@ void EditorPropertyLayers::_button_pressed() { } void EditorPropertyLayers::_menu_pressed(int p_menu) { - if (grid->value & (1 << p_menu)) { - grid->value &= ~(1 << p_menu); + if (p_menu == grid->layer_count) { + ProjectSettingsEditor::get_singleton()->popup_project_settings(); + ProjectSettingsEditor::get_singleton()->set_general_page(basename); } else { - grid->value |= (1 << p_menu); + if (grid->value & (1 << p_menu)) { + grid->value &= ~(1 << p_menu); + } else { + grid->value |= (1 << p_menu); + } + grid->queue_redraw(); + layers->set_item_checked(layers->get_item_index(p_menu), grid->value & (1 << p_menu)); + _grid_changed(grid->value); } - grid->queue_redraw(); - layers->set_item_checked(layers->get_item_index(p_menu), grid->value & (1 << p_menu)); - _grid_changed(grid->value); } void EditorPropertyLayers::_refresh_names() { @@ -1489,12 +1521,12 @@ void EditorPropertyFloat::update_property() { void EditorPropertyFloat::_bind_methods() { } -void EditorPropertyFloat::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_exp_range, bool p_greater, bool p_lesser, const String &p_suffix, bool p_angle_in_radians) { +void EditorPropertyFloat::setup(double p_min, double p_max, double p_step, bool p_hide_slider, bool p_exp_range, bool p_greater, bool p_lesser, const String &p_suffix, bool p_angle_in_radians) { angle_in_radians = p_angle_in_radians; spin->set_min(p_min); spin->set_max(p_max); spin->set_step(p_step); - spin->set_hide_slider(p_no_slider); + spin->set_hide_slider(p_hide_slider); spin->set_exp_ratio(p_exp_range); spin->set_allow_greater(p_greater); spin->set_allow_lesser(p_lesser); @@ -1786,8 +1818,8 @@ void EditorPropertyVector2::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); - linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + linked->set_texture_normal(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_texture_pressed(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); const Color *colors = _get_property_colors(); for (int i = 0; i < 2; i++) { @@ -1797,12 +1829,12 @@ void EditorPropertyVector2::_notification(int p_what) { } } -void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link, const String &p_suffix) { +void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, bool p_hide_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 2; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); @@ -1907,12 +1939,12 @@ void EditorPropertyRect2::_notification(int p_what) { void EditorPropertyRect2::_bind_methods() { } -void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 4; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); @@ -2064,8 +2096,8 @@ void EditorPropertyVector3::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); - linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + linked->set_texture_normal(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_texture_pressed(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); const Color *colors = _get_property_colors(); for (int i = 0; i < 3; i++) { @@ -2078,13 +2110,13 @@ void EditorPropertyVector3::_notification(int p_what) { void EditorPropertyVector3::_bind_methods() { } -void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link, const String &p_suffix, bool p_angle_in_radians) { +void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, bool p_hide_slider, bool p_link, const String &p_suffix, bool p_angle_in_radians) { angle_in_radians = p_angle_in_radians; for (int i = 0; i < 3; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); @@ -2199,8 +2231,8 @@ void EditorPropertyVector2i::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); - linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + linked->set_texture_normal(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_texture_pressed(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); const Color *colors = _get_property_colors(); for (int i = 0; i < 2; i++) { @@ -2210,12 +2242,12 @@ void EditorPropertyVector2i::_notification(int p_what) { } } -void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider, bool p_link, const String &p_suffix) { +void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_hide_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 2; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(1); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); @@ -2320,12 +2352,12 @@ void EditorPropertyRect2i::_notification(int p_what) { void EditorPropertyRect2i::_bind_methods() { } -void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix) { +void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 4; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(1); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); @@ -2450,8 +2482,8 @@ void EditorPropertyVector3i::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); - linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + linked->set_texture_normal(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_texture_pressed(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); const Color *colors = _get_property_colors(); for (int i = 0; i < 3; i++) { @@ -2464,12 +2496,12 @@ void EditorPropertyVector3i::_notification(int p_what) { void EditorPropertyVector3i::_bind_methods() { } -void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider, bool p_link, const String &p_suffix) { +void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_hide_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 3; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(1); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); @@ -2573,12 +2605,12 @@ void EditorPropertyPlane::_notification(int p_what) { void EditorPropertyPlane::_bind_methods() { } -void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 4; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); } @@ -2660,7 +2692,7 @@ void EditorPropertyQuaternion::_custom_value_changed(double val) { v.y = Math::deg_to_rad(edit_euler.y); v.z = Math::deg_to_rad(edit_euler.z); - Quaternion temp_q = Quaternion(v); + Quaternion temp_q = Quaternion::from_euler(v); spin[0]->set_value(temp_q.x); spin[1]->set_value(temp_q.y); spin[2]->set_value(temp_q.z); @@ -2697,7 +2729,7 @@ void EditorPropertyQuaternion::update_property() { spin[2]->set_value(val.z); spin[3]->set_value(val.w); if (!is_grabbing_euler()) { - Vector3 v = val.normalized().get_euler_yxz(); + Vector3 v = val.normalized().get_euler(); edit_euler.x = Math::rad_to_deg(v.x); edit_euler.y = Math::rad_to_deg(v.y); edit_euler.z = Math::rad_to_deg(v.z); @@ -2734,12 +2766,12 @@ void EditorPropertyQuaternion::_notification(int p_what) { void EditorPropertyQuaternion::_bind_methods() { } -void EditorPropertyQuaternion::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix, bool p_hide_editor) { +void EditorPropertyQuaternion::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix, bool p_hide_editor) { for (int i = 0; i < 4; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); // Quaternion is inherently unitless, however someone may want to use it as @@ -2882,16 +2914,14 @@ void EditorPropertyVector4::_notification(int p_what) { void EditorPropertyVector4::_bind_methods() { } -void EditorPropertyVector4::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyVector4::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 4; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); - // Vector4 is inherently unitless, however someone may want to use it as - // a generic way to store 4 values, so we'll still respect the suffix. spin[i]->set_suffix(p_suffix); } } @@ -2974,11 +3004,11 @@ void EditorPropertyVector4i::_notification(int p_what) { void EditorPropertyVector4i::_bind_methods() { } -void EditorPropertyVector4i::setup(double p_min, double p_max, bool p_no_slider, const String &p_suffix) { +void EditorPropertyVector4i::setup(double p_min, double p_max, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 4; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); @@ -3069,12 +3099,12 @@ void EditorPropertyAABB::_notification(int p_what) { void EditorPropertyAABB::_bind_methods() { } -void EditorPropertyAABB::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyAABB::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 6; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); @@ -3157,12 +3187,12 @@ void EditorPropertyTransform2D::_notification(int p_what) { void EditorPropertyTransform2D::_bind_methods() { } -void EditorPropertyTransform2D::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyTransform2D::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 6; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); if (i % 3 == 2) { @@ -3249,12 +3279,12 @@ void EditorPropertyBasis::_notification(int p_what) { void EditorPropertyBasis::_bind_methods() { } -void EditorPropertyBasis::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyBasis::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 9; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); // Basis is inherently unitless, however someone may want to use it as @@ -3347,12 +3377,12 @@ void EditorPropertyTransform3D::_notification(int p_what) { void EditorPropertyTransform3D::_bind_methods() { } -void EditorPropertyTransform3D::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyTransform3D::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 12; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); if (i % 4 == 3) { @@ -3393,22 +3423,22 @@ void EditorPropertyProjection::_value_changed(double val, const String &p_name) } Projection p; - p.matrix[0][0] = spin[0]->get_value(); - p.matrix[0][1] = spin[1]->get_value(); - p.matrix[0][2] = spin[2]->get_value(); - p.matrix[0][3] = spin[3]->get_value(); - p.matrix[1][0] = spin[4]->get_value(); - p.matrix[1][1] = spin[5]->get_value(); - p.matrix[1][2] = spin[6]->get_value(); - p.matrix[1][3] = spin[7]->get_value(); - p.matrix[2][0] = spin[8]->get_value(); - p.matrix[2][1] = spin[9]->get_value(); - p.matrix[2][2] = spin[10]->get_value(); - p.matrix[2][3] = spin[11]->get_value(); - p.matrix[3][0] = spin[12]->get_value(); - p.matrix[3][1] = spin[13]->get_value(); - p.matrix[3][2] = spin[14]->get_value(); - p.matrix[3][3] = spin[15]->get_value(); + p.columns[0][0] = spin[0]->get_value(); + p.columns[0][1] = spin[1]->get_value(); + p.columns[0][2] = spin[2]->get_value(); + p.columns[0][3] = spin[3]->get_value(); + p.columns[1][0] = spin[4]->get_value(); + p.columns[1][1] = spin[5]->get_value(); + p.columns[1][2] = spin[6]->get_value(); + p.columns[1][3] = spin[7]->get_value(); + p.columns[2][0] = spin[8]->get_value(); + p.columns[2][1] = spin[9]->get_value(); + p.columns[2][2] = spin[10]->get_value(); + p.columns[2][3] = spin[11]->get_value(); + p.columns[3][0] = spin[12]->get_value(); + p.columns[3][1] = spin[13]->get_value(); + p.columns[3][2] = spin[14]->get_value(); + p.columns[3][3] = spin[15]->get_value(); emit_changed(get_edited_property(), p, p_name); } @@ -3419,22 +3449,22 @@ void EditorPropertyProjection::update_property() { void EditorPropertyProjection::update_using_transform(Projection p_transform) { setting = true; - spin[0]->set_value(p_transform.matrix[0][0]); - spin[1]->set_value(p_transform.matrix[0][1]); - spin[2]->set_value(p_transform.matrix[0][2]); - spin[3]->set_value(p_transform.matrix[0][3]); - spin[4]->set_value(p_transform.matrix[1][0]); - spin[5]->set_value(p_transform.matrix[1][1]); - spin[6]->set_value(p_transform.matrix[1][2]); - spin[7]->set_value(p_transform.matrix[1][3]); - spin[8]->set_value(p_transform.matrix[2][0]); - spin[9]->set_value(p_transform.matrix[2][1]); - spin[10]->set_value(p_transform.matrix[2][2]); - spin[11]->set_value(p_transform.matrix[2][3]); - spin[12]->set_value(p_transform.matrix[3][0]); - spin[13]->set_value(p_transform.matrix[3][1]); - spin[14]->set_value(p_transform.matrix[3][2]); - spin[15]->set_value(p_transform.matrix[3][3]); + spin[0]->set_value(p_transform.columns[0][0]); + spin[1]->set_value(p_transform.columns[0][1]); + spin[2]->set_value(p_transform.columns[0][2]); + spin[3]->set_value(p_transform.columns[0][3]); + spin[4]->set_value(p_transform.columns[1][0]); + spin[5]->set_value(p_transform.columns[1][1]); + spin[6]->set_value(p_transform.columns[1][2]); + spin[7]->set_value(p_transform.columns[1][3]); + spin[8]->set_value(p_transform.columns[2][0]); + spin[9]->set_value(p_transform.columns[2][1]); + spin[10]->set_value(p_transform.columns[2][2]); + spin[11]->set_value(p_transform.columns[2][3]); + spin[12]->set_value(p_transform.columns[3][0]); + spin[13]->set_value(p_transform.columns[3][1]); + spin[14]->set_value(p_transform.columns[3][2]); + spin[15]->set_value(p_transform.columns[3][3]); setting = false; } @@ -3453,12 +3483,12 @@ void EditorPropertyProjection::_notification(int p_what) { void EditorPropertyProjection::_bind_methods() { } -void EditorPropertyProjection::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyProjection::setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix) { for (int i = 0; i < 16; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); spin[i]->set_step(p_step); - spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_hide_slider(p_hide_slider); spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); if (i % 4 == 3) { @@ -3646,8 +3676,8 @@ bool EditorPropertyNodePath::can_drop_data_fw(const Point2 &p_point, const Varia void EditorPropertyNodePath::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { ERR_FAIL_COND(!is_drop_valid(p_data)); - Dictionary data = p_data; - Array nodes = data["nodes"]; + Dictionary data_dict = p_data; + Array nodes = data_dict["nodes"]; Node *node = get_tree()->get_edited_scene_root()->get_node(nodes[0]); if (node) { @@ -3673,7 +3703,8 @@ bool EditorPropertyNodePath::is_drop_valid(const Dictionary &p_drag_data) const } for (const StringName &E : valid_types) { - if (dropped_node->is_class(E)) { + if (dropped_node->is_class(E) || + EditorNode::get_singleton()->is_object_of_custom_type(dropped_node, E)) { return true; } } @@ -3820,8 +3851,11 @@ void EditorPropertyResource::_resource_selected(const Ref<Resource> &p_resource, void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource) { // Make visual script the correct type. Ref<Script> s = p_resource; + + // The bool is_script applies only to an object's main script. + // Changing the value of Script-type exported variables of the main script should not trigger saving/reloading properties. bool is_script = false; - if (get_edited_object() && s.is_valid()) { + if (get_edited_object() && s.is_valid() && get_edited_property() == CoreStringNames::get_singleton()->_script) { is_script = true; InspectorDock::get_singleton()->store_script_properties(get_edited_object()); s->call("set_instance_base_type", get_edited_object()->get_class()); @@ -3975,19 +4009,19 @@ void EditorPropertyResource::_update_preferred_shader() { if (parent_property) { EditorShaderPicker *shader_picker = Object::cast_to<EditorShaderPicker>(resource_picker); - Object *object = parent_property->get_edited_object(); - const StringName &property = parent_property->get_edited_property(); + Object *ed_object = parent_property->get_edited_object(); + const StringName &ed_property = parent_property->get_edited_property(); // Set preferred shader based on edited parent type. - if ((Object::cast_to<GPUParticles2D>(object) || Object::cast_to<GPUParticles3D>(object)) && property == SNAME("process_material")) { + if ((Object::cast_to<GPUParticles2D>(ed_object) || Object::cast_to<GPUParticles3D>(ed_object)) && ed_property == SNAME("process_material")) { shader_picker->set_preferred_mode(Shader::MODE_PARTICLES); - } else if (Object::cast_to<FogVolume>(object)) { + } else if (Object::cast_to<FogVolume>(ed_object)) { shader_picker->set_preferred_mode(Shader::MODE_FOG); - } else if (Object::cast_to<CanvasItem>(object)) { + } else if (Object::cast_to<CanvasItem>(ed_object)) { shader_picker->set_preferred_mode(Shader::MODE_CANVAS_ITEM); - } else if (Object::cast_to<Node3D>(object) || Object::cast_to<Mesh>(object)) { + } else if (Object::cast_to<Node3D>(ed_object) || Object::cast_to<Mesh>(ed_object)) { shader_picker->set_preferred_mode(Shader::MODE_SPATIAL); - } else if (Object::cast_to<Sky>(object)) { + } else if (Object::cast_to<Sky>(ed_object)) { shader_picker->set_preferred_mode(Shader::MODE_SKY); } } @@ -4070,7 +4104,6 @@ void EditorPropertyResource::update_property() { sub_inspector->set_keying(is_keying()); sub_inspector->set_read_only(is_read_only()); sub_inspector->set_use_folding(is_using_folding()); - sub_inspector->set_undo_redo(EditorNode::get_undo_redo()); sub_inspector_vbox = memnew(VBoxContainer); add_child(sub_inspector_vbox); @@ -4218,7 +4251,7 @@ static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const Stri hint.or_greater = true; } else if (slice == "or_less") { hint.or_less = true; - } else if (slice == "no_slider") { + } else if (slice == "hide_slider") { hint.hide_slider = true; } else if (slice == "exp") { hint.exp_range = true; diff --git a/editor/editor_properties.h b/editor/editor_properties.h index d6c9510634..f38e33d9e3 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -31,15 +31,19 @@ #ifndef EDITOR_PROPERTIES_H #define EDITOR_PROPERTIES_H -#include "editor/create_dialog.h" #include "editor/editor_inspector.h" -#include "editor/editor_locale_dialog.h" -#include "editor/editor_resource_picker.h" -#include "editor/editor_spin_slider.h" -#include "editor/property_selector.h" -#include "editor/scene_tree_editor.h" -#include "scene/gui/color_picker.h" -#include "scene/gui/line_edit.h" + +class CheckBox; +class ColorPickerButton; +class CreateDialog; +class EditorFileDialog; +class EditorLocaleDialog; +class EditorResourcePicker; +class EditorSpinSlider; +class PropertySelector; +class SceneTreeDialog; +class TextEdit; +class TextureButton; class EditorPropertyNil : public EditorProperty { GDCLASS(EditorPropertyNil, EditorProperty); @@ -357,6 +361,7 @@ protected: public: void setup(LayerType p_layer_type); void set_layer_name(int p_index, const String &p_name); + String get_layer_name(int p_index) const; virtual void update_property() override; EditorPropertyLayers(); }; @@ -433,7 +438,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_exp_range, bool p_greater, bool p_lesser, const String &p_suffix = String(), bool p_angle_in_radians = false); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, bool p_exp_range, bool p_greater, bool p_lesser, const String &p_suffix = String(), bool p_angle_in_radians = false); EditorPropertyFloat(); }; @@ -496,7 +501,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector2(bool p_force_wide = false); }; @@ -513,7 +518,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyRect2(bool p_force_wide = false); }; @@ -541,7 +546,7 @@ public: virtual void update_property() override; virtual void update_using_vector(Vector3 p_vector); virtual Vector3 get_vector(); - void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link = false, const String &p_suffix = String(), bool p_angle_in_radians = false); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, bool p_link = false, const String &p_suffix = String(), bool p_angle_in_radians = false); EditorPropertyVector3(bool p_force_wide = false); }; @@ -561,7 +566,7 @@ protected: public: virtual void update_property() override; - void setup(int p_min, int p_max, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); + void setup(int p_min, int p_max, bool p_hide_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector2i(bool p_force_wide = false); }; @@ -578,7 +583,7 @@ protected: public: virtual void update_property() override; - void setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix = String()); + void setup(int p_min, int p_max, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyRect2i(bool p_force_wide = false); }; @@ -603,7 +608,7 @@ protected: public: virtual void update_property() override; - void setup(int p_min, int p_max, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); + void setup(int p_min, int p_max, bool p_hide_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector3i(bool p_force_wide = false); }; @@ -620,7 +625,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyPlane(bool p_force_wide = false); }; @@ -638,7 +643,7 @@ class EditorPropertyQuaternion : public EditorProperty { EditorSpinSlider *euler[3]; Button *edit_button = nullptr; - Vector3 edit_euler = Vector3(); + Vector3 edit_euler; void _value_changed(double p_val, const String &p_name); void _edit_custom_value(); @@ -654,7 +659,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String(), bool p_hide_editor = false); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String(), bool p_hide_editor = false); EditorPropertyQuaternion(); }; @@ -671,7 +676,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyVector4(); }; @@ -688,7 +693,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyVector4i(); }; @@ -705,7 +710,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyAABB(); }; @@ -722,7 +727,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyTransform2D(bool p_include_origin = true); }; @@ -739,7 +744,7 @@ protected: public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyBasis(); }; @@ -757,7 +762,7 @@ protected: public: virtual void update_property() override; virtual void update_using_transform(Transform3D p_transform); - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyTransform3D(); }; @@ -775,7 +780,7 @@ protected: public: virtual void update_property() override; virtual void update_using_transform(Projection p_transform); - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_hide_slider, const String &p_suffix = String()); EditorPropertyProjection(); }; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 728a3b0f80..edda6c5d7b 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -34,6 +34,7 @@ #include "core/io/marshalls.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/inspector_dock.h" bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) { @@ -260,9 +261,9 @@ void EditorPropertyArray::update_property() { HBoxContainer *hbox = memnew(HBoxContainer); vbox->add_child(hbox); - Label *label = memnew(Label(TTR("Size:"))); - label->set_h_size_flags(SIZE_EXPAND_FILL); - hbox->add_child(label); + Label *size_label = memnew(Label(TTR("Size:"))); + size_label->set_h_size_flags(SIZE_EXPAND_FILL); + hbox->add_child(size_label); size_slider = memnew(EditorSpinSlider); size_slider->set_step(1); @@ -293,7 +294,7 @@ void EditorPropertyArray::update_property() { continue; // Don't remove the property that the user is moving. } - child->queue_delete(); // Button still needed after pressed is called. + child->queue_free(); // Button still needed after pressed is called. property_vbox->remove_child(child); } } @@ -367,17 +368,17 @@ void EditorPropertyArray::update_property() { bool is_untyped_array = array.get_type() == Variant::ARRAY && subtype == Variant::NIL; if (is_untyped_array) { - Button *edit = memnew(Button); - edit->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); - hbox->add_child(edit); - edit->set_disabled(is_read_only()); - edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_change_type).bind(edit, i + offset)); + Button *edit_btn = memnew(Button); + edit_btn->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); + hbox->add_child(edit_btn); + edit_btn->set_disabled(is_read_only()); + edit_btn->connect("pressed", callable_mp(this, &EditorPropertyArray::_change_type).bind(edit_btn, i + offset)); } else { - Button *remove = memnew(Button); - remove->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - remove->set_disabled(is_read_only()); - remove->connect("pressed", callable_mp(this, &EditorPropertyArray::_remove_pressed).bind(i + offset)); - hbox->add_child(remove); + Button *remove_btn = memnew(Button); + remove_btn->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); + remove_btn->set_disabled(is_read_only()); + remove_btn->connect("pressed", callable_mp(this, &EditorPropertyArray::_remove_pressed).bind(i + offset)); + hbox->add_child(remove_btn); } prop->update_property(); @@ -466,7 +467,7 @@ void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_d Variant array = object->get_array(); - // Handle the case where array is not initialised yet. + // Handle the case where array is not initialized yet. if (!array.is_array()) { Callable::CallError ce; Variant::construct(array_type, array, nullptr, 0, ce); @@ -510,7 +511,7 @@ void EditorPropertyArray::_notification(int p_what) { change_type->add_separator(); change_type->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Remove Item"), Variant::VARIANT_MAX); - if (Object::cast_to<Button>(button_add_item)) { + if (button_add_item) { button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } } break; @@ -692,6 +693,8 @@ void EditorPropertyArray::_reorder_button_up() { reorder_mouse_y_delta = 0.0f; Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); + + ERR_FAIL_NULL(reorder_selected_button); reorder_selected_button->warp_mouse(reorder_selected_button->get_size() / 2.0f); reorder_selected_element_hbox = nullptr; @@ -861,7 +864,7 @@ void EditorPropertyDictionary::update_property() { } else { // Queue children for deletion, deleting immediately might cause errors. for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) { - property_vbox->get_child(i)->queue_delete(); + property_vbox->get_child(i)->queue_free(); } } @@ -1155,11 +1158,11 @@ void EditorPropertyDictionary::update_property() { } hbox->add_child(prop); prop->set_h_size_flags(SIZE_EXPAND_FILL); - Button *edit = memnew(Button); - edit->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); - edit->set_disabled(is_read_only()); - hbox->add_child(edit); - edit->connect("pressed", callable_mp(this, &EditorPropertyDictionary::_change_type).bind(edit, change_index)); + Button *edit_btn = memnew(Button); + edit_btn->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); + edit_btn->set_disabled(is_read_only()); + hbox->add_child(edit_btn); + edit_btn->connect("pressed", callable_mp(this, &EditorPropertyDictionary::_change_type).bind(edit_btn, change_index)); prop->update_property(); @@ -1205,7 +1208,7 @@ void EditorPropertyDictionary::_notification(int p_what) { change_type->add_separator(); change_type->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Remove Item"), Variant::VARIANT_MAX); - if (Object::cast_to<Button>(button_add_item)) { + if (button_add_item) { button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } } break; @@ -1349,7 +1352,7 @@ void EditorPropertyLocalizableString::update_property() { } else { // Queue children for deletion, deleting immediately might cause errors. for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) { - property_vbox->get_child(i)->queue_delete(); + property_vbox->get_child(i)->queue_free(); } } @@ -1396,10 +1399,10 @@ void EditorPropertyLocalizableString::update_property() { property_vbox->add_child(hbox); hbox->add_child(prop); prop->set_h_size_flags(SIZE_EXPAND_FILL); - Button *edit = memnew(Button); - edit->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - hbox->add_child(edit); - edit->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_remove_item).bind(edit, remove_index)); + Button *edit_btn = memnew(Button); + edit_btn->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); + hbox->add_child(edit_btn); + edit_btn->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_remove_item).bind(edit_btn, remove_index)); prop->update_property(); } @@ -1431,7 +1434,7 @@ void EditorPropertyLocalizableString::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { - if (Object::cast_to<Button>(button_add_item)) { + if (button_add_item) { button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } } break; diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp index a2dfa4f80e..9587e65cad 100644 --- a/editor/editor_property_name_processor.cpp +++ b/editor/editor_property_name_processor.cpp @@ -64,6 +64,10 @@ String EditorPropertyNameProcessor::_capitalize_name(const String &p_name) const Vector<String> parts = p_name.split("_", false); for (int i = 0; i < parts.size(); i++) { + // Articles/conjunctions/prepositions which should only be capitalized when not at beginning and end. + if (i > 0 && i + 1 < parts.size() && stop_words.find(parts[i]) != -1) { + continue; + } HashMap<String, String>::ConstIterator remap = capitalize_string_remaps.find(parts[i]); if (remap) { parts.write[i] = remap->value; @@ -143,6 +147,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["gdscript"] = "GDScript"; capitalize_string_remaps["ggx"] = "GGX"; capitalize_string_remaps["gi"] = "GI"; + capitalize_string_remaps["gl"] = "GL"; capitalize_string_remaps["glb"] = "GLB"; capitalize_string_remaps["gles2"] = "GLES2"; capitalize_string_remaps["gles3"] = "GLES3"; @@ -157,6 +162,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["html"] = "HTML"; capitalize_string_remaps["http"] = "HTTP"; capitalize_string_remaps["id"] = "ID"; + capitalize_string_remaps["ids"] = "IDs"; capitalize_string_remaps["igd"] = "IGD"; capitalize_string_remaps["ik"] = "IK"; capitalize_string_remaps["image@2x"] = "Image @2x"; @@ -223,6 +229,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["svg"] = "SVG"; capitalize_string_remaps["taa"] = "TAA"; capitalize_string_remaps["tcp"] = "TCP"; + capitalize_string_remaps["tls"] = "TLS"; capitalize_string_remaps["ui"] = "UI"; capitalize_string_remaps["url"] = "URL"; capitalize_string_remaps["urls"] = "URLs"; @@ -237,6 +244,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["vector2"] = "Vector2"; capitalize_string_remaps["vpn"] = "VPN"; capitalize_string_remaps["vram"] = "VRAM"; + capitalize_string_remaps["vrs"] = "VRS"; capitalize_string_remaps["vsync"] = "V-Sync"; capitalize_string_remaps["wap"] = "WAP"; capitalize_string_remaps["webp"] = "WebP"; @@ -246,9 +254,33 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["wifi"] = "Wi-Fi"; capitalize_string_remaps["x86"] = "x86"; capitalize_string_remaps["xr"] = "XR"; + capitalize_string_remaps["xray"] = "X-Ray"; capitalize_string_remaps["xy"] = "XY"; capitalize_string_remaps["xz"] = "XZ"; capitalize_string_remaps["yz"] = "YZ"; + + // Articles, conjunctions, prepositions. + // The following initialization is parsed in `editor/translations/extract.py` with a regex. + // The word definition format should be kept synced with the regex. + stop_words = LocalVector<String>({ + "a", + "an", + "and", + "as", + "at", + "by", + "for", + "in", + "not", + "of", + "on", + "or", + "over", + "per", + "the", + "then", + "to", + }); } EditorPropertyNameProcessor::~EditorPropertyNameProcessor() { diff --git a/editor/editor_property_name_processor.h b/editor/editor_property_name_processor.h index 37d905c806..fcabbfd9d3 100644 --- a/editor/editor_property_name_processor.h +++ b/editor/editor_property_name_processor.h @@ -40,6 +40,7 @@ class EditorPropertyNameProcessor : public Node { mutable HashMap<String, String> capitalize_string_cache; HashMap<String, String> capitalize_string_remaps; + LocalVector<String> stop_words; // Exceptions that shouldn't be capitalized. // Capitalizes property path segments. String _capitalize_name(const String &p_name) const; diff --git a/editor/editor_quick_open.cpp b/editor/editor_quick_open.cpp index 539cb7cd8a..bb533b88d6 100644 --- a/editor/editor_quick_open.cpp +++ b/editor/editor_quick_open.cpp @@ -31,12 +31,21 @@ #include "editor_quick_open.h" #include "core/os/keyboard.h" +#include "editor/editor_node.h" +#include "editor/editor_scale.h" -void EditorQuickOpen::popup_dialog(const StringName &p_base, bool p_enable_multi, bool p_dontclear) { +void EditorQuickOpen::popup_dialog(const String &p_base, bool p_enable_multi, bool p_dontclear) { base_type = p_base; allow_multi_select = p_enable_multi; search_options->set_select_mode(allow_multi_select ? Tree::SELECT_MULTI : Tree::SELECT_SINGLE); - popup_centered_clamped(Size2i(600, 440), 0.8f); + + static bool was_showed = false; + if (!was_showed) { + was_showed = true; + popup_centered_clamped(Size2(600, 440) * EDSCALE, 0.8f); + } else { + show(); + } EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->get_filesystem(); _build_search_cache(efsd); @@ -55,19 +64,31 @@ void EditorQuickOpen::_build_search_cache(EditorFileSystemDirectory *p_efsd) { _build_search_cache(p_efsd->get_subdir(i)); } - Vector<String> base_types = String(base_type).split(String(",")); + Vector<String> base_types = base_type.split(","); for (int i = 0; i < p_efsd->get_file_count(); i++) { - String file_type = p_efsd->get_file_type(i); + String file = p_efsd->get_file_path(i); + String engine_type = p_efsd->get_file_type(i); + // TODO: Fix lack of caching for resource's script's global class name (if applicable). + String script_type; + if (_load_resources) { + Ref<Resource> res = ResourceLoader::load(file); + if (res.is_valid()) { + Ref<Script> scr = res->get_script(); + if (scr.is_valid()) { + script_type = scr->get_language()->get_global_class_name(file); + } + } + } + String actual_type = script_type.is_empty() ? engine_type : script_type; // Iterate all possible base types. for (String &parent_type : base_types) { - if (ClassDB::is_parent_class(file_type, parent_type)) { - String file = p_efsd->get_file_path(i); + if (ClassDB::is_parent_class(engine_type, parent_type) || EditorNode::get_editor_data().script_class_is_parent(script_type, parent_type)) { files.push_back(file.substr(6, file.length())); // Store refs to used icons. String ext = file.get_extension(); if (!icons.has(ext)) { - icons.insert(ext, get_theme_icon((has_theme_icon(file_type, SNAME("EditorIcons")) ? file_type : String("Object")), SNAME("EditorIcons"))); + icons.insert(ext, get_theme_icon((has_theme_icon(actual_type, SNAME("EditorIcons")) ? actual_type : "Object"), SNAME("EditorIcons"))); } // Stop testing base types as soon as we got a match. @@ -218,7 +239,7 @@ Vector<String> EditorQuickOpen::get_selected_files() const { return selected_files; } -StringName EditorQuickOpen::get_base_type() const { +String EditorQuickOpen::get_base_type() const { return base_type; } diff --git a/editor/editor_quick_open.h b/editor/editor_quick_open.h index e41a8c7e75..3b7e8136ef 100644 --- a/editor/editor_quick_open.h +++ b/editor/editor_quick_open.h @@ -41,8 +41,9 @@ class EditorQuickOpen : public ConfirmationDialog { LineEdit *search_box = nullptr; Tree *search_options = nullptr; - StringName base_type; + String base_type; bool allow_multi_select = false; + bool _load_resources = false; // Prohibitively slow for now. Vector<String> files; OAHashMap<String, Ref<Texture2D>> icons; @@ -76,12 +77,12 @@ protected: static void _bind_methods(); public: - StringName get_base_type() const; + String get_base_type() const; String get_selected() const; Vector<String> get_selected_files() const; - void popup_dialog(const StringName &p_base, bool p_enable_multi = false, bool p_dontclear = false); + void popup_dialog(const String &p_base, bool p_enable_multi = false, bool p_dontclear = false); EditorQuickOpen(); }; diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 84cb085551..acc8b3b6a2 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -53,6 +53,7 @@ void EditorResourcePicker::_update_resource() { if (edited_resource.is_valid() && edited_resource->get_path().is_resource_file()) { resource_path = edited_resource->get_path() + "\n"; } + String class_name = _get_resource_type(edited_resource); if (preview_rect) { preview_rect->set_texture(Ref<Texture2D>()); @@ -64,16 +65,20 @@ void EditorResourcePicker::_update_resource() { assign_button->set_text(TTR("<empty>")); assign_button->set_tooltip_text(""); } else { - assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object")); + assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), SNAME("Object"))); if (!edited_resource->get_name().is_empty()) { assign_button->set_text(edited_resource->get_name()); } else if (edited_resource->get_path().is_resource_file()) { assign_button->set_text(edited_resource->get_path().get_file()); } else { - assign_button->set_text(edited_resource->get_class()); + assign_button->set_text(class_name); } - assign_button->set_tooltip_text(resource_path + TTR("Type:") + " " + edited_resource->get_class()); + + if (edited_resource->get_path().is_resource_file()) { + resource_path = edited_resource->get_path() + "\n"; + } + assign_button->set_tooltip_text(resource_path + TTR("Type:") + " " + class_name); // Preview will override the above, so called at the end. EditorResourcePreview::get_singleton()->queue_edited_resource_preview(edited_resource, this, "_update_resource_preview", edited_resource->get_instance_id()); @@ -91,9 +96,9 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const } if (preview_rect) { - Ref<Script> script = edited_resource; - if (script.is_valid()) { - assign_button->set_text(script->get_path().get_file()); + Ref<Script> scr = edited_resource; + if (scr.is_valid()) { + assign_button->set_text(scr->get_path().get_file()); return; } @@ -106,7 +111,7 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const assign_button->set_custom_minimum_size(assign_button_min_size); } else { preview_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + int thumbnail_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); thumbnail_size *= EDSCALE; assign_button->set_custom_minimum_size(Size2(MAX(1, assign_button_min_size.x), MAX(thumbnail_size, assign_button_min_size.y))); } @@ -134,16 +139,29 @@ void EditorResourcePicker::_file_selected(const String &p_path) { if (!base_type.is_empty()) { bool any_type_matches = false; + String res_type = loaded_resource->get_class(); + Ref<Script> res_script = loaded_resource->get_script(); + bool is_global_class = false; + if (res_script.is_valid()) { + String script_type = EditorNode::get_editor_data().script_class_get_name(res_script->get_path()); + if (!script_type.is_empty()) { + is_global_class = true; + res_type = script_type; + } + } + for (int i = 0; i < base_type.get_slice_count(","); i++) { String base = base_type.get_slice(",", i); - if (loaded_resource->is_class(base)) { - any_type_matches = true; + + any_type_matches = is_global_class ? EditorNode::get_editor_data().script_class_is_parent(res_type, base) : loaded_resource->is_class(base); + + if (any_type_matches) { break; } } if (!any_type_matches) { - EditorNode::get_singleton()->show_warning(vformat(TTR("The selected resource (%s) does not match any type expected for this property (%s)."), loaded_resource->get_class(), base_type)); + EditorNode::get_singleton()->show_warning(vformat(TTR("The selected resource (%s) does not match any type expected for this property (%s)."), res_type, base_type)); return; } } @@ -227,16 +245,19 @@ void EditorResourcePicker::_update_menu_items() { // Add options to copy/paste resource. Ref<Resource> cb = EditorSettings::get_singleton()->get_resource_clipboard(); bool paste_valid = false; - if (is_editable()) { - if (cb.is_valid()) { - if (base_type.is_empty()) { - paste_valid = true; - } else { - for (int i = 0; i < base_type.get_slice_count(","); i++) { - if (ClassDB::is_parent_class(cb->get_class(), base_type.get_slice(",", i))) { - paste_valid = true; - break; - } + if (is_editable() && cb.is_valid()) { + if (base_type.is_empty()) { + paste_valid = true; + } else { + String res_type = _get_resource_type(cb); + + for (int i = 0; i < base_type.get_slice_count(","); i++) { + String base = base_type.get_slice(",", i); + + paste_valid = ClassDB::is_parent_class(res_type, base) || EditorNode::get_editor_data().script_class_is_parent(res_type, base); + + if (paste_valid) { + break; } } } @@ -281,6 +302,9 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { for (int i = 0; i < base_type.get_slice_count(","); i++) { String base = base_type.get_slice(",", i); ResourceLoader::get_recognized_extensions_for_type(base, &extensions); + if (ScriptServer::is_global_class(base)) { + ResourceLoader::get_recognized_extensions_for_type(ScriptServer::get_global_class_native_base(base), &extensions); + } } HashSet<String> valid_extensions; @@ -408,19 +432,13 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { Variant obj; if (ScriptServer::is_global_class(intype)) { - obj = ClassDB::instantiate(ScriptServer::get_global_class_native_base(intype)); - if (obj) { - Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype)); - if (script.is_valid()) { - ((Object *)obj)->set_script(script); - } - } + obj = EditorNode::get_editor_data().script_class_instance(intype); } else { obj = ClassDB::instantiate(intype); } if (!obj) { - obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); + obj = EditorNode::get_editor_data().instantiate_custom_type(intype, "Resource"); } Resource *resp = Object::cast_to<Resource>(obj); @@ -494,12 +512,9 @@ void EditorResourcePicker::set_create_options(Object *p_menu_node) { } bool EditorResourcePicker::handle_menu_selected(int p_which) { - bool success; - if (GDVIRTUAL_CALL(_handle_menu_selected, p_which, success)) { - return success; - } - - return false; + bool success = false; + GDVIRTUAL_CALL(_handle_menu_selected, p_which, success); + return success; } void EditorResourcePicker::_button_draw() { @@ -512,23 +527,40 @@ void EditorResourcePicker::_button_draw() { void EditorResourcePicker::_button_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { - // Only attempt to update and show the menu if we have - // a valid resource or the Picker is editable, as - // there will otherwise be nothing to display. - if (edited_resource.is_valid() || is_editable()) { - _update_menu_items(); - - Vector2 pos = get_screen_position() + mb->get_position(); - edit_menu->reset_size(); - edit_menu->set_position(pos); - edit_menu->popup(); - } + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { + // Only attempt to update and show the menu if we have + // a valid resource or the Picker is editable, as + // there will otherwise be nothing to display. + if (edited_resource.is_valid() || is_editable()) { + _update_menu_items(); + + Vector2 pos = get_screen_position() + mb->get_position(); + edit_menu->reset_size(); + edit_menu->set_position(pos); + edit_menu->popup(); } } } +String EditorResourcePicker::_get_resource_type(const Ref<Resource> &p_resource) const { + if (p_resource.is_null()) { + return String(); + } + String res_type = p_resource->get_class(); + + Ref<Script> res_script = p_resource->get_script(); + if (res_script.is_null()) { + return res_type; + } + + // TODO: Replace with EditorFileSystem when PR #60606 is merged to use cached resource type. + String script_type = EditorNode::get_editor_data().script_class_get_name(res_script->get_path()); + if (!script_type.is_empty()) { + res_type = script_type; + } + return res_type; +} + void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSet<String> *p_vector) const { Vector<String> allowed_types = base_type.split(","); int size = allowed_types.size(); @@ -538,27 +570,37 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSet<Strin for (int i = 0; i < size; i++) { String base = allowed_types[i].strip_edges(); - p_vector->insert(base); + if (!ClassDB::is_virtual(base)) { + p_vector->insert(base); + } // If we hit a familiar base type, take all the data from cache. if (allowed_types_cache.has(base)) { List<StringName> allowed_subtypes = allowed_types_cache[base]; for (const StringName &subtype_name : allowed_subtypes) { - p_vector->insert(subtype_name); + if (!ClassDB::is_virtual(subtype_name)) { + p_vector->insert(subtype_name); + } } } else { List<StringName> allowed_subtypes; List<StringName> inheriters; - ClassDB::get_inheriters_from_class(base, &inheriters); + if (!ScriptServer::is_global_class(base)) { + ClassDB::get_inheriters_from_class(base, &inheriters); + } for (const StringName &subtype_name : inheriters) { - p_vector->insert(subtype_name); + if (!ClassDB::is_virtual(subtype_name)) { + p_vector->insert(subtype_name); + } allowed_subtypes.push_back(subtype_name); } for (const StringName &subtype_name : global_classes) { if (EditorNode::get_editor_data().script_class_is_parent(subtype_name, base)) { - p_vector->insert(subtype_name); + if (!ClassDB::is_virtual(subtype_name)) { + p_vector->insert(subtype_name); + } allowed_subtypes.push_back(subtype_name); } } @@ -602,32 +644,29 @@ bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const { } } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { res = drag_data["resource"]; + } else if (drag_data.has("type") && String(drag_data["type"]) == "files") { + Vector<String> files = drag_data["files"]; + + // TODO: Extract the typename of the dropped filepath's resource in a more performant way, without fully loading it. + if (files.size() == 1) { + String file = files[0]; + res = ResourceLoader::load(file); + } } HashSet<String> allowed_types; _get_allowed_types(true, &allowed_types); - if (res.is_valid() && _is_type_valid(res->get_class(), allowed_types)) { - return true; - } + if (res.is_valid()) { + String res_type = _get_resource_type(res); - if (res.is_valid() && res->get_script()) { - StringName custom_class = EditorNode::get_singleton()->get_object_custom_type_name(res->get_script()); - if (_is_type_valid(custom_class, allowed_types)) { + if (_is_type_valid(res_type, allowed_types)) { return true; } - } - - if (drag_data.has("type") && String(drag_data["type"]) == "files") { - Vector<String> files = drag_data["files"]; - - if (files.size() == 1) { - String file = files[0]; - String file_type = EditorFileSystem::get_singleton()->get_file_type(file); - if (!file_type.is_empty() && _is_type_valid(file_type, allowed_types)) { - return true; - } + StringName custom_class = EditorNode::get_singleton()->get_object_custom_type_name(res.ptr()); + if (_is_type_valid(custom_class, allowed_types)) { + return true; } } @@ -685,8 +724,10 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ HashSet<String> allowed_types; _get_allowed_types(false, &allowed_types); + String res_type = _get_resource_type(dropped_resource); + // If the accepted dropped resource is from the extended list, it requires conversion. - if (!_is_type_valid(dropped_resource->get_class(), allowed_types)) { + if (!_is_type_valid(res_type, allowed_types)) { for (const String &E : allowed_types) { String at = E.strip_edges(); @@ -922,6 +963,7 @@ EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) { preview_rect->set_offset(SIDE_TOP, 1); preview_rect->set_offset(SIDE_BOTTOM, -1); preview_rect->set_offset(SIDE_RIGHT, -1); + preview_rect->set_texture_filter(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); assign_button->add_child(preview_rect); } @@ -945,8 +987,8 @@ void EditorScriptPicker::set_create_options(Object *p_menu_node) { menu_node->add_icon_item(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons")), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); if (script_owner) { - Ref<Script> script = script_owner->get_script(); - if (script.is_valid()) { + Ref<Script> scr = script_owner->get_script(); + if (scr.is_valid()) { menu_node->add_icon_item(get_theme_icon(SNAME("ScriptExtend"), SNAME("EditorIcons")), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT); } } @@ -1004,12 +1046,12 @@ void EditorShaderPicker::set_create_options(Object *p_menu_node) { } bool EditorShaderPicker::handle_menu_selected(int p_which) { - Ref<ShaderMaterial> material = Ref<ShaderMaterial>(get_edited_material()); + Ref<ShaderMaterial> ed_material = Ref<ShaderMaterial>(get_edited_material()); switch (p_which) { case OBJ_MENU_NEW_SHADER: { - if (material.is_valid()) { - SceneTreeDock::get_singleton()->open_shader_dialog(material, preferred_mode); + if (ed_material.is_valid()) { + SceneTreeDock::get_singleton()->open_shader_dialog(ed_material, preferred_mode); return true; } } break; diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index 3d6127e656..d1a20f04b7 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -91,6 +91,7 @@ class EditorResourcePicker : public HBoxContainer { void _button_draw(); void _button_input(const Ref<InputEvent> &p_event); + String _get_resource_type(const Ref<Resource> &p_resource) const; void _get_allowed_types(bool p_with_convert, HashSet<String> *p_vector) const; bool _is_drop_valid(const Dictionary &p_drag_data) const; bool _is_type_valid(const String p_type_name, HashSet<String> p_allowed_types) const; diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 706b77c142..083b382521 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -41,7 +41,7 @@ #include "editor/editor_settings.h" bool EditorResourcePreviewGenerator::handles(const String &p_type) const { - bool success; + bool success = false; if (GDVIRTUAL_CALL(_handles, p_type, success)) { return success; } @@ -70,21 +70,15 @@ Ref<Texture2D> EditorResourcePreviewGenerator::generate_from_path(const String & } bool EditorResourcePreviewGenerator::generate_small_preview_automatically() const { - bool success; - if (GDVIRTUAL_CALL(_generate_small_preview_automatically, success)) { - return success; - } - - return false; + bool success = false; + GDVIRTUAL_CALL(_generate_small_preview_automatically, success); + return success; } bool EditorResourcePreviewGenerator::can_generate_small_preview() const { - bool success; - if (GDVIRTUAL_CALL(_can_generate_small_preview, success)) { - return success; - } - - return false; + bool success = false; + GDVIRTUAL_CALL(_can_generate_small_preview, success); + return success; } void EditorResourcePreviewGenerator::_bind_methods() { @@ -148,7 +142,7 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref< return; //could not guess type } - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + int thumbnail_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); thumbnail_size *= EDSCALE; r_texture = Ref<ImageTexture>(); @@ -232,7 +226,7 @@ void EditorResourcePreview::_iterate() { Ref<ImageTexture> texture; Ref<ImageTexture> small_texture; - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + int thumbnail_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); thumbnail_size *= EDSCALE; if (item.resource.is_valid()) { diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index b909129b18..913a0ba104 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -31,6 +31,7 @@ #include "editor_run.h" #include "core/config/project_settings.h" +#include "editor/debugger/editor_debugger_node.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "main/main.h" @@ -57,13 +58,16 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { args.push_back(resource_path.replace(" ", "%20")); } - args.push_back("--remote-debug"); - args.push_back(EditorDebuggerNode::get_singleton()->get_server_uri()); + const String debug_uri = EditorDebuggerNode::get_singleton()->get_server_uri(); + if (debug_uri.size()) { + args.push_back("--remote-debug"); + args.push_back(debug_uri); + } args.push_back("--editor-pid"); args.push_back(itos(OS::get_singleton()->get_process_id())); - bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false); + bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisions", false); bool debug_paths = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_paths", false); bool debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false); if (debug_collisions) { @@ -88,7 +92,7 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { } } - int screen = EditorSettings::get_singleton()->get("run/window_placement/screen"); + int screen = EDITOR_GET("run/window_placement/screen"); if (screen == 0) { // Same as editor screen = DisplayServer::get_singleton()->window_get_current_screen(); @@ -114,21 +118,21 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { screen_rect.position = DisplayServer::get_singleton()->screen_get_position(screen); screen_rect.size = DisplayServer::get_singleton()->screen_get_size(screen); - int window_placement = EditorSettings::get_singleton()->get("run/window_placement/rect"); + int window_placement = EDITOR_GET("run/window_placement/rect"); if (screen_rect != Rect2()) { Size2 window_size; - window_size.x = ProjectSettings::get_singleton()->get("display/window/size/viewport_width"); - window_size.y = ProjectSettings::get_singleton()->get("display/window/size/viewport_height"); + window_size.x = GLOBAL_GET("display/window/size/viewport_width"); + window_size.y = GLOBAL_GET("display/window/size/viewport_height"); Size2 desired_size; - desired_size.x = ProjectSettings::get_singleton()->get("display/window/size/window_width_override"); - desired_size.y = ProjectSettings::get_singleton()->get("display/window/size/window_height_override"); + desired_size.x = GLOBAL_GET("display/window/size/window_width_override"); + desired_size.y = GLOBAL_GET("display/window/size/window_height_override"); if (desired_size.x > 0 && desired_size.y > 0) { window_size = desired_size; } if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_HIDPI)) { - bool hidpi_proj = ProjectSettings::get_singleton()->get("display/window/dpi/allow_hidpi"); + bool hidpi_proj = GLOBAL_GET("display/window/dpi/allow_hidpi"); int display_scale = 1; if (OS::get_singleton()->is_hidpi_allowed()) { @@ -159,7 +163,7 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { args.push_back(itos(pos.x) + "," + itos(pos.y)); } break; case 2: { // custom pos - Vector2 pos = EditorSettings::get_singleton()->get("run/window_placement/rect_custom_position"); + Vector2 pos = EDITOR_GET("run/window_placement/rect_custom_position"); pos += screen_rect.position; args.push_back("--position"); args.push_back(itos(pos.x) + "," + itos(pos.y)); @@ -215,7 +219,7 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { String exec = OS::get_singleton()->get_executable_path(); - const String raw_custom_args = ProjectSettings::get_singleton()->get("editor/run/main_run_args"); + const String raw_custom_args = GLOBAL_GET("editor/run/main_run_args"); if (!raw_custom_args.is_empty()) { // Allow the user to specify a command to run, similar to Steam's launch options. // In this case, Godot will no longer be run directly; it's up to the underlying command @@ -260,7 +264,7 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { // Pass the debugger stop shortcut to the running instance(s). String shortcut; - VariantWriter::write_to_string(ED_GET_SHORTCUT("editor/stop"), shortcut); + VariantWriter::write_to_string(ED_GET_SHORTCUT("editor/stop_running_project"), shortcut); OS::get_singleton()->set_environment("__GODOT_EDITOR_STOP_SHORTCUT__", shortcut); printf("Running: %s", exec.utf8().get_data()); diff --git a/editor/editor_run.h b/editor/editor_run.h index 4cbc6838e4..935e32ee2a 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -32,7 +32,7 @@ #define EDITOR_RUN_H #include "core/os/os.h" -#include "scene/main/node.h" + class EditorRun { public: enum Status { diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 3e8f17085d..47a9661bcb 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -134,7 +134,7 @@ Error EditorRunNative::run_native(int p_idx, int p_platform) { bool deploy_debug_remote = is_deploy_debug_remote_enabled(); bool deploy_dumb = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_file_server", false); - bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false); + bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisions", false); bool debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false); if (deploy_debug_remote) { @@ -144,7 +144,7 @@ Error EditorRunNative::run_native(int p_idx, int p_platform) { flags |= EditorExportPlatform::DEBUG_FLAG_DUMB_CLIENT; } if (debug_collisions) { - flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_COLLISONS; + flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_COLLISIONS; } if (debug_navigation) { flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_NAVIGATION; diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index e078bea037..5c8ef89ac9 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -151,7 +151,9 @@ void SectionedInspector::_section_selected() { void SectionedInspector::set_current_section(const String &p_section) { if (section_map.has(p_section)) { - section_map[p_section]->select(0); + TreeItem *item = section_map[p_section]; + item->select(0); + sections->scroll_to_item(item); } } @@ -226,9 +228,9 @@ void SectionedInspector::update_category_list() { TreeItem *root = sections->create_item(); section_map[""] = root; - String filter; + String filter_text; if (search_box) { - filter = search_box->get_text(); + filter_text = search_box->get_text(); } const EditorPropertyNameProcessor::Style name_style = EditorPropertyNameProcessor::get_settings_style(); @@ -245,7 +247,7 @@ void SectionedInspector::update_category_list() { continue; } - if (!filter.is_empty() && !_property_path_matches(pi.name, filter, name_style)) { + if (!filter_text.is_empty() && !_property_path_matches(pi.name, filter_text, name_style)) { continue; } @@ -310,7 +312,9 @@ void SectionedInspector::_search_changed(const String &p_what) { void SectionedInspector::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - inspector->set_property_name_style(EditorPropertyNameProcessor::get_settings_style()); + if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/localize_settings")) { + inspector->set_property_name_style(EditorPropertyNameProcessor::get_settings_style()); + } } break; } } diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 74445e6caa..c44fe04442 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -76,14 +76,14 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) Array arr = p_value; for (int i = 0; i < arr.size(); i++) { Dictionary dict = arr[i]; - String name = dict["name"]; + String shortcut_name = dict["name"]; Array shortcut_events = dict["shortcuts"]; Ref<Shortcut> sc; sc.instantiate(); sc->set_events(shortcut_events); - add_shortcut(name, sc); + add_shortcut(shortcut_name, sc); } return false; @@ -92,16 +92,16 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) for (int i = 0; i < actions_arr.size(); i++) { Dictionary action_dict = actions_arr[i]; - String name = action_dict["name"]; + String action_name = action_dict["name"]; Array events = action_dict["events"]; InputMap *im = InputMap::get_singleton(); - im->action_erase_events(name); + im->action_erase_events(action_name); - builtin_action_overrides[name].clear(); + builtin_action_overrides[action_name].clear(); for (int ev_idx = 0; ev_idx < events.size(); ev_idx++) { - im->action_add_event(name, events[ev_idx]); - builtin_action_overrides[name].push_back(events[ev_idx]); + im->action_add_event(action_name, events[ev_idx]); + builtin_action_overrides[action_name].push_back(events[ev_idx]); } } return false; @@ -159,7 +159,7 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const { if (!sc->has_meta("original")) { // Getting the meta when it doesn't exist will return an empty array. If the 'shortcut_events' have been cleared, - // we still want save the shortcut in this case so that shortcuts that the user has customised are not reset, + // we still want save the shortcut in this case so that shortcuts that the user has customized are not reset, // even if the 'original' has not been populated yet. This can happen when calling save() from the Project Manager. save_array.push_back(dict); continue; @@ -412,16 +412,16 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { EDITOR_SETTING_USAGE(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/editor/custom_display_scale", 1.0, "0.5,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED) EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/editor/main_font_size", 14, "8,48,1") EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/editor/code_font_size", 14, "8,48,1") - EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/code_font_contextual_ligatures", 0, "Default,Disable Contextual Alternates (Coding Ligatures),Use Custom OpenType Feature Set") + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/code_font_contextual_ligatures", 1, "Enabled,Disable Contextual Alternates (Coding Ligatures),Use Custom OpenType Feature Set") _initial_set("interface/editor/code_font_custom_opentype_features", ""); _initial_set("interface/editor/code_font_custom_variations", ""); - EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_antialiasing", 1, "None,Grayscale,LCD sub-pixel") + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_antialiasing", 1, "None,Grayscale,LCD Subpixel") #ifdef MACOS_ENABLED EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_hinting", 0, "Auto (None),None,Light,Normal") #else EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_hinting", 0, "Auto (Light),None,Light,Normal") #endif - EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_subpixel_positioning", 1, "Disabled,Auto,One half of a pixel,One quarter of a pixel") + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_subpixel_positioning", 1, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel") EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "interface/editor/main_font", "", "*.ttf,*.otf,*.woff,*.woff2,*.pfb,*.pfm") EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "interface/editor/main_font_bold", "", "*.ttf,*.otf,*.woff,*.woff2,*.pfb,*.pfm") @@ -438,6 +438,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/single_window_mode", false, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED) _initial_set("interface/editor/mouse_extra_buttons_navigate_history", true); _initial_set("interface/editor/save_each_scene_on_quit", true); // Regression + EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/accept_dialog_cancel_ok_buttons", 0, + vformat("Auto (%s),Cancel First,OK First", DisplayServer::get_singleton()->get_swap_cancel_ok() ? "OK First" : "Cancel First"), + PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); #ifdef DEV_ENABLED EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/show_internal_errors_in_toast_notifications", 0, "Auto (Enabled),Enabled,Disabled") #else @@ -449,11 +452,12 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/inspector/show_low_level_opentype_features", false, "") // Theme - EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_ENUM, "interface/theme/preset", "Default", "Default,Breeze Dark,Godot 2,Gray,Light,Solarized (Dark),Solarized (Light),Custom") + EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_ENUM, "interface/theme/preset", "Default", "Default,Breeze Dark,Godot 2,Gray,Light,Solarized (Dark),Solarized (Light),Black (OLED),Custom") EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/theme/icon_and_font_color", 0, "Auto,Dark,Light") EDITOR_SETTING(Variant::COLOR, PROPERTY_HINT_NONE, "interface/theme/base_color", Color(0.2, 0.23, 0.31), "") EDITOR_SETTING(Variant::COLOR, PROPERTY_HINT_NONE, "interface/theme/accent_color", Color(0.41, 0.61, 0.91), "") EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/theme/contrast", 0.3, "-1,1,0.01") + EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/theme/draw_extra_borders", false, "") EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/theme/icon_saturation", 1.0, "0,2,0.01") EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/theme/relationship_line_opacity", 0.1, "0.00,1,0.01") EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/theme/border_size", 0, "0,2,1") @@ -735,8 +739,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { if (p_extra_config->has_section("init_projects") && p_extra_config->has_section_key("init_projects", "list")) { Vector<String> list = p_extra_config->get_value("init_projects", "list"); for (int i = 0; i < list.size(); i++) { - String name = list[i].replace("/", "::"); - set("projects/" + name, list[i]); + String proj_name = list[i].replace("/", "::"); + set("projects/" + proj_name, list[i]); } } @@ -774,7 +778,7 @@ void EditorSettings::_load_godot2_text_editor_theme() { _initial_set("text_editor/theme/highlighting/safe_line_number_color", Color(0.67, 0.78, 0.67, 0.6)); _initial_set("text_editor/theme/highlighting/caret_color", Color(0.67, 0.67, 0.67)); _initial_set("text_editor/theme/highlighting/caret_background_color", Color(0, 0, 0)); - _initial_set("text_editor/theme/highlighting/text_selected_color", Color(0, 0, 0)); + _initial_set("text_editor/theme/highlighting/text_selected_color", Color(0, 0, 0, 0)); _initial_set("text_editor/theme/highlighting/selection_color", Color(0.41, 0.61, 0.91, 0.35)); _initial_set("text_editor/theme/highlighting/brace_mismatch_color", Color(1, 0.2, 0.2)); _initial_set("text_editor/theme/highlighting/current_line_color", Color(0.3, 0.5, 0.8, 0.15)); @@ -1057,7 +1061,7 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_re Variant ret = p_default; if (EditorSettings::get_singleton()->has_setting(p_setting)) { - ret = EditorSettings::get_singleton()->get(p_setting); + ret = EDITOR_GET(p_setting); } else { EditorSettings::get_singleton()->set_manually(p_setting, p_default); EditorSettings::get_singleton()->set_restart_if_changed(p_setting, p_restart_if_changed); diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 8062b6f756..6c11572d10 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -41,6 +41,8 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/event_listener_line_edit.h" +#include "editor/input_event_configuration_dialog.h" #include "scene/gui/margin_container.h" void EditorSettingsDialog::ok_pressed() { @@ -59,7 +61,7 @@ void EditorSettingsDialog::_settings_changed() { void EditorSettingsDialog::_settings_property_edited(const String &p_name) { String full_name = inspector->get_full_item_path(p_name); - if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast") { + if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast" || full_name == "interface/theme/draw_extra_borders") { EditorSettings::get_singleton()->set_manually("interface/theme/preset", "Custom"); // set preset to Custom } else if (full_name.begins_with("text_editor/theme/highlighting")) { EditorSettings::get_singleton()->set_manually("text_editor/theme/color_theme", "Custom"); @@ -106,11 +108,16 @@ void EditorSettingsDialog::popup_edit_settings() { _focus_current_search_box(); } -void EditorSettingsDialog::_filter_shortcuts(const String &p_filter) { - shortcut_filter = p_filter; +void EditorSettingsDialog::_filter_shortcuts(const String &) { _update_shortcuts(); } +void EditorSettingsDialog::_filter_shortcuts_by_event(const Ref<InputEvent> &p_event) { + if (p_event.is_null() || (p_event->is_pressed() && !p_event->is_echo())) { + _update_shortcuts(); + } +} + void EditorSettingsDialog::_undo_redo_callback(void *p_self, const String &p_name) { EditorNode::get_log()->add_message(p_name, EditorLog::MSG_TYPE_EDITOR); } @@ -125,6 +132,7 @@ void EditorSettingsDialog::_notification(int p_what) { } break; case NOTIFICATION_READY: { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY).undo_redo->set_method_notify_callback(EditorDebuggerNode::_method_changeds, nullptr); undo_redo->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY).undo_redo->set_property_notify_callback(EditorDebuggerNode::_property_changeds, nullptr); undo_redo->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY).undo_redo->set_commit_notify_callback(_undo_redo_callback, this); @@ -144,16 +152,18 @@ void EditorSettingsDialog::_notification(int p_what) { _update_shortcuts(); } - inspector->update_category_list(); + if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/localize_settings")) { + inspector->update_category_list(); + } } break; } } void EditorSettingsDialog::shortcut_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); const Ref<InputEventKey> k = p_event; - if (k.is_valid() && k->is_pressed()) { bool handled = false; @@ -222,6 +232,7 @@ void EditorSettingsDialog::_event_config_confirmed() { void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Array &p_events) { Array old_input_array = EditorSettings::get_singleton()->get_builtin_action_overrides(p_name); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Edit Built-in Action") + " '" + p_name + "'"); undo_redo->add_do_method(EditorSettings::get_singleton(), "mark_setting_changed", "builtin_action_overrides"); undo_redo->add_undo_method(EditorSettings::get_singleton(), "mark_setting_changed", "builtin_action_overrides"); @@ -237,6 +248,7 @@ void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Ar void EditorSettingsDialog::_update_shortcut_events(const String &p_path, const Array &p_events) { Ref<Shortcut> current_sc = EditorSettings::get_singleton()->get_shortcut(p_path); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Edit Shortcut") + " '" + p_path + "'"); undo_redo->add_do_method(current_sc.ptr(), "set_events", p_events); undo_redo->add_undo_method(current_sc.ptr(), "set_events", current_sc->get_events()); @@ -326,6 +338,22 @@ void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const S } } +bool EditorSettingsDialog::_should_display_shortcut(const String &p_name, const Array &p_events) const { + const Ref<InputEvent> search_ev = shortcut_search_by_event->get_event(); + bool event_match = true; + if (search_ev.is_valid()) { + event_match = false; + for (int i = 0; i < p_events.size(); ++i) { + const Ref<InputEvent> ev = p_events[i]; + if (ev.is_valid() && ev->is_match(search_ev, true)) { + event_match = true; + } + } + } + + return event_match && shortcut_search_box->get_text().is_subsequence_ofn(p_name); +} + void EditorSettingsDialog::_update_shortcuts() { // Before clearing the tree, take note of which categories are collapsed so that this state can be maintained when the tree is repopulated. HashMap<String, bool> collapsed; @@ -379,32 +407,17 @@ void EditorSettingsDialog::_update_shortcuts() { const String &action_name = E.key; const InputMap::Action &action = E.value; - Array events; // Need to get the list of events into an array so it can be set as metadata on the item. - Vector<String> event_strings; - // Skip non-builtin actions. if (!InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().has(action_name)) { continue; } const List<Ref<InputEvent>> &all_default_events = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(action_name)->value; - List<Ref<InputEventKey>> key_default_events; - // Remove all non-key events from the defaults. Only check keys, since we are in the editor. - for (const List<Ref<InputEvent>>::Element *I = all_default_events.front(); I; I = I->next()) { - Ref<InputEventKey> k = I->get(); - if (k.is_valid()) { - key_default_events.push_back(k); - } - } - - // Join the text of the events with a delimiter so they can all be displayed in one cell. - String events_display_string = event_strings.is_empty() ? "None" : String("; ").join(event_strings); - - if (!shortcut_filter.is_subsequence_ofn(action_name) && (events_display_string == "None" || !shortcut_filter.is_subsequence_ofn(events_display_string))) { + Array action_events = _event_list_to_array_helper(action.inputs); + if (!_should_display_shortcut(action_name, action_events)) { continue; } - Array action_events = _event_list_to_array_helper(action.inputs); Array default_events = _event_list_to_array_helper(all_default_events); bool same_as_defaults = Shortcut::is_event_array_equal(default_events, action_events); bool collapse = !collapsed.has(action_name) || (collapsed.has(action_name) && collapsed[action_name]); @@ -416,46 +429,50 @@ void EditorSettingsDialog::_update_shortcuts() { List<String> slist; EditorSettings::get_singleton()->get_shortcut_list(&slist); + slist.sort(); // Sort alphabetically. const EditorPropertyNameProcessor::Style name_style = EditorPropertyNameProcessor::get_settings_style(); const EditorPropertyNameProcessor::Style tooltip_style = EditorPropertyNameProcessor::get_tooltip_style(name_style); + // Create all sections first. for (const String &E : slist) { Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E); - if (!sc->has_meta("original")) { + String section_name = E.get_slice("/", 0); + + if (sections.has(section_name)) { continue; } - // Shortcut Section + TreeItem *section = shortcuts->create_item(root); - TreeItem *section; - String section_name = E.get_slice("/", 0); + const String item_name = EditorPropertyNameProcessor::get_singleton()->process_name(section_name, name_style); + const String tooltip = EditorPropertyNameProcessor::get_singleton()->process_name(section_name, tooltip_style); - if (sections.has(section_name)) { - section = sections[section_name]; - } else { - section = shortcuts->create_item(root); - - const String item_name = EditorPropertyNameProcessor::get_singleton()->process_name(section_name, name_style); - const String tooltip = EditorPropertyNameProcessor::get_singleton()->process_name(section_name, tooltip_style); - - section->set_text(0, item_name); - section->set_tooltip_text(0, tooltip); - section->set_selectable(0, false); - section->set_selectable(1, false); - section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); - section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); - - if (collapsed.has(item_name)) { - section->set_collapsed(collapsed[item_name]); - } + section->set_text(0, item_name); + section->set_tooltip_text(0, tooltip); + section->set_selectable(0, false); + section->set_selectable(1, false); + section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); + section->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); - sections[section_name] = section; + if (collapsed.has(item_name)) { + section->set_collapsed(collapsed[item_name]); } - // Shortcut Item + sections[section_name] = section; + } - if (!shortcut_filter.is_subsequence_ofn(sc->get_name())) { + // Add shortcuts to sections. + for (const String &E : slist) { + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E); + if (!sc->has_meta("original")) { + continue; + } + + String section_name = E.get_slice("/", 0); + TreeItem *section = sections[section_name]; + + if (!_should_display_shortcut(sc->get_name(), sc->get_events())) { continue; } @@ -472,6 +489,7 @@ void EditorSettingsDialog::_update_shortcuts() { TreeItem *section = E.value; if (section->get_first_child() == nullptr) { root->remove_child(section); + memdelete(section); } } } @@ -685,8 +703,6 @@ void EditorSettingsDialog::_bind_methods() { EditorSettingsDialog::EditorSettingsDialog() { set_title(TTR("Editor Settings")); - undo_redo = EditorNode::get_undo_redo(); - tabs = memnew(TabContainer); tabs->set_theme_type_variation("TabContainerOdd"); tabs->connect("tab_changed", callable_mp(this, &EditorSettingsDialog::_tabs_tab_changed)); @@ -711,7 +727,6 @@ EditorSettingsDialog::EditorSettingsDialog() { inspector->get_inspector()->set_use_filter(true); inspector->register_search_box(search_box); inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL); - inspector->get_inspector()->set_undo_redo(undo_redo); tab_general->add_child(inspector); inspector->get_inspector()->connect("property_edited", callable_mp(this, &EditorSettingsDialog::_settings_property_edited)); inspector->get_inspector()->connect("restart_requested", callable_mp(this, &EditorSettingsDialog::_editor_restart_request)); @@ -744,12 +759,29 @@ EditorSettingsDialog::EditorSettingsDialog() { tabs->add_child(tab_shortcuts); tab_shortcuts->set_name(TTR("Shortcuts")); + HBoxContainer *top_hbox = memnew(HBoxContainer); + top_hbox->set_h_size_flags(Control::SIZE_EXPAND_FILL); + tab_shortcuts->add_child(top_hbox); + shortcut_search_box = memnew(LineEdit); - shortcut_search_box->set_placeholder(TTR("Filter Shortcuts")); + shortcut_search_box->set_placeholder(TTR("Filter by name...")); shortcut_search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - tab_shortcuts->add_child(shortcut_search_box); + top_hbox->add_child(shortcut_search_box); shortcut_search_box->connect("text_changed", callable_mp(this, &EditorSettingsDialog::_filter_shortcuts)); + shortcut_search_by_event = memnew(EventListenerLineEdit); + shortcut_search_by_event->set_h_size_flags(Control::SIZE_EXPAND_FILL); + shortcut_search_by_event->set_stretch_ratio(0.75); + shortcut_search_by_event->set_allowed_input_types(INPUT_KEY); + shortcut_search_by_event->connect("event_changed", callable_mp(this, &EditorSettingsDialog::_filter_shortcuts_by_event)); + top_hbox->add_child(shortcut_search_by_event); + + Button *clear_all_search = memnew(Button); + clear_all_search->set_text(TTR("Clear All")); + clear_all_search->connect("pressed", callable_mp(shortcut_search_box, &LineEdit::clear)); + clear_all_search->connect("pressed", callable_mp(shortcut_search_by_event, &EventListenerLineEdit::clear_event)); + top_hbox->add_child(clear_all_search); + shortcuts = memnew(Tree); shortcuts->set_v_size_flags(Control::SIZE_EXPAND_FILL); shortcuts->set_columns(2); @@ -766,7 +798,7 @@ EditorSettingsDialog::EditorSettingsDialog() { // Adding event dialog shortcut_editor = memnew(InputEventConfigurationDialog); shortcut_editor->connect("confirmed", callable_mp(this, &EditorSettingsDialog::_event_config_confirmed)); - shortcut_editor->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY); + shortcut_editor->set_allowed_input_types(INPUT_KEY); add_child(shortcut_editor); set_hide_on_ok(true); diff --git a/editor/editor_settings_dialog.h b/editor/editor_settings_dialog.h index 87ed6a77eb..a330de1e2c 100644 --- a/editor/editor_settings_dialog.h +++ b/editor/editor_settings_dialog.h @@ -40,8 +40,6 @@ #include "scene/gui/tab_container.h" #include "scene/gui/texture_rect.h" -class EditorUndoRedoManager; - class EditorSettingsDialog : public AcceptDialog { GDCLASS(EditorSettingsDialog, AcceptDialog); @@ -53,6 +51,7 @@ class EditorSettingsDialog : public AcceptDialog { LineEdit *search_box = nullptr; LineEdit *shortcut_search_box = nullptr; + EventListenerLineEdit *shortcut_search_by_event = nullptr; SectionedInspector *inspector = nullptr; // Shortcuts @@ -64,7 +63,6 @@ class EditorSettingsDialog : public AcceptDialog { }; Tree *shortcuts = nullptr; - String shortcut_filter; InputEventConfigurationDialog *shortcut_editor = nullptr; @@ -75,8 +73,6 @@ class EditorSettingsDialog : public AcceptDialog { Timer *timer = nullptr; - Ref<EditorUndoRedoManager> undo_redo; - virtual void cancel_pressed() override; virtual void ok_pressed() override; @@ -103,13 +99,13 @@ class EditorSettingsDialog : public AcceptDialog { void _focus_current_search_box(); void _filter_shortcuts(const String &p_filter); + void _filter_shortcuts_by_event(const Ref<InputEvent> &p_event); + bool _should_display_shortcut(const String &p_name, const Array &p_events) const; void _update_shortcuts(); void _shortcut_button_pressed(Object *p_item, int p_column, int p_idx, MouseButton p_button = MouseButton::LEFT); void _shortcut_cell_double_clicked(); - void _builtin_action_popup_index_pressed(int p_index); - static void _undo_redo_callback(void *p_self, const String &p_name); Label *restart_label = nullptr; diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 4cd046e811..11a8fce9c3 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -143,7 +143,7 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) { } Ref<InputEventKey> k = p_event; - if (k.is_valid() && k->is_pressed() && k->is_action("ui_accept")) { + if (k.is_valid() && k->is_pressed() && k->is_action("ui_accept", true)) { _focus_entered(); } } @@ -398,7 +398,7 @@ void EditorSpinSlider::_draw_spin_slider() { grabbing_spinner_mouse_pos = get_global_position() + grabber_rect.get_center(); - bool display_grabber = (mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !(value_input_popup && value_input_popup->is_visible()); + bool display_grabber = (grabbing_grabber || mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !(value_input_popup && value_input_popup->is_visible()); if (grabber->is_visible() != display_grabber) { if (display_grabber) { grabber->show(); @@ -619,11 +619,9 @@ bool EditorSpinSlider::is_grabbing() const { void EditorSpinSlider::_focus_entered() { _ensure_input_popup(); - Rect2 gr = get_screen_rect(); value_input->set_text(get_text_value()); - value_input_popup->set_position(gr.position); - value_input_popup->set_size(gr.size); - value_input_popup->call_deferred(SNAME("popup")); + value_input_popup->set_size(get_size()); + value_input_popup->call_deferred(SNAME("show")); value_input->call_deferred(SNAME("grab_focus")); value_input->call_deferred(SNAME("select_all")); value_input->set_focus_next(find_next_valid_focus()->get_path()); @@ -658,14 +656,13 @@ void EditorSpinSlider::_ensure_input_popup() { return; } - value_input_popup = memnew(Popup); + value_input_popup = memnew(Control); add_child(value_input_popup); value_input = memnew(LineEdit); value_input_popup->add_child(value_input); - value_input_popup->set_wrap_controls(true); value_input->set_anchors_and_offsets_preset(PRESET_FULL_RECT); - value_input_popup->connect("popup_hide", callable_mp(this, &EditorSpinSlider::_value_input_closed)); + value_input_popup->connect("hidden", callable_mp(this, &EditorSpinSlider::_value_input_closed)); value_input->connect("text_submitted", callable_mp(this, &EditorSpinSlider::_value_input_submitted)); value_input->connect("focus_exited", callable_mp(this, &EditorSpinSlider::_value_focus_exited)); value_input->connect("gui_input", callable_mp(this, &EditorSpinSlider::_value_input_gui_input)); diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h index afcaa3e4b6..fd5c3dc5df 100644 --- a/editor/editor_spin_slider.h +++ b/editor/editor_spin_slider.h @@ -63,7 +63,7 @@ class EditorSpinSlider : public Range { Vector2 grabbing_spinner_mouse_pos; double pre_grab_value = 0.0; - Popup *value_input_popup = nullptr; + Control *value_input_popup = nullptr; LineEdit *value_input = nullptr; bool value_input_just_closed = false; bool value_input_dirty = false; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index edbd2dd62f..96834f4a6c 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -42,10 +42,15 @@ #include "modules/svg/image_loader_svg.h" #endif -HashMap<Color, Color> EditorColorMap::editor_color_map; +HashMap<Color, Color> EditorColorMap::color_conversion_map; +HashSet<StringName> EditorColorMap::color_conversion_exceptions; -void EditorColorMap::add_color_pair(const String p_from_color, const String p_to_color) { - editor_color_map[Color::html(p_from_color)] = Color::html(p_to_color); +void EditorColorMap::add_conversion_color_pair(const String p_from_color, const String p_to_color) { + color_conversion_map[Color::html(p_from_color)] = Color::html(p_to_color); +} + +void EditorColorMap::add_conversion_exception(const StringName p_icon_name) { + color_conversion_exceptions.insert(p_icon_name); } void EditorColorMap::create() { @@ -53,105 +58,139 @@ void EditorColorMap::create() { // This can be a basis for proper palette validation later. // Convert: FROM TO - add_color_pair("#478cbf", "#478cbf"); // Godot Blue - add_color_pair("#414042", "#414042"); // Godot Gray + add_conversion_color_pair("#478cbf", "#478cbf"); // Godot Blue + add_conversion_color_pair("#414042", "#414042"); // Godot Gray - add_color_pair("#ffffff", "#414141"); // Pure white - add_color_pair("#000000", "#bfbfbf"); // Pure black + add_conversion_color_pair("#ffffff", "#414141"); // Pure white + add_conversion_color_pair("#000000", "#bfbfbf"); // Pure black // Keep pure RGB colors as is, but list them for explicitly. - add_color_pair("#ff0000", "#ff0000"); // Pure red - add_color_pair("#00ff00", "#00ff00"); // Pure green - add_color_pair("#0000ff", "#0000ff"); // Pure blue + add_conversion_color_pair("#ff0000", "#ff0000"); // Pure red + add_conversion_color_pair("#00ff00", "#00ff00"); // Pure green + add_conversion_color_pair("#0000ff", "#0000ff"); // Pure blue // GUI Colors - add_color_pair("#e0e0e0", "#5a5a5a"); // Common icon color - add_color_pair("#fefefe", "#fefefe"); // Forced light color - add_color_pair("#808080", "#808080"); // GUI disabled color - add_color_pair("#b3b3b3", "#363636"); // GUI disabled light color - add_color_pair("#699ce8", "#699ce8"); // GUI highlight color - add_color_pair("#f9f9f9", "#606060"); // Scrollbar grabber highlight color - - add_color_pair("#c38ef1", "#a85de9"); // Animation - add_color_pair("#fc7f7f", "#cd3838"); // Spatial - add_color_pair("#8da5f3", "#3d64dd"); // 2D - add_color_pair("#4b70ea", "#1a3eac"); // 2D Dark - add_color_pair("#8eef97", "#2fa139"); // Control - - add_color_pair("#5fb2ff", "#0079f0"); // Selection (blue) - add_color_pair("#003e7a", "#2b74bb"); // Selection (darker blue) - add_color_pair("#f7f5cf", "#615f3a"); // Gizmo (yellow) + add_conversion_color_pair("#e0e0e0", "#5a5a5a"); // Common icon color + add_conversion_color_pair("#fefefe", "#fefefe"); // Forced light color + add_conversion_color_pair("#808080", "#808080"); // GUI disabled color + add_conversion_color_pair("#b3b3b3", "#363636"); // GUI disabled light color + add_conversion_color_pair("#699ce8", "#699ce8"); // GUI highlight color + add_conversion_color_pair("#f9f9f9", "#606060"); // Scrollbar grabber highlight color + + add_conversion_color_pair("#c38ef1", "#a85de9"); // Animation + add_conversion_color_pair("#fc7f7f", "#cd3838"); // Spatial + add_conversion_color_pair("#8da5f3", "#3d64dd"); // 2D + add_conversion_color_pair("#4b70ea", "#1a3eac"); // 2D Dark + add_conversion_color_pair("#8eef97", "#2fa139"); // Control + + add_conversion_color_pair("#5fb2ff", "#0079f0"); // Selection (blue) + add_conversion_color_pair("#003e7a", "#2b74bb"); // Selection (darker blue) + add_conversion_color_pair("#f7f5cf", "#615f3a"); // Gizmo (yellow) // Rainbow - add_color_pair("#ff4545", "#ff2929"); // Red - add_color_pair("#ffe345", "#ffe337"); // Yellow - add_color_pair("#80ff45", "#74ff34"); // Green - add_color_pair("#45ffa2", "#2cff98"); // Aqua - add_color_pair("#45d7ff", "#22ccff"); // Blue - add_color_pair("#8045ff", "#702aff"); // Purple - add_color_pair("#ff4596", "#ff2781"); // Pink + add_conversion_color_pair("#ff4545", "#ff2929"); // Red + add_conversion_color_pair("#ffe345", "#ffe337"); // Yellow + add_conversion_color_pair("#80ff45", "#74ff34"); // Green + add_conversion_color_pair("#45ffa2", "#2cff98"); // Aqua + add_conversion_color_pair("#45d7ff", "#22ccff"); // Blue + add_conversion_color_pair("#8045ff", "#702aff"); // Purple + add_conversion_color_pair("#ff4596", "#ff2781"); // Pink // Audio gradients - add_color_pair("#e1da5b", "#d6cf4b"); // Yellow + add_conversion_color_pair("#e1da5b", "#d6cf4b"); // Yellow - add_color_pair("#62aeff", "#1678e0"); // Frozen gradient top - add_color_pair("#75d1e6", "#41acc5"); // Frozen gradient middle - add_color_pair("#84ffee", "#49ccba"); // Frozen gradient bottom + add_conversion_color_pair("#62aeff", "#1678e0"); // Frozen gradient top + add_conversion_color_pair("#75d1e6", "#41acc5"); // Frozen gradient middle + add_conversion_color_pair("#84ffee", "#49ccba"); // Frozen gradient bottom - add_color_pair("#f70000", "#c91616"); // Color track red - add_color_pair("#eec315", "#d58c0b"); // Color track orange - add_color_pair("#dbee15", "#b7d10a"); // Color track yellow - add_color_pair("#288027", "#218309"); // Color track green + add_conversion_color_pair("#f70000", "#c91616"); // Color track red + add_conversion_color_pair("#eec315", "#d58c0b"); // Color track orange + add_conversion_color_pair("#dbee15", "#b7d10a"); // Color track yellow + add_conversion_color_pair("#288027", "#218309"); // Color track green // Resource groups - add_color_pair("#ffca5f", "#fea900"); // Mesh resource (orange) - add_color_pair("#2998ff", "#68b6ff"); // Shape resource (blue) - add_color_pair("#a2d2ff", "#4998e3"); // Shape resource (light blue) + add_conversion_color_pair("#ffca5f", "#fea900"); // Mesh resource (orange) + add_conversion_color_pair("#2998ff", "#68b6ff"); // Shape resource (blue) + add_conversion_color_pair("#a2d2ff", "#4998e3"); // Shape resource (light blue) // Animation editor tracks // The property track icon color is set by the common icon color. - add_color_pair("#ea7940", "#bd5e2c"); // 3D Position track - add_color_pair("#ff2b88", "#bd165f"); // 3D Rotation track - add_color_pair("#eac840", "#bd9d1f"); // 3D Scale track - add_color_pair("#3cf34e", "#16a827"); // Call Method track - add_color_pair("#2877f6", "#236be6"); // Bezier Curve track - add_color_pair("#eae440", "#9f9722"); // Audio Playback track - add_color_pair("#a448f0", "#9853ce"); // Animation Playback track - add_color_pair("#5ad5c4", "#0a9c88"); // Blend Shape track + add_conversion_color_pair("#ea7940", "#bd5e2c"); // 3D Position track + add_conversion_color_pair("#ff2b88", "#bd165f"); // 3D Rotation track + add_conversion_color_pair("#eac840", "#bd9d1f"); // 3D Scale track + add_conversion_color_pair("#3cf34e", "#16a827"); // Call Method track + add_conversion_color_pair("#2877f6", "#236be6"); // Bezier Curve track + add_conversion_color_pair("#eae440", "#9f9722"); // Audio Playback track + add_conversion_color_pair("#a448f0", "#9853ce"); // Animation Playback track + add_conversion_color_pair("#5ad5c4", "#0a9c88"); // Blend Shape track // Control layouts - add_color_pair("#d6d6d6", "#474747"); // Highlighted part - add_color_pair("#474747", "#d6d6d6"); // Background part - add_color_pair("#919191", "#6e6e6e"); // Border part + add_conversion_color_pair("#d6d6d6", "#474747"); // Highlighted part + add_conversion_color_pair("#474747", "#d6d6d6"); // Background part + add_conversion_color_pair("#919191", "#6e6e6e"); // Border part // TileSet editor icons - add_color_pair("#fce00e", "#aa8d24"); // New Single Tile - add_color_pair("#0e71fc", "#0350bd"); // New Autotile - add_color_pair("#c6ced4", "#828f9b"); // New Atlas + add_conversion_color_pair("#fce00e", "#aa8d24"); // New Single Tile + add_conversion_color_pair("#0e71fc", "#0350bd"); // New Autotile + add_conversion_color_pair("#c6ced4", "#828f9b"); // New Atlas // Visual script - add_color_pair("#41ecad", "#25e3a0"); // VisualScript variant - add_color_pair("#6f91f0", "#6d8eeb"); // VisualScript bool - add_color_pair("#5abbef", "#4fb2e9"); // VisualScript int - add_color_pair("#35d4f4", "#27ccf0"); // VisualScript float - add_color_pair("#4593ec", "#4690e7"); // VisualScript String - add_color_pair("#ac73f1", "#ad76ee"); // VisualScript Vector2 - add_color_pair("#f1738f", "#ee758e"); // VisualScript Rect2 - add_color_pair("#de66f0", "#dc6aed"); // VisualScript Vector3 - add_color_pair("#b9ec41", "#96ce1a"); // VisualScript Transform2D - add_color_pair("#f74949", "#f77070"); // VisualScript Plane - add_color_pair("#ec418e", "#ec69a3"); // VisualScript Quat - add_color_pair("#ee5677", "#ee7991"); // VisualScript AABB - add_color_pair("#e1ec41", "#b2bb19"); // VisualScript Basis - add_color_pair("#f68f45", "#f49047"); // VisualScript Transform - add_color_pair("#417aec", "#6993ec"); // VisualScript NodePath - add_color_pair("#41ec80", "#2ce573"); // VisualScript RID - add_color_pair("#55f3e3", "#12d5c3"); // VisualScript Object - add_color_pair("#54ed9e", "#57e99f"); // VisualScript Dictionary + add_conversion_color_pair("#41ecad", "#25e3a0"); // VisualScript variant + add_conversion_color_pair("#6f91f0", "#6d8eeb"); // VisualScript bool + add_conversion_color_pair("#5abbef", "#4fb2e9"); // VisualScript int + add_conversion_color_pair("#35d4f4", "#27ccf0"); // VisualScript float + add_conversion_color_pair("#4593ec", "#4690e7"); // VisualScript String + add_conversion_color_pair("#ac73f1", "#ad76ee"); // VisualScript Vector2 + add_conversion_color_pair("#f1738f", "#ee758e"); // VisualScript Rect2 + add_conversion_color_pair("#de66f0", "#dc6aed"); // VisualScript Vector3 + add_conversion_color_pair("#b9ec41", "#96ce1a"); // VisualScript Transform2D + add_conversion_color_pair("#f74949", "#f77070"); // VisualScript Plane + add_conversion_color_pair("#ec418e", "#ec69a3"); // VisualScript Quat + add_conversion_color_pair("#ee5677", "#ee7991"); // VisualScript AABB + add_conversion_color_pair("#e1ec41", "#b2bb19"); // VisualScript Basis + add_conversion_color_pair("#f68f45", "#f49047"); // VisualScript Transform + add_conversion_color_pair("#417aec", "#6993ec"); // VisualScript NodePath + add_conversion_color_pair("#41ec80", "#2ce573"); // VisualScript RID + add_conversion_color_pair("#55f3e3", "#12d5c3"); // VisualScript Object + add_conversion_color_pair("#54ed9e", "#57e99f"); // VisualScript Dictionary // Visual shaders - add_color_pair("#77ce57", "#67c046"); // Vector funcs - add_color_pair("#ea686c", "#d95256"); // Vector transforms - add_color_pair("#eac968", "#d9b64f"); // Textures and cubemaps - add_color_pair("#cf68ea", "#c050dd"); // Functions and expressions + add_conversion_color_pair("#77ce57", "#67c046"); // Vector funcs + add_conversion_color_pair("#ea686c", "#d95256"); // Vector transforms + add_conversion_color_pair("#eac968", "#d9b64f"); // Textures and cubemaps + add_conversion_color_pair("#cf68ea", "#c050dd"); // Functions and expressions + + // These icons should not be converted. + add_conversion_exception("EditorPivot"); + add_conversion_exception("EditorHandle"); + add_conversion_exception("Editor3DHandle"); + add_conversion_exception("EditorBoneHandle"); + add_conversion_exception("Godot"); + add_conversion_exception("Sky"); + add_conversion_exception("EditorControlAnchor"); + add_conversion_exception("DefaultProjectIcon"); + add_conversion_exception("GuiChecked"); + add_conversion_exception("GuiRadioChecked"); + add_conversion_exception("GuiIndeterminate"); + add_conversion_exception("GuiCloseCustomizable"); + add_conversion_exception("GuiGraphNodePort"); + add_conversion_exception("GuiResizer"); + add_conversion_exception("ZoomMore"); + add_conversion_exception("ZoomLess"); + add_conversion_exception("ZoomReset"); + add_conversion_exception("LockViewport"); + add_conversion_exception("GroupViewport"); + add_conversion_exception("StatusError"); + add_conversion_exception("StatusSuccess"); + add_conversion_exception("StatusWarning"); + add_conversion_exception("OverbrightIndicator"); + add_conversion_exception("GuiMiniCheckerboard"); + + /// Code Editor. + add_conversion_exception("GuiTab"); + add_conversion_exception("GuiSpace"); + add_conversion_exception("CodeFoldedRightArrow"); + add_conversion_exception("CodeFoldDownArrow"); + add_conversion_exception("TextEditorPlay"); + add_conversion_exception("Breakpoint"); } static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) { @@ -201,72 +240,55 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, float p_scale, float // with integer editor scales. const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale); ImageLoaderSVG img_loader; - img_loader.create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_colors); + Error err = img_loader.create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_colors); + ERR_FAIL_COND_V_MSG(err != OK, Ref<ImageTexture>(), "Failed generating icon, unsupported or invalid SVG data in editor theme."); if (p_saturation != 1.0) { img->adjust_bcs(1.0, 1.0, p_saturation); } - // In this case filter really helps. return ImageTexture::create_from_image(img); } #endif -void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false, float p_icon_saturation = 1.0) { +void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, float p_icon_saturation, int p_thumb_size, bool p_only_thumbs = false) { #ifdef MODULE_SVG_ENABLED - HashMap<Color, Color> icon_color_map; - - // The names of the icons to never convert, even if one of their colors - // are contained in the dictionary above. - HashSet<StringName> exceptions; - + // Before we register the icons, we adjust their colors and saturation. + // Most icons follow the standard rules for color conversion to follow the editor + // theme's polarity (dark/light). We also adjust the saturation for most icons, + // following the editor setting. + // Some icons are excluded from this conversion, and instead use the configured + // accent color to replace their innate accent color to match the editor theme. + // And then some icons are completely excluded from the conversion. + + // Standard color conversion map. + HashMap<Color, Color> color_conversion_map; + // Icons by default are set up for the dark theme, so if the theme is light, + // we apply the dark-to-light color conversion map. if (!p_dark_theme) { - for (KeyValue<Color, Color> &E : EditorColorMap::get()) { - icon_color_map[E.key] = E.value; + for (KeyValue<Color, Color> &E : EditorColorMap::get_color_conversion_map()) { + color_conversion_map[E.key] = E.value; } - - exceptions.insert("EditorPivot"); - exceptions.insert("EditorHandle"); - exceptions.insert("Editor3DHandle"); - exceptions.insert("EditorBoneHandle"); - exceptions.insert("Godot"); - exceptions.insert("Sky"); - exceptions.insert("EditorControlAnchor"); - exceptions.insert("DefaultProjectIcon"); - exceptions.insert("GuiChecked"); - exceptions.insert("GuiRadioChecked"); - exceptions.insert("GuiIndeterminate"); - exceptions.insert("GuiCloseCustomizable"); - exceptions.insert("GuiGraphNodePort"); - exceptions.insert("GuiResizer"); - exceptions.insert("ZoomMore"); - exceptions.insert("ZoomLess"); - exceptions.insert("ZoomReset"); - exceptions.insert("LockViewport"); - exceptions.insert("GroupViewport"); - exceptions.insert("StatusError"); - exceptions.insert("StatusSuccess"); - exceptions.insert("StatusWarning"); - exceptions.insert("OverbrightIndicator"); - exceptions.insert("GuiMiniCheckerboard"); - - // Prevents Code Editor icons from changing - exceptions.insert("GuiTab"); - exceptions.insert("GuiSpace"); - exceptions.insert("CodeFoldedRightArrow"); - exceptions.insert("CodeFoldDownArrow"); - exceptions.insert("TextEditorPlay"); - exceptions.insert("Breakpoint"); } - - // These ones should be converted even if we are using a dark theme. + // These colors should be converted even if we are using a dark theme. const Color error_color = p_theme->get_color(SNAME("error_color"), SNAME("Editor")); const Color success_color = p_theme->get_color(SNAME("success_color"), SNAME("Editor")); const Color warning_color = p_theme->get_color(SNAME("warning_color"), SNAME("Editor")); - icon_color_map[Color::html("#ff5f5f")] = error_color; - icon_color_map[Color::html("#5fff97")] = success_color; - icon_color_map[Color::html("#ffdd65")] = warning_color; - - // Use the accent color for some icons (checkbox, radio, toggle, etc.). + color_conversion_map[Color::html("#ff5f5f")] = error_color; + color_conversion_map[Color::html("#5fff97")] = success_color; + color_conversion_map[Color::html("#ffdd65")] = warning_color; + + // The names of the icons to exclude from the standard color conversion. + HashSet<StringName> conversion_exceptions = EditorColorMap::get_color_conversion_exceptions(); + + // The names of the icons to exclude when adjusting for saturation. + HashSet<StringName> saturation_exceptions; + saturation_exceptions.insert("DefaultProjectIcon"); + saturation_exceptions.insert("Godot"); + saturation_exceptions.insert("Logo"); + + // Accent color conversion map. + // It is used on some icons (checkbox, radio, toggle, etc.), regardless of the dark + // or light mode. HashMap<Color, Color> accent_color_map; HashSet<StringName> accent_color_icons; @@ -292,16 +314,14 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = icon = editor_generate_icon(i, EDSCALE, 1.0, accent_color_map); } else { float saturation = p_icon_saturation; - - if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0 || strcmp(editor_icons_names[i], "Godot") == 0 || strcmp(editor_icons_names[i], "Logo") == 0) { + if (saturation_exceptions.has(editor_icons_names[i])) { saturation = 1.0; } - const int is_exception = exceptions.has(editor_icons_names[i]); - if (is_exception) { + if (conversion_exceptions.has(editor_icons_names[i])) { icon = editor_generate_icon(i, EDSCALE, saturation); } else { - icon = editor_generate_icon(i, EDSCALE, saturation, icon_color_map); + icon = editor_generate_icon(i, EDSCALE, saturation, color_conversion_map); } } @@ -310,19 +330,26 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = } // Generate thumbnail icons with the given thumbnail size. - // We don't need filtering when generating at one of the default resolutions. - const bool force_filter = p_thumb_size != 64 && p_thumb_size != 32; + // See editor\icons\editor_icons_builders.py for the code that determines which icons are thumbnails. if (p_thumb_size >= 64) { const float scale = (float)p_thumb_size / 64.0 * EDSCALE; for (int i = 0; i < editor_bg_thumbs_count; i++) { const int index = editor_bg_thumbs_indices[i]; - const int is_exception = exceptions.has(editor_icons_names[index]); - Ref<ImageTexture> icon; - if (!p_dark_theme && !is_exception) { - icon = editor_generate_icon(index, scale, force_filter, icon_color_map); + + if (accent_color_icons.has(editor_icons_names[index])) { + icon = editor_generate_icon(index, scale, 1.0, accent_color_map); } else { - icon = editor_generate_icon(index, scale, force_filter); + float saturation = p_icon_saturation; + if (saturation_exceptions.has(editor_icons_names[index])) { + saturation = 1.0; + } + + if (conversion_exceptions.has(editor_icons_names[index])) { + icon = editor_generate_icon(index, scale, saturation); + } else { + icon = editor_generate_icon(index, scale, saturation, color_conversion_map); + } } p_theme->set_icon(editor_icons_names[index], SNAME("EditorIcons"), icon); @@ -331,13 +358,21 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = const float scale = (float)p_thumb_size / 32.0 * EDSCALE; for (int i = 0; i < editor_md_thumbs_count; i++) { const int index = editor_md_thumbs_indices[i]; - const bool is_exception = exceptions.has(editor_icons_names[index]); - Ref<ImageTexture> icon; - if (!p_dark_theme && !is_exception) { - icon = editor_generate_icon(index, scale, force_filter, icon_color_map); + + if (accent_color_icons.has(editor_icons_names[index])) { + icon = editor_generate_icon(index, scale, 1.0, accent_color_map); } else { - icon = editor_generate_icon(index, scale, force_filter); + float saturation = p_icon_saturation; + if (saturation_exceptions.has(editor_icons_names[index])) { + saturation = 1.0; + } + + if (conversion_exceptions.has(editor_icons_names[index])) { + icon = editor_generate_icon(index, scale, saturation); + } else { + icon = editor_generate_icon(index, scale, saturation, color_conversion_map); + } } p_theme->set_icon(editor_icons_names[index], SNAME("EditorIcons"), icon); @@ -358,6 +393,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color accent_color = EDITOR_GET("interface/theme/accent_color"); Color base_color = EDITOR_GET("interface/theme/base_color"); float contrast = EDITOR_GET("interface/theme/contrast"); + bool draw_extra_borders = EDITOR_GET("interface/theme/draw_extra_borders"); float icon_saturation = EDITOR_GET("interface/theme/icon_saturation"); float relationship_line_opacity = EDITOR_GET("interface/theme/relationship_line_opacity"); @@ -369,6 +405,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color preset_accent_color; Color preset_base_color; float preset_contrast = 0; + bool preset_draw_extra_borders = false; const float default_contrast = 0.3; @@ -405,6 +442,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { preset_base_color = Color(0.89, 0.86, 0.79); // A negative contrast rate looks better for light themes, since it better follows the natural order of UI "elevation". preset_contrast = -0.08; + } else if (preset == "Black (OLED)") { + preset_accent_color = Color(0.45, 0.75, 1.0); + preset_base_color = Color(0, 0, 0); + // The contrast rate value is irrelevant on a fully black theme. + preset_contrast = 0.0; + preset_draw_extra_borders = true; } else { // Default preset_accent_color = Color(0.44, 0.73, 0.98); preset_base_color = Color(0.21, 0.24, 0.29); @@ -415,15 +458,18 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { accent_color = preset_accent_color; base_color = preset_base_color; contrast = preset_contrast; + draw_extra_borders = preset_draw_extra_borders; EditorSettings::get_singleton()->set_initial_value("interface/theme/accent_color", accent_color); EditorSettings::get_singleton()->set_initial_value("interface/theme/base_color", base_color); EditorSettings::get_singleton()->set_initial_value("interface/theme/contrast", contrast); + EditorSettings::get_singleton()->set_initial_value("interface/theme/draw_extra_borders", draw_extra_borders); } EditorSettings::get_singleton()->set_manually("interface/theme/preset", preset); EditorSettings::get_singleton()->set_manually("interface/theme/accent_color", accent_color); EditorSettings::get_singleton()->set_manually("interface/theme/base_color", base_color); EditorSettings::get_singleton()->set_manually("interface/theme/contrast", contrast); + EditorSettings::get_singleton()->set_manually("interface/theme/draw_extra_borders", draw_extra_borders); // Colors bool dark_theme = EditorSettings::get_singleton()->is_dark_theme(); @@ -432,7 +478,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { if (dark_theme) { ImageLoaderSVG::set_forced_color_map(HashMap<Color, Color>()); } else { - ImageLoaderSVG::set_forced_color_map(EditorColorMap::get()); + ImageLoaderSVG::set_forced_color_map(EditorColorMap::get_color_conversion_map()); } #endif @@ -442,6 +488,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color dark_color_2 = base_color.lerp(Color(0, 0, 0, 1), contrast * 1.5).clamp(); const Color dark_color_3 = base_color.lerp(Color(0, 0, 0, 1), contrast * 2).clamp(); + // Only used when the Draw Extra Borders editor setting is enabled. + const Color extra_border_color_1 = Color(0.5, 0.5, 0.5); + const Color extra_border_color_2 = dark_theme ? Color(0.3, 0.3, 0.3) : Color(0.7, 0.7, 0.7); + const Color background_color = dark_color_2; // White (dark theme) or black (light theme), will be used to generate the rest of the colors @@ -454,7 +504,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color font_hover_color = mono_color.lerp(base_color, 0.125); const Color font_focus_color = mono_color.lerp(base_color, 0.125); const Color font_hover_pressed_color = font_hover_color.lerp(accent_color, 0.74); - const Color font_disabled_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.3); + const Color font_disabled_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.35); const Color font_readonly_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.65); const Color font_placeholder_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.6); const Color selection_color = accent_color * Color(1, 1, 1, 0.4); @@ -475,9 +525,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color highlight_color = Color(accent_color.r, accent_color.g, accent_color.b, 0.275); const Color disabled_highlight_color = highlight_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); - float prev_icon_saturation = theme->has_color(SNAME("icon_saturation"), SNAME("Editor")) ? theme->get_color(SNAME("icon_saturation"), SNAME("Editor")).r : 1.0; - - theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); // can't save single float in theme, so using color + // Can't save single float in theme, so using Color. + theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); theme->set_color("accent_color", "Editor", accent_color); theme->set_color("highlight_color", "Editor", highlight_color); theme->set_color("disabled_highlight_color", "Editor", disabled_highlight_color); @@ -518,7 +567,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color readonly_warning_color = error_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.25); if (!dark_theme) { - // Darken some colors to be readable on a light background + // Darken some colors to be readable on a light background. success_color = success_color.lerp(mono_color, 0.35); warning_color = warning_color.lerp(mono_color, 0.35); error_color = error_color.lerp(mono_color, 0.25); @@ -531,9 +580,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("readonly_color", "Editor", readonly_color); if (!dark_theme) { - theme->set_color("vulkan_color", "Editor", Color::hex(0xad1128ff)); + theme->set_color("highend_color", "Editor", Color::hex(0xad1128ff)); } else { - theme->set_color("vulkan_color", "Editor", Color(1.0, 0.0, 0.0)); + theme->set_color("highend_color", "Editor", Color(1.0, 0.0, 0.0)); } const int thumb_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); theme->set_constant("scale", "Editor", EDSCALE); @@ -541,22 +590,43 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("dark_theme", "Editor", dark_theme); theme->set_constant("color_picker_button_height", "Editor", 28 * EDSCALE); - // Register icons + font + // Register editor icons. + // If the settings are comparable to the old theme, then just copy them over. + // Otherwise, regenerate them. Also check if we need to regenerate "thumb" icons. + bool keep_old_icons = false; + bool regenerate_thumb_icons = true; + if (p_theme != nullptr) { + // We check editor scale, theme dark/light mode, icon saturation, and accent color. + + // That doesn't really work as expected, since theme constants are integers, and scales are floats. + // So this check will never work when changing between 100-199% values. + const float prev_scale = (float)p_theme->get_constant(SNAME("scale"), SNAME("Editor")); + const bool prev_dark_theme = (bool)p_theme->get_constant(SNAME("dark_theme"), SNAME("Editor")); + const Color prev_accent_color = p_theme->get_color(SNAME("accent_color"), SNAME("Editor")); + const float prev_icon_saturation = p_theme->get_color(SNAME("icon_saturation"), SNAME("Editor")).r; + + keep_old_icons = (Math::is_equal_approx(prev_scale, EDSCALE) && + prev_dark_theme == dark_theme && + prev_accent_color == accent_color && + prev_icon_saturation == icon_saturation); + + const double prev_thumb_size = (double)p_theme->get_constant(SNAME("thumb_size"), SNAME("Editor")); + + regenerate_thumb_icons = !Math::is_equal_approx(prev_thumb_size, thumb_size); + } - // The editor scale, icon color (dark_theme bool), icon saturation, and accent color has not changed, so we do not regenerate the icons. - if (p_theme != nullptr && fabs(p_theme->get_constant(SNAME("scale"), SNAME("Editor")) - EDSCALE) < 0.00001 && (bool)p_theme->get_constant(SNAME("dark_theme"), SNAME("Editor")) == dark_theme && prev_icon_saturation == icon_saturation && p_theme->get_color(SNAME("accent_color"), SNAME("Editor")) == accent_color) { - // Register already generated icons. + if (keep_old_icons) { for (int i = 0; i < editor_icons_count; i++) { theme->set_icon(editor_icons_names[i], SNAME("EditorIcons"), p_theme->get_icon(editor_icons_names[i], SNAME("EditorIcons"))); } } else { - editor_register_and_generate_icons(theme, dark_theme, thumb_size, false, icon_saturation); + editor_register_and_generate_icons(theme, dark_theme, icon_saturation, thumb_size, false); } - // Thumbnail size has changed, so we regenerate the medium sizes - if (p_theme != nullptr && fabs((double)p_theme->get_constant(SNAME("thumb_size"), SNAME("Editor")) - thumb_size) > 0.00001) { - editor_register_and_generate_icons(p_theme, dark_theme, thumb_size, true); + if (regenerate_thumb_icons) { + editor_register_and_generate_icons(theme, dark_theme, icon_saturation, thumb_size, true); } + // Register editor fonts. editor_register_fonts(theme); // Ensure borders are visible when using an editor scale below 100%. @@ -579,10 +649,19 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_widget = style_default->duplicate(); style_widget->set_default_margin_individual(widget_default_margin.x, widget_default_margin.y, widget_default_margin.x, widget_default_margin.y); style_widget->set_bg_color(dark_color_1); - style_widget->set_border_color(dark_color_2); + if (draw_extra_borders) { + style_widget->set_border_width_all(Math::round(EDSCALE)); + style_widget->set_border_color(extra_border_color_1); + } else { + style_widget->set_border_color(dark_color_2); + } Ref<StyleBoxFlat> style_widget_disabled = style_widget->duplicate(); - style_widget_disabled->set_border_color(disabled_color); + if (draw_extra_borders) { + style_widget_disabled->set_border_color(extra_border_color_2); + } else { + style_widget_disabled->set_border_color(disabled_color); + } style_widget_disabled->set_bg_color(disabled_bg_color); Ref<StyleBoxFlat> style_widget_focus = style_widget->duplicate(); @@ -595,7 +674,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_widget_hover = style_widget->duplicate(); style_widget_hover->set_bg_color(mono_color * Color(1, 1, 1, 0.11)); - style_widget_hover->set_border_color(mono_color * Color(1, 1, 1, 0.05)); + if (draw_extra_borders) { + style_widget_hover->set_border_color(extra_border_color_1); + } else { + style_widget_hover->set_border_color(mono_color * Color(1, 1, 1, 0.05)); + } // Style for windows, popups, etc.. Ref<StyleBoxFlat> style_popup = style_default->duplicate(); @@ -936,7 +1019,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_popup_menu->set_default_margin_individual(EDSCALE, 2 * EDSCALE, EDSCALE, 2 * EDSCALE); // Always display a border for PopupMenus so they can be distinguished from their background. style_popup_menu->set_border_width_all(EDSCALE); - style_popup_menu->set_border_color(dark_color_2); + if (draw_extra_borders) { + style_popup_menu->set_border_color(extra_border_color_2); + } else { + style_popup_menu->set_border_color(dark_color_2); + } theme->set_stylebox("panel", "PopupMenu", style_popup_menu); Ref<StyleBoxFlat> style_menu_hover = style_widget_hover->duplicate(); @@ -1056,7 +1143,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_tree_bg = style_default->duplicate(); // Make Trees easier to distinguish from other controls by using a darker background color. style_tree_bg->set_bg_color(dark_color_1.lerp(dark_color_2, 0.5)); - style_tree_bg->set_border_color(dark_color_3); + if (draw_extra_borders) { + style_tree_bg->set_border_width_all(Math::round(EDSCALE)); + style_tree_bg->set_border_color(extra_border_color_2); + } else { + style_tree_bg->set_border_color(dark_color_3); + } + theme->set_stylebox("panel", "Tree", style_tree_bg); // Tree @@ -1152,8 +1245,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // ItemList Ref<StyleBoxFlat> style_itemlist_bg = style_default->duplicate(); style_itemlist_bg->set_bg_color(dark_color_1); - style_itemlist_bg->set_border_width_all(border_width); - style_itemlist_bg->set_border_color(dark_color_3); + + if (draw_extra_borders) { + style_itemlist_bg->set_border_width_all(Math::round(EDSCALE)); + style_itemlist_bg->set_border_color(extra_border_color_2); + } else { + style_itemlist_bg->set_border_width_all(border_width); + style_itemlist_bg->set_border_color(dark_color_3); + } Ref<StyleBoxFlat> style_itemlist_cursor = style_default->duplicate(); style_itemlist_cursor->set_draw_center(false); @@ -1271,14 +1370,21 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // The original style_widget style has an extra 1 pixel offset that makes LineEdits not align with Buttons, // so this compensates for that. style_line_edit->set_default_margin(SIDE_TOP, style_line_edit->get_default_margin(SIDE_TOP) - 1 * EDSCALE); - // Add a bottom line to make LineEdits more visible, especially in sectioned inspectors - // such as the Project Settings. - style_line_edit->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); - style_line_edit->set_border_color(dark_color_2); + // Don't round the bottom corner to make the line look sharper. style_tab_selected->set_corner_radius(CORNER_BOTTOM_LEFT, 0); style_tab_selected->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); + if (draw_extra_borders) { + style_line_edit->set_border_width_all(Math::round(EDSCALE)); + style_line_edit->set_border_color(extra_border_color_1); + } else { + // Add a bottom line to make LineEdits more visible, especially in sectioned inspectors + // such as the Project Settings. + style_line_edit->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); + style_line_edit->set_border_color(dark_color_2); + } + Ref<StyleBoxFlat> style_line_edit_disabled = style_line_edit->duplicate(); style_line_edit_disabled->set_border_color(disabled_color); style_line_edit_disabled->set_bg_color(disabled_bg_color); @@ -1417,6 +1523,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("slider", "HSlider", make_flat_stylebox(dark_color_3, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width)); theme->set_stylebox("grabber_area", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width)); theme->set_stylebox("grabber_area_highlight", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2)); + theme->set_constant("grabber_offset", "HSlider", 0); // VSlider theme->set_icon("grabber", "VSlider", theme->get_icon(SNAME("GuiSliderGrabber"), SNAME("EditorIcons"))); @@ -1424,6 +1531,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("slider", "VSlider", make_flat_stylebox(dark_color_3, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width)); theme->set_stylebox("grabber_area", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width)); theme->set_stylebox("grabber_area_highlight", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0)); + theme->set_constant("grabber_offset", "VSlider", 0); // RichTextLabel theme->set_color("default_color", "RichTextLabel", font_color); @@ -1435,6 +1543,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("normal", "RichTextLabel", style_tree_bg); // Editor help. + Ref<StyleBoxFlat> style_editor_help = style_default->duplicate(); + style_editor_help->set_bg_color(dark_color_2); + style_editor_help->set_border_color(dark_color_3); + theme->set_stylebox("background", "EditorHelp", style_editor_help); + theme->set_color("title_color", "EditorHelp", accent_color); theme->set_color("headline_color", "EditorHelp", mono_color); theme->set_color("text_color", "EditorHelp", font_color); @@ -1447,9 +1560,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("link_color", "EditorHelp", accent_color.lerp(mono_color, 0.8)); theme->set_color("code_color", "EditorHelp", accent_color.lerp(mono_color, 0.6)); theme->set_color("kbd_color", "EditorHelp", accent_color.lerp(property_color, 0.6)); + theme->set_color("code_bg_color", "EditorHelp", dark_color_3); + theme->set_color("kbd_bg_color", "EditorHelp", dark_color_1); + theme->set_color("param_bg_color", "EditorHelp", dark_color_1); theme->set_constant("line_separation", "EditorHelp", Math::round(6 * EDSCALE)); theme->set_constant("table_h_separation", "EditorHelp", 16 * EDSCALE); theme->set_constant("table_v_separation", "EditorHelp", 6 * EDSCALE); + theme->set_constant("text_highlight_h_padding", "EditorHelp", 1 * EDSCALE); + theme->set_constant("text_highlight_v_padding", "EditorHelp", 2 * EDSCALE); // Panel theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4, corner_width)); @@ -1660,6 +1778,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("h_width", "ColorPicker", 30 * EDSCALE); theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE); theme->set_icon("screen_picker", "ColorPicker", theme->get_icon(SNAME("ColorPick"), SNAME("EditorIcons"))); + theme->set_icon("shape_circle", "ColorPicker", theme->get_icon(SNAME("PickerShapeCircle"), SNAME("EditorIcons"))); + theme->set_icon("shape_rect", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangle"), SNAME("EditorIcons"))); + theme->set_icon("shape_rect_wheel", "ColorPicker", theme->get_icon(SNAME("PickerShapeRectangleWheel"), SNAME("EditorIcons"))); theme->set_icon("add_preset", "ColorPicker", theme->get_icon(SNAME("Add"), SNAME("EditorIcons"))); theme->set_icon("sample_bg", "ColorPicker", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons"))); @@ -1742,7 +1863,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color safe_line_number_color = dark_theme ? (dim_color * Color(1, 1.2, 1, 1.5)) : Color(0, 0.4, 0, 0.75); const Color caret_color = mono_color; const Color caret_background_color = mono_color.inverted(); - const Color text_selected_color = dark_color_3; + const Color text_selected_color = Color(0, 0, 0, 0); const Color brace_mismatch_color = dark_theme ? error_color : Color(1, 0.08, 0, 1); const Color current_line_color = alpha1; const Color line_length_guideline_color = dark_theme ? base_color : background_color; @@ -1848,7 +1969,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<Theme> create_custom_theme(const Ref<Theme> p_theme) { Ref<Theme> theme = create_editor_theme(p_theme); - const String custom_theme_path = EditorSettings::get_singleton()->get("interface/theme/custom_theme"); + const String custom_theme_path = EDITOR_GET("interface/theme/custom_theme"); if (!custom_theme_path.is_empty()) { Ref<Theme> custom_theme = ResourceLoader::load(custom_theme_path); if (custom_theme.is_valid()) { diff --git a/editor/editor_themes.h b/editor/editor_themes.h index 37db8160fa..da5db95d0e 100644 --- a/editor/editor_themes.h +++ b/editor/editor_themes.h @@ -39,13 +39,18 @@ class EditorColorMap { // Godot Color values are used to avoid the ambiguity of strings // (where "#ffffff", "fff", and "white" are all equivalent). - static HashMap<Color, Color> editor_color_map; + static HashMap<Color, Color> color_conversion_map; + // The names of the icons to never convert, even if one of their colors + // are contained in the color map from above. + static HashSet<StringName> color_conversion_exceptions; public: static void create(); - static void add_color_pair(const String p_from_color, const String p_to_color); + static void add_conversion_color_pair(const String p_from_color, const String p_to_color); + static void add_conversion_exception(const StringName p_icon_name); - static HashMap<Color, Color> &get() { return editor_color_map; }; + static HashMap<Color, Color> &get_color_conversion_map() { return color_conversion_map; }; + static HashSet<StringName> &get_color_conversion_exceptions() { return color_conversion_exceptions; }; }; Ref<Theme> create_editor_theme(Ref<Theme> p_theme = nullptr); diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 6a5242f0c6..504c8f0432 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -78,19 +78,19 @@ void EditorToaster::_notification(int p_what) { // Change alpha over time. bool needs_update = false; for (const KeyValue<Control *, Toast> &element : toasts) { - Color modulate = element.key->get_modulate(); + Color modulate_fade = element.key->get_modulate(); // Change alpha over time. - if (element.value.popped && modulate.a < 1.0) { - modulate.a += delta * 3; - element.key->set_modulate(modulate); - } else if (!element.value.popped && modulate.a > 0.0) { - modulate.a -= delta * 2; - element.key->set_modulate(modulate); + if (element.value.popped && modulate_fade.a < 1.0) { + modulate_fade.a += delta * 3; + element.key->set_modulate(modulate_fade); + } else if (!element.value.popped && modulate_fade.a > 0.0) { + modulate_fade.a -= delta * 2; + element.key->set_modulate(modulate_fade); } // Hide element if it is not visible anymore. - if (modulate.a <= 0) { + if (modulate_fade.a <= 0) { if (element.key->is_visible()) { element.key->hide(); needs_update = true; @@ -231,7 +231,7 @@ void EditorToaster::_auto_hide_or_free_toasts() { // Delete the control right away (removed as child) as it might cause issues otherwise when iterative over the vbox_container children. for (unsigned int i = 0; i < to_delete.size(); i++) { vbox_container->remove_child(to_delete[i]); - to_delete[i]->queue_delete(); + to_delete[i]->queue_free(); toasts.erase(to_delete[i]); } @@ -317,7 +317,7 @@ void EditorToaster::_set_notifications_enabled(bool p_enabled) { void EditorToaster::_repop_old() { // Repop olds, up to max_temporary_count bool needs_update = false; - int visible = 0; + int visible_count = 0; for (int i = vbox_container->get_child_count() - 1; i >= 0; i--) { Control *control = Object::cast_to<Control>(vbox_container->get_child(i)); if (!control->is_visible()) { @@ -326,8 +326,8 @@ void EditorToaster::_repop_old() { toasts[control].popped = true; needs_update = true; } - visible++; - if (visible >= max_temporary_count) { + visible_count++; + if (visible_count >= max_temporary_count) { break; } } diff --git a/editor/editor_undo_redo_manager.cpp b/editor/editor_undo_redo_manager.cpp index 8c04a4d595..4bfa9b686c 100644 --- a/editor/editor_undo_redo_manager.cpp +++ b/editor/editor_undo_redo_manager.cpp @@ -33,6 +33,7 @@ #include "core/io/resource.h" #include "core/os/os.h" #include "core/templates/local_vector.h" +#include "editor/debugger/editor_debugger_node.h" #include "editor/editor_log.h" #include "editor/editor_node.h" #include "scene/main/node.h" @@ -109,9 +110,14 @@ EditorUndoRedoManager::History &EditorUndoRedoManager::get_history_for_object(Ob } void EditorUndoRedoManager::create_action_for_history(const String &p_name, int p_history_id, UndoRedo::MergeMode p_mode) { - pending_action.action_name = p_name; - pending_action.timestamp = OS::get_singleton()->get_unix_time(); - pending_action.merge_mode = p_mode; + if (pending_action.history_id != INVALID_HISTORY) { + // Nested action. + p_history_id = pending_action.history_id; + } else { + pending_action.action_name = p_name; + pending_action.timestamp = OS::get_singleton()->get_unix_time(); + pending_action.merge_mode = p_mode; + } if (p_history_id != INVALID_HISTORY) { pending_action.history_id = p_history_id; @@ -131,12 +137,12 @@ void EditorUndoRedoManager::create_action(const String &p_name, UndoRedo::MergeM void EditorUndoRedoManager::add_do_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount) { UndoRedo *undo_redo = get_history_for_object(p_object).undo_redo; - undo_redo->add_do_methodp(p_object, p_method, p_args, p_argcount); + undo_redo->add_do_method(Callable(p_object, p_method).bindp(p_args, p_argcount)); } void EditorUndoRedoManager::add_undo_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount) { UndoRedo *undo_redo = get_history_for_object(p_object).undo_redo; - undo_redo->add_undo_methodp(p_object, p_method, p_args, p_argcount); + undo_redo->add_undo_method(Callable(p_object, p_method).bindp(p_args, p_argcount)); } void EditorUndoRedoManager::_add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { @@ -228,6 +234,12 @@ void EditorUndoRedoManager::commit_action(bool p_execute) { history.undo_redo->commit_action(p_execute); history.redo_stack.clear(); + if (history.undo_redo->get_action_level() > 0) { + // Nested action. + is_committing = false; + return; + } + if (!history.undo_stack.is_empty()) { const Action &prev_action = history.undo_stack.back()->get(); if (pending_action.merge_mode != UndoRedo::MERGE_DISABLE && pending_action.merge_mode == prev_action.merge_mode && pending_action.action_name == prev_action.action_name) { @@ -241,6 +253,7 @@ void EditorUndoRedoManager::commit_action(bool p_execute) { history.undo_stack.push_back(pending_action); pending_action = Action(); is_committing = false; + emit_signal(SNAME("history_changed")); } bool EditorUndoRedoManager::is_committing_action() const { @@ -252,14 +265,14 @@ bool EditorUndoRedoManager::undo() { return false; } - History *selected_history = nullptr; + int selected_history = INVALID_HISTORY; double global_timestamp = 0; // Pick the history with greatest last action timestamp (either global or current scene). { History &history = get_or_create_history(GLOBAL_HISTORY); if (!history.undo_stack.is_empty()) { - selected_history = &history; + selected_history = history.id; global_timestamp = history.undo_stack.back()->get().timestamp; } } @@ -267,32 +280,44 @@ bool EditorUndoRedoManager::undo() { { History &history = get_or_create_history(EditorNode::get_editor_data().get_current_edited_scene_history_id()); if (!history.undo_stack.is_empty() && history.undo_stack.back()->get().timestamp > global_timestamp) { - selected_history = &history; + selected_history = history.id; } } - if (selected_history) { - Action action = selected_history->undo_stack.back()->get(); - selected_history->undo_stack.pop_back(); - selected_history->redo_stack.push_back(action); - return selected_history->undo_redo->undo(); + if (selected_history != INVALID_HISTORY) { + return undo_history(selected_history); } return false; } +bool EditorUndoRedoManager::undo_history(int p_id) { + ERR_FAIL_COND_V(p_id == INVALID_HISTORY, false); + History &history = get_or_create_history(p_id); + + Action action = history.undo_stack.back()->get(); + history.undo_stack.pop_back(); + history.redo_stack.push_back(action); + + bool success = history.undo_redo->undo(); + if (success) { + emit_signal(SNAME("version_changed")); + } + return success; +} + bool EditorUndoRedoManager::redo() { if (!has_redo()) { return false; } - History *selected_history = nullptr; + int selected_history = INVALID_HISTORY; double global_timestamp = INFINITY; // Pick the history with lowest last action timestamp (either global or current scene). { History &history = get_or_create_history(GLOBAL_HISTORY); if (!history.redo_stack.is_empty()) { - selected_history = &history; + selected_history = history.id; global_timestamp = history.redo_stack.back()->get().timestamp; } } @@ -300,19 +325,31 @@ bool EditorUndoRedoManager::redo() { { History &history = get_or_create_history(EditorNode::get_editor_data().get_current_edited_scene_history_id()); if (!history.redo_stack.is_empty() && history.redo_stack.back()->get().timestamp < global_timestamp) { - selected_history = &history; + selected_history = history.id; } } - if (selected_history) { - Action action = selected_history->redo_stack.back()->get(); - selected_history->redo_stack.pop_back(); - selected_history->undo_stack.push_back(action); - return selected_history->undo_redo->redo(); + if (selected_history != INVALID_HISTORY) { + return redo_history(selected_history); } return false; } +bool EditorUndoRedoManager::redo_history(int p_id) { + ERR_FAIL_COND_V(p_id == INVALID_HISTORY, false); + History &history = get_or_create_history(p_id); + + Action action = history.redo_stack.back()->get(); + history.redo_stack.pop_back(); + history.undo_stack.push_back(action); + + bool success = history.undo_redo->redo(); + if (success) { + emit_signal(SNAME("version_changed")); + } + return success; +} + void EditorUndoRedoManager::set_history_as_saved(int p_id) { History &history = get_or_create_history(p_id); history.saved_version = history.undo_redo->get_version(); @@ -352,6 +389,7 @@ void EditorUndoRedoManager::clear_history(bool p_increase_version, int p_idx) { if (!p_increase_version) { set_history_as_saved(p_idx); } + emit_signal(SNAME("history_changed")); return; } @@ -359,6 +397,7 @@ void EditorUndoRedoManager::clear_history(bool p_increase_version, int p_idx) { E.value.undo_redo->clear_history(p_increase_version); set_history_as_saved(E.key); } + emit_signal(SNAME("history_changed")); } String EditorUndoRedoManager::get_current_action_name() { @@ -434,6 +473,9 @@ void EditorUndoRedoManager::_bind_methods() { ClassDB::bind_method(D_METHOD("get_object_history_id", "object"), &EditorUndoRedoManager::get_history_id_for_object); ClassDB::bind_method(D_METHOD("get_history_undo_redo", "id"), &EditorUndoRedoManager::get_history_undo_redo); + ADD_SIGNAL(MethodInfo("history_changed")); + ADD_SIGNAL(MethodInfo("version_changed")); + BIND_ENUM_CONSTANT(GLOBAL_HISTORY); BIND_ENUM_CONSTANT(INVALID_HISTORY); } diff --git a/editor/editor_undo_redo_manager.h b/editor/editor_undo_redo_manager.h index c4d85daa22..60bcd059df 100644 --- a/editor/editor_undo_redo_manager.h +++ b/editor/editor_undo_redo_manager.h @@ -44,7 +44,6 @@ public: INVALID_HISTORY = -99, }; -private: struct Action { int history_id = INVALID_HISTORY; double timestamp = 0; @@ -60,6 +59,7 @@ private: List<Action> redo_stack; }; +private: HashMap<int, History> history_map; Action pending_action; @@ -114,7 +114,9 @@ public: bool is_committing_action() const; bool undo(); + bool undo_history(int p_id); bool redo(); + bool redo_history(int p_id); void clear_history(bool p_increase_version = true, int p_idx = INVALID_HISTORY); void set_history_as_saved(int p_idx); diff --git a/editor/editor_zoom_widget.cpp b/editor/editor_zoom_widget.cpp index 88e99d9b30..8e820f41ee 100644 --- a/editor/editor_zoom_widget.cpp +++ b/editor/editor_zoom_widget.cpp @@ -161,13 +161,19 @@ void EditorZoomWidget::_bind_methods() { ADD_SIGNAL(MethodInfo("zoom_changed", PropertyInfo(Variant::FLOAT, "zoom"))); } +void EditorZoomWidget::set_shortcut_context(Node *p_node) const { + zoom_minus->set_shortcut_context(p_node); + zoom_plus->set_shortcut_context(p_node); + zoom_reset->set_shortcut_context(p_node); +} + EditorZoomWidget::EditorZoomWidget() { // Zoom buttons zoom_minus = memnew(Button); zoom_minus->set_flat(true); add_child(zoom_minus); zoom_minus->connect("pressed", callable_mp(this, &EditorZoomWidget::_button_zoom_minus)); - zoom_minus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_minus", TTR("Zoom Out"), KeyModifierMask::CMD_OR_CTRL | Key::MINUS)); + zoom_minus->set_shortcut(ED_SHORTCUT_ARRAY("canvas_item_editor/zoom_minus", TTR("Zoom Out"), { int32_t(KeyModifierMask::CMD_OR_CTRL | Key::MINUS), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_SUBTRACT) })); zoom_minus->set_shortcut_context(this); zoom_minus->set_focus_mode(FOCUS_NONE); @@ -189,7 +195,7 @@ EditorZoomWidget::EditorZoomWidget() { zoom_plus->set_flat(true); add_child(zoom_plus); zoom_plus->connect("pressed", callable_mp(this, &EditorZoomWidget::_button_zoom_plus)); - zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom In"), KeyModifierMask::CMD_OR_CTRL | Key::EQUAL)); // Usually direct access key for PLUS + zoom_plus->set_shortcut(ED_SHORTCUT_ARRAY("canvas_item_editor/zoom_plus", TTR("Zoom In"), { int32_t(KeyModifierMask::CMD_OR_CTRL | Key::EQUAL), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_ADD) })); zoom_plus->set_shortcut_context(this); zoom_plus->set_focus_mode(FOCUS_NONE); diff --git a/editor/editor_zoom_widget.h b/editor/editor_zoom_widget.h index 4690a57a2b..995b9e1808 100644 --- a/editor/editor_zoom_widget.h +++ b/editor/editor_zoom_widget.h @@ -57,6 +57,8 @@ public: float get_zoom(); void set_zoom(float p_zoom); void set_zoom_by_increments(int p_increment_count, bool p_integer_only = false); + // Sets the shortcut context for the zoom buttons. By default their context is this EditorZoomWidget control. + void set_shortcut_context(Node *p_node) const; }; #endif // EDITOR_ZOOM_WIDGET_H diff --git a/editor/event_listener_line_edit.cpp b/editor/event_listener_line_edit.cpp new file mode 100644 index 0000000000..1b081f9091 --- /dev/null +++ b/editor/event_listener_line_edit.cpp @@ -0,0 +1,204 @@ +/*************************************************************************/ +/* event_listener_line_edit.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor/event_listener_line_edit.h" + +#include "core/input/input_map.h" + +// Maps to 2*axis if value is neg, or 2*axis+1 if value is pos. +static const char *_joy_axis_descriptions[(size_t)JoyAxis::MAX * 2] = { + TTRC("Left Stick Left, Joystick 0 Left"), + TTRC("Left Stick Right, Joystick 0 Right"), + TTRC("Left Stick Up, Joystick 0 Up"), + TTRC("Left Stick Down, Joystick 0 Down"), + TTRC("Right Stick Left, Joystick 1 Left"), + TTRC("Right Stick Right, Joystick 1 Right"), + TTRC("Right Stick Up, Joystick 1 Up"), + TTRC("Right Stick Down, Joystick 1 Down"), + TTRC("Joystick 2 Left"), + TTRC("Left Trigger, Sony L2, Xbox LT, Joystick 2 Right"), + TTRC("Joystick 2 Up"), + TTRC("Right Trigger, Sony R2, Xbox RT, Joystick 2 Down"), + TTRC("Joystick 3 Left"), + TTRC("Joystick 3 Right"), + TTRC("Joystick 3 Up"), + TTRC("Joystick 3 Down"), + TTRC("Joystick 4 Left"), + TTRC("Joystick 4 Right"), + TTRC("Joystick 4 Up"), + TTRC("Joystick 4 Down"), +}; + +String EventListenerLineEdit::get_event_text(const Ref<InputEvent> &p_event, bool p_include_device) { + ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEvent"); + + String text = p_event->as_text(); + + Ref<InputEventKey> key = p_event; + if (key.is_valid() && key->is_command_or_control_autoremap()) { +#ifdef MACOS_ENABLED + text = text.replace("Command", "Command/Ctrl"); +#else + text = text.replace("Ctrl", "Command/Ctrl"); +#endif + } + Ref<InputEventMouse> mouse = p_event; + Ref<InputEventJoypadMotion> jp_motion = p_event; + Ref<InputEventJoypadButton> jp_button = p_event; + if (jp_motion.is_valid()) { + // Joypad motion events will display slightly differently than what the event->as_text() provides. See #43660. + String desc = TTR("Unknown Joypad Axis"); + if (jp_motion->get_axis() < JoyAxis::MAX) { + desc = RTR(_joy_axis_descriptions[2 * (size_t)jp_motion->get_axis() + (jp_motion->get_axis_value() < 0 ? 0 : 1)]); + } + + text = vformat("Joypad Axis %s %s (%s)", itos((int64_t)jp_motion->get_axis()), jp_motion->get_axis_value() < 0 ? "-" : "+", desc); + } + if (p_include_device && (mouse.is_valid() || jp_button.is_valid() || jp_motion.is_valid())) { + String device_string = get_device_string(p_event->get_device()); + text += vformat(" - %s", device_string); + } + + return text; +} + +String EventListenerLineEdit::get_device_string(int p_device) { + if (p_device == InputMap::ALL_DEVICES) { + return TTR("All Devices"); + } + return TTR("Device") + " " + itos(p_device); +} + +bool EventListenerLineEdit::_is_event_allowed(const Ref<InputEvent> &p_event) const { + const Ref<InputEventMouseButton> mb = p_event; + const Ref<InputEventKey> k = p_event; + const Ref<InputEventJoypadButton> jb = p_event; + const Ref<InputEventJoypadMotion> jm = p_event; + + return (mb.is_valid() && (allowed_input_types & INPUT_MOUSE_BUTTON)) || + (k.is_valid() && (allowed_input_types & INPUT_KEY)) || + (jb.is_valid() && (allowed_input_types & INPUT_JOY_BUTTON)) || + (jm.is_valid() && (allowed_input_types & INPUT_JOY_MOTION)); +} + +void EventListenerLineEdit::gui_input(const Ref<InputEvent> &p_event) { + const Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid()) { + LineEdit::gui_input(p_event); + return; + } + + // Allow mouse button click on the clear button without being treated as an event. + const Ref<InputEventMouseButton> b = p_event; + if (b.is_valid() && _is_over_clear_button(b->get_position())) { + LineEdit::gui_input(p_event); + return; + } + + // First event will be an event which is used to focus this control - i.e. a mouse click, or a tab press. + // Ignore the first one so that clicking into the LineEdit does not override the current event. + // Ignore is reset to true when the control is unfocused. + // This class also specially handles grab_focus() calls. + if (ignore_next_event) { + ignore_next_event = false; + return; + } + + accept_event(); + if (!p_event->is_pressed() || p_event->is_echo() || p_event->is_match(event) || !_is_event_allowed(p_event)) { + return; + } + + event = p_event; + set_text(get_event_text(event, false)); + emit_signal("event_changed", event); +} + +void EventListenerLineEdit::_on_text_changed(const String &p_text) { + if (p_text.is_empty()) { + clear_event(); + } +} + +void EventListenerLineEdit::_on_focus() { + set_placeholder(TTR("Listening for input...")); +} + +void EventListenerLineEdit::_on_unfocus() { + ignore_next_event = true; + set_placeholder(TTR("Filter by event...")); +} + +Ref<InputEvent> EventListenerLineEdit::get_event() const { + return event; +} + +void EventListenerLineEdit::clear_event() { + if (event.is_valid()) { + event = Ref<InputEvent>(); + set_text(""); + emit_signal("event_changed", event); + } +} + +void EventListenerLineEdit::set_allowed_input_types(int input_types) { + allowed_input_types = input_types; +} + +int EventListenerLineEdit::get_allowed_input_types() const { + return allowed_input_types; +} + +void EventListenerLineEdit::grab_focus() { + // If we grab focus through code, we don't need to ignore the first event! + ignore_next_event = false; + Control::grab_focus(); +} + +void EventListenerLineEdit::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + connect("text_changed", callable_mp(this, &EventListenerLineEdit::_on_text_changed)); + connect("focus_entered", callable_mp(this, &EventListenerLineEdit::_on_focus)); + connect("focus_exited", callable_mp(this, &EventListenerLineEdit::_on_unfocus)); + set_right_icon(get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons"))); + set_clear_button_enabled(true); + } break; + } +} + +void EventListenerLineEdit::_bind_methods() { + ADD_SIGNAL(MethodInfo("event_changed", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); +} + +EventListenerLineEdit::EventListenerLineEdit() { + set_caret_blink_enabled(false); + set_placeholder(TTR("Filter by event...")); +} diff --git a/editor/event_listener_line_edit.h b/editor/event_listener_line_edit.h new file mode 100644 index 0000000000..487efbc368 --- /dev/null +++ b/editor/event_listener_line_edit.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* event_listener_line_edit.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EVENT_LISTENER_LINE_EDIT_H +#define EVENT_LISTENER_LINE_EDIT_H + +#include "scene/gui/line_edit.h" + +enum InputType { + INPUT_KEY = 1, + INPUT_MOUSE_BUTTON = 2, + INPUT_JOY_BUTTON = 4, + INPUT_JOY_MOTION = 8 +}; + +class EventListenerLineEdit : public LineEdit { + GDCLASS(EventListenerLineEdit, LineEdit) + + int allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION; + bool ignore_next_event = true; + bool share_keycodes = false; + Ref<InputEvent> event; + + bool _is_event_allowed(const Ref<InputEvent> &p_event) const; + + void gui_input(const Ref<InputEvent> &p_event) override; + void _on_text_changed(const String &p_text); + + void _on_focus(); + void _on_unfocus(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + static String get_event_text(const Ref<InputEvent> &p_event, bool p_include_device); + static String get_device_string(int p_device); + + Ref<InputEvent> get_event() const; + void clear_event(); + + void set_allowed_input_types(int input_types); + int get_allowed_input_types() const; + + void grab_focus(); + +public: + EventListenerLineEdit(); +}; + +#endif // EVENT_LISTENER_LINE_EDIT_H diff --git a/editor/export/editor_export.cpp b/editor/export/editor_export.cpp index 29b6a5e546..c2aa27b34d 100644 --- a/editor/export/editor_export.cpp +++ b/editor/export/editor_export.cpp @@ -124,7 +124,7 @@ void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, in } String EditorExportPlatform::test_etc2() const { - const bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2"); + const bool etc2_supported = GLOBAL_GET("rendering/textures/vram_compression/import_etc2"); if (!etc2_supported) { return TTR("Target platform requires 'ETC2' texture compression. Enable 'Import Etc 2' in Project Settings."); diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index bcc85570ed..7c5c7da2ef 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -77,7 +77,7 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) } else { p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER); p_log->add_text(" "); - p_log->add_text(TTR("Completed sucessfully.")); + p_log->add_text(TTR("Completed successfully.")); if (msg_count > 0) { has_messages = true; } @@ -136,16 +136,16 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) } void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) { - String host = EditorSettings::get_singleton()->get("network/debug/remote_host"); - int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); + String host = EDITOR_GET("network/debug/remote_host"); + int remote_port = (int)EDITOR_GET("network/debug/remote_port"); if (p_flags & DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST) { host = "localhost"; } if (p_flags & DEBUG_FLAG_DUMB_CLIENT) { - int port = EditorSettings::get_singleton()->get("filesystem/file_server/port"); - String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password"); + int port = EDITOR_GET("filesystem/file_server/port"); + String passwd = EDITOR_GET("filesystem/file_server/password"); r_flags.push_back("--remote-fs"); r_flags.push_back(host + ":" + itos(port)); if (!passwd.is_empty()) { @@ -176,7 +176,7 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) } } - if (p_flags & DEBUG_FLAG_VIEW_COLLISONS) { + if (p_flags & DEBUG_FLAG_VIEW_COLLISIONS) { r_flags.push_back("--debug-collisions"); } @@ -710,7 +710,7 @@ String EditorExportPlatform::_export_customize(const String &p_path, LocalVector if (type == "PackedScene") { // Its a scene. Ref<PackedScene> ps = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_FAIL_COND_V(ps.is_null(), p_path); - Node *node = ps->instantiate(); + Node *node = ps->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); // Make sure the child scene root gets the correct inheritance chain. ERR_FAIL_COND_V(node == nullptr, p_path); if (customize_scenes_plugins.size()) { for (uint32_t i = 0; i < customize_scenes_plugins.size(); i++) { @@ -813,7 +813,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & continue; } - String autoload_path = ProjectSettings::get_singleton()->get(pi.name); + String autoload_path = GLOBAL_GET(pi.name); if (autoload_path.begins_with("*")) { autoload_path = autoload_path.substr(1); @@ -1241,8 +1241,8 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } // Store icon and splash images directly, they need to bypass the import system and be loaded as images - String icon = ProjectSettings::get_singleton()->get("application/config/icon"); - String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image"); + String icon = GLOBAL_GET("application/config/icon"); + String splash = GLOBAL_GET("application/boot_splash/image"); if (!icon.is_empty() && FileAccess::exists(icon)) { Vector<uint8_t> array = FileAccess::get_file_as_array(icon); err = p_func(p_udata, icon, array, idx, total, enc_in_filters, enc_ex_filters, key); @@ -1277,7 +1277,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & // Store text server data if it is supported. if (TS->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { - bool use_data = ProjectSettings::get_singleton()->get("internationalization/locale/include_text_server_data"); + bool use_data = GLOBAL_GET("internationalization/locale/include_text_server_data"); if (use_data) { // Try using user provided data file. String ts_data = "res://" + TS->get_support_data_filename(); @@ -1569,16 +1569,16 @@ Error EditorExportPlatform::export_zip(const Ref<EditorExportPreset> &p_preset, } void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags) { - String host = EditorSettings::get_singleton()->get("network/debug/remote_host"); - int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); + String host = EDITOR_GET("network/debug/remote_host"); + int remote_port = (int)EDITOR_GET("network/debug/remote_port"); if (p_flags & DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST) { host = "localhost"; } if (p_flags & DEBUG_FLAG_DUMB_CLIENT) { - int port = EditorSettings::get_singleton()->get("filesystem/file_server/port"); - String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password"); + int port = EDITOR_GET("filesystem/file_server/port"); + String passwd = EDITOR_GET("filesystem/file_server/password"); r_flags.push_back("--remote-fs"); r_flags.push_back(host + ":" + itos(port)); if (!passwd.is_empty()) { @@ -1609,7 +1609,7 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags } } - if (p_flags & DEBUG_FLAG_VIEW_COLLISONS) { + if (p_flags & DEBUG_FLAG_VIEW_COLLISIONS) { r_flags.push_back("--debug-collisions"); } diff --git a/editor/export/editor_export_platform.h b/editor/export/editor_export_platform.h index 93bc54284f..5db79b98d1 100644 --- a/editor/export/editor_export_platform.h +++ b/editor/export/editor_export_platform.h @@ -144,6 +144,7 @@ public: }; virtual Ref<EditorExportPreset> create_preset(); + virtual bool is_executable(const String &p_path) const { return false; } virtual void clear_messages() { messages.clear(); } virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) { @@ -210,7 +211,7 @@ public: DEBUG_FLAG_DUMB_CLIENT = 1, DEBUG_FLAG_REMOTE_DEBUG = 2, DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST = 4, - DEBUG_FLAG_VIEW_COLLISONS = 8, + DEBUG_FLAG_VIEW_COLLISIONS = 8, DEBUG_FLAG_VIEW_NAVIGATION = 16, }; diff --git a/editor/export/editor_export_platform_pc.cpp b/editor/export/editor_export_platform_pc.cpp index 8538414523..9de2f94900 100644 --- a/editor/export/editor_export_platform_pc.cpp +++ b/editor/export/editor_export_platform_pc.cpp @@ -146,9 +146,16 @@ Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_ return ERR_FILE_NOT_FOUND; } + String wrapper_template_path = template_path.get_basename() + "_console.exe"; + int con_wrapper_mode = p_preset->get("debug/export_console_script"); + bool copy_wrapper = (con_wrapper_mode == 1 && p_debug) || (con_wrapper_mode == 2); + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); da->make_dir_recursive(p_path.get_base_dir()); Error err = da->copy(template_path, p_path, get_chmod_flags()); + if (err == OK && copy_wrapper && FileAccess::exists(wrapper_template_path)) { + err = da->copy(wrapper_template_path, p_path.get_basename() + ".console.exe", get_chmod_flags()); + } if (err != OK) { add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template.")); } @@ -185,10 +192,12 @@ Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path); String target_path; if (so_files[i].target.is_empty()) { - target_path = p_path.get_base_dir().path_join(src_path.get_file()); + target_path = p_path.get_base_dir(); } else { - target_path = p_path.get_base_dir().path_join(so_files[i].target).path_join(src_path.get_file()); + target_path = p_path.get_base_dir().path_join(so_files[i].target); + da->make_dir_recursive(target_path); } + target_path = target_path.path_join(src_path.get_file()); if (da->dir_exists(src_path)) { err = da->make_dir_recursive(target_path); diff --git a/editor/export/editor_export_plugin.cpp b/editor/export/editor_export_plugin.cpp index 971ea579cc..78d4f93dfe 100644 --- a/editor/export/editor_export_plugin.cpp +++ b/editor/export/editor_export_plugin.cpp @@ -142,10 +142,8 @@ void EditorExportPlugin::_export_end_script() { bool EditorExportPlugin::_begin_customize_resources(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) const { bool ret = false; - if (GDVIRTUAL_CALL(_begin_customize_resources, p_platform, p_features, ret)) { - return ret; - } - return false; + GDVIRTUAL_CALL(_begin_customize_resources, p_platform, p_features, ret); + return ret; } Ref<Resource> EditorExportPlugin::_customize_resource(const Ref<Resource> &p_resource, const String &p_path) { @@ -158,10 +156,8 @@ Ref<Resource> EditorExportPlugin::_customize_resource(const Ref<Resource> &p_res bool EditorExportPlugin::_begin_customize_scenes(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) const { bool ret = false; - if (GDVIRTUAL_CALL(_begin_customize_scenes, p_platform, p_features, ret)) { - return ret; - } - return false; + GDVIRTUAL_CALL(_begin_customize_scenes, p_platform, p_features, ret); + return ret; } Node *EditorExportPlugin::_customize_scene(Node *p_root, const String &p_path) { diff --git a/editor/export/export_template_manager.cpp b/editor/export/export_template_manager.cpp index ceb5b63293..84766a5bef 100644 --- a/editor/export/export_template_manager.cpp +++ b/editor/export/export_template_manager.cpp @@ -40,6 +40,7 @@ #include "editor/editor_settings.h" #include "editor/progress_dialog.h" #include "scene/gui/file_dialog.h" +#include "scene/gui/menu_button.h" #include "scene/gui/separator.h" #include "scene/gui/tree.h" #include "scene/main/http_request.h" @@ -265,9 +266,9 @@ void ExportTemplateManager::_refresh_mirrors_completed(int p_status, int p_code, mirrors_available = false; - Dictionary data = json.get_data(); - if (data.has("mirrors")) { - Array mirrors = data["mirrors"]; + Dictionary mirror_data = json.get_data(); + if (mirror_data.has("mirrors")) { + Array mirrors = mirror_data["mirrors"]; for (int i = 0; i < mirrors.size(); i++) { Dictionary m = mirrors[i]; @@ -401,17 +402,17 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_ String file = String::utf8(fname); if (file.ends_with("version.txt")) { - Vector<uint8_t> data; - data.resize(info.uncompressed_size); + Vector<uint8_t> uncomp_data; + uncomp_data.resize(info.uncompressed_size); // Read. unzOpenCurrentFile(pkg); - ret = unzReadCurrentFile(pkg, data.ptrw(), data.size()); + ret = unzReadCurrentFile(pkg, uncomp_data.ptrw(), uncomp_data.size()); ERR_BREAK_MSG(ret < 0, vformat("An error occurred while attempting to read from file: %s. This file will not be used.", file)); unzCloseCurrentFile(pkg); String data_str; - data_str.parse_utf8((const char *)data.ptr(), data.size()); + data_str.parse_utf8((const char *)uncomp_data.ptr(), uncomp_data.size()); data_str = data_str.strip_edges(); // Version number should be of the form major.minor[.patch].status[.module_config] @@ -473,12 +474,12 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_ continue; } - Vector<uint8_t> data; - data.resize(info.uncompressed_size); + Vector<uint8_t> uncomp_data; + uncomp_data.resize(info.uncompressed_size); // Read unzOpenCurrentFile(pkg); - ret = unzReadCurrentFile(pkg, data.ptrw(), data.size()); + ret = unzReadCurrentFile(pkg, uncomp_data.ptrw(), uncomp_data.size()); ERR_BREAK_MSG(ret < 0, vformat("An error occurred while attempting to read from file: %s. This file will not be used.", file)); unzCloseCurrentFile(pkg); @@ -512,7 +513,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_ ERR_CONTINUE_MSG(true, "Can't open file from path '" + String(to_write) + "'."); } - f->store_buffer(data.ptr(), data.size()); + f->store_buffer(uncomp_data.ptr(), uncomp_data.size()); f.unref(); // close file. #ifndef WINDOWS_ENABLED FileAccess::set_unix_permissions(to_write, (info.external_fa >> 16) & 0x01FF); @@ -714,12 +715,12 @@ Error ExportTemplateManager::install_android_template_from_file(const String &p_ String base_dir = path.get_base_dir(); if (!path.ends_with("/")) { - Vector<uint8_t> data; - data.resize(info.uncompressed_size); + Vector<uint8_t> uncomp_data; + uncomp_data.resize(info.uncompressed_size); // Read. unzOpenCurrentFile(pkg); - unzReadCurrentFile(pkg, data.ptrw(), data.size()); + unzReadCurrentFile(pkg, uncomp_data.ptrw(), uncomp_data.size()); unzCloseCurrentFile(pkg); if (!dirs_tested.has(base_dir)) { @@ -730,7 +731,7 @@ Error ExportTemplateManager::install_android_template_from_file(const String &p_ String to_write = String("res://android/build").path_join(path); Ref<FileAccess> f = FileAccess::open(to_write, FileAccess::WRITE); if (f.is_valid()) { - f->store_buffer(data.ptr(), data.size()); + f->store_buffer(uncomp_data.ptr(), uncomp_data.size()); f.unref(); // close file. #ifndef WINDOWS_ENABLED FileAccess::set_unix_permissions(to_write, (info.external_fa >> 16) & 0x01FF); diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index 8c67885971..f5c5aafb5d 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -37,9 +37,16 @@ #include "editor/editor_node.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/export/editor_export.h" +#include "scene/gui/check_box.h" #include "scene/gui/check_button.h" +#include "scene/gui/item_list.h" #include "scene/gui/link_button.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/option_button.h" +#include "scene/gui/split_container.h" +#include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" void ProjectExportDialog::_theme_changed() { @@ -94,7 +101,7 @@ void ProjectExportDialog::_add_preset(int p_platform) { Ref<EditorExportPreset> preset = EditorExport::get_singleton()->get_export_platform(p_platform)->create_preset(); ERR_FAIL_COND(!preset.is_valid()); - String name = EditorExport::get_singleton()->get_export_platform(p_platform)->get_name(); + String preset_name = EditorExport::get_singleton()->get_export_platform(p_platform)->get_name(); bool make_runnable = true; int attempt = 1; while (true) { @@ -105,7 +112,7 @@ void ProjectExportDialog::_add_preset(int p_platform) { if (p->get_platform() == preset->get_platform() && p->is_runnable()) { make_runnable = false; } - if (p->get_name() == name) { + if (p->get_name() == preset_name) { valid = false; break; } @@ -116,10 +123,10 @@ void ProjectExportDialog::_add_preset(int p_platform) { } attempt++; - name = EditorExport::get_singleton()->get_export_platform(p_platform)->get_name() + " " + itos(attempt); + preset_name = EditorExport::get_singleton()->get_export_platform(p_platform)->get_name() + " " + itos(attempt); } - preset->set_name(name); + preset->set_name(preset_name); if (make_runnable) { preset->set_runnable(make_runnable); } @@ -154,12 +161,12 @@ void ProjectExportDialog::_update_presets() { current_idx = i; } - String name = preset->get_name(); + String preset_name = preset->get_name(); if (preset->is_runnable()) { - name += " (" + TTR("Runnable") + ")"; + preset_name += " (" + TTR("Runnable") + ")"; } preset->update_files_to_export(); - presets->add_item(name, preset->get_platform()->get_logo()); + presets->add_item(preset_name, preset->get_platform()->get_logo()); } if (current_idx != -1) { @@ -552,7 +559,7 @@ void ProjectExportDialog::_duplicate_preset() { Ref<EditorExportPreset> preset = current->get_platform()->create_preset(); ERR_FAIL_COND(!preset.is_valid()); - String name = current->get_name() + " (copy)"; + String preset_name = current->get_name() + " (copy)"; bool make_runnable = true; while (true) { bool valid = true; @@ -562,7 +569,7 @@ void ProjectExportDialog::_duplicate_preset() { if (p->get_platform() == preset->get_platform() && p->is_runnable()) { make_runnable = false; } - if (p->get_name() == name) { + if (p->get_name() == preset_name) { valid = false; break; } @@ -572,10 +579,10 @@ void ProjectExportDialog::_duplicate_preset() { break; } - name += " (copy)"; + preset_name += " (copy)"; } - preset->set_name(name); + preset->set_name(preset_name); if (make_runnable) { preset->set_runnable(make_runnable); } @@ -865,10 +872,10 @@ void ProjectExportDialog::_validate_export_path(const String &p_path) { if (invalid_path) { export_project->get_ok_button()->set_disabled(true); - export_project->get_line_edit()->disconnect("text_submitted", Callable(export_project, "_file_submitted")); + export_project->get_line_edit()->disconnect("text_submitted", callable_mp(export_project, &EditorFileDialog::_file_submitted)); } else { export_project->get_ok_button()->set_disabled(false); - export_project->get_line_edit()->connect("text_submitted", Callable(export_project, "_file_submitted")); + export_project->get_line_edit()->connect("text_submitted", callable_mp(export_project, &EditorFileDialog::_file_submitted)); } } @@ -901,9 +908,9 @@ void ProjectExportDialog::_export_project() { // with _validate_export_path. // FIXME: This is a hack, we should instead change EditorFileDialog to allow // disabling validation by the "text_submitted" signal. - if (!export_project->get_line_edit()->is_connected("text_submitted", Callable(export_project, "_file_submitted"))) { + if (!export_project->get_line_edit()->is_connected("text_submitted", callable_mp(export_project, &EditorFileDialog::_file_submitted))) { export_project->get_ok_button()->set_disabled(false); - export_project->get_line_edit()->connect("text_submitted", Callable(export_project, "_file_submitted")); + export_project->get_line_edit()->connect("text_submitted", callable_mp(export_project, &EditorFileDialog::_file_submitted)); } export_project->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); @@ -945,8 +952,8 @@ void ProjectExportDialog::_export_all_dialog_action(const String &p_str) { } void ProjectExportDialog::_export_all(bool p_debug) { - String mode = p_debug ? TTR("Debug") : TTR("Release"); - EditorProgress ep("exportall", TTR("Exporting All") + " " + mode, EditorExport::get_singleton()->get_export_preset_count(), true); + String export_target = p_debug ? TTR("Debug") : TTR("Release"); + EditorProgress ep("exportall", TTR("Exporting All") + " " + export_target, EditorExport::get_singleton()->get_export_preset_count(), true); bool show_dialog = false; result_dialog_log->clear(); @@ -1015,9 +1022,7 @@ ProjectExportDialog::ProjectExportDialog() { preset_vb->add_child(mc); mc->set_v_size_flags(Control::SIZE_EXPAND_FILL); presets = memnew(ItemList); -#ifndef _MSC_VER -#warning must reimplement drag forward -#endif + // TODO: Must reimplement drag forwarding. //presets->set_drag_forwarding(this); mc->add_child(presets); presets->connect("item_selected", callable_mp(this, &ProjectExportDialog::_edit_preset)); @@ -1292,7 +1297,7 @@ ProjectExportDialog::ProjectExportDialog() { // If no default set, use project name if (default_filename.is_empty()) { // If no project name defined, use a sane default - default_filename = ProjectSettings::get_singleton()->get("application/config/name"); + default_filename = GLOBAL_GET("application/config/name"); if (default_filename.is_empty()) { default_filename = "UnnamedProject"; } diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 19b4932d3d..8df5808b11 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -42,6 +42,7 @@ #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/import/resource_importer_scene.h" #include "editor/import_dock.h" #include "editor/scene_create_dialog.h" #include "editor/scene_tree_dock.h" @@ -106,7 +107,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory // Create all items for the files in the subdirectory. if (display_mode == DISPLAY_MODE_TREE_ONLY) { - String main_scene = ProjectSettings::get_singleton()->get("application/run/main_scene"); + String main_scene = GLOBAL_GET("application/run/main_scene"); // Build the list of the files to display. List<FileInfo> file_list; @@ -218,11 +219,11 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo TreeItem *root = tree->create_item(); // Handles the favorites. - TreeItem *favorites = tree->create_item(root); - favorites->set_icon(0, get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); - favorites->set_text(0, TTR("Favorites:")); - favorites->set_metadata(0, "Favorites"); - favorites->set_collapsed(p_uncollapsed_paths.find("Favorites") < 0); + TreeItem *favorites_item = tree->create_item(root); + favorites_item->set_icon(0, get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); + favorites_item->set_text(0, TTR("Favorites:")); + favorites_item->set_metadata(0, "Favorites"); + favorites_item->set_collapsed(p_uncollapsed_paths.find("Favorites") < 0); Vector<String> favorite_paths = EditorSettings::get_singleton()->get_favorites(); @@ -272,7 +273,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo } if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { - TreeItem *ti = tree->create_item(favorites); + TreeItem *ti = tree->create_item(favorites_item); ti->set_text(0, text); ti->set_icon(0, icon); ti->set_icon_modulate(0, color); @@ -383,7 +384,7 @@ void FileSystemDock::_notification(int p_what) { current_path->connect("text_submitted", callable_mp(this, &FileSystemDock::_navigate_to_path).bind(false)); - always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); + always_show_folders = bool(EDITOR_GET("docks/filesystem/always_show_folders")); set_file_list_display_mode(FileSystemDock::FILE_LIST_DISPLAY_LIST); @@ -464,7 +465,7 @@ void FileSystemDock::_notification(int p_what) { file_list_button_sort->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons"))); // Update always show folders. - bool new_always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); + bool new_always_show_folders = bool(EDITOR_GET("docks/filesystem/always_show_folders")); if (new_always_show_folders != always_show_folders) { always_show_folders = new_always_show_folders; _update_file_list(true); @@ -511,7 +512,15 @@ void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_s } } -String FileSystemDock::get_selected_path() const { +Vector<String> FileSystemDock::get_selected_paths() const { + return _tree_get_selected(false); +} + +String FileSystemDock::get_current_path() const { + return path; +} + +String FileSystemDock::get_current_directory() const { if (path.ends_with("/")) { return path; } else { @@ -519,10 +528,6 @@ String FileSystemDock::get_selected_path() const { } } -String FileSystemDock::get_current_path() const { - return path; -} - void FileSystemDock::_set_current_path_text(const String &p_path) { if (p_path == "Favorites") { current_path->set_text(TTR("Favorites")); @@ -743,7 +748,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { String directory = path; String file = ""; - int thumbnail_size = EditorSettings::get_singleton()->get("docks/filesystem/thumbnail_size"); + int thumbnail_size = EDITOR_GET("docks/filesystem/thumbnail_size"); thumbnail_size *= EDSCALE; Ref<Texture2D> folder_thumbnail; Ref<Texture2D> file_thumbnail; @@ -784,9 +789,8 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { List<FileInfo> file_list; if (path == "Favorites") { // Display the favorites. - Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); - for (int i = 0; i < favorites.size(); i++) { - String favorite = favorites[i]; + Vector<String> favorites_list = EditorSettings::get_singleton()->get_favorites(); + for (const String &favorite : favorites_list) { String text; Ref<Texture2D> icon; if (favorite == "res://") { @@ -894,7 +898,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { _sort_file_info_list(file_list); // Fills the ItemList control node from the FileInfos. - String main_scene = ProjectSettings::get_singleton()->get("application/run/main_scene"); + String main_scene = GLOBAL_GET("application/run/main_scene"); for (FileInfo &E : file_list) { FileInfo *finfo = &(E); String fname = finfo->name; @@ -1056,15 +1060,15 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit void FileSystemDock::_tree_activate_file() { TreeItem *selected = tree->get_selected(); if (selected) { - String path = selected->get_metadata(0); + String file_path = selected->get_metadata(0); TreeItem *parent = selected->get_parent(); bool is_favorite = parent != nullptr && parent->get_metadata(0) == "Favorites"; - if ((!is_favorite && path.ends_with("/")) || path == "Favorites") { + if ((!is_favorite && file_path.ends_with("/")) || file_path == "Favorites") { bool collapsed = selected->is_collapsed(); selected->set_collapsed(!collapsed); } else { - _select_file(path, is_favorite && !path.ends_with("/")); + _select_file(file_path, is_favorite && !file_path.ends_with("/")); } } } @@ -1169,29 +1173,29 @@ void FileSystemDock::_push_to_history() { button_hist_next->set_disabled(history_pos == history.size() - 1); } -void FileSystemDock::_get_all_items_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files, Vector<String> &folders) const { - if (efsd == nullptr) { +void FileSystemDock::_get_all_items_in_dir(EditorFileSystemDirectory *p_efsd, Vector<String> &r_files, Vector<String> &r_folders) const { + if (p_efsd == nullptr) { return; } - for (int i = 0; i < efsd->get_subdir_count(); i++) { - folders.push_back(efsd->get_subdir(i)->get_path()); - _get_all_items_in_dir(efsd->get_subdir(i), files, folders); + for (int i = 0; i < p_efsd->get_subdir_count(); i++) { + r_folders.push_back(p_efsd->get_subdir(i)->get_path()); + _get_all_items_in_dir(p_efsd->get_subdir(i), r_files, r_folders); } - for (int i = 0; i < efsd->get_file_count(); i++) { - files.push_back(efsd->get_file_path(i)); + for (int i = 0; i < p_efsd->get_file_count(); i++) { + r_files.push_back(p_efsd->get_file_path(i)); } } -void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, const HashMap<String, String> &renames, Vector<String> &to_remaps) const { - for (int i = 0; i < efsd->get_subdir_count(); i++) { - _find_remaps(efsd->get_subdir(i), renames, to_remaps); +void FileSystemDock::_find_remaps(EditorFileSystemDirectory *p_efsd, const HashMap<String, String> &r_renames, Vector<String> &r_to_remaps) const { + for (int i = 0; i < p_efsd->get_subdir_count(); i++) { + _find_remaps(p_efsd->get_subdir(i), r_renames, r_to_remaps); } - for (int i = 0; i < efsd->get_file_count(); i++) { - Vector<String> deps = efsd->get_file_deps(i); + for (int i = 0; i < p_efsd->get_file_count(); i++) { + Vector<String> deps = p_efsd->get_file_deps(i); for (int j = 0; j < deps.size(); j++) { - if (renames.has(deps[j])) { - to_remaps.push_back(efsd->get_file_path(i)); + if (r_renames.has(deps[j])) { + r_to_remaps.push_back(p_efsd->get_file_path(i)); break; } } @@ -1284,42 +1288,71 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin } Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - print_verbose("Duplicating " + old_path + " -> " + new_path); - Error err = p_item.is_file ? da->copy(old_path, new_path) : da->copy_dir(old_path, new_path); - if (err == OK) { - // Move/Rename any corresponding import settings too. - if (p_item.is_file && FileAccess::exists(old_path + ".import")) { - err = da->copy(old_path + ".import", new_path + ".import"); + + if (p_item.is_file) { + print_verbose("Duplicating " + old_path + " -> " + new_path); + + // Create the directory structure. + da->make_dir_recursive(new_path.get_base_dir()); + + if (FileAccess::exists(old_path + ".import")) { + Error err = da->copy(old_path, new_path); if (err != OK) { - EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import\n"); + EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n"); + return; } // Remove uid from .import file to avoid conflict. Ref<ConfigFile> cfg; cfg.instantiate(); - cfg->load(new_path + ".import"); + cfg->load(old_path + ".import"); cfg->erase_section_key("remap", "uid"); - cfg->save(new_path + ".import"); - } else if (p_item.is_file && (old_path.get_extension() == "tscn" || old_path.get_extension() == "tres")) { - // FIXME: Quick hack to fix text resources. This should be fixed properly. - Ref<FileAccess> file = FileAccess::open(old_path, FileAccess::READ, &err); - if (err == OK) { - PackedStringArray lines = file->get_as_utf8_string().split("\n"); - String line = lines[0]; - - if (line.contains("uid")) { - line = line.substr(0, line.find(" uid")) + "]"; - lines.write[0] = line; + err = cfg->save(new_path + ".import"); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import: " + error_names[err] + "\n"); + return; + } + } else { + // Files which do not use an uid can just be copied. + if (ResourceLoader::get_resource_uid(old_path) == ResourceUID::INVALID_ID) { + Error err = da->copy(old_path, new_path); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n"); + } + return; + } - Ref<FileAccess> file2 = FileAccess::open(new_path, FileAccess::WRITE, &err); - if (err == OK) { - file2->store_string(String("\n").join(lines)); - } + // Load the resource and save it again in the new location (this generates a new UID). + Error err; + Ref<Resource> res = ResourceLoader::load(old_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); + if (err == OK && res.is_valid()) { + err = ResourceSaver::save(res, new_path, ResourceSaver::FLAG_COMPRESS); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + " " + vformat(TTR("Failed to save resource at %s: %s"), new_path, error_names[err])); } + } else if (err != OK) { + // When loading files like text files the error is OK but the resource is still null. + // We can ignore such files. + EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + " " + vformat(TTR("Failed to load resource at %s: %s"), new_path, error_names[err])); } } } else { - EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + "\n"); + // Recursively duplicate all files inside the folder. + Ref<DirAccess> old_dir = DirAccess::open(old_path); + Ref<FileAccess> file_access = FileAccess::create(FileAccess::ACCESS_RESOURCES); + old_dir->set_include_navigational(false); + old_dir->list_dir_begin(); + for (String f = old_dir->_get_next(); !f.is_empty(); f = old_dir->_get_next()) { + if (f.get_extension() == "import") { + continue; + } + if (file_access->file_exists(old_path + f)) { + _try_duplicate_item(FileOrFolder(old_path + f, true), new_path + f); + } else if (da->dir_exists(old_path + f)) { + _try_duplicate_item(FileOrFolder(old_path + f, false), new_path + f); + } + } + old_dir->list_dir_end(); } } @@ -1345,25 +1378,25 @@ void FileSystemDock::_update_resource_paths_after_move(const HashMap<String, Str } for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) { - String path; + String file_path; if (i == EditorNode::get_editor_data().get_edited_scene()) { if (!get_tree()->get_edited_scene_root()) { continue; } - path = get_tree()->get_edited_scene_root()->get_scene_file_path(); + file_path = get_tree()->get_edited_scene_root()->get_scene_file_path(); } else { - path = EditorNode::get_editor_data().get_scene_path(i); + file_path = EditorNode::get_editor_data().get_scene_path(i); } - if (p_renames.has(path)) { - path = p_renames[path]; + if (p_renames.has(file_path)) { + file_path = p_renames[file_path]; } if (i == EditorNode::get_editor_data().get_edited_scene()) { - get_tree()->get_edited_scene_root()->set_scene_file_path(path); + get_tree()->get_edited_scene_root()->set_scene_file_path(file_path); } else { - EditorNode::get_editor_data().set_scene_path(i, path); + EditorNode::get_editor_data().set_scene_path(i, file_path); } } } @@ -1421,11 +1454,10 @@ void FileSystemDock::_update_project_settings_after_move(const HashMap<String, S } void FileSystemDock::_update_favorites_list_after_move(const HashMap<String, String> &p_files_renames, const HashMap<String, String> &p_folders_renames) const { - Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + Vector<String> favorites_list = EditorSettings::get_singleton()->get_favorites(); Vector<String> new_favorites; - for (int i = 0; i < favorites.size(); i++) { - String old_path = favorites[i]; + for (const String &old_path : favorites_list) { if (p_folders_renames.has(old_path)) { new_favorites.push_back(p_folders_renames[old_path]); } else if (p_files_renames.has(old_path)) { @@ -1699,7 +1731,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_ove } } -Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { +Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) const { // Build a list of selected items with the active one at the first position. Vector<String> selected_strings; @@ -1751,22 +1783,7 @@ void FileSystemDock::_tree_rmb_option(int p_option) { case FOLDER_COLLAPSE_ALL: { // Expand or collapse the folder if (selected_strings.size() == 1) { - bool is_collapsed = (p_option == FOLDER_COLLAPSE_ALL); - - Vector<TreeItem *> needs_check; - needs_check.push_back(tree->get_selected()); - - while (needs_check.size()) { - needs_check[0]->set_collapsed(is_collapsed); - - TreeItem *child = needs_check[0]->get_first_child(); - while (child) { - needs_check.push_back(child); - child = child->get_next(); - } - - needs_check.remove_at(0); - } + tree->get_selected()->set_collapsed_recursive(p_option == FOLDER_COLLAPSE_ALL); } } break; default: { @@ -1835,8 +1852,8 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } } break; - case FILE_INSTANCE: { - // Instance all selected scenes. + case FILE_INSTANTIATE: { + // Instantiate all selected scenes. Vector<String> paths; for (int i = 0; i < p_selected.size(); i++) { String fpath = p_selected[i]; @@ -1845,29 +1862,29 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } } if (!paths.is_empty()) { - emit_signal(SNAME("instance"), paths); + emit_signal(SNAME("instantiate"), paths); } } break; case FILE_ADD_FAVORITE: { // Add the files from favorites. - Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + Vector<String> favorites_list = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < p_selected.size(); i++) { - if (!favorites.has(p_selected[i])) { - favorites.push_back(p_selected[i]); + if (!favorites_list.has(p_selected[i])) { + favorites_list.push_back(p_selected[i]); } } - EditorSettings::get_singleton()->set_favorites(favorites); + EditorSettings::get_singleton()->set_favorites(favorites_list); _update_tree(_compute_uncollapsed_paths()); } break; case FILE_REMOVE_FAVORITE: { // Remove the files from favorites. - Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + Vector<String> favorites_list = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < p_selected.size(); i++) { - favorites.erase(p_selected[i]); + favorites_list.erase(p_selected[i]); } - EditorSettings::get_singleton()->set_favorites(favorites); + EditorSettings::get_singleton()->set_favorites(favorites_list); _update_tree(_compute_uncollapsed_paths()); if (path == "Favorites") { _update_file_list(true); @@ -2060,7 +2077,7 @@ void FileSystemDock::_resource_created() { return; } - Variant c = new_resource_dialog->instance_selected(); + Variant c = new_resource_dialog->instantiate_selected(); ERR_FAIL_COND(!c); Resource *r = Object::cast_to<Resource>(c); @@ -2289,7 +2306,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, int drop_section = tree->get_drop_section_at_position(p_point); int drop_position; - Vector<String> files = drag_data["files"]; + Vector<String> drag_files = drag_data["files"]; TreeItem *favorites_item = tree->get_root()->get_first_child(); TreeItem *resources_item = favorites_item->get_next(); @@ -2310,8 +2327,8 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, // Remove dragged favorites. Vector<int> to_remove; int offset = 0; - for (int i = 0; i < files.size(); i++) { - int to_remove_pos = dirs.find(files[i]); + for (int i = 0; i < drag_files.size(); i++) { + int to_remove_pos = dirs.find(drag_files[i]); to_remove.push_back(to_remove_pos); if (to_remove_pos < drop_position) { offset++; @@ -2324,8 +2341,8 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } // Re-add them at the right position. - for (int i = 0; i < files.size(); i++) { - dirs.insert(drop_position, files[i]); + for (int i = 0; i < drag_files.size(); i++) { + dirs.insert(drop_position, drag_files[i]); drop_position++; } @@ -2394,13 +2411,13 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } else if (favorite) { // Add the files from favorites. Vector<String> fnames = drag_data["files"]; - Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + Vector<String> favorites_list = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < fnames.size(); i++) { - if (!favorites.has(fnames[i])) { - favorites.push_back(fnames[i]); + if (!favorites_list.has(fnames[i])) { + favorites_list.push_back(fnames[i]); } } - EditorSettings::get_singleton()->set_favorites(favorites); + EditorSettings::get_singleton()->set_favorites(favorites_list); _update_tree(_compute_uncollapsed_paths()); } } @@ -2478,7 +2495,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str Vector<String> filenames; Vector<String> foldernames; - Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); + Vector<String> favorites_list = EditorSettings::get_singleton()->get_favorites(); bool all_files = true; bool all_files_scenes = true; @@ -2499,8 +2516,8 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str // Check if in favorites. bool found = false; - for (int j = 0; j < favorites.size(); j++) { - if (favorites[j] == fpath) { + for (int j = 0; j < favorites_list.size(); j++) { + if (favorites_list[j] == fpath) { found = true; break; } @@ -2517,13 +2534,13 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str if (filenames.size() == 1) { p_popup->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open Scene"), FILE_OPEN); p_popup->add_icon_item(get_theme_icon(SNAME("CreateNewSceneFrom"), SNAME("EditorIcons")), TTR("New Inherited Scene"), FILE_INHERIT); - if (ProjectSettings::get_singleton()->get("application/run/main_scene") != filenames[0]) { + if (GLOBAL_GET("application/run/main_scene") != filenames[0]) { p_popup->add_icon_item(get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons")), TTR("Set As Main Scene"), FILE_MAIN_SCENE); } } else { p_popup->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open Scenes"), FILE_OPEN); } - p_popup->add_icon_item(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instance"), FILE_INSTANCE); + p_popup->add_icon_item(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instantiate"), FILE_INSTANTIATE); p_popup->add_separator(); } else if (filenames.size() == 1) { p_popup->add_icon_item(get_theme_icon(SNAME("Load"), SNAME("EditorIcons")), TTR("Open"), FILE_OPEN); @@ -2867,10 +2884,10 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { } } -void FileSystemDock::_get_imported_files(const String &p_path, Vector<String> &files) const { +void FileSystemDock::_get_imported_files(const String &p_path, Vector<String> &r_files) const { if (!p_path.ends_with("/")) { if (FileAccess::exists(p_path + ".import")) { - files.push_back(p_path); + r_files.push_back(p_path); } return; } @@ -2881,7 +2898,7 @@ void FileSystemDock::_get_imported_files(const String &p_path, Vector<String> &f while (!n.is_empty()) { if (n != "." && n != ".." && !n.ends_with(".import")) { String npath = p_path + n + (da->current_is_dir() ? "/" : ""); - _get_imported_files(npath, files); + _get_imported_files(npath, r_files); } n = da->get_next(); } @@ -2977,7 +2994,7 @@ void FileSystemDock::_file_sort_popup(int p_id) { MenuButton *FileSystemDock::_create_file_menu_button() { MenuButton *button = memnew(MenuButton); button->set_flat(true); - button->set_tooltip_text(TTR("Sort files")); + button->set_tooltip_text(TTR("Sort Files")); PopupMenu *p = button->get_popup(); p->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_sort_popup)); @@ -3006,12 +3023,12 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_import_dock"), &FileSystemDock::_update_import_dock); ADD_SIGNAL(MethodInfo("inherit", PropertyInfo(Variant::STRING, "file"))); - ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"))); + ADD_SIGNAL(MethodInfo("instantiate", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"))); ADD_SIGNAL(MethodInfo("file_removed", PropertyInfo(Variant::STRING, "file"))); ADD_SIGNAL(MethodInfo("folder_removed", PropertyInfo(Variant::STRING, "folder"))); ADD_SIGNAL(MethodInfo("files_moved", PropertyInfo(Variant::STRING, "old_file"), PropertyInfo(Variant::STRING, "new_file"))); - ADD_SIGNAL(MethodInfo("folder_moved", PropertyInfo(Variant::STRING, "old_folder"), PropertyInfo(Variant::STRING, "new_file"))); + ADD_SIGNAL(MethodInfo("folder_moved", PropertyInfo(Variant::STRING, "old_folder"), PropertyInfo(Variant::STRING, "new_folder"))); ADD_SIGNAL(MethodInfo("display_mode_changed")); } @@ -3040,14 +3057,14 @@ FileSystemDock::FileSystemDock() { button_hist_prev->set_flat(true); button_hist_prev->set_disabled(true); button_hist_prev->set_focus_mode(FOCUS_NONE); - button_hist_prev->set_tooltip_text(TTR("Previous Folder/File")); + button_hist_prev->set_tooltip_text(TTR("Go to previous selected folder/file.")); toolbar_hbc->add_child(button_hist_prev); button_hist_next = memnew(Button); button_hist_next->set_flat(true); button_hist_next->set_disabled(true); button_hist_next->set_focus_mode(FOCUS_NONE); - button_hist_next->set_tooltip_text(TTR("Next Folder/File")); + button_hist_next->set_tooltip_text(TTR("Go to next selected folder/file.")); toolbar_hbc->add_child(button_hist_next); current_path = memnew(LineEdit); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index c38b3f8a47..c4ce500c1e 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -79,7 +79,7 @@ private: FILE_OPEN, FILE_INHERIT, FILE_MAIN_SCENE, - FILE_INSTANCE, + FILE_INSTANTIATE, FILE_ADD_FAVORITE, FILE_REMOVE_FAVORITE, FILE_DEPENDENCIES, @@ -213,11 +213,11 @@ private: void _file_multi_selected(int p_index, bool p_selected); void _tree_multi_selected(Object *p_item, int p_column, bool p_selected); - void _get_imported_files(const String &p_path, Vector<String> &files) const; + void _get_imported_files(const String &p_path, Vector<String> &r_files) const; void _update_import_dock(); - void _get_all_items_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files, Vector<String> &folders) const; - void _find_remaps(EditorFileSystemDirectory *efsd, const HashMap<String, String> &renames, Vector<String> &to_remaps) const; + void _get_all_items_in_dir(EditorFileSystemDirectory *p_efsd, Vector<String> &r_files, Vector<String> &r_folders) const; + void _find_remaps(EditorFileSystemDirectory *p_efsd, const HashMap<String, String> &r_renames, Vector<String> &r_to_remaps) const; void _try_move_item(const FileOrFolder &p_item, const String &p_new_path, HashMap<String, String> &p_file_renames, HashMap<String, String> &p_folder_renames); void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const; void _update_dependencies_after_move(const HashMap<String, String> &p_renames) const; @@ -297,12 +297,12 @@ private: void _update_display_mode(bool p_force = false); - Vector<String> _tree_get_selected(bool remove_self_inclusion = true); + Vector<String> _tree_get_selected(bool remove_self_inclusion = true) const; bool _is_file_type_disabled_by_feature_profile(const StringName &p_class); void _feature_profile_changed(); - Vector<String> _remove_self_included_paths(Vector<String> selected_strings); + static Vector<String> _remove_self_included_paths(Vector<String> selected_strings); private: static FileSystemDock *singleton; @@ -315,9 +315,11 @@ protected: static void _bind_methods(); public: - String get_selected_path() const; + Vector<String> get_selected_paths() const; String get_current_path() const; + String get_current_directory() const; + void navigate_to_path(const String &p_path); void focus_on_filter(); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index 16c5003fdc..666444eaf9 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -422,8 +422,7 @@ void FindInFilesDialog::set_find_in_files_mode(FindInFilesMode p_mode) { } String FindInFilesDialog::get_search_text() const { - String text = _search_text_line_edit->get_text(); - return text.strip_edges(); + return _search_text_line_edit->get_text(); } String FindInFilesDialog::get_replace_text() const { @@ -464,9 +463,9 @@ void FindInFilesDialog::_notification(int p_what) { _search_text_line_edit->select_all(); // Extensions might have changed in the meantime, we clean them and instance them again. for (int i = 0; i < _filters_container->get_child_count(); i++) { - _filters_container->get_child(i)->queue_delete(); + _filters_container->get_child(i)->queue_free(); } - Array exts = ProjectSettings::get_singleton()->get("editor/script/search_in_file_extensions"); + Array exts = GLOBAL_GET("editor/script/search_in_file_extensions"); for (int i = 0; i < exts.size(); ++i) { CheckBox *cb = memnew(CheckBox); cb->set_text(exts[i]); @@ -607,6 +606,7 @@ FindInFilesPanel::FindInFilesPanel() { _results_display->set_hide_root(true); _results_display->set_select_mode(Tree::SELECT_ROW); _results_display->set_allow_rmb_select(true); + _results_display->set_allow_reselect(true); _results_display->create_item(); // Root vbc->add_child(_results_display); @@ -718,6 +718,10 @@ void FindInFilesPanel::_on_result_found(String fpath, int line_number, int begin file_item = E->value; } + Color file_item_color = _results_display->get_theme_color(SNAME("font_color")) * Color(1, 1, 1, 0.67); + file_item->set_custom_color(0, file_item_color); + file_item->set_selectable(0, false); + int text_index = _with_replace ? 1 : 0; TreeItem *item = _results_display->create_item(file_item); @@ -764,13 +768,13 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) { int font_size = _results_display->get_theme_font_size(SNAME("font_size")); Rect2 match_rect = rect; - match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x; - match_rect.size.x = font->get_string_size(_search_text_label->get_text(), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x; + match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x - 1; + match_rect.size.x = font->get_string_size(_search_text_label->get_text(), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x + 2; match_rect.position.y += 1 * EDSCALE; match_rect.size.y -= 2 * EDSCALE; - // Use the inverted accent color to help match rectangles stand out even on the currently selected line. - _results_display->draw_rect(match_rect, get_theme_color(SNAME("accent_color"), SNAME("Editor")).inverted() * Color(1, 1, 1, 0.5)); + _results_display->draw_rect(match_rect, get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.33), false, 2.0); + _results_display->draw_rect(match_rect, get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.17), true); // Text is drawn by Tree already. } @@ -778,14 +782,12 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) { void FindInFilesPanel::_on_item_edited() { TreeItem *item = _results_display->get_selected(); - if (item->is_checked(0)) { - item->set_custom_color(1, _results_display->get_theme_color(SNAME("font_color"))); - } else { - // Grey out. - Color color = _results_display->get_theme_color(SNAME("font_color")); - color.a /= 2.0; - item->set_custom_color(1, color); + // Change opacity to half if checkbox is checked, otherwise full. + Color use_color = _results_display->get_theme_color(SNAME("font_color")); + if (!item->is_checked(0)) { + use_color.a *= 0.5; } + item->set_custom_color(1, use_color); } void FindInFilesPanel::_on_finished() { @@ -794,11 +796,11 @@ void FindInFilesPanel::_on_finished() { int file_count = _file_items.size(); if (result_count == 1 && file_count == 1) { - results_text = vformat(TTR("%d match in %d file."), result_count, file_count); + results_text = vformat(TTR("%d match in %d file"), result_count, file_count); } else if (result_count != 1 && file_count == 1) { - results_text = vformat(TTR("%d matches in %d file."), result_count, file_count); + results_text = vformat(TTR("%d matches in %d file"), result_count, file_count); } else { - results_text = vformat(TTR("%d matches in %d files."), result_count, file_count); + results_text = vformat(TTR("%d matches in %d files"), result_count, file_count); } _status_label->set_text(results_text); @@ -968,8 +970,8 @@ void FindInFilesPanel::update_replace_buttons() { _replace_all_button->set_disabled(disabled); } -void FindInFilesPanel::set_progress_visible(bool visible) { - _progress_bar->set_self_modulate(Color(1, 1, 1, visible ? 1 : 0)); +void FindInFilesPanel::set_progress_visible(bool p_visible) { + _progress_bar->set_self_modulate(Color(1, 1, 1, p_visible ? 1 : 0)); } void FindInFilesPanel::_bind_methods() { diff --git a/editor/find_in_files.h b/editor/find_in_files.h index c57a084779..46ba3842af 100644 --- a/editor/find_in_files.h +++ b/editor/find_in_files.h @@ -198,7 +198,7 @@ private: void draw_result_text(Object *item_obj, Rect2 rect); - void set_progress_visible(bool visible); + void set_progress_visible(bool p_visible); void clear(); FindInFiles *_finder = nullptr; diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index dac86acae4..ab96caa88c 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -39,6 +39,24 @@ #include "scene/gui/label.h" #include "scene/resources/packed_scene.h" +static bool can_edit(Node *p_node, String p_group) { + Node *n = p_node; + bool can_edit = true; + while (n) { + Ref<SceneState> ss = (n == EditorNode::get_singleton()->get_edited_scene()) ? n->get_scene_inherited_state() : n->get_scene_instance_state(); + if (ss.is_valid()) { + int path = ss->find_node_by_path(n->get_path_to(p_node)); + if (path != -1) { + if (ss->is_node_in_group(path, p_group)) { + can_edit = false; + } + } + } + n = n->get_owner(); + } + return can_edit; +} + void GroupDialog::_group_selected() { nodes_to_add->clear(); add_node_root = nodes_to_add->create_item(); @@ -94,7 +112,7 @@ void GroupDialog::_load_nodes(Node *p_current) { Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(p_current, "Node"); node->set_icon(0, icon); - if (!_can_edit(p_current, selected_group)) { + if (!can_edit(p_current, selected_group)) { node->set_selectable(0, false); node->set_custom_color(0, groups->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); } @@ -105,24 +123,6 @@ void GroupDialog::_load_nodes(Node *p_current) { } } -bool GroupDialog::_can_edit(Node *p_node, String p_group) { - Node *n = p_node; - bool can_edit = true; - while (n) { - Ref<SceneState> ss = (n == EditorNode::get_singleton()->get_edited_scene()) ? n->get_scene_inherited_state() : n->get_scene_instance_state(); - if (ss.is_valid()) { - int path = ss->find_node_by_path(n->get_path_to(p_node)); - if (path != -1) { - if (ss->is_node_in_group(path, p_group)) { - can_edit = false; - } - } - } - n = n->get_owner(); - } - return can_edit; -} - void GroupDialog::_add_pressed() { TreeItem *selected = nodes_to_add->get_next_selected(nullptr); @@ -130,6 +130,7 @@ void GroupDialog::_add_pressed() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add to Group")); while (selected) { @@ -159,6 +160,7 @@ void GroupDialog::_removed_pressed() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove from Group")); while (selected) { @@ -218,19 +220,14 @@ void GroupDialog::_add_group_text_changed(const String &p_new_text) { } void GroupDialog::_group_renamed() { - TreeItem *renamed_group = groups->get_edited(); + TreeItem *renamed_group = groups->get_selected(); if (!renamed_group) { return; } const String name = renamed_group->get_text(0).strip_edges(); - for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) { - if (E != renamed_group && E->get_text(0) == name) { - renamed_group->set_text(0, selected_group); - error->set_text(TTR("Group name already exists.")); - error->popup_centered(); - return; - } + if (name == selected_group) { + return; } if (name.is_empty()) { @@ -240,15 +237,25 @@ void GroupDialog::_group_renamed() { return; } + for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) { + if (E != renamed_group && E->get_text(0) == name) { + renamed_group->set_text(0, selected_group); + error->set_text(TTR("Group name already exists.")); + error->popup_centered(); + return; + } + } + renamed_group->set_text(0, name); // Spaces trimmed. + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Rename Group")); List<Node *> nodes; scene_tree->get_nodes_in_group(selected_group, &nodes); bool removed_all = true; for (Node *node : nodes) { - if (_can_edit(node, selected_group)) { + if (can_edit(node, selected_group)) { undo_redo->add_do_method(node, "remove_from_group", selected_group); undo_redo->add_undo_method(node, "remove_from_group", name); undo_redo->add_do_method(node, "add_to_group", name, true); @@ -318,13 +325,14 @@ void GroupDialog::_modify_group_pressed(Object *p_item, int p_column, int p_id, case DELETE_GROUP: { String name = ti->get_text(0); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete Group")); List<Node *> nodes; scene_tree->get_nodes_in_group(name, &nodes); bool removed_all = true; for (Node *E : nodes) { - if (_can_edit(E, name)) { + if (can_edit(E, name)) { undo_redo->add_do_method(E, "remove_from_group", name); undo_redo->add_undo_method(E, "add_to_group", name, true); } else { @@ -398,10 +406,6 @@ void GroupDialog::_notification(int p_what) { } } -void GroupDialog::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void GroupDialog::edit() { popup_centered(); @@ -571,7 +575,7 @@ GroupDialog::GroupDialog() { set_title(TTR("Group Editor")); - error = memnew(ConfirmationDialog); + error = memnew(AcceptDialog); add_child(error); error->set_ok_button_text(TTR("Close")); @@ -584,17 +588,16 @@ void GroupsEditor::_add_group(const String &p_group) { if (!node) { return; } - const String name = group_name->get_text().strip_edges(); - if (name.is_empty()) { - return; - } group_name->clear(); if (node->is_in_group(name)) { + error->set_text(TTR("Group name already exists.")); + error->popup_centered(); return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add to Group")); undo_redo->add_do_method(node, "add_to_group", name, true); @@ -609,6 +612,66 @@ void GroupsEditor::_add_group(const String &p_group) { undo_redo->commit_action(); } +void GroupsEditor::_group_selected() { + if (!tree->is_anything_selected()) { + return; + } + selected_group = tree->get_selected()->get_text(0); +} + +void GroupsEditor::_group_renamed() { + if (!node || !can_edit(node, selected_group)) { + return; + } + + TreeItem *ti = tree->get_selected(); + if (!ti) { + return; + } + + const String name = ti->get_text(0).strip_edges(); + if (name == selected_group) { + return; + } + + if (name.is_empty()) { + ti->set_text(0, selected_group); + error->set_text(TTR("Invalid group name.")); + error->popup_centered(); + return; + } + + for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) { + if (E != ti && E->get_text(0) == name) { + ti->set_text(0, selected_group); + error->set_text(TTR("Group name already exists.")); + error->popup_centered(); + return; + } + } + + ti->set_text(0, name); // Spaces trimmed. + + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Rename Group")); + + undo_redo->add_do_method(node, "remove_from_group", selected_group); + undo_redo->add_undo_method(node, "remove_from_group", name); + undo_redo->add_do_method(node, "add_to_group", name, true); + undo_redo->add_undo_method(node, "add_to_group", selected_group, true); + + undo_redo->add_do_method(this, "_group_selected"); + undo_redo->add_undo_method(this, "_group_selected"); + undo_redo->add_do_method(this, "update_tree"); + undo_redo->add_undo_method(this, "update_tree"); + + // To force redraw of scene tree. + undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); + + undo_redo->commit_action(); +} + void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id, MouseButton p_button) { if (p_button != MouseButton::LEFT) { return; @@ -624,7 +687,8 @@ void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id, MouseBu } switch (p_id) { case DELETE_GROUP: { - String name = ti->get_text(0); + const String name = ti->get_text(0); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove from Group")); undo_redo->add_do_method(node, "remove_from_group", name); @@ -666,6 +730,7 @@ void GroupsEditor::update_tree() { groups.sort_custom<_GroupInfoComparator>(); TreeItem *root = tree->create_item(); + groups_root = root; for (const GroupInfo &gi : groups) { if (!gi.persistent) { @@ -692,6 +757,7 @@ void GroupsEditor::update_tree() { TreeItem *item = tree->create_item(root); item->set_text(0, gi.name); + item->set_editable(0, true); if (can_be_deleted) { item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), DELETE_GROUP); item->add_button(0, get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), COPY_GROUP); @@ -701,10 +767,6 @@ void GroupsEditor::update_tree() { } } -void GroupsEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void GroupsEditor::set_current(Node *p_node) { node = p_node; update_tree(); @@ -712,11 +774,11 @@ void GroupsEditor::set_current(Node *p_node) { void GroupsEditor::_show_group_dialog() { group_dialog->edit(); - group_dialog->set_undo_redo(undo_redo); } void GroupsEditor::_bind_methods() { ClassDB::bind_method("update_tree", &GroupsEditor::update_tree); + ClassDB::bind_method("_group_selected", &GroupsEditor::_group_selected); } GroupsEditor::GroupsEditor() { @@ -749,13 +811,21 @@ GroupsEditor::GroupsEditor() { add->connect("pressed", callable_mp(this, &GroupsEditor::_add_group).bind(String())); tree = memnew(Tree); + vbc->add_child(tree); tree->set_hide_root(true); + tree->set_allow_reselect(true); + tree->set_allow_rmb_select(true); tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); - vbc->add_child(tree); + tree->connect("item_selected", callable_mp(this, &GroupsEditor::_group_selected)); tree->connect("button_clicked", callable_mp(this, &GroupsEditor::_modify_group)); + tree->connect("item_edited", callable_mp(this, &GroupsEditor::_group_renamed)); tree->add_theme_constant_override("draw_guides", 1); add_theme_constant_override("separation", 3 * EDSCALE); + error = memnew(AcceptDialog); + add_child(error); + error->get_ok_button()->set_text(TTR("Close")); + _group_name_changed(""); } diff --git a/editor/groups_editor.h b/editor/groups_editor.h index 8bbea4e652..3900e0e28c 100644 --- a/editor/groups_editor.h +++ b/editor/groups_editor.h @@ -39,12 +39,10 @@ #include "scene/gui/popup.h" #include "scene/gui/tree.h" -class EditorUndoRedoManager; - class GroupDialog : public AcceptDialog { GDCLASS(GroupDialog, AcceptDialog); - ConfirmationDialog *error = nullptr; + AcceptDialog *error = nullptr; SceneTree *scene_tree = nullptr; TreeItem *groups_root = nullptr; @@ -69,8 +67,6 @@ class GroupDialog : public AcceptDialog { String selected_group; - Ref<EditorUndoRedoManager> undo_redo; - void _group_selected(); void _remove_filter_changed(const String &p_filter); @@ -88,8 +84,6 @@ class GroupDialog : public AcceptDialog { void _modify_group_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button); void _delete_group_item(const String &p_name); - bool _can_edit(Node *p_node, String p_group); - void _load_groups(Node *p_current); void _load_nodes(Node *p_current); @@ -104,7 +98,6 @@ public: }; void edit(); - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); GroupDialog(); }; @@ -113,20 +106,25 @@ class GroupsEditor : public VBoxContainer { GDCLASS(GroupsEditor, VBoxContainer); Node *node = nullptr; + TreeItem *groups_root = nullptr; GroupDialog *group_dialog = nullptr; + AcceptDialog *error = nullptr; LineEdit *group_name = nullptr; Button *add = nullptr; Tree *tree = nullptr; - Ref<EditorUndoRedoManager> undo_redo; + String selected_group; void update_tree(); void _add_group(const String &p_group = ""); void _modify_group(Object *p_item, int p_column, int p_id, MouseButton p_button); void _group_name_changed(const String &p_new_text); + void _group_selected(); + void _group_renamed(); + void _show_group_dialog(); protected: @@ -138,7 +136,6 @@ public: COPY_GROUP, }; - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); void set_current(Node *p_node); GroupsEditor(); diff --git a/editor/history_dock.cpp b/editor/history_dock.cpp new file mode 100644 index 0000000000..93599eff56 --- /dev/null +++ b/editor/history_dock.cpp @@ -0,0 +1,253 @@ +/*************************************************************************/ +/* history_dock.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "history_dock.h" + +#include "editor/editor_node.h" +#include "editor/editor_undo_redo_manager.h" +#include "scene/gui/check_box.h" +#include "scene/gui/item_list.h" + +struct SortActionsByTimestamp { + bool operator()(const EditorUndoRedoManager::Action &l, const EditorUndoRedoManager::Action &r) const { + return l.timestamp > r.timestamp; + } +}; + +void HistoryDock::on_history_changed() { + if (is_visible_in_tree()) { + refresh_history(); + } else { + need_refresh = true; + } +} + +void HistoryDock::refresh_history() { + action_list->clear(); + bool include_scene = current_scene_checkbox->is_pressed(); + bool include_global = global_history_checkbox->is_pressed(); + + if (!include_scene && !include_global) { + action_list->add_item(TTR("The Beginning")); + return; + } + + const EditorUndoRedoManager::History ¤t_scene_history = ur_manager->get_or_create_history(EditorNode::get_editor_data().get_current_edited_scene_history_id()); + const EditorUndoRedoManager::History &global_history = ur_manager->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY); + + Vector<EditorUndoRedoManager::Action> full_history; + { + int full_size = 0; + if (include_scene) { + full_size += current_scene_history.redo_stack.size() + current_scene_history.undo_stack.size(); + } + if (include_global) { + full_size += global_history.redo_stack.size() + global_history.undo_stack.size(); + } + full_history.resize(full_size); + } + + int i = 0; + if (include_scene) { + for (const EditorUndoRedoManager::Action &E : current_scene_history.redo_stack) { + full_history.write[i] = E; + i++; + } + for (const EditorUndoRedoManager::Action &E : current_scene_history.undo_stack) { + full_history.write[i] = E; + i++; + } + } + if (include_global) { + for (const EditorUndoRedoManager::Action &E : global_history.redo_stack) { + full_history.write[i] = E; + i++; + } + for (const EditorUndoRedoManager::Action &E : global_history.undo_stack) { + full_history.write[i] = E; + i++; + } + } + + full_history.sort_custom<SortActionsByTimestamp>(); + for (const EditorUndoRedoManager::Action &E : full_history) { + action_list->add_item(E.action_name); + if (E.history_id == EditorUndoRedoManager::GLOBAL_HISTORY) { + action_list->set_item_custom_fg_color(-1, get_theme_color(SNAME("accent_color"), SNAME("Editor"))); + } + } + + action_list->add_item(TTR("The Beginning")); + refresh_version(); +} + +void HistoryDock::on_version_changed() { + if (is_visible_in_tree()) { + refresh_version(); + } else { + need_refresh = true; + } +} + +void HistoryDock::refresh_version() { + int idx = 0; + bool include_scene = current_scene_checkbox->is_pressed(); + bool include_global = global_history_checkbox->is_pressed(); + + if (!include_scene && !include_global) { + current_version = idx; + action_list->set_current(idx); + return; + } + + const EditorUndoRedoManager::History ¤t_scene_history = ur_manager->get_or_create_history(EditorNode::get_editor_data().get_current_edited_scene_history_id()); + const EditorUndoRedoManager::History &global_history = ur_manager->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY); + double newest_undo_timestamp = 0; + + if (include_scene && !current_scene_history.undo_stack.is_empty()) { + newest_undo_timestamp = current_scene_history.undo_stack.front()->get().timestamp; + } + + if (include_global && !global_history.undo_stack.is_empty()) { + double global_undo_timestamp = global_history.undo_stack.front()->get().timestamp; + if (global_undo_timestamp > newest_undo_timestamp) { + newest_undo_timestamp = global_undo_timestamp; + } + } + + if (include_scene) { + int skip = 0; + for (const EditorUndoRedoManager::Action &E : current_scene_history.redo_stack) { + if (E.timestamp < newest_undo_timestamp) { + skip++; + } else { + break; + } + } + idx += current_scene_history.redo_stack.size() - skip; + } + + if (include_global) { + int skip = 0; + for (const EditorUndoRedoManager::Action &E : global_history.redo_stack) { + if (E.timestamp < newest_undo_timestamp) { + skip++; + } else { + break; + } + } + idx += global_history.redo_stack.size() - skip; + } + + current_version = idx; + action_list->set_current(idx); +} + +void HistoryDock::seek_history(int p_index) { + bool include_scene = current_scene_checkbox->is_pressed(); + bool include_global = global_history_checkbox->is_pressed(); + + if (!include_scene && !include_global) { + return; + } + int current_scene_id = EditorNode::get_editor_data().get_current_edited_scene_history_id(); + + while (current_version < p_index) { + if (include_scene) { + if (include_global) { + ur_manager->undo(); + } else { + ur_manager->undo_history(current_scene_id); + } + } else { + ur_manager->undo_history(EditorUndoRedoManager::GLOBAL_HISTORY); + } + } + + while (current_version > p_index) { + if (include_scene) { + if (include_global) { + ur_manager->redo(); + } else { + ur_manager->redo_history(current_scene_id); + } + } else { + ur_manager->redo_history(EditorUndoRedoManager::GLOBAL_HISTORY); + } + } +} + +void HistoryDock::_notification(int p_notification) { + switch (p_notification) { + case NOTIFICATION_READY: { + EditorNode::get_singleton()->connect("scene_changed", callable_mp(this, &HistoryDock::on_history_changed)); + } break; + + case NOTIFICATION_VISIBILITY_CHANGED: { + if (is_visible_in_tree() && need_refresh) { + refresh_history(); + } + } break; + } +} + +HistoryDock::HistoryDock() { + set_name("History"); + + ur_manager = EditorNode::get_undo_redo(); + ur_manager->connect("history_changed", callable_mp(this, &HistoryDock::on_history_changed)); + ur_manager->connect("version_changed", callable_mp(this, &HistoryDock::on_version_changed)); + + HBoxContainer *mode_hb = memnew(HBoxContainer); + add_child(mode_hb); + + current_scene_checkbox = memnew(CheckBox); + mode_hb->add_child(current_scene_checkbox); + current_scene_checkbox->set_flat(true); + current_scene_checkbox->set_pressed(true); + current_scene_checkbox->set_text(TTR("Scene")); + current_scene_checkbox->set_h_size_flags(SIZE_EXPAND_FILL); + current_scene_checkbox->set_clip_text(true); + current_scene_checkbox->connect("toggled", callable_mp(this, &HistoryDock::refresh_history).unbind(1)); + + global_history_checkbox = memnew(CheckBox); + mode_hb->add_child(global_history_checkbox); + global_history_checkbox->set_flat(true); + global_history_checkbox->set_pressed(true); + global_history_checkbox->set_text(TTR("Global")); + global_history_checkbox->set_h_size_flags(SIZE_EXPAND_FILL); + global_history_checkbox->set_clip_text(true); + global_history_checkbox->connect("toggled", callable_mp(this, &HistoryDock::refresh_history).unbind(1)); + + action_list = memnew(ItemList); + add_child(action_list); + action_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); + action_list->connect("item_selected", callable_mp(this, &HistoryDock::seek_history)); +} diff --git a/editor/debugger/editor_network_profiler.h b/editor/history_dock.h index aea7ce3eec..9dda8165e6 100644 --- a/editor/debugger/editor_network_profiler.h +++ b/editor/history_dock.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* editor_network_profiler.h */ +/* history_dock.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,45 +28,39 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITOR_NETWORK_PROFILER_H -#define EDITOR_NETWORK_PROFILER_H +#ifndef HISTORY_DOCK_H +#define HISTORY_DOCK_H -#include "scene/debugger/scene_debugger.h" #include "scene/gui/box_container.h" -#include "scene/gui/button.h" -#include "scene/gui/label.h" -#include "scene/gui/split_container.h" -#include "scene/gui/tree.h" -class EditorNetworkProfiler : public VBoxContainer { - GDCLASS(EditorNetworkProfiler, VBoxContainer) +class CheckBox; +class ItemList; +class EditorUndoRedoManager; -private: - Button *activate = nullptr; - Button *clear_button = nullptr; - Tree *counters_display = nullptr; - LineEdit *incoming_bandwidth_text = nullptr; - LineEdit *outgoing_bandwidth_text = nullptr; +class HistoryDock : public VBoxContainer { + GDCLASS(HistoryDock, VBoxContainer); - Timer *frame_delay = nullptr; + Ref<EditorUndoRedoManager> ur_manager; + ItemList *action_list = nullptr; - HashMap<ObjectID, SceneDebugger::RPCNodeInfo> nodes_data; + CheckBox *current_scene_checkbox = nullptr; + CheckBox *global_history_checkbox = nullptr; - void _update_frame(); + bool need_refresh = true; + int current_version = 0; - void _activate_pressed(); - void _clear_pressed(); + void on_history_changed(); + void refresh_history(); + void on_version_changed(); + void refresh_version(); protected: - void _notification(int p_what); - static void _bind_methods(); + void _notification(int p_notification); public: - void add_node_frame_data(const SceneDebugger::RPCNodeInfo p_frame); - void set_bandwidth(int p_incoming, int p_outgoing); - bool is_profiling(); + void seek_history(int p_index); - EditorNetworkProfiler(); + HistoryDock(); }; -#endif // EDITOR_NETWORK_PROFILER_H +#endif // HISTORY_DOCK_H diff --git a/editor/icons/ArrowDown.svg b/editor/icons/ArrowDown.svg index d24357d2c5..f17c1bede7 100644 --- a/editor/icons/ArrowDown.svg +++ b/editor/icons/ArrowDown.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3.002a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l2.293 2.293h-4.5859c-.55228 0-1 .4477-1 1s.44772 1 1 1h4.5859l-2.293 2.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l4-4a1.0001 1.0001 0 0 0 0-1.4141l-4-4a1 1 0 0 0 -.7207-.29102z" fill="#e0e0e0" fill-opacity=".99608" transform="matrix(0 1 -1 0 16.0021 -.00004)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3.002a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l2.293 2.293h-4.5859c-.55228 0-1 .4477-1 1s.44772 1 1 1h4.5859l-2.293 2.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l4-4a1.0001 1.0001 0 0 0 0-1.4141l-4-4a1 1 0 0 0 -.7207-.29102z" fill="#e0e0e0" transform="matrix(0 1 -1 0 16.0021 -.00004)"/></svg> diff --git a/editor/icons/ArrowLeft.svg b/editor/icons/ArrowLeft.svg index ddd2f4e353..1a923cb6db 100644 --- a/editor/icons/ArrowLeft.svg +++ b/editor/icons/ArrowLeft.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9863 3.002a1 1 0 0 0 -.69336.29102l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-2.293-2.293h4.5859a1 1 0 0 0 1-1 1 1 0 0 0 -1-1h-4.5859l2.293-2.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9863 3.002a1 1 0 0 0 -.69336.29102l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-2.293-2.293h4.5859a1 1 0 0 0 1-1 1 1 0 0 0 -1-1h-4.5859l2.293-2.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/ArrowRight.svg b/editor/icons/ArrowRight.svg index a0c78dc1eb..da706c17ba 100644 --- a/editor/icons/ArrowRight.svg +++ b/editor/icons/ArrowRight.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3.002a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l2.293 2.293h-4.5859c-.55228 0-1 .4477-1 1s.44772 1 1 1h4.5859l-2.293 2.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l4-4a1.0001 1.0001 0 0 0 0-1.4141l-4-4a1 1 0 0 0 -.7207-.29102z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3.002a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l2.293 2.293h-4.5859c-.55228 0-1 .4477-1 1s.44772 1 1 1h4.5859l-2.293 2.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l4-4a1.0001 1.0001 0 0 0 0-1.4141l-4-4a1 1 0 0 0 -.7207-.29102z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/ArrowUp.svg b/editor/icons/ArrowUp.svg index f71f95c7b1..1381fea1b4 100644 --- a/editor/icons/ArrowUp.svg +++ b/editor/icons/ArrowUp.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.00008 1049.4022a1 1 0 0 0 .69336-.291 1 1 0 0 0 0-1.4141l-2.293-2.293h4.5859c.55228 0 1-.4477 1-1s-.44772-1-1-1h-4.5859l2.293-2.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -1.4141 0l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1 1 0 0 0 .7207.291z" fill="#e0e0e0" fill-opacity=".99608" transform="matrix(0 1 -1 0 1052.4021 -.00004)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.00008 1049.4022a1 1 0 0 0 .69336-.291 1 1 0 0 0 0-1.4141l-2.293-2.293h4.5859c.55228 0 1-.4477 1-1s-.44772-1-1-1h-4.5859l2.293-2.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -1.4141 0l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1 1 0 0 0 .7207.291z" fill="#e0e0e0" transform="matrix(0 1 -1 0 1052.4021 -.00004)"/></svg> diff --git a/editor/icons/AutoKey.svg b/editor/icons/AutoKey.svg index acc6665baf..877b00722f 100644 --- a/editor/icons/AutoKey.svg +++ b/editor/icons/AutoKey.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><circle cx="8" cy="5" r="4"/><path d="m11 13c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1 .00001-.55228.44772-.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3z" fill-opacity=".99608"/><path d="m4 10c-1.6569 0-3 1.3431-3 3v3h2v-3c.0000096-.5523.44772-1 1-1h1v-2z" fill-opacity=".99608"/><path d="m8 10c-3 0-3 3-3 3s0 3 3 3h1v-2h-1s-1 0-1-1h3 1s0-3-3-3zm-1 1h2v1h-2z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><circle cx="8" cy="5" r="4"/><path d="m11 13c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1 .00001-.55228.44772-.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3z"/><path d="m4 10c-1.6569 0-3 1.3431-3 3v3h2v-3c.0000096-.5523.44772-1 1-1h1v-2z"/><path d="m8 10c-3 0-3 3-3 3s0 3 3 3h1v-2h-1s-1 0-1-1h3 1s0-3-3-3zm-1 1h2v1h-2z"/></g></svg> diff --git a/editor/icons/Blend.svg b/editor/icons/Blend.svg index 4de2fa5a43..e692fc1c30 100644 --- a/editor/icons/Blend.svg +++ b/editor/icons/Blend.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1v2h2.5859l-3.5859 3.5859-4.293-4.293-1.4141 1.4141 4.293 4.293-4.293 4.293 1.4141 1.4141 4.293-4.293 3.5859 3.5859h-2.5859v2h5a1.0001 1.0001 0 0 0 1-1v-5h-2v2.5859l-3.5859-3.5859 3.5859-3.5859v2.5859h2v-5a1.0001 1.0001 0 0 0 -1-1h-5z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1v2h2.5859l-3.5859 3.5859-4.293-4.293-1.4141 1.4141 4.293 4.293-4.293 4.293 1.4141 1.4141 4.293-4.293 3.5859 3.5859h-2.5859v2h5a1.0001 1.0001 0 0 0 1-1v-5h-2v2.5859l-3.5859-3.5859 3.5859-3.5859v2.5859h2v-5a1.0001 1.0001 0 0 0 -1-1h-5z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Bone.svg b/editor/icons/Bone.svg index cbfa4794ed..f86b981619 100644 --- a/editor/icons/Bone.svg +++ b/editor/icons/Bone.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804.7205 2.4664 2.4663 0 0 0 -.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397.6955 2.4664 2.4663 0 0 0 .69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 .31408-3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004-.3102 2.4664 2.4663 0 0 0 0-3.4875 2.4664 2.4663 0 0 0 -1.397-.6974 2.4664 2.4663 0 0 0 -.69561-1.3971 2.4664 2.4663 0 0 0 -1.7072-.7205z" fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804.7205 2.4664 2.4663 0 0 0 -.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397.6955 2.4664 2.4663 0 0 0 .69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 .31408-3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004-.3102 2.4664 2.4663 0 0 0 0-3.4875 2.4664 2.4663 0 0 0 -1.397-.6974 2.4664 2.4663 0 0 0 -.69561-1.3971 2.4664 2.4663 0 0 0 -1.7072-.7205z" fill="#e0e0e0" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/BoneMapHumanBody.svg b/editor/icons/BoneMapHumanBody.svg index 2c2c5db1f6..8674157aaa 100644 --- a/editor/icons/BoneMapHumanBody.svg +++ b/editor/icons/BoneMapHumanBody.svg @@ -1 +1,26 @@ -<svg enable-background="new 0 0 1024 1024" height="1024" viewBox="0 0 1024 1024" width="1024" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1024v1024h-1024z" fill="#3f3f3f"/><path d="m926.5 217.162c-11.5-2-26.03 4.547-37.5 6.5-15.723 2.678-25.238 3.24-33.333 5.167-1.227.292-3.103.763-5.792.958 0 0-.019.16-.052.437-36.819.994-106.823-6.062-138.156-2.062-23.816 3.041-86.334-5.667-105.667-6-13.911-.239-59.292-4.583-71.75-2.5-.667-4.083-1.5-10.75.95-17.468 14.881-7.246 27.229-21.569 35.341-38.467.922 4.424 6.252 4.929 12.459-14.231 5.662-17.478 2.324-22.254-2.313-22.525.172-2.056.279-4.105.313-6.142.788-48.041-15-78.667-69-78.667s-69.787 30.626-69 78.667c.033 2.036.141 4.086.313 6.142-4.637.271-7.975 5.048-2.313 22.525 6.207 19.16 11.537 18.655 12.459 14.231 8.113 16.897 20.461 31.221 35.342 38.467 2.449 6.718 1.617 13.385.949 17.468-12.457-2.083-57.838 2.261-71.75 2.5-19.332.333-81.85 9.041-105.666 6-31.333-4-101.337 3.056-138.156 2.062-.033-.276-.053-.437-.053-.437-2.689-.195-4.564-.666-5.791-.958-8.096-1.927-17.611-2.489-33.334-5.167-11.469-1.953-26-8.5-37.5-6.5-3.367.586 6 9.834 15.5 12.334 13.635 3.588 25.25 10.666 36 13.166-2.25 3.75-15.59 7.063-23 12-5.336 3.557 6.5 6.5 12 5 20.842-5.684 22.973.389 37.514-9.019 30.078 4.078 102.537 20.514 122.154 14.186 12.457-4.018 100.332 7.083 142.332 5.833 6.039-.18 1.656 65.563 2 73.5 3 69-16.842 133.135-18.666 169.667-1.92 38.42-3.42 57.919 7.666 131.333 6.967 46.126-2.521 82.079-2 94 6 137 29 172 4 221-14 27.44 67.449 26.958 65 9-3.012-22.092-12.666-22.333-10.666-46.333 1.896-22.768 16.049-151.298 8.666-206.667-2-15 0-26 2-66 2.355-47.101 7-88 14-123 7 35 11.645 75.899 14 123 2 40 4 51 2 66-7.383 55.369 6.77 183.899 8.667 206.667 2 24-7.654 24.241-10.667 46.333-2.449 17.958 79 18.44 65-9-25-49-2-84 4-221 .522-11.921-8.966-47.874-2-94 11.086-73.414 9.586-92.913 7.667-131.333-1.824-36.532-21.667-100.667-18.667-169.667.345-7.938-4.039-73.68 2-73.5 42 1.25 129.876-9.852 142.333-5.833 19.616 6.328 92.076-10.107 122.153-14.186 14.541 9.407 16.673 3.335 37.514 9.019 5.5 1.5 17.336-1.443 12-5-7.409-4.937-20.75-8.25-23-12 10.75-2.5 22.366-9.578 36.001-13.166 9.5-2.5 18.866-11.748 15.499-12.334z" fill="#b2b2b2"/></svg> +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" + y="0px" width="1024px" height="1024px" viewBox="0 0 1024 1024" enable-background="new 0 0 1024 1024" xml:space="preserve"> +<path fill="#3F3F3F" d="M0,0h1024v1024H0V0z"/> +<path fill="#B2B2B2" d="M512,536.162c7,35,11.645,66.898,14,114c2,40,4,51,2,66c-7.384,55.369,6.77,183.898,8.666,206.667 + c2,24-7.653,24.241-10.666,46.333c-2.449,17.958,79,18.439,65-9c-25-49-2-84,4-221c0.521-11.921-8.967-47.874-2-94 + c11.086-73.414,8.42-107.242,6.5-145.662c-1.245-31.973-1-56.963-9-138.963c-0.976-10.002,5.915-79.268,11.954-79.088 + c42,1.25,97.313-5.009,118.145-14.68c28.901,3.73,97.81-12.047,127.887-16.126c14.541,9.407,16.673,3.335,37.515,9.019 + c5.5,1.5,17.336-1.443,12-5c-7.409-4.937-20.75-8.25-23-12c10.75-2.5,22.365-9.578,36-13.166c9.5-2.5,18.866-11.748,15.5-12.334l0,0 + c-11.5-2-26.03,4.547-37.5,6.5c-15.724,2.678-25.238,3.24-33.334,5.167c-1.227,0.292-3.103,0.763-5.791,0.958 + c0,0-0.02,0.16-0.053,0.437c-36.818,0.994-80.322-9.724-130.31-5.569c-34.026-3.925-94.181-5.16-113.513-5.493 + c-13.911-0.239-59.293-2.583-71.75-0.5c-0.668-4.083-1.5-9.75,0.949-16.468c14.881-7.246,19.188-17.796,27.301-34.694 + c0.922,4.424,6.252,4.929,12.459-14.231c5.661-17.478,2.323-22.254-2.313-22.525c0.172-2.056,0.279-4.105,0.313-6.142 + C573.746,76.562,566,42.163,512,42.163s-61.746,34.399-60.959,82.44c0.034,2.037,0.142,4.086,0.313,6.142 + c-4.637,0.271-7.975,5.047-2.313,22.525c6.207,19.16,11.537,18.655,12.459,14.231c8.112,16.898,12.42,27.448,27.301,34.694 + c2.449,6.718,1.617,12.385,0.949,16.468c-12.457-2.083-57.839,0.261-71.75,0.5c-19.332,0.333-79.486,1.568-113.513,5.493 + c-49.987-4.155-93.491,6.563-130.31,5.569c-0.033-0.277-0.053-0.437-0.053-0.437c-2.688-0.195-4.564-0.666-5.791-0.958 + c-8.096-1.927-17.61-2.489-33.334-5.167c-11.47-1.953-26-8.5-37.5-6.5l0,0c-3.366,0.586,6,9.834,15.5,12.334 + c13.635,3.588,25.25,10.666,36,13.166c-2.25,3.75-15.591,7.063-23,12c-5.336,3.557,6.5,6.5,12,5 + c20.842-5.684,22.974,0.388,37.515-9.019c30.077,4.079,98.985,19.857,127.887,16.126c20.832,9.671,76.145,15.93,118.145,14.68 + c6.039-0.18,12.93,69.085,11.954,79.088c-8,82-7.755,106.99-9,138.963c-1.92,38.419-4.586,72.248,6.5,145.662 + c6.967,46.126-2.521,82.079-2,94c6,137,29,172,4,221c-14,27.439,67.449,26.958,65,9c-3.013-22.092-12.666-22.333-10.666-46.333 + c1.896-22.769,16.05-151.298,8.666-206.667c-2-15,0-26,2-66C500.356,603.061,505,571.162,512,536.162z"/> +</svg> diff --git a/editor/icons/CPUParticles3D.svg b/editor/icons/CPUParticles3D.svg index d7ced5fc6b..5001375f80 100644 --- a/editor/icons/CPUParticles3D.svg +++ b/editor/icons/CPUParticles3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.5587261.60940813c-.4226244 0-.7617187.3410473-.7617187.76367177v.5078126c0 .1028478.020058.199689.056641.2890624h-1.1933597c-.4226245 0-.7617188.3390944-.7617188.7617188v.921875c-.040428-.00657-.0767989-.0234375-.1191406-.0234375h-.5078125c-.42262448 0-.76367188.3410475-.76367188.7636719v.3730468c0 .4226245.3410474.7617188.76367188.7617188h.5078125c.042396 0 .078663-.016851.1191406-.023437v4.4531248c-.040428-.0066-.076799-.02344-.1191406-.02344h-.5078125c-.42262448 0-.76367188.341047-.76367188.763672v.373047c0 .422625.3410474.761718.76367188.761718h.5078125c.042396 0 .078663-.01685.1191406-.02344v1.125c0 .422624.3390944.763672.7617188.763672h1.1367187v.457031c0 .422624.3390943.763672.7617187.763672h.3730469c.4226244 0 .7636719-.341048.7636719-.763672v-.457031h4.4062501v.457031c0 .422624.339094.763672.761719.763672h.373047c.422624 0 .763671-.341048.763671-.763672v-.457031h1.269532c.422625 0 .763672-.341048.763672-.763672v-1.111328c.01774.0012.03272.0098.05078.0098h.507812c.422624 0 .763672-.339093.763672-.761718v-.373047c0-.422624-.341048-.763672-.763672-.763672h-.507812c-.01803 0-.03307.0085-.05078.0098v-4.4258454c.01774.00122.03272.00977.05078.00977h.507812c.422624 0 .763672-.3390943.763672-.7617188v-.3730512c0-.4226244-.341048-.7636719-.763672-.7636719h-.507812c-.01803 0-.03307.00855-.05078.00977v-.9082075c0-.4226244-.341047-.7617187-.763672-.7617188h-1.328125c.03658-.089375.05859-.1862118.05859-.2890624v-.5078126c0-.42262437-.341047-.76367177-.763671-.76367177h-.373047c-.422625 0-.761719.3410474-.761719.76367177v.5078126c0 .1028478.02006.1996891.05664.2890624h-4.5214809c.036585-.0893749.0585938-.1862118.0585938-.2890624v-.5078126c0-.42262437-.3410475-.76367177-.7636719-.76367177zm3.2382813 2.35742177a3.279661 3.6440678 0 0 1 3.2128906 2.9394532 2.1864407 2.1864407 0 0 1 1.888672 2.1621094 2.1864407 2.1864407 0 0 1 -2.1875 2.1855475h-5.8300782a2.1864407 2.1864407 0 0 1 -2.1855469-2.1855475 2.1864407 2.1864407 0 0 1 1.8847656-2.1640626 3.279661 3.6440678 0 0 1 3.2167969-2.9375zm-2.9160156 8.0156251a.72881355.72881355 0 0 1 .7285156.728516.72881355.72881355 0 0 1 -.7285156.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm5.8300782 0a.72881355.72881355 0 0 1 .730469.728516.72881355.72881355 0 0 1 -.730469.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm-2.9140626.728516a.72881355.72881355 0 0 1 .7285156.730469.72881355.72881355 0 0 1 -.7285156.728515.72881355.72881355 0 0 1 -.7285156-.728515.72881355.72881355 0 0 1 .7285156-.730469z" fill="#fc7f7f" fill-opacity=".996078"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.5587261.60940813c-.4226244 0-.7617187.3410473-.7617187.76367177v.5078126c0 .1028478.020058.199689.056641.2890624h-1.1933597c-.4226245 0-.7617188.3390944-.7617188.7617188v.921875c-.040428-.00657-.0767989-.0234375-.1191406-.0234375h-.5078125c-.42262448 0-.76367188.3410475-.76367188.7636719v.3730468c0 .4226245.3410474.7617188.76367188.7617188h.5078125c.042396 0 .078663-.016851.1191406-.023437v4.4531248c-.040428-.0066-.076799-.02344-.1191406-.02344h-.5078125c-.42262448 0-.76367188.341047-.76367188.763672v.373047c0 .422625.3410474.761718.76367188.761718h.5078125c.042396 0 .078663-.01685.1191406-.02344v1.125c0 .422624.3390944.763672.7617188.763672h1.1367187v.457031c0 .422624.3390943.763672.7617187.763672h.3730469c.4226244 0 .7636719-.341048.7636719-.763672v-.457031h4.4062501v.457031c0 .422624.339094.763672.761719.763672h.373047c.422624 0 .763671-.341048.763671-.763672v-.457031h1.269532c.422625 0 .763672-.341048.763672-.763672v-1.111328c.01774.0012.03272.0098.05078.0098h.507812c.422624 0 .763672-.339093.763672-.761718v-.373047c0-.422624-.341048-.763672-.763672-.763672h-.507812c-.01803 0-.03307.0085-.05078.0098v-4.4258454c.01774.00122.03272.00977.05078.00977h.507812c.422624 0 .763672-.3390943.763672-.7617188v-.3730512c0-.4226244-.341048-.7636719-.763672-.7636719h-.507812c-.01803 0-.03307.00855-.05078.00977v-.9082075c0-.4226244-.341047-.7617187-.763672-.7617188h-1.328125c.03658-.089375.05859-.1862118.05859-.2890624v-.5078126c0-.42262437-.341047-.76367177-.763671-.76367177h-.373047c-.422625 0-.761719.3410474-.761719.76367177v.5078126c0 .1028478.02006.1996891.05664.2890624h-4.5214809c.036585-.0893749.0585938-.1862118.0585938-.2890624v-.5078126c0-.42262437-.3410475-.76367177-.7636719-.76367177zm3.2382813 2.35742177a3.279661 3.6440678 0 0 1 3.2128906 2.9394532 2.1864407 2.1864407 0 0 1 1.888672 2.1621094 2.1864407 2.1864407 0 0 1 -2.1875 2.1855475h-5.8300782a2.1864407 2.1864407 0 0 1 -2.1855469-2.1855475 2.1864407 2.1864407 0 0 1 1.8847656-2.1640626 3.279661 3.6440678 0 0 1 3.2167969-2.9375zm-2.9160156 8.0156251a.72881355.72881355 0 0 1 .7285156.728516.72881355.72881355 0 0 1 -.7285156.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm5.8300782 0a.72881355.72881355 0 0 1 .730469.728516.72881355.72881355 0 0 1 -.730469.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm-2.9140626.728516a.72881355.72881355 0 0 1 .7285156.730469.72881355.72881355 0 0 1 -.7285156.728515.72881355.72881355 0 0 1 -.7285156-.728515.72881355.72881355 0 0 1 .7285156-.730469z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/CameraTexture.svg b/editor/icons/CameraTexture.svg index adb4762082..91e3fe9b41 100644 --- a/editor/icons/CameraTexture.svg +++ b/editor/icons/CameraTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55228 0-1 .44772-1 1v12c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-12c0-.55228-.44772-1-1-1zm1 2h10v8h-10zm5.8184 1.0039c-.85534.0009758-1.5654.66069-1.6289 1.5137-.30036-.27229-.69029-.4234-1.0957-.42383-.90315 0-1.6367.73162-1.6367 1.6348.0009732.69217.43922 1.3103 1.0918 1.541v1.1855c0 .30198.24293.54492.54492.54492h3.2695c.30199 0 .54492-.24294.54492-.54492v-.54492l1.6367 1.0898v-3.2715l-1.6367 1.0918v-.96484c.34606-.30952.54406-.75251.54492-1.2168 0-.90315-.73162-1.6348-1.6348-1.6348z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55228 0-1 .44772-1 1v12c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-12c0-.55228-.44772-1-1-1zm1 2h10v8h-10zm5.8184 1.0039c-.85534.0009758-1.5654.66069-1.6289 1.5137-.30036-.27229-.69029-.4234-1.0957-.42383-.90315 0-1.6367.73162-1.6367 1.6348.0009732.69217.43922 1.3103 1.0918 1.541v1.1855c0 .30198.24293.54492.54492.54492h3.2695c.30199 0 .54492-.24294.54492-.54492v-.54492l1.6367 1.0898v-3.2715l-1.6367 1.0918v-.96484c.34606-.30952.54406-.75251.54492-1.2168 0-.90315-.73162-1.6348-1.6348-1.6348z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/CanvasItem.svg b/editor/icons/CanvasItem.svg index f396290436..0d9b47613a 100644 --- a/editor/icons/CanvasItem.svg +++ b/editor/icons/CanvasItem.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9208 1046.4c-.26373.3-.4204.7296-.4204 1.2383 0 1.6277-3.1381-.1781-.33757 2.6703.88382.899 2.6544.6701 3.5382-.2288.88384-.899.88382-2.3565 0-3.2554-1.1002-1.1191-2.2001-1.0845-2.7803-.4244zm2.3802-1.6103 2.4005 2.4416 6.8014-6.9177c.66286-.6742.66286-1.7673 0-2.4415-.66288-.6741-1.7376-.6741-2.4005 0z" fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9208 1046.4c-.26373.3-.4204.7296-.4204 1.2383 0 1.6277-3.1381-.1781-.33757 2.6703.88382.899 2.6544.6701 3.5382-.2288.88384-.899.88382-2.3565 0-3.2554-1.1002-1.1191-2.2001-1.0845-2.7803-.4244zm2.3802-1.6103 2.4005 2.4416 6.8014-6.9177c.66286-.6742.66286-1.7673 0-2.4415-.66288-.6741-1.7376-.6741-2.4005 0z" fill="#e0e0e0" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/CanvasLayer.svg b/editor/icons/CanvasLayer.svg index 6e98fd1ba9..87295e6099 100644 --- a/editor/icons/CanvasLayer.svg +++ b/editor/icons/CanvasLayer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2v6h1v-6a1 1 0 0 1 1-1h6v-1zm10.303 0c-.4344 0-.86973.16881-1.2012.50586l-6.8008 6.918 2.4004 2.4414 6.8008-6.918c.66286-.6742.66286-1.7672 0-2.4414-.33144-.33705-.76482-.50586-1.1992-.50586zm.69727 6v6a1 1 0 0 1 -1 1h-6v1h6a2 2 0 0 0 2-2v-6zm-9.8848 2.5781c-.48501-.048725-.90521.12503-1.1953.45508-.26373.3-.41992.72958-.41992 1.2383 0 1.6277-3.1385-.17848-.33789 2.6699.88382.899 2.6552.67038 3.5391-.22852.88384-.899.88382-2.357 0-3.2559-.55011-.55955-1.1009-.83018-1.5859-.87891z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2v6h1v-6a1 1 0 0 1 1-1h6v-1zm10.303 0c-.4344 0-.86973.16881-1.2012.50586l-6.8008 6.918 2.4004 2.4414 6.8008-6.918c.66286-.6742.66286-1.7672 0-2.4414-.33144-.33705-.76482-.50586-1.1992-.50586zm.69727 6v6a1 1 0 0 1 -1 1h-6v1h6a2 2 0 0 0 2-2v-6zm-9.8848 2.5781c-.48501-.048725-.90521.12503-1.1953.45508-.26373.3-.41992.72958-.41992 1.2383 0 1.6277-3.1385-.17848-.33789 2.6699.88382.899 2.6552.67038 3.5391-.22852.88384-.899.88382-2.357 0-3.2559-.55011-.55955-1.1009-.83018-1.5859-.87891z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/CharacterBody3D.svg b/editor/icons/CharacterBody3D.svg index d0def4f14a..21a642cacb 100644 --- a/editor/icons/CharacterBody3D.svg +++ b/editor/icons/CharacterBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1c-.55401 0-1 .44599-1 1v3c0 .55401.44599 1 1 1h1v.99023a1.0001 1.0001 0 0 0 -.31641.0625l-2.0508.68359-.68359-2.0508a1.0001 1.0001 0 0 0 -.99023-.69727 1.0001 1.0001 0 0 0 -.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656.63281l1.6836-.56055v.61133c0 .04088.018715.07566.023437.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109.50195l3-1a1.0001 1.0001 0 1 0 -.63281-1.8965l-2.1777.72461-.97461-1.9512c.2759-.17764.46875-.47227.46875-.82617v-1h1.3828l.72266 1.4473a1.0001 1.0001 0 1 0 1.7891-.89453l-1-2a1.0001 1.0001 0 0 0 -.89453-.55273h-3v-1h1c.55401 0 1-.44599 1-1v-3c0-.55401-.44599-1-1-1zm0 2h1v2h-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1c-.55401 0-1 .44599-1 1v3c0 .55401.44599 1 1 1h1v.99023a1.0001 1.0001 0 0 0 -.31641.0625l-2.0508.68359-.68359-2.0508a1.0001 1.0001 0 0 0 -.99023-.69727 1.0001 1.0001 0 0 0 -.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656.63281l1.6836-.56055v.61133c0 .04088.018715.07566.023437.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109.50195l3-1a1.0001 1.0001 0 1 0 -.63281-1.8965l-2.1777.72461-.97461-1.9512c.2759-.17764.46875-.47227.46875-.82617v-1h1.3828l.72266 1.4473a1.0001 1.0001 0 1 0 1.7891-.89453l-1-2a1.0001 1.0001 0 0 0 -.89453-.55273h-3v-1h1c.55401 0 1-.44599 1-1v-3c0-.55401-.44599-1-1-1zm0 2h1v2h-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/Clear.svg b/editor/icons/Clear.svg index 43c00311bc..577cacba22 100644 --- a/editor/icons/Clear.svg +++ b/editor/icons/Clear.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a1 1 0 0 0 -1 1v5h-2c-1.108 0-2 .892-2 2v1h10v-1c0-1.108-.892-2-2-2h-2v-5a1 1 0 0 0 -1-1zm-5 10v4l10-1v-3z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a1 1 0 0 0 -1 1v5h-2c-1.108 0-2 .892-2 2v1h10v-1c0-1.108-.892-2-2-2h-2v-5a1 1 0 0 0 -1-1zm-5 10v4l10-1v-3z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/CollisionPolygon3D.svg b/editor/icons/CollisionPolygon3D.svg index 57531fa9f4..121bd82685 100644 --- a/editor/icons/CollisionPolygon3D.svg +++ b/editor/icons/CollisionPolygon3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/CollisionShape3D.svg b/editor/icons/CollisionShape3D.svg index 7a8bbf8050..d7f8a308e6 100644 --- a/editor/icons/CollisionShape3D.svg +++ b/editor/icons/CollisionShape3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1050.4-6-3v-6l6-3 6 3v6z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2" transform="translate(0 -1036.399988)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1050.4-6-3v-6l6-3 6 3v6z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.399988)"/></svg> diff --git a/editor/icons/CompressedTexture2D.svg b/editor/icons/CompressedTexture2D.svg index 068f65dead..54ff10b3c1 100644 --- a/editor/icons/CompressedTexture2D.svg +++ b/editor/icons/CompressedTexture2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h6v-2h2v-2h-2-5v-8h5v-2zm6 2v2h2v-2zm2 0h2v-2h-2zm2 0v2h2v-2zm0 2h-2v2h2zm0 2v2h2v-2zm0 2h-2v2h2zm0 2v2h2v-2zm0 2h-2v2h2zm-2-4v-2h-2v-1h-1v1h-1v1h-1v1h-1v1h2 2v-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h6v-2h2v-2h-2-5v-8h5v-2zm6 2v2h2v-2zm2 0h2v-2h-2zm2 0v2h2v-2zm0 2h-2v2h2zm0 2v2h2v-2zm0 2h-2v2h2zm0 2v2h2v-2zm0 2h-2v2h2zm-2-4v-2h-2v-1h-1v1h-1v1h-1v1h-1v1h2 2v-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/CurveTexture.svg b/editor/icons/CurveTexture.svg index 761fb9a45b..f5a2eec195 100644 --- a/editor/icons/CurveTexture.svg +++ b/editor/icons/CurveTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55228 0-1 .44772-1 1v9.1602c.32185-.10966.66-.16382 1-.16016.33117 0 .66575-.007902 1-.013672v-7.9863h10v1.1348c.29007-.10393.59442-.16256.90234-.17383.37315-.012796.74541.044169 1.0977.16797v-2.1289c0-.55228-.44772-1-1-1h-12zm7 4v1h-1v1h-2v1h-1v1h-1v1h2 2 .39062c1.1119-.56677 1.9678-1.4538 2.6094-3.4727v-.52734h-1v-1h-1zm4.9668.98828a1.0001 1.0001 0 0 0 -.92774.73828c-.92743 3.246-2.6356 4.6825-4.6523 5.4668-2.0168.7843-4.3867.80664-6.3867.80664a1.0001 1.0001 0 1 0 0 2c2 0 4.6301.023994 7.1133-.94141 2.4832-.9657 4.7751-3.0292 5.8477-6.7832a1.0001 1.0001 0 0 0 -.99414-1.2871z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55228 0-1 .44772-1 1v9.1602c.32185-.10966.66-.16382 1-.16016.33117 0 .66575-.007902 1-.013672v-7.9863h10v1.1348c.29007-.10393.59442-.16256.90234-.17383.37315-.012796.74541.044169 1.0977.16797v-2.1289c0-.55228-.44772-1-1-1h-12zm7 4v1h-1v1h-2v1h-1v1h-1v1h2 2 .39062c1.1119-.56677 1.9678-1.4538 2.6094-3.4727v-.52734h-1v-1h-1zm4.9668.98828a1.0001 1.0001 0 0 0 -.92774.73828c-.92743 3.246-2.6356 4.6825-4.6523 5.4668-2.0168.7843-4.3867.80664-6.3867.80664a1.0001 1.0001 0 1 0 0 2c2 0 4.6301.023994 7.1133-.94141 2.4832-.9657 4.7751-3.0292 5.8477-6.7832a1.0001 1.0001 0 0 0 -.99414-1.2871z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/DebugSkipBreakpointsOff.svg b/editor/icons/DebugSkipBreakpointsOff.svg index aef0d45a05..c0b6e8d188 100644 --- a/editor/icons/DebugSkipBreakpointsOff.svg +++ b/editor/icons/DebugSkipBreakpointsOff.svg @@ -1 +1,2 @@ -<svg height="17" viewBox="0 0 17 17" width="17" xmlns="http://www.w3.org/2000/svg"><path d="m4.8983252 3.006855a1.6192284 1.3289529 0 0 1 -.0000431.0097" stroke-width=".626319"/><path d="m8.796752 5.0553513a2.563139 3.6270869 0 0 1 -.0000683.02648" stroke-width=".626319"/><path d="m13.121337 4.512148a6.1594577 6.0545759 0 0 1 -.248787 8.20109 6.1594577 6.0545759 0 0 1 -8.3355404.427215 6.1594577 6.0545759 0 0 1 -1.1151058-8.1311866 6.1594577 6.0545759 0 0 1 8.1530832-1.7576713" fill="#fc7f7f" fill-opacity=".996078" stroke-width="1.019123"/></svg> +<svg height="17" width="17" xmlns="http://www.w3.org/2000/svg"><circle cx="8.5" cy="8.5" r="6" fill="#fc7f7f" stroke-width="1"/></svg> + diff --git a/editor/icons/DebugSkipBreakpointsOn.svg b/editor/icons/DebugSkipBreakpointsOn.svg index d8fbc6e43a..abea9579cf 100644 --- a/editor/icons/DebugSkipBreakpointsOn.svg +++ b/editor/icons/DebugSkipBreakpointsOn.svg @@ -1 +1,2 @@ -<svg height="17" viewBox="0 0 17 17" width="17" xmlns="http://www.w3.org/2000/svg"><path d="m4.8983252 3.006855a1.6192284 1.3289529 0 0 1 -.0000431.0097" stroke-width=".626319"/><path d="m8.796752 5.0553513a2.563139 3.6270869 0 0 1 -.0000683.02648" stroke-width=".626319"/><path d="m13.121337 4.512148a6.1594577 6.0545759 0 0 1 -.248787 8.20109 6.1594577 6.0545759 0 0 1 -8.3355404.427215 6.1594577 6.0545759 0 0 1 -1.1151058-8.1311866 6.1594577 6.0545759 0 0 1 8.1530832-1.7576713" fill="#fc7f7f" fill-opacity=".996078" stroke-width="1.019123"/><path d="m-9.290675 10.816157h18.575495v2.518711h-18.575495z" fill="#e0e0e0" stroke-width="1.187332" transform="matrix(.70605846 -.70815355 .70605846 .70815355 0 0)"/></svg> +<svg height="17" width="17" xmlns="http://www.w3.org/2000/svg"><circle cx="8.5" cy="8.5" r="6" fill="#fc7f7f" stroke-width="1"/><path d="M1.077 14.239 14.192 1.084l1.779 1.784L2.855 16.022z" fill="#e0e0e0"/></svg> + diff --git a/editor/icons/DirectionalLight3D.svg b/editor/icons/DirectionalLight3D.svg index ef25fd473a..a7c05452de 100644 --- a/editor/icons/DirectionalLight3D.svg +++ b/editor/icons/DirectionalLight3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-2.5352 2.0508-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-3.5352 1.9492c-1.6569 0-3 1.3432-3 3s1.3431 3 3 3 3-1.3432 3-3-1.3431-3-3-3zm-7 2v2h3v-2zm11 0v2h3v-2zm-7.5352 3.1211-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.5352 1.8789v3h2v-3z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-2.5352 2.0508-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-3.5352 1.9492c-1.6569 0-3 1.3432-3 3s1.3431 3 3 3 3-1.3432 3-3-1.3431-3-3-3zm-7 2v2h3v-2zm11 0v2h3v-2zm-7.5352 3.1211-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.5352 1.8789v3h2v-3z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/EditorPlugin.svg b/editor/icons/EditorPlugin.svg index 7008762fa8..8fab923c6d 100644 --- a/editor/icons/EditorPlugin.svg +++ b/editor/icons/EditorPlugin.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v8c.0000552.5523.44774.9999 1 1h3v.27148a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-.26953h3c.55226-.0001.99994-.4477 1-1v-3h.27148a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-.26953v-3c-.000055-.5523-.44774-.9999-1-1h-8z" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v8c.0000552.5523.44774.9999 1 1h3v.27148a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-.26953h3c.55226-.0001.99994-.4477 1-1v-3h.27148a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-.26953v-3c-.000055-.5523-.44774-.9999-1-1h-8z" fill="#e0e0e0" fill-rule="evenodd"/></svg> diff --git a/editor/icons/Eraser.svg b/editor/icons/Eraser.svg index 4995fa863c..c9be2569ef 100644 --- a/editor/icons/Eraser.svg +++ b/editor/icons/Eraser.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.228155 1.5447161-9.60250173 9.6107429 1.41421353 1.414213 1.6134635 1.885612.00693-.0069 4.2288056.000024 7.4852811-7.4852817zm-4.4456043 7.2823178 2.3136653 2.5858141-1.0357479 1.035746h-2.5853592l-1.0209853-1.293133z" fill="#e0e0e0" fill-opacity=".996078" stroke-width="1.02405"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.228155 1.5447161-9.60250173 9.6107429 1.41421353 1.414213 1.6134635 1.885612.00693-.0069 4.2288056.000024 7.4852811-7.4852817zm-4.4456043 7.2823178 2.3136653 2.5858141-1.0357479 1.035746h-2.5853592l-1.0209853-1.293133z" fill="#e0e0e0" stroke-width="1.02405"/></svg> diff --git a/editor/icons/FogVolume.svg b/editor/icons/FogVolume.svg index b0a18eb29d..89ee466db4 100644 --- a/editor/icons/FogVolume.svg +++ b/editor/icons/FogVolume.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><g fill-opacity=".996078"><path d="m4.5 9.0000002c-.2761429-.0000014-.5000014.2238571-.5.5-.0000014.2761429.2238571.5000008.5.4999998l8-.0000002c.276143.0000012.500001-.2238569.5-.4999998.000001-.2761429-.223857-.5000014-.5-.5z"/><path d="m3.5 11c-.2761429-.000001-.5000014.223857-.5.5-.0000014.276143.2238571.500001.5.5h5c.2761429.000001.500001-.223857.5-.5.000001-.276143-.2238571-.500001-.5-.5z"/><path d="m5.5 13c-.2761424 0-.5.223858-.5.5s.2238576.5.5.5h5c.276142 0 .5-.223858.5-.5s-.223858-.5-.5-.5z"/></g><path d="m2.5 8s-1.5 0-1.5-1.5 2-1.5 2-1.5 0-4 3.5-4 3.5 3 3.5 3 1.260711-2 3-1 .5 3 .5 3 1.5 0 1.5 1-1 1-1 1z" fill-opacity=".99608"/><path d="m10.5 11c-.276143-.000001-.500001.223857-.5.5-.000001.276143.223857.500001.5.5h2.5c.276143.000001.500001-.223857.5-.5.000001-.276143-.223857-.500001-.5-.5z" fill-opacity=".996078"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><g><path d="m4.5 9.0000002c-.2761429-.0000014-.5000014.2238571-.5.5-.0000014.2761429.2238571.5000008.5.4999998l8-.0000002c.276143.0000012.500001-.2238569.5-.4999998.000001-.2761429-.223857-.5000014-.5-.5z"/><path d="m3.5 11c-.2761429-.000001-.5000014.223857-.5.5-.0000014.276143.2238571.500001.5.5h5c.2761429.000001.500001-.223857.5-.5.000001-.276143-.2238571-.500001-.5-.5z"/><path d="m5.5 13c-.2761424 0-.5.223858-.5.5s.2238576.5.5.5h5c.276142 0 .5-.223858.5-.5s-.223858-.5-.5-.5z"/></g><path d="m2.5 8s-1.5 0-1.5-1.5 2-1.5 2-1.5 0-4 3.5-4 3.5 3 3.5 3 1.260711-2 3-1 .5 3 .5 3 1.5 0 1.5 1-1 1-1 1z"/><path d="m10.5 11c-.276143-.000001-.500001.223857-.5.5-.000001.276143.223857.500001.5.5h2.5c.276143.000001.500001-.223857.5-.5.000001-.276143-.223857-.500001-.5-.5z"/></g></svg> diff --git a/editor/icons/GPUParticles3D.svg b/editor/icons/GPUParticles3D.svg index bbc90ec35f..521a93efc6 100644 --- a/editor/icons/GPUParticles3D.svg +++ b/editor/icons/GPUParticles3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -4.4141 4.0312 3 3 0 0 0 -2.5859 2.9688 3 3 0 0 0 3 3h8a3 3 0 0 0 3-3 3 3 0 0 0 -2.5898-2.9668 4.5 5 0 0 0 -4.4102-4.0332zm-4 11a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -4.4141 4.0312 3 3 0 0 0 -2.5859 2.9688 3 3 0 0 0 3 3h8a3 3 0 0 0 3-3 3 3 0 0 0 -2.5898-2.9668 4.5 5 0 0 0 -4.4102-4.0332zm-4 11a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/GPUParticlesAttractorBox3D.svg b/editor/icons/GPUParticlesAttractorBox3D.svg index 7a2ee7a6b9..fdf65d11cb 100644 --- a/editor/icons/GPUParticlesAttractorBox3D.svg +++ b/editor/icons/GPUParticlesAttractorBox3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#fc7f7f" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc7f7f" stroke-opacity=".996078"><ellipse cx="8" cy="-8" rx="2.339226" ry="4.949748" transform="rotate(90)"/><ellipse cx="8" cy="8" rx="2.339226" ry="4.949748"/><path d="m1.498906 1.498906h13.002189v13.002188h-13.002189z" stroke-width=".997813"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#fc7f7f" r="1"/><g fill="none" stroke="#fc7f7f"><ellipse cx="8" cy="-8" rx="2.339226" ry="4.949748" transform="rotate(90)"/><ellipse cx="8" cy="8" rx="2.339226" ry="4.949748"/><path d="m1.498906 1.498906h13.002189v13.002188h-13.002189z" stroke-width=".997813"/></g></svg> diff --git a/editor/icons/GPUParticlesAttractorSphere3D.svg b/editor/icons/GPUParticlesAttractorSphere3D.svg index 2215331a18..15a8016827 100644 --- a/editor/icons/GPUParticlesAttractorSphere3D.svg +++ b/editor/icons/GPUParticlesAttractorSphere3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-8" cy="-7.999999" fill="none" rx="6.499003" ry="6.499001" stroke="#fc7f7f" stroke-opacity=".996078" stroke-width="1.002" transform="scale(-1)"/><circle cx="8" cy="8" fill="#fc7f7f" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc7f7f" stroke-opacity=".996078"><ellipse cx="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 .70710678 -.70710678 .70710678 0 0)"/><ellipse cy="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 0)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-8" cy="-7.999999" fill="none" rx="6.499003" ry="6.499001" stroke="#fc7f7f" stroke-width="1.002" transform="scale(-1)"/><circle cx="8" cy="8" fill="#fc7f7f" r="1"/><g fill="none" stroke="#fc7f7f"><ellipse cx="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 .70710678 -.70710678 .70710678 0 0)"/><ellipse cy="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 0)"/></g></svg> diff --git a/editor/icons/GPUParticlesAttractorVectorField3D.svg b/editor/icons/GPUParticlesAttractorVectorField3D.svg index 87b2b21804..c9e0b4fae3 100644 --- a/editor/icons/GPUParticlesAttractorVectorField3D.svg +++ b/editor/icons/GPUParticlesAttractorVectorField3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="6.663637" cy="9.245457" fill="#fc7f7f" fill-opacity=".996078" rx="1.030661" ry=".998146"/><ellipse cx="-6.672815" cy="-9.387111" fill="none" rx="2.408711" ry="5.096776" stroke="#fc7f7f" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.99999945 .00104887 .00104887 -.99999945 0 0)"/><ellipse cx="9.387111" cy="-6.672815" fill="none" rx="2.408711" ry="5.096776" stroke="#fc7f7f" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.00104887 .99999945 -.99999945 .00104887 0 0)"/><g fill="#fc7f7f" fill-opacity=".996078"><path d="m11.8 15 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/><path d="m11 6 3-3 1 1v-3h-3l1 1-3 3z"/><path d="m1.8 5 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="6.663637" cy="9.245457" fill="#fc7f7f" rx="1.030661" ry=".998146"/><ellipse cx="-6.672815" cy="-9.387111" fill="none" rx="2.408711" ry="5.096776" stroke="#fc7f7f" stroke-width="1.0297" transform="matrix(-.99999945 .00104887 .00104887 -.99999945 0 0)"/><ellipse cx="9.387111" cy="-6.672815" fill="none" rx="2.408711" ry="5.096776" stroke="#fc7f7f" stroke-width="1.0297" transform="matrix(-.00104887 .99999945 -.99999945 .00104887 0 0)"/><g fill="#fc7f7f"><path d="m11.8 15 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/><path d="m11 6 3-3 1 1v-3h-3l1 1-3 3z"/><path d="m1.8 5 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionBox3D.svg b/editor/icons/GPUParticlesCollisionBox3D.svg index 4f7325d086..ca595f16eb 100644 --- a/editor/icons/GPUParticlesCollisionBox3D.svg +++ b/editor/icons/GPUParticlesCollisionBox3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f" fill-opacity=".996078"><path d="m7.5 2.8124998-5.5883107 2.7941554v5.7660988l5.5883107 2.794155 5.588311-2.794155v-5.7660988zm0 1.6886278 3.145021 1.5732692-3.145021 1.5717523-3.1450214-1.5717523zm-3.9916505 2.8362274 3.1933204 1.5966602v3.1465378l-3.1933204-1.598256zm7.9833015 0v3.145021l-3.1933209 1.598257v-3.146538z" stroke-width=".851579"/><circle cx="1.875" cy="3.75" r=".9375"/><circle cx="13.124999" cy="3.75" r=".9375"/><circle cx="9.374999" cy="1.875" r=".9375"/><circle cx="5.625" cy="1.875" r=".9375"/></g></svg> +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><path d="m7.5 2.8124998-5.5883107 2.7941554v5.7660988l5.5883107 2.794155 5.588311-2.794155v-5.7660988zm0 1.6886278 3.145021 1.5732692-3.145021 1.5717523-3.1450214-1.5717523zm-3.9916505 2.8362274 3.1933204 1.5966602v3.1465378l-3.1933204-1.598256zm7.9833015 0v3.145021l-3.1933209 1.598257v-3.146538z" stroke-width=".851579"/><circle cx="1.875" cy="3.75" r=".9375"/><circle cx="13.124999" cy="3.75" r=".9375"/><circle cx="9.374999" cy="1.875" r=".9375"/><circle cx="5.625" cy="1.875" r=".9375"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionSDF3D.svg b/editor/icons/GPUParticlesCollisionSDF3D.svg index 00eca8295d..38fe6c49f8 100644 --- a/editor/icons/GPUParticlesCollisionSDF3D.svg +++ b/editor/icons/GPUParticlesCollisionSDF3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 14h-12v-9s3 4 5.9999999 3.9999999c3.0000001-.0000001 6.0000001-3.9999999 6.0000001-3.9999999z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-opacity=".996078" stroke-width="2"/><g fill="#fc7f7f" fill-opacity=".996078"><circle cx="2" cy="2" r="1"/><circle cx="14" cy="2" r="1"/><circle cx="10" cy="5" r="1"/><circle cx="6" cy="5" r="1"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 14h-12v-9s3 4 5.9999999 3.9999999c3.0000001-.0000001 6.0000001-3.9999999 6.0000001-3.9999999z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-width="2"/><g fill="#fc7f7f"><circle cx="2" cy="2" r="1"/><circle cx="14" cy="2" r="1"/><circle cx="10" cy="5" r="1"/><circle cx="6" cy="5" r="1"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionSphere3D.svg b/editor/icons/GPUParticlesCollisionSphere3D.svg index cd188ddacc..4aa3f7c5bf 100644 --- a/editor/icons/GPUParticlesCollisionSphere3D.svg +++ b/editor/icons/GPUParticlesCollisionSphere3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f" fill-opacity=".996078"><path d="m8 3.0532484c-3.2888554 0-5.9733758 2.6845204-5.9733758 5.9733758 0 3.2889408 2.6845204 5.9733758 5.9733758 5.9733758 3.288855 0 5.973376-2.684435 5.973376-5.9733758 0-3.2888554-2.684521-5.9733758-5.973376-5.9733758zm-.8533394 1.79005v4.1567016c-1.1034532-.0608789-2.2238878-.2544573-3.3650586-.5900074.256693-1.7901354 1.6087154-3.2141029 3.3650586-3.5667027zm1.7066788 0c1.7535276.3520281 3.1035956 1.77213 3.3633516 3.55834-1.113266.3129793-2.2321649.5142138-3.3633516.5866709zm3.2300606 5.3599956c-.434043 1.51792-1.663927 2.690664-3.2300606 3.005035v-2.518376c1.0915918-.0617 2.1691036-.227875 3.2300606-.486668zm-8.161765.015c1.0865571.272147 2.162106.428504 3.2250256.480003v2.510013c-1.5608431-.313338-2.7870065-1.479605-3.2250256-2.990016z" stroke-width=".853339"/><circle cx="2" cy="5" r="1"/><circle cx="14" cy="5" r="1"/><circle cx="10" cy="2" r="1"/><circle cx="6" cy="2" r="1"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><path d="m8 3.0532484c-3.2888554 0-5.9733758 2.6845204-5.9733758 5.9733758 0 3.2889408 2.6845204 5.9733758 5.9733758 5.9733758 3.288855 0 5.973376-2.684435 5.973376-5.9733758 0-3.2888554-2.684521-5.9733758-5.973376-5.9733758zm-.8533394 1.79005v4.1567016c-1.1034532-.0608789-2.2238878-.2544573-3.3650586-.5900074.256693-1.7901354 1.6087154-3.2141029 3.3650586-3.5667027zm1.7066788 0c1.7535276.3520281 3.1035956 1.77213 3.3633516 3.55834-1.113266.3129793-2.2321649.5142138-3.3633516.5866709zm3.2300606 5.3599956c-.434043 1.51792-1.663927 2.690664-3.2300606 3.005035v-2.518376c1.0915918-.0617 2.1691036-.227875 3.2300606-.486668zm-8.161765.015c1.0865571.272147 2.162106.428504 3.2250256.480003v2.510013c-1.5608431-.313338-2.7870065-1.479605-3.2250256-2.990016z" stroke-width=".853339"/><circle cx="2" cy="5" r="1"/><circle cx="14" cy="5" r="1"/><circle cx="10" cy="2" r="1"/><circle cx="6" cy="2" r="1"/></g></svg> diff --git a/editor/icons/GradientTexture1D.svg b/editor/icons/GradientTexture1D.svg index fa03e69805..9be4b00329 100644 --- a/editor/icons/GradientTexture1D.svg +++ b/editor/icons/GradientTexture1D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m12.5 10.5v-7h-3v1h-1v1h1v1h-1v1h1v1h-1v1h1v1zm-4-1h-1v1h1zm-1 0v-1h-1v1zm0-1h1v-1h-1zm0-1v-1h-1v1zm0-1h1v-1h-1zm0-1v-1h-1v1zm0-1h1v-1h-1z" stroke-width=".787342"/><path d="m2 1c-.552285 0-1 .4477153-1 1v12.000001c0 .552285.447715 1 1 1h11.999999c.552285 0 1-.447715 1-1v-12.000001c0-.5522847-.447715-1-1-1zm1 2.0000001h9.999999v8.0000009h-9.999999z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m12.5 10.5v-7h-3v1h-1v1h1v1h-1v1h1v1h-1v1h1v1zm-4-1h-1v1h1zm-1 0v-1h-1v1zm0-1h1v-1h-1zm0-1v-1h-1v1zm0-1h1v-1h-1zm0-1v-1h-1v1zm0-1h1v-1h-1z" stroke-width=".787342"/><path d="m2 1c-.552285 0-1 .4477153-1 1v12.000001c0 .552285.447715 1 1 1h11.999999c.552285 0 1-.447715 1-1v-12.000001c0-.5522847-.447715-1-1-1zm1 2.0000001h9.999999v8.0000009h-9.999999z"/></g></svg> diff --git a/editor/icons/GuiVisibilityHidden.svg b/editor/icons/GuiVisibilityHidden.svg index 6152fe8acf..1052d6dfcb 100644 --- a/editor/icons/GuiVisibilityHidden.svg +++ b/editor/icons/GuiVisibilityHidden.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9609 7.7266-1.9219.54883c.31999 1.12.8236 2.0593 1.4316 2.8398l-.83398.83398 1.4141 1.4141.84375-.84375c.98585.74762 2.0766 1.2067 3.1055 1.3867v1.0938h2v-1.0938c1.0288-.17998 2.1196-.6391 3.1055-1.3867l.84375.84375 1.4141-1.4141-.83398-.83398c.60804-.78055 1.1117-1.7199 1.4316-2.8398l-1.9219-.54883c-.8756 3.0646-3.5391 4.2734-5.0391 4.2734s-4.1635-1.2088-5.0391-4.2734z" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9609 7.7266-1.9219.54883c.31999 1.12.8236 2.0593 1.4316 2.8398l-.83398.83398 1.4141 1.4141.84375-.84375c.98585.74762 2.0766 1.2067 3.1055 1.3867v1.0938h2v-1.0938c1.0288-.17998 2.1196-.6391 3.1055-1.3867l.84375.84375 1.4141-1.4141-.83398-.83398c.60804-.78055 1.1117-1.7199 1.4316-2.8398l-1.9219-.54883c-.8756 3.0646-3.5391 4.2734-5.0391 4.2734s-4.1635-1.2088-5.0391-4.2734z" fill="#e0e0e0" fill-rule="evenodd"/></svg> diff --git a/editor/icons/GuiVisibilityVisible.svg b/editor/icons/GuiVisibilityVisible.svg index 32eaea633b..96659eb655 100644 --- a/editor/icons/GuiVisibilityVisible.svg +++ b/editor/icons/GuiVisibilityVisible.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.00586.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.00586.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#e0e0e0" fill-rule="evenodd"/></svg> diff --git a/editor/icons/GuiVisibilityXray.svg b/editor/icons/GuiVisibilityXray.svg index 109911df45..29ca9d0810 100644 --- a/editor/icons/GuiVisibilityXray.svg +++ b/editor/icons/GuiVisibilityXray.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-rule="evenodd"><path d="m7.9998 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.00586.5703c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.5527c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill-opacity=".39216"/><path d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.00586.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246v-2a4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-rule="evenodd"><path d="m7.9998 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.00586.5703c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.5527c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill-opacity=".39216"/><path d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.00586.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246v-2a4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2z"/></g></svg> diff --git a/editor/icons/HTTPRequest.svg b/editor/icons/HTTPRequest.svg index 1a2187fe15..34912dcd2b 100644 --- a/editor/icons/HTTPRequest.svg +++ b/editor/icons/HTTPRequest.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1-3 4h2v3h2v-3h2zm7 0v3h-2l3 4 3-4h-2v-3zm-10 9v2 1 2h1v-2h1v2h1v-5h-1v2h-1v-2zm4 0v1h1v4h1v-4h1v-1zm4 0v1h1v4h1v-4h1v-1zm4 0v2 1 2h1v-2h1 1v-1-2h-2zm1 1h1v1h-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1-3 4h2v3h2v-3h2zm7 0v3h-2l3 4 3-4h-2v-3zm-10 9v2 1 2h1v-2h1v2h1v-5h-1v2h-1v-2zm4 0v1h1v4h1v-4h1v-1zm4 0v1h1v4h1v-4h1v-1zm4 0v2 1 2h1v-2h1 1v-1-2h-2zm1 1h1v1h-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/History.svg b/editor/icons/History.svg index 45bc565088..cb1bb4178f 100644 --- a/editor/icons/History.svg +++ b/editor/icons/History.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/><path d="m8 1041.4h2v4h-2z"/><path d="m8 1043.4h4v2h-4z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/><path d="m8 1041.4h2v4h-2z"/><path d="m8 1043.4h4v2h-4z"/></g></svg> diff --git a/editor/icons/Hsize.svg b/editor/icons/Hsize.svg index c7b62e58c8..cf805fce50 100644 --- a/editor/icons/Hsize.svg +++ b/editor/icons/Hsize.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 7v-2l-3 3 3 3v-2h8v2l3-3-3-3v2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 7v-2l-3 3 3 3v-2h8v2l3-3-3-3v2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Image.svg b/editor/icons/Image.svg index ddf97ec59e..a990974a4f 100644 --- a/editor/icons/Image.svg +++ b/editor/icons/Image.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-12a1 1 0 0 0 -1-1zm1 2h10v8h-10zm6 2-1.5 2.5-.70117 1.168-.099609-.16797-.89844-1.5-.90039 1.5-.90039 1.5h1.8008.19922 1.5996 1.4004 3l-1.5-2.5-1.5-2.5z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-12a1 1 0 0 0 -1-1zm1 2h10v8h-10zm6 2-1.5 2.5-.70117 1.168-.099609-.16797-.89844-1.5-.90039 1.5-.90039 1.5h1.8008.19922 1.5996 1.4004 3l-1.5-2.5-1.5-2.5z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/ImageTexture.svg b/editor/icons/ImageTexture.svg index 013e847db3..25d4b53d00 100644 --- a/editor/icons/ImageTexture.svg +++ b/editor/icons/ImageTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-12a1 1 0 0 0 -1-1zm1 2h10v8h-10zm6 2v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-2h-1v-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-12a1 1 0 0 0 -1-1zm1 2h10v8h-10zm6 2v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-2h-1v-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/JoyAxis.svg b/editor/icons/JoyAxis.svg index 1ab65f0af0..11c694aede 100644 --- a/editor/icons/JoyAxis.svg +++ b/editor/icons/JoyAxis.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m27 1038.4h7v14h-7z" fill="#fff" fill-opacity=".99608"/><g fill="#e0e0e0"><path d="m3 1a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h12v-14zm4 2h2a1 1 0 0 1 1 1v2h2a1 1 0 0 1 1 1v2a1 1 0 0 1 -1 1h-2v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1-1v-2h-2a1 1 0 0 1 -1-1v-2a1 1 0 0 1 1-1h2v-2a1 1 0 0 1 1-1z" fill-opacity=".99608" transform="translate(0 1036.4)"/><circle cx="8" cy="1044.4" r="1"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m27 1038.4h7v14h-7z" fill="#fff"/><g fill="#e0e0e0"><path d="m3 1a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h12v-14zm4 2h2a1 1 0 0 1 1 1v2h2a1 1 0 0 1 1 1v2a1 1 0 0 1 -1 1h-2v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1-1v-2h-2a1 1 0 0 1 -1-1v-2a1 1 0 0 1 1-1h2v-2a1 1 0 0 1 1-1z" transform="translate(0 1036.4)"/><circle cx="8" cy="1044.4" r="1"/></g></g></svg> diff --git a/editor/icons/JoyButton.svg b/editor/icons/JoyButton.svg index 080d91ad53..d3d6e22929 100644 --- a/editor/icons/JoyButton.svg +++ b/editor/icons/JoyButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".99608" transform="translate(0 -1036.4)"><path d="m27 1038.4h7v14h-7z" fill="#fff"/><path d="m1 1v14h12c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm7 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-4 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-4 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m27 1038.4h7v14h-7z" fill="#fff"/><path d="m1 1v14h12c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm7 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-4 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-4 4a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/Joypad.svg b/editor/icons/Joypad.svg index 3c6bbf2980..ead745379b 100644 --- a/editor/icons/Joypad.svg +++ b/editor/icons/Joypad.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 3c-.55226.0000552-.99994.44774-1 1v8c.0000552.55226.44774.99994 1 1h14c.55226-.000055.99994-.44774 1-1v-8c-.000055-.55226-.44774-.99994-1-1zm2 2h2v2h2v2h-2v2h-2v-2h-2v-2h2zm10.5 0a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1 -1.5 1.5 1.5 1.5 0 0 1 -1.5-1.5 1.5 1.5 0 0 1 1.5-1.5zm-3 3a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1 -1.5 1.5 1.5 1.5 0 0 1 -1.5-1.5 1.5 1.5 0 0 1 1.5-1.5z" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 3c-.55226.0000552-.99994.44774-1 1v8c.0000552.55226.44774.99994 1 1h14c.55226-.000055.99994-.44774 1-1v-8c-.000055-.55226-.44774-.99994-1-1zm2 2h2v2h2v2h-2v2h-2v-2h-2v-2h2zm10.5 0a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1 -1.5 1.5 1.5 1.5 0 0 1 -1.5-1.5 1.5 1.5 0 0 1 1.5-1.5zm-3 3a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1 -1.5 1.5 1.5 1.5 0 0 1 -1.5-1.5 1.5 1.5 0 0 1 1.5-1.5z" fill="#e0e0e0" fill-rule="evenodd"/></svg> diff --git a/editor/icons/Key.svg b/editor/icons/Key.svg index 544ebe5a47..01bf51dbd8 100644 --- a/editor/icons/Key.svg +++ b/editor/icons/Key.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11 4a4 4 0 0 0 -3.8691 3h-6.1309v2h1v2h3v-2h2.1328a4 4 0 0 0 3.8672 3 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11 4a4 4 0 0 0 -3.8691 3h-6.1309v2h1v2h3v-2h2.1328a4 4 0 0 0 3.8672 3 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/KeyNext.svg b/editor/icons/KeyNext.svg index 83a8329494..47387c875a 100644 --- a/editor/icons/KeyNext.svg +++ b/editor/icons/KeyNext.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/><path d="m11 1a4 4 0 0 0 -3.8691 3h-6.1309v2h1v2h3v-2h2.1328a4 4 0 0 0 2.8672 2.8691v-.86914h3.6387a4 4 0 0 0 1.3613-3 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/><path d="m11 1a4 4 0 0 0 -3.8691 3h-6.1309v2h1v2h3v-2h2.1328a4 4 0 0 0 2.8672 2.8691v-.86914h3.6387a4 4 0 0 0 1.3613-3 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/KeyPosition.svg b/editor/icons/KeyPosition.svg index 260a6f582f..c0fa703462 100644 --- a/editor/icons/KeyPosition.svg +++ b/editor/icons/KeyPosition.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-.195 0-.38964.07519-.53906.22461l-3.2363 3.2363c-.29884.29884-.29884.77929 0 1.0781l3.2363 3.2363c.29884.29884.77929.29884 1.0781 0l3.2363-3.2363c.29884-.29884.29884-.77929 0-1.0781l-3.2363-3.2363c-.14942-.14942-.34406-.22461-.53906-.22461zm-7 7v5c0 1.6569 1.3471 3.114 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1v-5zm7 2c-1.645 0-3 1.355-3 3s1.355 3 3 3 3-1.355 3-3-1.355-3-3-3zm3 3c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1 .00001-.55228.44772-.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3zm-3-1c.56413 0 1 .4359 1 1 0 .5642-.43587 1-1 1s-1-.4358-1-1c0-.5641.43587-1 1-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-.195 0-.38964.07519-.53906.22461l-3.2363 3.2363c-.29884.29884-.29884.77929 0 1.0781l3.2363 3.2363c.29884.29884.77929.29884 1.0781 0l3.2363-3.2363c.29884-.29884.29884-.77929 0-1.0781l-3.2363-3.2363c-.14942-.14942-.34406-.22461-.53906-.22461zm-7 7v5c0 1.6569 1.3471 3.114 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1v-5zm7 2c-1.645 0-3 1.355-3 3s1.355 3 3 3 3-1.355 3-3-1.355-3-3-3zm3 3c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1 .00001-.55228.44772-.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3zm-3-1c.56413 0 1 .4359 1 1 0 .5642-.43587 1-1 1s-1-.4358-1-1c0-.5641.43587-1 1-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/KeyRotation.svg b/editor/icons/KeyRotation.svg index 284a835467..391511df7c 100644 --- a/editor/icons/KeyRotation.svg +++ b/editor/icons/KeyRotation.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-.195 0-.38964.07519-.53906.22461l-3.2363 3.2363c-.29884.29884-.29884.77929 0 1.0781l3.2363 3.2363c.29884.29884.77929.29884 1.0781 0l3.2363-3.2363c.29884-.29884.29884-.77929 0-1.0781l-3.2363-3.2363c-.14942-.14942-.34406-.22461-.53906-.22461zm3 7v5c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228 0-.99999-.4477-1-1v-1h2v-2h-2v-2zm0 5c0-1.645-1.355-3-3-3s-3 1.355-3 3 1.355 3 3 3 3-1.355 3-3zm-7-3c-1.6569 0-3 1.3431-3 3v3h2v-3c.0000096-.5523.44772-1 1-1h1v-2zm4 2c.56413 0 1 .4359 1 1 0 .5642-.43587 1-1 1s-1-.4358-1-1c0-.5641.43587-1 1-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-.195 0-.38964.07519-.53906.22461l-3.2363 3.2363c-.29884.29884-.29884.77929 0 1.0781l3.2363 3.2363c.29884.29884.77929.29884 1.0781 0l3.2363-3.2363c.29884-.29884.29884-.77929 0-1.0781l-3.2363-3.2363c-.14942-.14942-.34406-.22461-.53906-.22461zm3 7v5c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228 0-.99999-.4477-1-1v-1h2v-2h-2v-2zm0 5c0-1.645-1.355-3-3-3s-3 1.355-3 3 1.355 3 3 3 3-1.355 3-3zm-7-3c-1.6569 0-3 1.3431-3 3v3h2v-3c.0000096-.5523.44772-1 1-1h1v-2zm4 2c.56413 0 1 .4359 1 1 0 .5642-.43587 1-1 1s-1-.4358-1-1c0-.5641.43587-1 1-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/KeyScale.svg b/editor/icons/KeyScale.svg index 84805191f2..5caf80e68e 100644 --- a/editor/icons/KeyScale.svg +++ b/editor/icons/KeyScale.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-.195 0-.38964.07519-.53906.22461l-3.2363 3.2363c-.29884.29884-.29884.77929 0 1.0781l3.2363 3.2363c.29884.29884.77929.29884 1.0781 0l3.2363-3.2363c.29884-.29884.29884-.77929 0-1.0781l-3.2363-3.2363c-.14942-.14942-.34406-.22461-.53906-.22461zm3 7v5c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1v-5zm-8 2c-.71466-.0001-1.3751.3811-1.7324 1-.35727.6188-.35727 1.3812 0 2 .35733.6189 1.0178 1.0001 1.7324 1h-2v2h2c.71466.0001 1.3751-.3811 1.7324-1 .35727-.6188.35727-1.3812 0-2-.35733-.6189-1.0178-1.0001-1.7324-1h2v-2zm6 0c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1 .0000096-.55228.44772-.99999 1-1h1v-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-.195 0-.38964.07519-.53906.22461l-3.2363 3.2363c-.29884.29884-.29884.77929 0 1.0781l3.2363 3.2363c.29884.29884.77929.29884 1.0781 0l3.2363-3.2363c.29884-.29884.29884-.77929 0-1.0781l-3.2363-3.2363c-.14942-.14942-.34406-.22461-.53906-.22461zm3 7v5c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1v-5zm-8 2c-.71466-.0001-1.3751.3811-1.7324 1-.35727.6188-.35727 1.3812 0 2 .35733.6189 1.0178 1.0001 1.7324 1h-2v2h2c.71466.0001 1.3751-.3811 1.7324-1 .35727-.6188.35727-1.3812 0-2-.35733-.6189-1.0178-1.0001-1.7324-1h2v-2zm6 0c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1 .0000096-.55228.44772-.99999 1-1h1v-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/LightmapProbe.svg b/editor/icons/LightmapProbe.svg index 07f2b41a7c..dc5d8321e7 100644 --- a/editor/icons/LightmapProbe.svg +++ b/editor/icons/LightmapProbe.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 9h3v-2h-3zm2.050781 2.535156 1.414063 1.414063 1.414062-1.414063-1.414062-1.414062zm0-7.070312 1.414063 1.414062 1.414062-1.414062-1.414062-1.414063zm1.949219 3.535156c0 1.6569 1.3432 3 3 3s3-1.3431 3-3-1.3432-3-3-3-3 1.3431-3 3zm3 7c3.865993 0 7-3.134007 7-7s-3.134007-7-7-7v2.333984c2.577329 0 4.666016 2.088687 4.666016 4.666016s-2.088687 4.666016-4.666016 4.666016z" fill="#fc7f7f" fill-opacity=".996078" stroke-width="1.16667"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 9h3v-2h-3zm2.050781 2.535156 1.414063 1.414063 1.414062-1.414063-1.414062-1.414062zm0-7.070312 1.414063 1.414062 1.414062-1.414062-1.414062-1.414063zm1.949219 3.535156c0 1.6569 1.3432 3 3 3s3-1.3431 3-3-1.3432-3-3-3-3 1.3431-3 3zm3 7c3.865993 0 7-3.134007 7-7s-3.134007-7-7-7v2.333984c2.577329 0 4.666016 2.088687 4.666016 4.666016s-2.088687 4.666016-4.666016 4.666016z" fill="#fc7f7f" stroke-width="1.16667"/></svg> diff --git a/editor/icons/Line.svg b/editor/icons/Line.svg new file mode 100644 index 0000000000..c7b1f8a701 --- /dev/null +++ b/editor/icons/Line.svg @@ -0,0 +1 @@ +<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 8-8" fill="none" stroke="#ffffff" stroke-linecap="round" stroke-width="2" transform="translate(0 -1040.4)"/></svg> diff --git a/editor/icons/ListSelect.svg b/editor/icons/ListSelect.svg index 9e2bf381d3..f1dac744d4 100644 --- a/editor/icons/ListSelect.svg +++ b/editor/icons/ListSelect.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h8.2578l-.82227-2h-5.4355v-2h4.6113l-.82227-2h-3.7891v-2h3.8867a1.5002 1.5002 0 0 1 1.0977-.49805v-.0019531a1.5002 1.5002 0 0 1 .58594.11133l.94531.38867h.48438v.19922l2 .82227v-7.0215h-11zm2 2h7v2h-7zm5 5 3.291 8 .94726-2.8203 1.8828 1.8828.94336-.94141-1.8848-1.8828 2.8203-.94726-8-3.291z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h8.2578l-.82227-2h-5.4355v-2h4.6113l-.82227-2h-3.7891v-2h3.8867a1.5002 1.5002 0 0 1 1.0977-.49805v-.0019531a1.5002 1.5002 0 0 1 .58594.11133l.94531.38867h.48438v.19922l2 .82227v-7.0215h-11zm2 2h7v2h-7zm5 5 3.291 8 .94726-2.8203 1.8828 1.8828.94336-.94141-1.8848-1.8828 2.8203-.94726-8-3.291z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Loop.svg b/editor/icons/Loop.svg index 7fd8561bc4..9bbf168189 100644 --- a/editor/icons/Loop.svg +++ b/editor/icons/Loop.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1v2h-2a5 5 0 0 0 -5 5 5 5 0 0 0 1.0039 2.9961l1.4355-1.4355a3 3 0 0 1 -.43945-1.5605 3 3 0 0 1 3-3h2v2l2-1.5 2-1.5-2-1.5-2-1.5zm5.9961 4.0039-1.4355 1.4355a3 3 0 0 1 .43945 1.5605 3 3 0 0 1 -3 3h-2v-2l-2 1.5-2 1.5 2 1.5 2 1.5v-2h2a5 5 0 0 0 5-5 5 5 0 0 0 -1.0039-2.9961z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1v2h-2a5 5 0 0 0 -5 5 5 5 0 0 0 1.0039 2.9961l1.4355-1.4355a3 3 0 0 1 -.43945-1.5605 3 3 0 0 1 3-3h2v2l2-1.5 2-1.5-2-1.5-2-1.5zm5.9961 4.0039-1.4355 1.4355a3 3 0 0 1 .43945 1.5605 3 3 0 0 1 -3 3h-2v-2l-2 1.5-2 1.5 2 1.5 2 1.5v-2h2a5 5 0 0 0 5-5 5 5 0 0 0 -1.0039-2.9961z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Marker3D.svg b/editor/icons/Marker3D.svg index 894b195589..bbc531cc3e 100644 --- a/editor/icons/Marker3D.svg +++ b/editor/icons/Marker3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v4h2v-4zm-6 6v2h4v-2zm10 0v2h4v-2zm-4 4v4h2v-4z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v4h2v-4zm-6 6v2h4v-2zm10 0v2h4v-2zm-4 4v4h2v-4z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/MemberAnnotation.svg b/editor/icons/MemberAnnotation.svg index c73ebf7b9b..39bef6d9ee 100644 --- a/editor/icons/MemberAnnotation.svg +++ b/editor/icons/MemberAnnotation.svg @@ -1 +1 @@ -<svg width="16" height="16" version="1.0" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><script id="custom-useragent-string-page-script"/><path d="m13.821 12.756c-5.0033 3.9148-12.551 2.248-12.49-4.538 0.67424-11.471 17.312-7.4502 12.446 2.1173-1.0549 1.1955-2.0737 1.4617-3.1983 0.4329-0.21023-0.19282-0.44783-1.1594-0.3819-1.5089 0.35827-1.8946 1.0885-4.0778-0.72151-4.7234-2.4171-0.86457-4.5592 1.6495-4.9697 4.0193-0.47396 2.7343 2.284 3.3749 4.1487 1.9879 0.4553-0.36324 1.6433-1.3796 1.6806-1.9742" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="1.4928"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.821 12.756c-5.0033 3.9148-12.551 2.248-12.49-4.538.67424-11.471 17.312-7.4502 12.446 2.1173-1.0549 1.1955-2.0737 1.4617-3.1983.4329-.21023-.19282-.44783-1.1594-.3819-1.5089.35827-1.8946 1.0885-4.0778-.72151-4.7234-2.4171-.86457-4.5592 1.6495-4.9697 4.0193-.47396 2.7343 2.284 3.3749 4.1487 1.9879.4553-.36324 1.6433-1.3796 1.6806-1.9742" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="1.4928"/></svg> diff --git a/editor/icons/MeshInstance3D.svg b/editor/icons/MeshInstance3D.svg index a9258505f8..67757dafd2 100644 --- a/editor/icons/MeshInstance3D.svg +++ b/editor/icons/MeshInstance3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/MeshTexture.svg b/editor/icons/MeshTexture.svg index 988882c960..ccf16b828b 100644 --- a/editor/icons/MeshTexture.svg +++ b/editor/icons/MeshTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h6.541c.35663.61771 1.0152.99874 1.7285 1 1.1046 0 2-.89543 2-2 .000101-.72747-.39481-1.3976-1.0312-1.75h.03125v-6.5215c.61771-.35663.99874-1.0152 1-1.7285 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1zm1.7266 3h.6875 5.168.68945c.17478.30301.42598.55488.72852.73047v.68359 5.1719.68555c-.30301.17478-.55488.42598-.73047.72852h-.68359-5.1719-.68555c-.17478-.30301-.42598-.55488-.72852-.73047v-.6875l-.0039062.003907v-5.8574c.30302-.17478.55488-.42598.73047-.72852zm4.0859 2.25v.70117h-.8125v.69922h-1.625v.69922h-.8125v.69922h-.8125v.70117h1.625 1.625 1.625 1.625v-1.4004h-.8125v-1.3984h-.8125v-.70117h-.8125z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h6.541c.35663.61771 1.0152.99874 1.7285 1 1.1046 0 2-.89543 2-2 .000101-.72747-.39481-1.3976-1.0312-1.75h.03125v-6.5215c.61771-.35663.99874-1.0152 1-1.7285 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1zm1.7266 3h.6875 5.168.68945c.17478.30301.42598.55488.72852.73047v.68359 5.1719.68555c-.30301.17478-.55488.42598-.73047.72852h-.68359-5.1719-.68555c-.17478-.30301-.42598-.55488-.72852-.73047v-.6875l-.0039062.003907v-5.8574c.30302-.17478.55488-.42598.73047-.72852zm4.0859 2.25v.70117h-.8125v.69922h-1.625v.69922h-.8125v.69922h-.8125v.70117h1.625 1.625 1.625 1.625v-1.4004h-.8125v-1.3984h-.8125v-.70117h-.8125z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/MethodOverride.svg b/editor/icons/MethodOverride.svg new file mode 100644 index 0000000000..004b9bf283 --- /dev/null +++ b/editor/icons/MethodOverride.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 4.2333332 4.2333332" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m.49005985 3.3580432.83285685-.0000001v-.7093212c.0027125-.6681099.2054076-1.1321001 1.0021593-1.1328214h.3207573v-.79375l1.3229167 1.0648649-1.3229167 1.0518017v-.79375h-.3364788c-.2888876 0-.4514151.2436282-.4573001.5980603 0 .2833012.0000193.4455045.0000289.7134508h.79375v.4907171l-2.15577345.00147z" fill="#5fb2ff"/></svg> diff --git a/editor/icons/MethodOverrideAndSlot.svg b/editor/icons/MethodOverrideAndSlot.svg new file mode 100644 index 0000000000..d3bd9f0253 --- /dev/null +++ b/editor/icons/MethodOverrideAndSlot.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 4.2333332 4.2333332" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m.15761184 3.636193h.37155483l.004252-.7093212c.0027092-.6681099.12999225-1.1321001.92674393-1.1328214h.1273374l.0042585-.7357171 1.3186582 1.006832-1.3229167 1.0700676v-.8531081h-.1260545c-.2888876 0-.3972562.2847204-.4031411.6391525 0 .2833012.0000193.4455045.0000289.7134508h1.2412654v.4907171h-2.14198686z" fill="#5fb2ff"/><path d="m2.38125.79375h1.5875v2.6458333h-1.5875v-.5291666h1.0583333v-1.5875h-1.0583333z" fill="#5fff97"/></svg> diff --git a/editor/icons/MirrorX.svg b/editor/icons/MirrorX.svg index fa668986ac..84c1da1b66 100644 --- a/editor/icons/MirrorX.svg +++ b/editor/icons/MirrorX.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#e0e0e0" stroke-opacity=".99608" stroke-width="2" transform="translate(0 -1036.4)"><path d="m4 1042.4-2 2 2 2" stroke-linecap="round" stroke-linejoin="round"/><path d="m2 1044.4h11"/><path d="m12 1042.4 2 2-2 2" stroke-linecap="round" stroke-linejoin="round"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#e0e0e0" stroke-width="2" transform="translate(0 -1036.4)"><path d="m4 1042.4-2 2 2 2" stroke-linecap="round" stroke-linejoin="round"/><path d="m2 1044.4h11"/><path d="m12 1042.4 2 2-2 2" stroke-linecap="round" stroke-linejoin="round"/></g></svg> diff --git a/editor/icons/MirrorY.svg b/editor/icons/MirrorY.svg index bb4e4d3543..beaf8b0536 100644 --- a/editor/icons/MirrorY.svg +++ b/editor/icons/MirrorY.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11.012 1048.4a1.0001 1.0001 0 0 0 -1.7168-.6973l-.29297.293v-7.1719l.29297.293a1.0001 1.0001 0 0 0 1.7148-.7266 1.0001 1.0001 0 0 0 -.30078-.6875l-2-2a1.0001 1.0001 0 0 0 -1.4141 0l-2 2a1.0001 1.0001 0 1 0 1.4141 1.4141l.29297-.293v7.1719l-.29297-.293a1.0001 1.0001 0 1 0 -1.4141 1.4141l2 2a1.0001 1.0001 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 .30273-.7168z" fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11.012 1048.4a1.0001 1.0001 0 0 0 -1.7168-.6973l-.29297.293v-7.1719l.29297.293a1.0001 1.0001 0 0 0 1.7148-.7266 1.0001 1.0001 0 0 0 -.30078-.6875l-2-2a1.0001 1.0001 0 0 0 -1.4141 0l-2 2a1.0001 1.0001 0 1 0 1.4141 1.4141l.29297-.293v7.1719l-.29297-.293a1.0001 1.0001 0 1 0 -1.4141 1.4141l2 2a1.0001 1.0001 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 .30273-.7168z" fill="#e0e0e0" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/MoveDown.svg b/editor/icons/MoveDown.svg index 3c2d771cd5..85301f7f22 100644 --- a/editor/icons/MoveDown.svg +++ b/editor/icons/MoveDown.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a1.0001 1.0001 0 1 0 0 2h4a1.0001 1.0001 0 1 0 0-2zm2 4c-.55231 0-1 .4477-1 1v5.1484l-2.2188-2.7734c-.34504-.4317-.97482-.50165-1.4062-.15625-.4305.3449-.5004.9732-.15625 1.4043l4 5c.18868.2369.4745.37695.77734.37695.30559.0009.59477-.13795.78516-.37695l4-5c.34415-.4311.27424-1.0594-.15625-1.4043-.43143-.3454-1.0612-.27545-1.4062.15625l-2.2188 2.7734v-5.1484c0-.5523-.44769-1-1-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a1.0001 1.0001 0 1 0 0 2h4a1.0001 1.0001 0 1 0 0-2zm2 4c-.55231 0-1 .4477-1 1v5.1484l-2.2188-2.7734c-.34504-.4317-.97482-.50165-1.4062-.15625-.4305.3449-.5004.9732-.15625 1.4043l4 5c.18868.2369.4745.37695.77734.37695.30559.0009.59477-.13795.78516-.37695l4-5c.34415-.4311.27424-1.0594-.15625-1.4043-.43143-.3454-1.0612-.27545-1.4062.15625l-2.2188 2.7734v-5.1484c0-.5523-.44769-1-1-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/MoveLeft.svg b/editor/icons/MoveLeft.svg index 8f96ee0060..eedae80a81 100644 --- a/editor/icons/MoveLeft.svg +++ b/editor/icons/MoveLeft.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 10a1.0001 1.0001 0 1 1 -2 0v-4a1.0001 1.0001 0 1 1 2 0zm-4-2c0 .55231-.4477 1-1 1h-5.1484l2.7734 2.2188c.4317.34504.50165.97482.15625 1.4062-.3449.4305-.9732.5004-1.4043.15625l-5-4c-.2369-.18868-.37695-.4745-.37695-.77734-.0009-.30559.13795-.59477.37695-.78516l5-4c.4311-.34415 1.0594-.27424 1.4043.15625.3454.43143.27545 1.0612-.15625 1.4062l-2.7734 2.2188h5.1484c.5523 0 1 .44769 1 1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 10a1.0001 1.0001 0 1 1 -2 0v-4a1.0001 1.0001 0 1 1 2 0zm-4-2c0 .55231-.4477 1-1 1h-5.1484l2.7734 2.2188c.4317.34504.50165.97482.15625 1.4062-.3449.4305-.9732.5004-1.4043.15625l-5-4c-.2369-.18868-.37695-.4745-.37695-.77734-.0009-.30559.13795-.59477.37695-.78516l5-4c.4311-.34415 1.0594-.27424 1.4043.15625.3454.43143.27545 1.0612-.15625 1.4062l-2.7734 2.2188h5.1484c.5523 0 1 .44769 1 1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/MoveRight.svg b/editor/icons/MoveRight.svg index ee8d1b45a4..951755fabe 100644 --- a/editor/icons/MoveRight.svg +++ b/editor/icons/MoveRight.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 10a1.0001 1.0001 0 1 0 2 0v-4a1.0001 1.0001 0 1 0 -2 0zm4-2c0 .55231.4477 1 1 1h5.1484l-2.7734 2.2188c-.4317.34504-.50165.97482-.15625 1.4062.3449.4305.9732.5004 1.4043.15625l5-4c.2369-.18868.37695-.4745.37695-.77734.0009-.30559-.13795-.59477-.37695-.78516l-5-4c-.4311-.34415-1.0594-.27424-1.4043.15625-.3454.43143-.27545 1.0612.15625 1.4062l2.7734 2.2188h-5.1484c-.5523 0-1 .44769-1 1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 10a1.0001 1.0001 0 1 0 2 0v-4a1.0001 1.0001 0 1 0 -2 0zm4-2c0 .55231.4477 1 1 1h5.1484l-2.7734 2.2188c-.4317.34504-.50165.97482-.15625 1.4062.3449.4305.9732.5004 1.4043.15625l5-4c.2369-.18868.37695-.4745.37695-.77734.0009-.30559-.13795-.59477-.37695-.78516l-5-4c-.4311-.34415-1.0594-.27424-1.4043.15625-.3454.43143-.27545 1.0612.15625 1.4062l2.7734 2.2188h-5.1484c-.5523 0-1 .44769-1 1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/MoveUp.svg b/editor/icons/MoveUp.svg index f1302b2984..6cdc984ebc 100644 --- a/editor/icons/MoveUp.svg +++ b/editor/icons/MoveUp.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 15a1.0001 1.0001 0 1 1 0-2h4a1.0001 1.0001 0 1 1 0 2zm2-4c-.55231 0-1-.4477-1-1v-5.1484l-2.2188 2.7734c-.34504.4317-.97482.50165-1.4062.15625-.4305-.3449-.5004-.9732-.15625-1.4043l4-5c.18868-.2369.4745-.37695.77734-.37695.30559-.0009.59477.13795.78516.37695l4 5c.34415.4311.27424 1.0594-.15625 1.4043-.43143.3454-1.0612.27545-1.4062-.15625l-2.2188-2.7734v5.1484c0 .5523-.44769 1-1 1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 15a1.0001 1.0001 0 1 1 0-2h4a1.0001 1.0001 0 1 1 0 2zm2-4c-.55231 0-1-.4477-1-1v-5.1484l-2.2188 2.7734c-.34504.4317-.97482.50165-1.4062.15625-.4305-.3449-.5004-.9732-.15625-1.4043l4-5c.18868-.2369.4745-.37695.77734-.37695.30559-.0009.59477.13795.78516.37695l4 5c.34415.4311.27424 1.0594-.15625 1.4043-.43143.3454-1.0612.27545-1.4062-.15625l-2.2188-2.7734v5.1484c0 .5523-.44769 1-1 1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/MultiMeshInstance3D.svg b/editor/icons/MultiMeshInstance3D.svg index 3ccd2c9cbe..eb82d4928b 100644 --- a/editor/icons/MultiMeshInstance3D.svg +++ b/editor/icons/MultiMeshInstance3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h1.2695v-2h-1.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c.17532.30158.42647.55205.72852.72656v1.2734h2v-1.2695c.61831-.35698.99944-1.0165 1-1.7305 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h1.2695v-2h-1.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c.17532.30158.42647.55205.72852.72656v1.2734h2v-1.2695c.61831-.35698.99944-1.0165 1-1.7305 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/Navigation3D.svg b/editor/icons/Navigation3D.svg index 646500d9ed..79cca958f8 100644 --- a/editor/icons/Navigation3D.svg +++ b/editor/icons/Navigation3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1050.4 5-2 5 2-5-12z" fill="#fc7f7f" fill-opacity=".99608" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1050.4 5-2 5 2-5-12z" fill="#fc7f7f" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/NavigationLink2D.svg b/editor/icons/NavigationLink2D.svg index 6c5f17e256..df470ece57 100644 --- a/editor/icons/NavigationLink2D.svg +++ b/editor/icons/NavigationLink2D.svg @@ -1,4 +1,4 @@ <svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<path d="m12.386 5.3097c-0.69157-0.021112-1.3071 0.36382-1.7492 0.86685-0.58 0.58-1.16 1.16-1.74 1.74 0.4588-0.28502 1.0599-0.064948 1.4771-0.037996 0.45549-0.44357 0.89024-0.91006 1.3596-1.3383 0.56256-0.44564 1.4906-0.15731 1.7028 0.52802 0.18967 0.4871-0.049221 1.0098-0.43284 1.3208-0.70048 0.68896-1.3789 1.4022-2.0935 2.0755-0.47999 0.3725-1.2044 0.226-1.5679-0.24034-0.38763-0.38194-1.0641 0.16031-0.78317 0.6241 0.6767 0.94379 2.1573 1.1282 3.0411 0.36751 0.80287-0.7704 1.5793-1.5696 2.3665-2.3564 0.79925-0.83719 0.70104-2.3112-0.19552-3.0393-0.38108-0.32877-0.8822-0.5119-1.385-0.51049zm-3.051 3.051c-0.69157-0.021106-1.3071 0.36382-1.7492 0.86685-0.67513 0.68452-1.37 1.3506-2.0319 2.0474-0.75433 0.87744-0.58087 2.3428 0.34933 3.0252 0.84748 0.68613 2.192 0.54839 2.8998-0.27341 0.63032-0.63031 1.2606-1.2606 1.8909-1.8909-0.4587 0.28554-1.0602 0.0659-1.477 0.038069-0.45445 0.44348-0.88773 0.91034-1.3564 1.3383-0.56256 0.44565-1.4906 0.15731-1.7028-0.52802-0.18967-0.4871 0.049229-1.0098 0.43284-1.3208 0.70048-0.68896 1.3789-1.4022 2.0935-2.0755 0.48-0.3725 1.2044-0.22601 1.5679 0.24036 0.38733 0.38325 1.064-0.16067 0.78313-0.6241-0.39353-0.52481-1.0429-0.84871-1.7002-0.8434z" fill="#8ea6f4" fill-opacity=".99608" stroke-linecap="round" stroke-linejoin="round" stroke-width=".013911"/> -<path d="m2 1c-0.61942-0.0066969-1.0877 0.60314-1 1.198 0.00345 3.968-0.006897 7.9364 0.00517 11.904 0.043388 0.62851 0.69346 0.98513 1.272 0.89776h2.5896c-0.77174-0.5015-1.2078-1.2613-1.3143-2.3356-0.11601-1.1701 0.63729-2.024 1.6748-3.1566 0.65335-0.71326 1.4757-1.5822 2.3587-2.3316 0.76308-0.64765 1.7509-1.679 2.9376-2.578 0.91259-0.69136 2.2893-0.74691 3.1014-0.33143 0.91184 0.46649 1.2635 1.1209 1.4067 1.3826-0.0052-2.335-0.02135-1.3526-0.03955-3.6863 5e-3 -0.64349-0.67497-1.0568-1.2694-0.96289z" fill="#8ea6f4" fill-opacity=".99608"/> +<path d="m12.386 5.3097c-0.69157-0.021112-1.3071 0.36382-1.7492 0.86685-0.58 0.58-1.16 1.16-1.74 1.74 0.4588-0.28502 1.0599-0.064948 1.4771-0.037996 0.45549-0.44357 0.89024-0.91006 1.3596-1.3383 0.56256-0.44564 1.4906-0.15731 1.7028 0.52802 0.18967 0.4871-0.049221 1.0098-0.43284 1.3208-0.70048 0.68896-1.3789 1.4022-2.0935 2.0755-0.47999 0.3725-1.2044 0.226-1.5679-0.24034-0.38763-0.38194-1.0641 0.16031-0.78317 0.6241 0.6767 0.94379 2.1573 1.1282 3.0411 0.36751 0.80287-0.7704 1.5793-1.5696 2.3665-2.3564 0.79925-0.83719 0.70104-2.3112-0.19552-3.0393-0.38108-0.32877-0.8822-0.5119-1.385-0.51049zm-3.051 3.051c-0.69157-0.021106-1.3071 0.36382-1.7492 0.86685-0.67513 0.68452-1.37 1.3506-2.0319 2.0474-0.75433 0.87744-0.58087 2.3428 0.34933 3.0252 0.84748 0.68613 2.192 0.54839 2.8998-0.27341 0.63032-0.63031 1.2606-1.2606 1.8909-1.8909-0.4587 0.28554-1.0602 0.0659-1.477 0.038069-0.45445 0.44348-0.88773 0.91034-1.3564 1.3383-0.56256 0.44565-1.4906 0.15731-1.7028-0.52802-0.18967-0.4871 0.049229-1.0098 0.43284-1.3208 0.70048-0.68896 1.3789-1.4022 2.0935-2.0755 0.48-0.3725 1.2044-0.22601 1.5679 0.24036 0.38733 0.38325 1.064-0.16067 0.78313-0.6241-0.39353-0.52481-1.0429-0.84871-1.7002-0.8434z" fill="#8ea6f4" stroke-linecap="round" stroke-linejoin="round" stroke-width=".013911"/> +<path d="m2 1c-0.61942-0.0066969-1.0877 0.60314-1 1.198 0.00345 3.968-0.006897 7.9364 0.00517 11.904 0.043388 0.62851 0.69346 0.98513 1.272 0.89776h2.5896c-0.77174-0.5015-1.2078-1.2613-1.3143-2.3356-0.11601-1.1701 0.63729-2.024 1.6748-3.1566 0.65335-0.71326 1.4757-1.5822 2.3587-2.3316 0.76308-0.64765 1.7509-1.679 2.9376-2.578 0.91259-0.69136 2.2893-0.74691 3.1014-0.33143 0.91184 0.46649 1.2635 1.1209 1.4067 1.3826-0.0052-2.335-0.02135-1.3526-0.03955-3.6863 5e-3 -0.64349-0.67497-1.0568-1.2694-0.96289z" fill="#8ea6f4"/> </svg> diff --git a/editor/icons/NavigationLink3D.svg b/editor/icons/NavigationLink3D.svg index ea4092c2c7..05f36da2b2 100644 --- a/editor/icons/NavigationLink3D.svg +++ b/editor/icons/NavigationLink3D.svg @@ -1,4 +1,4 @@ <svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<path d="m12.386 5.3097c-0.69157-0.021112-1.3071 0.36382-1.7492 0.86685-0.58 0.58-1.16 1.16-1.74 1.74 0.4588-0.28502 1.0599-0.064948 1.4771-0.037996 0.45549-0.44357 0.89024-0.91006 1.3596-1.3383 0.56256-0.44564 1.4906-0.15731 1.7028 0.52802 0.18967 0.4871-0.049221 1.0098-0.43284 1.3208-0.70048 0.68896-1.3789 1.4022-2.0935 2.0755-0.47999 0.3725-1.2044 0.226-1.5679-0.24034-0.38763-0.38194-1.0641 0.16031-0.78317 0.6241 0.6767 0.94379 2.1573 1.1282 3.0411 0.36751 0.80287-0.7704 1.5793-1.5696 2.3665-2.3564 0.79925-0.83719 0.70104-2.3112-0.19552-3.0393-0.38108-0.32877-0.8822-0.5119-1.385-0.51049zm-3.051 3.051c-0.69157-0.021106-1.3071 0.36382-1.7492 0.86685-0.67513 0.68452-1.37 1.3506-2.0319 2.0474-0.75433 0.87744-0.58087 2.3428 0.34933 3.0252 0.84748 0.68613 2.192 0.54839 2.8998-0.27341 0.63032-0.63031 1.2606-1.2606 1.8909-1.8909-0.4587 0.28554-1.0602 0.0659-1.477 0.038069-0.45445 0.44348-0.88773 0.91034-1.3564 1.3383-0.56256 0.44565-1.4906 0.15731-1.7028-0.52802-0.18967-0.4871 0.049229-1.0098 0.43284-1.3208 0.70048-0.68896 1.3789-1.4022 2.0935-2.0755 0.48-0.3725 1.2044-0.22601 1.5679 0.24036 0.38733 0.38325 1.064-0.16067 0.78313-0.6241-0.39353-0.52481-1.0429-0.84871-1.7002-0.8434z" fill="#fc7e7e" fill-opacity=".99608" stroke-linecap="round" stroke-linejoin="round" stroke-width=".013911"/> -<path d="m2 1c-0.61942-0.0066969-1.0877 0.60314-1 1.198 0.00345 3.968-0.006897 7.9364 0.00517 11.904 0.043388 0.62851 0.69346 0.98513 1.272 0.89776h2.5896c-0.77174-0.5015-1.2078-1.2613-1.3143-2.3356-0.11601-1.1701 0.63729-2.024 1.6748-3.1566 0.65335-0.71326 1.4757-1.5822 2.3587-2.3316 0.76308-0.64765 1.7509-1.679 2.9376-2.578 0.91259-0.69136 2.2893-0.74691 3.1014-0.33143 0.91184 0.46649 1.2635 1.1209 1.4067 1.3826-0.0052-2.335-0.02135-1.3526-0.03955-3.6863 5e-3 -0.64349-0.67497-1.0568-1.2694-0.96289z" fill="#fc7d7d" fill-opacity=".99608"/> +<path d="m12.386 5.3097c-0.69157-0.021112-1.3071 0.36382-1.7492 0.86685-0.58 0.58-1.16 1.16-1.74 1.74 0.4588-0.28502 1.0599-0.064948 1.4771-0.037996 0.45549-0.44357 0.89024-0.91006 1.3596-1.3383 0.56256-0.44564 1.4906-0.15731 1.7028 0.52802 0.18967 0.4871-0.049221 1.0098-0.43284 1.3208-0.70048 0.68896-1.3789 1.4022-2.0935 2.0755-0.47999 0.3725-1.2044 0.226-1.5679-0.24034-0.38763-0.38194-1.0641 0.16031-0.78317 0.6241 0.6767 0.94379 2.1573 1.1282 3.0411 0.36751 0.80287-0.7704 1.5793-1.5696 2.3665-2.3564 0.79925-0.83719 0.70104-2.3112-0.19552-3.0393-0.38108-0.32877-0.8822-0.5119-1.385-0.51049zm-3.051 3.051c-0.69157-0.021106-1.3071 0.36382-1.7492 0.86685-0.67513 0.68452-1.37 1.3506-2.0319 2.0474-0.75433 0.87744-0.58087 2.3428 0.34933 3.0252 0.84748 0.68613 2.192 0.54839 2.8998-0.27341 0.63032-0.63031 1.2606-1.2606 1.8909-1.8909-0.4587 0.28554-1.0602 0.0659-1.477 0.038069-0.45445 0.44348-0.88773 0.91034-1.3564 1.3383-0.56256 0.44565-1.4906 0.15731-1.7028-0.52802-0.18967-0.4871 0.049229-1.0098 0.43284-1.3208 0.70048-0.68896 1.3789-1.4022 2.0935-2.0755 0.48-0.3725 1.2044-0.22601 1.5679 0.24036 0.38733 0.38325 1.064-0.16067 0.78313-0.6241-0.39353-0.52481-1.0429-0.84871-1.7002-0.8434z" fill="#fc7e7e" stroke-linecap="round" stroke-linejoin="round" stroke-width=".013911"/> +<path d="m2 1c-0.61942-0.0066969-1.0877 0.60314-1 1.198 0.00345 3.968-0.006897 7.9364 0.00517 11.904 0.043388 0.62851 0.69346 0.98513 1.272 0.89776h2.5896c-0.77174-0.5015-1.2078-1.2613-1.3143-2.3356-0.11601-1.1701 0.63729-2.024 1.6748-3.1566 0.65335-0.71326 1.4757-1.5822 2.3587-2.3316 0.76308-0.64765 1.7509-1.679 2.9376-2.578 0.91259-0.69136 2.2893-0.74691 3.1014-0.33143 0.91184 0.46649 1.2635 1.1209 1.4067 1.3826-0.0052-2.335-0.02135-1.3526-0.03955-3.6863 5e-3 -0.64349-0.67497-1.0568-1.2694-0.96289z" fill="#fc7d7d"/> </svg> diff --git a/editor/icons/NavigationRegion3D.svg b/editor/icons/NavigationRegion3D.svg index 39b6d0ca13..523ae4d20d 100644 --- a/editor/icons/NavigationRegion3D.svg +++ b/editor/icons/NavigationRegion3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.1339223.0000569-.2535666.030668-.3652344.074219-.022275.00881-.041042.020919-.0625.03125-.088962.042467-.1681009.095499-.2382812.1601562-.021532.01952-.042739.037285-.0625.058594-.074111.081092-.13722.1698052-.1816406.2695312-.00343.00765-.00847.013733-.011719.021484l-.00195.00195c-.0452281.1091913-.0629952.2269004-.0683623.3457062-.0005086.0130821-.0078112.023903-.0078125.0371094v12c.0000552.552262.4477381.999945 1 1h4.8847656a2.1184381 2.1184381 0 0 1 .1328125-.744141l2.9999999-7.9999996a2.1184381 2.1184381 0 0 1 2.007813-1.3730469 2.1184381 2.1184381 0 0 1 1.957031 1.3730469l1.017578 2.7128906v-6.96875c-.000001-.013206-.0073-.024027-.0078-.037109-.0054-.1188058-.02313-.2365149-.06836-.3457031l-.002-.00195c-.0032-.00756-.0084-.013999-.01172-.021484-.04442-.099726-.107529-.188439-.18164-.2695312-.01976-.021308-.04097-.039073-.0625-.058594-.07018-.064657-.149319-.1176895-.238282-.1601562-.02146-.010331-.04022-.022439-.0625-.03125-.111631-.0435548-.231276-.0741656-.365198-.0742225zm10 6-3 8 3-2 3 2z" fill="#fc7f7f" fill-opacity=".996078" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.1339223.0000569-.2535666.030668-.3652344.074219-.022275.00881-.041042.020919-.0625.03125-.088962.042467-.1681009.095499-.2382812.1601562-.021532.01952-.042739.037285-.0625.058594-.074111.081092-.13722.1698052-.1816406.2695312-.00343.00765-.00847.013733-.011719.021484l-.00195.00195c-.0452281.1091913-.0629952.2269004-.0683623.3457062-.0005086.0130821-.0078112.023903-.0078125.0371094v12c.0000552.552262.4477381.999945 1 1h4.8847656a2.1184381 2.1184381 0 0 1 .1328125-.744141l2.9999999-7.9999996a2.1184381 2.1184381 0 0 1 2.007813-1.3730469 2.1184381 2.1184381 0 0 1 1.957031 1.3730469l1.017578 2.7128906v-6.96875c-.000001-.013206-.0073-.024027-.0078-.037109-.0054-.1188058-.02313-.2365149-.06836-.3457031l-.002-.00195c-.0032-.00756-.0084-.013999-.01172-.021484-.04442-.099726-.107529-.188439-.18164-.2695312-.01976-.021308-.04097-.039073-.0625-.058594-.07018-.064657-.149319-.1176895-.238282-.1601562-.02146-.010331-.04022-.022439-.0625-.03125-.111631-.0435548-.231276-.0741656-.365198-.0742225zm10 6-3 8 3-2 3 2z" fill="#fc7f7f" fill-rule="evenodd"/></svg> diff --git a/editor/icons/Node3D.svg b/editor/icons/Node3D.svg index c8a3163e51..620bc95229 100644 --- a/editor/icons/Node3D.svg +++ b/editor/icons/Node3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/OccluderInstance3D.svg b/editor/icons/OccluderInstance3D.svg index cc7ccc410f..18f6054873 100644 --- a/editor/icons/OccluderInstance3D.svg +++ b/editor/icons/OccluderInstance3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.90625 1a7 7 0 0 0 -1.2988281.1386719 4.5 4.5 0 0 1 3.3925781 4.3613281 4.5 4.5 0 0 1 -4.5 4.5 4.5 4.5 0 0 1 -4.359375-3.3886719 7 7 0 0 0 -.140625 1.3886719 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7 7 7 0 0 0 -.09375 0z" fill="#fc7f7f" fill-opacity=".996078" stroke-width=".365215"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.90625 1a7 7 0 0 0 -1.2988281.1386719 4.5 4.5 0 0 1 3.3925781 4.3613281 4.5 4.5 0 0 1 -4.5 4.5 4.5 4.5 0 0 1 -4.359375-3.3886719 7 7 0 0 0 -.140625 1.3886719 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7 7 7 0 0 0 -.09375 0z" fill="#fc7f7f" stroke-width=".365215"/></svg> diff --git a/editor/icons/OmniLight3D.svg b/editor/icons/OmniLight3D.svg index 391e9104a1..9d874b359c 100644 --- a/editor/icons/OmniLight3D.svg +++ b/editor/icons/OmniLight3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3-4.5801 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3zm-1 11v1h2v-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3-4.5801 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3zm-1 11v1h2v-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/ParallaxBackground.svg b/editor/icons/ParallaxBackground.svg index f188230fcc..71a586eff4 100644 --- a/editor/icons/ParallaxBackground.svg +++ b/editor/icons/ParallaxBackground.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m2 2a1 1 0 0 0 -1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-10a1 1 0 0 0 -1-1zm0 1h12v10h-12zm5 2-3 3 3 3zm2 0v6l3-3z" fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m2 2a1 1 0 0 0 -1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-10a1 1 0 0 0 -1-1zm0 1h12v10h-12zm5 2-3 3 3 3zm2 0v6l3-3z" fill="#e0e0e0" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/Path3D.svg b/editor/icons/Path3D.svg index 076ce9acd2..4e84cf9789 100644 --- a/editor/icons/Path3D.svg +++ b/editor/icons/Path3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1a2 2 0 0 0 -2 2 2 2 0 0 0 .84961 1.6328c-.19239.88508-.55317 1.3394-.98633 1.6426-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c.8927-.62488 1.5321-1.6538 1.8184-3.0977a2 2 0 0 0 1.1699-1.8164 2 2 0 0 0 -2-2z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1a2 2 0 0 0 -2 2 2 2 0 0 0 .84961 1.6328c-.19239.88508-.55317 1.3394-.98633 1.6426-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c.8927-.62488 1.5321-1.6538 1.8184-3.0977a2 2 0 0 0 1.1699-1.8164 2 2 0 0 0 -2-2z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/PathFollow3D.svg b/editor/icons/PathFollow3D.svg index f9bb38939e..01da0b0114 100644 --- a/editor/icons/PathFollow3D.svg +++ b/editor/icons/PathFollow3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 0-3 4h1.9473c-.1385 1.3203-.5583 1.9074-1.084 2.2754-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c1.0528-.73697 1.7552-2.032 1.9375-3.9141h2.0508l-3-4z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 0-3 4h1.9473c-.1385 1.3203-.5583 1.9074-1.084 2.2754-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c1.0528-.73697 1.7552-2.032 1.9375-3.9141h2.0508l-3-4z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/PickerShapeCircle.svg b/editor/icons/PickerShapeCircle.svg new file mode 100644 index 0000000000..8e7fb7f06e --- /dev/null +++ b/editor/icons/PickerShapeCircle.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path d="m0 0h16v16h-16z"/></clipPath><g clip-path="url(#a)" fill="#eaeaea"><rect height="11" rx="5.5" transform="translate(1 2)" width="11"/><path d="m0 0h2v11h-2z" transform="translate(13 2)"/></g></svg> diff --git a/editor/icons/PickerShapeRectangle.svg b/editor/icons/PickerShapeRectangle.svg new file mode 100644 index 0000000000..3c7dd46884 --- /dev/null +++ b/editor/icons/PickerShapeRectangle.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path d="m0 0h16v16h-16z"/></clipPath><g clip-path="url(#a)" fill="#eaeaea"><path d="m0 0h11v11h-11z" transform="translate(1 2)"/><path d="m0 0h2v11h-2z" transform="translate(13 2)"/></g></svg> diff --git a/editor/icons/PickerShapeRectangleWheel.svg b/editor/icons/PickerShapeRectangleWheel.svg new file mode 100644 index 0000000000..e85665a8f2 --- /dev/null +++ b/editor/icons/PickerShapeRectangleWheel.svg @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + height="16" + viewBox="0 0 16 16" + width="16" + version="1.1" + id="svg11" + sodipodi:docname="PickerShapeRectangleWheel.svg" + inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs15" /> + <sodipodi:namedview + id="namedview13" + pagecolor="#505050" + bordercolor="#ffffff" + borderopacity="1" + inkscape:pageshadow="0" + inkscape:pageopacity="0" + inkscape:pagecheckerboard="1" + showgrid="true" + inkscape:zoom="16" + inkscape:cx="0.53125" + inkscape:cy="5.28125" + inkscape:window-width="1920" + inkscape:window-height="1001" + inkscape:window-x="-9" + inkscape:window-y="-9" + inkscape:window-maximized="1" + inkscape:current-layer="svg11"> + <inkscape:grid + type="xygrid" + id="grid944" /> + </sodipodi:namedview> + <clipPath + id="a"> + <path + d="m0 0h16v16h-16z" + id="path2" /> + </clipPath> + <g + clip-path="url(#a)" + fill="#eaeaea" + id="g9" + transform="matrix(0.85714286,0,0,0.85714286,1.1428571,1.1428571)"> + <path + d="M 7,2 A 5,5 0 1 0 12,7 5.006,5.006 0 0 0 7,2 M 7,0 A 7,7 0 1 1 0,7 7,7 0 0 1 7,0 Z" + transform="translate(1,1)" + id="path5" /> + <path + d="M 0,0 H 7 V 7 H 0 Z" + transform="translate(4.5,4.5)" + id="path7" /> + </g> +</svg> diff --git a/editor/icons/Progress1.svg b/editor/icons/Progress1.svg index 07505ddd67..d9a58d837e 100644 --- a/editor/icons/Progress1.svg +++ b/editor/icons/Progress1.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273.4258l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223z" fill-opacity=".99608"/><path d="m7 1.0801a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1037.4v3.0547a4 4 0 0 1 1.0273.4258l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223z"/><path d="m7 1.0801a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/Progress2.svg b/editor/icons/Progress2.svg index 0a48f7d3f5..d98de2e78b 100644 --- a/editor/icons/Progress2.svg +++ b/editor/icons/Progress2.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm-1.3203 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm-1.3203 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m13.6 1040.2-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855z"/></g></svg> diff --git a/editor/icons/Progress3.svg b/editor/icons/Progress3.svg index a7f0f9c973..a1e84fa7cf 100644 --- a/editor/icons/Progress3.svg +++ b/editor/icons/Progress3.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm4.8926 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m11.867 1045.4a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm4.8926 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m11.867 1045.4a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547z"/></g></svg> diff --git a/editor/icons/Progress4.svg b/editor/icons/Progress4.svg index 171920915e..04a556fd93 100644 --- a/editor/icons/Progress4.svg +++ b/editor/icons/Progress4.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m10.027 1047.8a4 4 0 0 1 -1.0273.4277v3.0508a7 7 0 0 0 3.1855-1.3203z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m10.027 1047.8a4 4 0 0 1 -1.0273.4277v3.0508a7 7 0 0 0 3.1855-1.3203z"/></g></svg> diff --git a/editor/icons/Progress5.svg b/editor/icons/Progress5.svg index 7289b7b8fe..d5a5432781 100644 --- a/editor/icons/Progress5.svg +++ b/editor/icons/Progress5.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-1.8398 2.4414a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.4258z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-1.8398 2.4414a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m5.9727 1047.8-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.4258z"/></g></svg> diff --git a/editor/icons/Progress6.svg b/editor/icons/Progress6.svg index 3deba6d48c..95aebb3cf5 100644 --- a/editor/icons/Progress6.svg +++ b/editor/icons/Progress6.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-1.7324 5.1855a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm-4.5996 2.7344a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-1.7324 5.1855a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m1.0801 1045.4a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508z"/></g></svg> diff --git a/editor/icons/Progress7.svg b/editor/icons/Progress7.svg index 546155dc59..cbcd7df35f 100644 --- a/editor/icons/Progress7.svg +++ b/editor/icons/Progress7.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm6.5996 2.7344-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-2 .0019531a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.42773v-3.0508zm6.5996 2.7344-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m2.4004 1040.2a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582z"/></g></svg> diff --git a/editor/icons/Progress8.svg b/editor/icons/Progress8.svg index b56ffcb727..900b681c69 100644 --- a/editor/icons/Progress8.svg +++ b/editor/icons/Progress8.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-6.5996 2.7363a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.4277z" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 1.0781v3.0547a4 4 0 0 1 1.0273.42578l2.1582-2.1582a7 7 0 0 0 -3.1855-1.3223zm-6.5996 2.7363a7 7 0 0 0 -1.3223 3.1855h3.0547a4 4 0 0 1 .42578-1.0273l-2.1582-2.1582zm11.199 0-2.1582 2.1582a4 4 0 0 1 .42774 1.0273h3.0508a7 7 0 0 0 -1.3203-3.1855zm-12.52 5.1855a7 7 0 0 0 1.3203 3.1855l2.1582-2.1582a4 4 0 0 1 -.42773-1.0273h-3.0508zm10.787 0a4 4 0 0 1 -.42578 1.0273l2.1582 2.1582a7 7 0 0 0 1.3223-3.1855h-3.0547zm-5.8945 2.4414-2.1582 2.1582a7 7 0 0 0 3.1855 1.3223v-3.0547a4 4 0 0 1 -1.0273-.42578zm4.0547 0a4 4 0 0 1 -1.0273.42774v3.0508a7 7 0 0 0 3.1855-1.3203l-2.1582-2.1582z" fill-opacity=".19608" transform="translate(0 1036.4)"/><path d="m7 1037.4a7 7 0 0 0 -3.1855 1.3203l2.1582 2.1582a4 4 0 0 1 1.0273-.4277z"/></g></svg> diff --git a/editor/icons/ProxyTexture.svg b/editor/icons/ProxyTexture.svg index 526f21c379..5435e72a1b 100644 --- a/editor/icons/ProxyTexture.svg +++ b/editor/icons/ProxyTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h4v-4zm6 0v2h6v8h-6v4h7a1 1 0 0 0 1-1v-12a1 1 0 0 0 -1-1zm2 4v1h-1v1h-1v3h1 2 2v-2h-1v-2h-1v-1zm-8 1v4h4v-4zm0 5v4h4v-4z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h4v-4zm6 0v2h6v8h-6v4h7a1 1 0 0 0 1-1v-12a1 1 0 0 0 -1-1zm2 4v1h-1v1h-1v3h1 2 2v-2h-1v-2h-1v-1zm-8 1v4h4v-4zm0 5v4h4v-4z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Quad.svg b/editor/icons/Quad.svg index 70ef6b7227..5627876bfb 100644 --- a/editor/icons/Quad.svg +++ b/editor/icons/Quad.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 10 2h2 12v-2-12h-12zm3.4141 2h8.5859v8.5859zm-1.4141 1.4141 8.5859 8.5859h-8.5859z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 10 2h2 12v-2-12h-12zm3.4141 2h8.5859v8.5859zm-1.4141 1.4141 8.5859 8.5859h-8.5859z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/RayCast3D.svg b/editor/icons/RayCast3D.svg index 9670e63022..59a5e181d6 100644 --- a/editor/icons/RayCast3D.svg +++ b/editor/icons/RayCast3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v9h-3l4 5 4-5h-3v-9z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v9h-3l4 5 4-5h-3v-9z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/ReflectionProbe.svg b/editor/icons/ReflectionProbe.svg index a88a3524be..dee37be8be 100644 --- a/editor/icons/ReflectionProbe.svg +++ b/editor/icons/ReflectionProbe.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10 2a1.0001 1.0001 0 1 0 0 2h1.5859l-4.5195 4.5195-4.2988-5.1582-1.5352 1.2793 5 6a1.0001 1.0001 0 0 0 1.4746.064453l5.293-5.293v1.5879a1.0001 1.0001 0 1 0 2 0v-4a1.0001 1.0001 0 0 0 -1-1h-4zm-9 7v5a1.0001 1.0001 0 0 0 1 1h12a1.0001 1.0001 0 0 0 1-1v-4h-2v3h-10v-4z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10 2a1.0001 1.0001 0 1 0 0 2h1.5859l-4.5195 4.5195-4.2988-5.1582-1.5352 1.2793 5 6a1.0001 1.0001 0 0 0 1.4746.064453l5.293-5.293v1.5879a1.0001 1.0001 0 1 0 2 0v-4a1.0001 1.0001 0 0 0 -1-1h-4zm-9 7v5a1.0001 1.0001 0 0 0 1 1h12a1.0001 1.0001 0 0 0 1-1v-4h-2v3h-10v-4z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/Reload.svg b/editor/icons/Reload.svg index 1200df1dde..4891455cea 100644 --- a/editor/icons/Reload.svg +++ b/editor/icons/Reload.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg> diff --git a/editor/icons/ReloadSmall.svg b/editor/icons/ReloadSmall.svg index 9418a57ab1..ca13da056d 100644 --- a/editor/icons/ReloadSmall.svg +++ b/editor/icons/ReloadSmall.svg @@ -1 +1 @@ -<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1038.4)"><path d="m8 1039.4a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1618 1050.3)"/></g></svg> +<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1038.4)"><path d="m8 1039.4a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1618 1050.3)"/></g></svg> diff --git a/editor/icons/Remove.svg b/editor/icons/Remove.svg index 5bcdf8e569..eb8e244d9a 100644 --- a/editor/icons/Remove.svg +++ b/editor/icons/Remove.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1v1h-4v2h14v-2h-4v-1zm-3 4v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8zm1 2h2v6h-2zm4 0h2v6h-2zm4 0h2v6h-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1v1h-4v2h14v-2h-4v-1zm-3 4v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8zm1 2h2v6h-2zm4 0h2v6h-2zm4 0h2v6h-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/RigidBody3D.svg b/editor/icons/RigidBody3D.svg index 7f5db4ce88..593f6e1f57 100644 --- a/editor/icons/RigidBody3D.svg +++ b/editor/icons/RigidBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 .035156.69922 7 7 0 0 0 .27734 1.3691 7 7 0 0 0 .91016 1.8848 7 7 0 0 0 .30273.4082c.000785-.00256.0011667-.005252.0019532-.007812a7 7 0 0 0 5.4727 2.6465 7 7 0 0 0 3.2422-.80273c.001374.000393.002531.00156.003906.001953a7 7 0 0 0 .035156-.021485 7 7 0 0 0 .42578-.25 7 7 0 0 0 .16992-.10352 7 7 0 0 0 .36914-.26953 7 7 0 0 0 .20508-.15625 7 7 0 0 0 .3418-.30859 7 7 0 0 0 .16406-.1543 7 7 0 0 0 .33008-.36133 7 7 0 0 0 .14062-.16016 7 7 0 0 0 .27734-.37305 7 7 0 0 0 .13867-.19531 7 7 0 0 0 .21875-.36133 7 7 0 0 0 .14258-.25 7 7 0 0 0 .15625-.33398 7 7 0 0 0 .13867-.31055 7 7 0 0 0 .10742-.30859 7 7 0 0 0 .11914-.35352 7 7 0 0 0 .087891-.36914 7 7 0 0 0 .066406-.29297 7 7 0 0 0 .056641-.40039 7 7 0 0 0 .037109-.3125 7 7 0 0 0 .025391-.55273 7 7 0 0 0 -4.3848-6.4883 7 7 0 0 0 -.007812-.0039063 7 7 0 0 0 -.001953 0 7 7 0 0 0 -.61523-.21289 7 7 0 0 0 -.044922-.015625 7 7 0 0 0 -.0058594-.0019531 7 7 0 0 0 -.55078-.13086 7 7 0 0 0 -.14062-.03125 7 7 0 0 0 -.55078-.072266 7 7 0 0 0 -.14258-.017578 7 7 0 0 0 -.55469-.025391zm1.9512 1.334a6 6 0 0 1 4.0488 5.666h-7a2 2 0 0 0 -.94922-1.6992c1.3464-2.0289 2.6038-3.2631 3.9004-3.9668zm-6.8281 2.1797c.14632.65093.35776 1.2833.68359 1.8848a2 2 0 0 0 -.80664 1.6016h-1a6 6 0 0 1 1.123-3.4863zm1.877 1.4863a2 2 0 0 0 -.10938.0039062 2 2 0 0 1 .10938-.0039062zm-.18945.011719a2 2 0 0 0 -.12109.013672 2 2 0 0 1 .12109-.013672zm-.44141.09375a2 2 0 0 0 -.056641.019531 2 2 0 0 1 .056641-.019531zm-1.3594 2.0605a2 2 0 0 0 .013672.11914 2 2 0 0 1 -.013672-.11914zm.027344.20898a2 2 0 0 0 .017578.080078 2 2 0 0 1 -.017578-.080078zm.73438 1.1992a2 2 0 0 0 1.2285.42578 2 2 0 0 0 1.0508-.30078c1.345 2.0268 2.6013 3.2645 3.8965 3.9688a6 6 0 0 1 -1.9473.33203 6 6 0 0 1 -5.0547-2.7695c.23771-.5785.50336-1.1403.82617-1.6563z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 .035156.69922 7 7 0 0 0 .27734 1.3691 7 7 0 0 0 .91016 1.8848 7 7 0 0 0 .30273.4082c.000785-.00256.0011667-.005252.0019532-.007812a7 7 0 0 0 5.4727 2.6465 7 7 0 0 0 3.2422-.80273c.001374.000393.002531.00156.003906.001953a7 7 0 0 0 .035156-.021485 7 7 0 0 0 .42578-.25 7 7 0 0 0 .16992-.10352 7 7 0 0 0 .36914-.26953 7 7 0 0 0 .20508-.15625 7 7 0 0 0 .3418-.30859 7 7 0 0 0 .16406-.1543 7 7 0 0 0 .33008-.36133 7 7 0 0 0 .14062-.16016 7 7 0 0 0 .27734-.37305 7 7 0 0 0 .13867-.19531 7 7 0 0 0 .21875-.36133 7 7 0 0 0 .14258-.25 7 7 0 0 0 .15625-.33398 7 7 0 0 0 .13867-.31055 7 7 0 0 0 .10742-.30859 7 7 0 0 0 .11914-.35352 7 7 0 0 0 .087891-.36914 7 7 0 0 0 .066406-.29297 7 7 0 0 0 .056641-.40039 7 7 0 0 0 .037109-.3125 7 7 0 0 0 .025391-.55273 7 7 0 0 0 -4.3848-6.4883 7 7 0 0 0 -.007812-.0039063 7 7 0 0 0 -.001953 0 7 7 0 0 0 -.61523-.21289 7 7 0 0 0 -.044922-.015625 7 7 0 0 0 -.0058594-.0019531 7 7 0 0 0 -.55078-.13086 7 7 0 0 0 -.14062-.03125 7 7 0 0 0 -.55078-.072266 7 7 0 0 0 -.14258-.017578 7 7 0 0 0 -.55469-.025391zm1.9512 1.334a6 6 0 0 1 4.0488 5.666h-7a2 2 0 0 0 -.94922-1.6992c1.3464-2.0289 2.6038-3.2631 3.9004-3.9668zm-6.8281 2.1797c.14632.65093.35776 1.2833.68359 1.8848a2 2 0 0 0 -.80664 1.6016h-1a6 6 0 0 1 1.123-3.4863zm1.877 1.4863a2 2 0 0 0 -.10938.0039062 2 2 0 0 1 .10938-.0039062zm-.18945.011719a2 2 0 0 0 -.12109.013672 2 2 0 0 1 .12109-.013672zm-.44141.09375a2 2 0 0 0 -.056641.019531 2 2 0 0 1 .056641-.019531zm-1.3594 2.0605a2 2 0 0 0 .013672.11914 2 2 0 0 1 -.013672-.11914zm.027344.20898a2 2 0 0 0 .017578.080078 2 2 0 0 1 -.017578-.080078zm.73438 1.1992a2 2 0 0 0 1.2285.42578 2 2 0 0 0 1.0508-.30078c1.345 2.0268 2.6013 3.2645 3.8965 3.9688a6 6 0 0 1 -1.9473.33203 6 6 0 0 1 -5.0547-2.7695c.23771-.5785.50336-1.1403.82617-1.6563z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/RotateLeft.svg b/editor/icons/RotateLeft.svg index 1200df1dde..4891455cea 100644 --- a/editor/icons/RotateLeft.svg +++ b/editor/icons/RotateLeft.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg> diff --git a/editor/icons/RotateRight.svg b/editor/icons/RotateRight.svg index d69e6a7705..7c9da781dc 100644 --- a/editor/icons/RotateRight.svg +++ b/editor/icons/RotateRight.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-opacity=".99608" transform="matrix(-1 0 0 1 16.026308 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="matrix(-1 0 0 1 16.026308 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg> diff --git a/editor/icons/Search.svg b/editor/icons/Search.svg index fff4a3cb19..847163d766 100644 --- a/editor/icons/Search.svg +++ b/editor/icons/Search.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 2.7539-.83203l4.3164 4.3164 1.4141-1.4141-4.3164-4.3164a5 5 0 0 0 .83203-2.7539 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 2.7539-.83203l4.3164 4.3164 1.4141-1.4141-4.3164-4.3164a5 5 0 0 0 .83203-2.7539 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Shortcut.svg b/editor/icons/Shortcut.svg index 4ef16f0401..2e9a69d8b6 100644 --- a/editor/icons/Shortcut.svg +++ b/editor/icons/Shortcut.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 2c-.55228 0-1 .4477-1 1v9.084c.0004015.506.448.91602 1 .91602h8c.552 0 .9996-.41002 1-.91602v-9.084c0-.5523-.44772-1-1-1zm-3 2v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a.99998.99998 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9zm6 0h3l-1 3h2l-4 4 1-3h-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 2c-.55228 0-1 .4477-1 1v9.084c.0004015.506.448.91602 1 .91602h8c.552 0 .9996-.41002 1-.91602v-9.084c0-.5523-.44772-1-1-1zm-3 2v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a.99998.99998 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9zm6 0h3l-1 3h2l-4 4 1-3h-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Skeleton3D.svg b/editor/icons/Skeleton3D.svg index f1a1db86a9..19a796c4f1 100644 --- a/editor/icons/Skeleton3D.svg +++ b/editor/icons/Skeleton3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 .26562v.001953h4v-.001953a2 2 0 0 0 1-.26562 2 2 0 0 0 1-1.7324v-3.5469a4 4 0 0 0 2-3.4531 4 4 0 0 0 -4-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-4 2h2v1h-2zm-2 2h1v1h1v-1h1 1v1h1v-1h1v.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-.86914z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 .26562v.001953h4v-.001953a2 2 0 0 0 1-.26562 2 2 0 0 0 1-1.7324v-3.5469a4 4 0 0 0 2-3.4531 4 4 0 0 0 -4-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-4 2h2v1h-2zm-2 2h1v1h1v-1h1 1v1h1v-1h1v.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-.86914z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/SoftBody3D.svg b/editor/icons/SoftBody3D.svg index 7bc9a22c22..1bd2531ce9 100644 --- a/editor/icons/SoftBody3D.svg +++ b/editor/icons/SoftBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1s-3 5 0 7-1 7-1 7h13s3-6 0-8 1-6 1-6zm2 2h7s-2 3 1 5 0 5 0 5h-7s2-4-1-6 0-4 0-4z" fill="#fc7f7f" fill-opacity=".996078"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1s-3 5 0 7-1 7-1 7h13s3-6 0-8 1-6 1-6zm2 2h7s-2 3 1 5 0 5 0 5h-7s2-4-1-6 0-4 0-4z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/SpotLight3D.svg b/editor/icons/SpotLight3D.svg index 73b738efcf..27c318257a 100644 --- a/editor/icons/SpotLight3D.svg +++ b/editor/icons/SpotLight3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a1 1 0 0 0 -1 1v3.6934c-1.7861.86608-3 2.4605-3 4.3066h4a2 2 0 0 0 2 2 2 2 0 0 0 2-2h4c0-1.8462-1.2139-3.4406-3-4.3066v-3.6934a1 1 0 0 0 -1-1zm-1.0977 9.6348-1.7324 1 1 1.7305 1.7324-1zm6.1953 0-1 1.7305 1.7324 1 1-1.7305zm-4.0977 2.3652v2h2v-2z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a1 1 0 0 0 -1 1v3.6934c-1.7861.86608-3 2.4605-3 4.3066h4a2 2 0 0 0 2 2 2 2 0 0 0 2-2h4c0-1.8462-1.2139-3.4406-3-4.3066v-3.6934a1 1 0 0 0 -1-1zm-1.0977 9.6348-1.7324 1 1 1.7305 1.7324-1zm6.1953 0-1 1.7305 1.7324 1 1-1.7305zm-4.0977 2.3652v2h2v-2z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/StaticBody3D.svg b/editor/icons/StaticBody3D.svg index 55b061571f..1172fb0821 100644 --- a/editor/icons/StaticBody3D.svg +++ b/editor/icons/StaticBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -1.4141.58594 2 2 0 0 0 -.58594 1.4141v10a2 2 0 0 0 .58594 1.4141 2 2 0 0 0 1.4141.58594h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-10a1 1 0 0 1 1-1zm0 1v2h2v-2zm8 0v2h2v-2zm-8 8v2h2v-2zm8 0v2h2v-2z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -1.4141.58594 2 2 0 0 0 -.58594 1.4141v10a2 2 0 0 0 .58594 1.4141 2 2 0 0 0 1.4141.58594h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-10a1 1 0 0 1 1-1zm0 1v2h2v-2zm8 0v2h2v-2zm-8 8v2h2v-2zm8 0v2h2v-2z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/SubViewport.svg b/editor/icons/SubViewport.svg index 1e17ae234f..d5da67ee53 100644 --- a/editor/icons/SubViewport.svg +++ b/editor/icons/SubViewport.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-.5304.0000801-1.0390625.2108475-1.4140625.5859375-.37509.37501-.5858575.8836225-.5859375 1.4140625v8c.0000803.5304.2108475 1.039063.5859375 1.414062.37501.375091.8836225.585858 1.4140625.585938h10c1.1046 0 2-.89543 2-2v-8c0-1.1046-.89543-2-2-2zm0 1h10c.55228.0000096.99999.44772 1 1v8c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-8c.0000096-.55228.44772-.99999 1-1zm3 1c-.5304.0001-1.0390625.2108375-1.4140625.5859375-.37509.375-.5858575.8836225-.5859375 1.4140625v4c.00008.5304.2108475 1.039062.5859375 1.414062.37501.3751.8836225.585838 1.4140625.585938h4c1.1046 0 2-.8954 2-2v-4c0-1.1046-.89543-2-2-2zm0 1h4c.55228 0 .99999.4477 1 1v4c-.00001.5523-.44772 1-1 1h-4c-.55228 0-.99999-.4477-1-1v-4c.00001-.5523.44772-1 1-1z" fill="#e0e0e0" fill-opacity=".996078"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-.5304.0000801-1.0390625.2108475-1.4140625.5859375-.37509.37501-.5858575.8836225-.5859375 1.4140625v8c.0000803.5304.2108475 1.039063.5859375 1.414062.37501.375091.8836225.585858 1.4140625.585938h10c1.1046 0 2-.89543 2-2v-8c0-1.1046-.89543-2-2-2zm0 1h10c.55228.0000096.99999.44772 1 1v8c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-8c.0000096-.55228.44772-.99999 1-1zm3 1c-.5304.0001-1.0390625.2108375-1.4140625.5859375-.37509.375-.5858575.8836225-.5859375 1.4140625v4c.00008.5304.2108475 1.039062.5859375 1.414062.37501.3751.8836225.585838 1.4140625.585938h4c1.1046 0 2-.8954 2-2v-4c0-1.1046-.89543-2-2-2zm0 1h4c.55228 0 .99999.4477 1 1v4c-.00001.5523-.44772 1-1 1h-4c-.55228 0-.99999-.4477-1-1v-4c.00001-.5523.44772-1 1-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Texture2DArray.svg b/editor/icons/Texture2DArray.svg index a71860023b..6d5bf0deb8 100644 --- a/editor/icons/Texture2DArray.svg +++ b/editor/icons/Texture2DArray.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(-.359546 .287637)"><path d="m2 1c-.5522847 0-1 .4477153-1 1v12c0 .552285.4477153 1 1 1h12c.552285 0 1-.447715 1-1v-12c0-.5522847-.447715-1-1-1zm1 2h10v8h-10z" fill-opacity=".99608" transform="translate(.359546 -.287637)"/><g fill-opacity=".996078" stroke-width=".207395" transform="matrix(1.6197742 0 0 .750929 -3.723153 1.832957)"><path d="m4.9900159 2.5027746h1.85211v1.3316838h-.926055v5.3267353h.926055v1.3316833h-1.85211z"/><path d="m9.9289759 10.492877h-1.85211v-1.3316833h.926055v-5.3267353h-.926055v-1.3316838h1.85211z"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(-.359546 .287637)"><path d="m2 1c-.5522847 0-1 .4477153-1 1v12c0 .552285.4477153 1 1 1h12c.552285 0 1-.447715 1-1v-12c0-.5522847-.447715-1-1-1zm1 2h10v8h-10z" transform="translate(.359546 -.287637)"/><g stroke-width=".207395" transform="matrix(1.6197742 0 0 .750929 -3.723153 1.832957)"><path d="m4.9900159 2.5027746h1.85211v1.3316838h-.926055v5.3267353h.926055v1.3316833h-1.85211z"/><path d="m9.9289759 10.492877h-1.85211v-1.3316833h.926055v-5.3267353h-.926055v-1.3316838h1.85211z"/></g></g></svg> diff --git a/editor/icons/ToolMove.svg b/editor/icons/ToolMove.svg index b83f62265f..8c14b76eba 100644 --- a/editor/icons/ToolMove.svg +++ b/editor/icons/ToolMove.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9844 1.002a1.0001 1.0001 0 0 0 -.69141.29102l-2 2 1.4141 1.4141 1.293-1.293 1.293 1.293 1.4141-1.4141-2-2a1.0001 1.0001 0 0 0 -.72266-.29102zm-4.6914 4.291-2 2a1.0001 1.0001 0 0 0 0 1.4141l2 2 1.4141-1.4141-1.293-1.293 1.293-1.293-1.4141-1.4141zm9.4141 0-1.4141 1.4141 1.293 1.293-1.293 1.293 1.4141 1.4141 2-2a1.0001 1.0001 0 0 0 0-1.4141l-2-2zm-4.707.70703a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-1.293 5.293-1.4141 1.4141 2 2a1.0001 1.0001 0 0 0 1.4141 0l2-2-1.4141-1.4141-1.293 1.293-1.293-1.293z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9844 1.002a1.0001 1.0001 0 0 0 -.69141.29102l-2 2 1.4141 1.4141 1.293-1.293 1.293 1.293 1.4141-1.4141-2-2a1.0001 1.0001 0 0 0 -.72266-.29102zm-4.6914 4.291-2 2a1.0001 1.0001 0 0 0 0 1.4141l2 2 1.4141-1.4141-1.293-1.293 1.293-1.293-1.4141-1.4141zm9.4141 0-1.4141 1.4141 1.293 1.293-1.293 1.293 1.4141 1.4141 2-2a1.0001 1.0001 0 0 0 0-1.4141l-2-2zm-4.707.70703a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-1.293 5.293-1.4141 1.4141 2 2a1.0001 1.0001 0 0 0 1.4141 0l2-2-1.4141-1.4141-1.293 1.293-1.293-1.293z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/ToolPan.svg b/editor/icons/ToolPan.svg index 28ffe6336a..51db68ae74 100644 --- a/editor/icons/ToolPan.svg +++ b/editor/icons/ToolPan.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10 1a1 1 0 0 0 -1 1v6h-1v-5a1 1 0 0 0 -1-1 1 1 0 0 0 -1 1v8 .033203l-2.4746-1.8086c-.52015-.3803-1.1948-.4556-1.6504 0-.45566.4556-.45561 1.1948 0 1.6504l4.125 4.125h6a2 2 0 0 0 2-2v-5-4a1 1 0 0 0 -1-1 1 1 0 0 0 -1 1v4h-1v-6a1 1 0 0 0 -1-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10 1a1 1 0 0 0 -1 1v6h-1v-5a1 1 0 0 0 -1-1 1 1 0 0 0 -1 1v8 .033203l-2.4746-1.8086c-.52015-.3803-1.1948-.4556-1.6504 0-.45566.4556-.45561 1.1948 0 1.6504l4.125 4.125h6a2 2 0 0 0 2-2v-5-4a1 1 0 0 0 -1-1 1 1 0 0 0 -1 1v4h-1v-6a1 1 0 0 0 -1-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/ToolRotate.svg b/editor/icons/ToolRotate.svg index 41dd22584d..0fa1904937 100644 --- a/editor/icons/ToolRotate.svg +++ b/editor/icons/ToolRotate.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.0879 1.002a7 7 0 0 0 -.30469.0019531 7 7 0 0 0 -.69727.056641 7 7 0 0 0 -5.9512 5.5742 7 7 0 0 0 1.9707 6.3652h-1.1055v2h4a1.0001 1.0001 0 0 0 .9707-1.2422l-1-4-1.9414.48633.28125 1.1211a5 5 0 0 1 -1.3105-3.3652 5 5 0 0 1 5-5 5 5 0 0 1 5 5 5 5 0 0 1 -1.4668 3.5332l1.416 1.416a7 7 0 0 0 1.3281-8.0449 7 7 0 0 0 -6.1895-3.9023zm-.087891 4.998a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.0879 1.002a7 7 0 0 0 -.30469.0019531 7 7 0 0 0 -.69727.056641 7 7 0 0 0 -5.9512 5.5742 7 7 0 0 0 1.9707 6.3652h-1.1055v2h4a1.0001 1.0001 0 0 0 .9707-1.2422l-1-4-1.9414.48633.28125 1.1211a5 5 0 0 1 -1.3105-3.3652 5 5 0 0 1 5-5 5 5 0 0 1 5 5 5 5 0 0 1 -1.4668 3.5332l1.416 1.416a7 7 0 0 0 1.3281-8.0449 7 7 0 0 0 -6.1895-3.9023zm-.087891 4.998a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/ToolScale.svg b/editor/icons/ToolScale.svg index 730143a474..9ebeaffeae 100644 --- a/editor/icons/ToolScale.svg +++ b/editor/icons/ToolScale.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h2.5859l-1.293 1.293 1.4141 1.4141 1.293-1.293v2.5859a1 1 0 0 0 1 1 1 1 0 0 0 1-1v-5a1.0001 1.0001 0 0 0 -1-1zm-1 5a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-6 2a1 1 0 0 0 -1 1v5a1.0001 1.0001 0 0 0 1 1h5a1 1 0 0 0 1-1 1 1 0 0 0 -1-1h-2.5859l1.293-1.293-1.4141-1.4141-1.293 1.293v-2.5859a1 1 0 0 0 -1-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h2.5859l-1.293 1.293 1.4141 1.4141 1.293-1.293v2.5859a1 1 0 0 0 1 1 1 1 0 0 0 1-1v-5a1.0001 1.0001 0 0 0 -1-1zm-1 5a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-6 2a1 1 0 0 0 -1 1v5a1.0001 1.0001 0 0 0 1 1h5a1 1 0 0 0 1-1 1 1 0 0 0 -1-1h-2.5859l1.293-1.293-1.4141-1.4141-1.293 1.293v-2.5859a1 1 0 0 0 -1-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/TripleBar.svg b/editor/icons/TripleBar.svg index 2b521e6c15..6baea09478 100644 --- a/editor/icons/TripleBar.svg +++ b/editor/icons/TripleBar.svg @@ -1 +1 @@ -<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m1.9375 4h12.062zm0 4h12.062zm0 4h12.062z" fill="none" stroke="#e0e0e0" stroke-opacity=".99608" stroke-width=".92823"/></svg> +<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m1.9375 4h12.062zm0 4h12.062zm0 4h12.062z" fill="none" stroke="#e0e0e0" stroke-width=".92823"/></svg> diff --git a/editor/icons/VehicleBody3D.svg b/editor/icons/VehicleBody3D.svg index 00e4696a17..5e21f40c85 100644 --- a/editor/icons/VehicleBody3D.svg +++ b/editor/icons/VehicleBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 3a1 1 0 0 0 -1 1l-1 3h-2v4h1.0508c.23167-1.1411 1.2398-2 2.4492-2s2.2175.85893 2.4492 2h2.1016c.23167-1.1411 1.2398-2 2.4492-2s2.2175.85893 2.4492 2h1.0508v-4h-4v-4zm1 1h4v3h-4zm-1.5 6a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5zm7 0a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 3a1 1 0 0 0 -1 1l-1 3h-2v4h1.0508c.23167-1.1411 1.2398-2 2.4492-2s2.2175.85893 2.4492 2h2.1016c.23167-1.1411 1.2398-2 2.4492-2s2.2175.85893 2.4492 2h1.0508v-4h-4v-4zm1 1h4v3h-4zm-1.5 6a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5zm7 0a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/VehicleWheel3D.svg b/editor/icons/VehicleWheel3D.svg index 4c825d6e34..540bad8ab0 100644 --- a/editor/icons/VehicleWheel3D.svg +++ b/editor/icons/VehicleWheel3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5zm0 1a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5zm0 1a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/Viewport.svg b/editor/icons/Viewport.svg index 7d388c1c6d..9de1e8b05a 100644 --- a/editor/icons/Viewport.svg +++ b/editor/icons/Viewport.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-.5304.0000801-1.0391.21085-1.4141.58594-.37509.37501-.58586.88366-.58594 1.4141v8c.0000803.5304.21085 1.0391.58594 1.4141.37501.37509.88366.58586 1.4141.58594h10c1.1046 0 2-.89543 2-2v-8c0-1.1046-.89543-2-2-2zm0 1h10c.55228.0000096.99999.44772 1 1v8c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-8c.0000096-.55228.44772-.99999 1-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-.5304.0000801-1.0391.21085-1.4141.58594-.37509.37501-.58586.88366-.58594 1.4141v8c.0000803.5304.21085 1.0391.58594 1.4141.37501.37509.88366.58586 1.4141.58594h10c1.1046 0 2-.89543 2-2v-8c0-1.1046-.89543-2-2-2zm0 1h10c.55228.0000096.99999.44772 1 1v8c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-8c.0000096-.55228.44772-.99999 1-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/ViewportSpeed.svg b/editor/icons/ViewportSpeed.svg index 57292e2e91..caed3cb1de 100644 --- a/editor/icons/ViewportSpeed.svg +++ b/editor/icons/ViewportSpeed.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="3.77953"><path d="m6.0285136 0c-1.0906961 0-2.0000127.90931655-2.0000127 2.0000126v2.3105008c-.3234859-.1927559-.6845858-.3367559-1.0781102-.3223937-1.3171276.048-2.24957487 1.4115024-1.8164032 2.6561764l.9960945 2.9883213c.183927.5526806.6039307.9375116 1.1054741 1.1581986l-2.30275287 1.537096c-.49591181.31937-.83535119.846198-.91211339 1.373102-.07676977.526904.06603212 1.019906.33007748 1.416.26404536.396095.66572598.719811 1.18163158.851603.5153008.131528 1.1318173.02268 1.6171842-.312566h.00195l4.1015433-2.734413.9863434 1.972611c.4415244.884069 1.4843716 1.316372 2.4218832 1.00388l3-.999987-.02929.01134c.570898-.17159 1.048139-.590173 1.265613-1.082078.217466-.491906.208418-1.011893.05664-1.466797-.119282-.357543-.41469-.637606-.728504-.892611.261162-.206362.546142-.39171.681638-.730394.195632-.489109.17105-1.1070991-.08984-1.6289007l-1.000027-2.0011107c-.337916-.6777827-1.033625-1.1077039-1.789039-1.1075905h-.419906c.196645-.3087874.419906-.6128126.419906-.9999874v-3.0000001c0-1.09069605-.909317-2.0000126-2.000012-2.0000126z"/><path d="m6.0285136.99998741c-.5540032 0-.9999874.44598429-.9999874 1.00002519v3.0000001c0 .5540031.4459842.9999874.9999874.9999874h.9999874v.9902362a1.0001008 1.0001008 0 0 0 -.316407.062362l-2.0507716.6835656-.6836032-2.0507717a1.0001008 1.0001008 0 0 0 -.9902362-.6972473 1.0001008 1.0001008 0 0 0 -.9082205 1.328126l.9999874 3.0000001a1.0001008 1.0001008 0 0 0 1.2656126.6328063l1.6835906-.5605418v.6113008c0 .040819.018709.075591.023433.1152757l-4.5781418 3.052762a1.0001008 1.0001008 0 1 0 1.1093669 1.664051l5.05663-3.371112 1.4941228 2.986356a1.0001008 1.0001008 0 0 0 1.210922.501921l3.000001-.999987a1.0001008 1.0001008 0 1 0 -.632807-1.896378l-2.177726.724611-.9746262-1.951182c.275898-.177637.4687372-.472252.4687372-.8261665v-.9999874h1.382815l.722646 1.4472569a1.0001246 1.0001246 0 1 0 1.789077-.8945388l-.999987-1.9999748a1.0001008 1.0001008 0 0 0 -.894539-.5527559h-2.9999995v-.9999874h.9999875c.554003 0 .999987-.4459843.999987-.9999874v-3.0000001c0-.5540409-.445984-1.00002519-.999987-1.00002519zm0 2.00001259h.9999874v2.0000127h-.9999874z" fill="#fff" fill-opacity=".99608"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="3.77953"><path d="m6.0285136 0c-1.0906961 0-2.0000127.90931655-2.0000127 2.0000126v2.3105008c-.3234859-.1927559-.6845858-.3367559-1.0781102-.3223937-1.3171276.048-2.24957487 1.4115024-1.8164032 2.6561764l.9960945 2.9883213c.183927.5526806.6039307.9375116 1.1054741 1.1581986l-2.30275287 1.537096c-.49591181.31937-.83535119.846198-.91211339 1.373102-.07676977.526904.06603212 1.019906.33007748 1.416.26404536.396095.66572598.719811 1.18163158.851603.5153008.131528 1.1318173.02268 1.6171842-.312566h.00195l4.1015433-2.734413.9863434 1.972611c.4415244.884069 1.4843716 1.316372 2.4218832 1.00388l3-.999987-.02929.01134c.570898-.17159 1.048139-.590173 1.265613-1.082078.217466-.491906.208418-1.011893.05664-1.466797-.119282-.357543-.41469-.637606-.728504-.892611.261162-.206362.546142-.39171.681638-.730394.195632-.489109.17105-1.1070991-.08984-1.6289007l-1.000027-2.0011107c-.337916-.6777827-1.033625-1.1077039-1.789039-1.1075905h-.419906c.196645-.3087874.419906-.6128126.419906-.9999874v-3.0000001c0-1.09069605-.909317-2.0000126-2.000012-2.0000126z"/><path d="m6.0285136.99998741c-.5540032 0-.9999874.44598429-.9999874 1.00002519v3.0000001c0 .5540031.4459842.9999874.9999874.9999874h.9999874v.9902362a1.0001008 1.0001008 0 0 0 -.316407.062362l-2.0507716.6835656-.6836032-2.0507717a1.0001008 1.0001008 0 0 0 -.9902362-.6972473 1.0001008 1.0001008 0 0 0 -.9082205 1.328126l.9999874 3.0000001a1.0001008 1.0001008 0 0 0 1.2656126.6328063l1.6835906-.5605418v.6113008c0 .040819.018709.075591.023433.1152757l-4.5781418 3.052762a1.0001008 1.0001008 0 1 0 1.1093669 1.664051l5.05663-3.371112 1.4941228 2.986356a1.0001008 1.0001008 0 0 0 1.210922.501921l3.000001-.999987a1.0001008 1.0001008 0 1 0 -.632807-1.896378l-2.177726.724611-.9746262-1.951182c.275898-.177637.4687372-.472252.4687372-.8261665v-.9999874h1.382815l.722646 1.4472569a1.0001246 1.0001246 0 1 0 1.789077-.8945388l-.999987-1.9999748a1.0001008 1.0001008 0 0 0 -.894539-.5527559h-2.9999995v-.9999874h.9999875c.554003 0 .999987-.4459843.999987-.9999874v-3.0000001c0-.5540409-.445984-1.00002519-.999987-1.00002519zm0 2.00001259h.9999874v2.0000127h-.9999874z" fill="#fff"/></g></svg> diff --git a/editor/icons/ViewportTexture.svg b/editor/icons/ViewportTexture.svg index 3dd448b1ac..a5b1e4ab07 100644 --- a/editor/icons/ViewportTexture.svg +++ b/editor/icons/ViewportTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-.5304.0000801-1.0391.21085-1.4141.58594-.37509.37501-.58586.88366-.58594 1.4141v8c.0000803.5304.21085 1.0391.58594 1.4141.37501.37509.88366.58586 1.4141.58594h10c1.1046 0 2-.89543 2-2v-8c0-1.1046-.89543-2-2-2h-10zm0 1h10c.55228.0000096.99999.44772 1 1v8c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-8c.0000096-.55228.44772-.99999 1-1zm6 3v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-1-1h-1v-1z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-.5304.0000801-1.0391.21085-1.4141.58594-.37509.37501-.58586.88366-.58594 1.4141v8c.0000803.5304.21085 1.0391.58594 1.4141.37501.37509.88366.58586 1.4141.58594h10c1.1046 0 2-.89543 2-2v-8c0-1.1046-.89543-2-2-2h-10zm0 1h10c.55228.0000096.99999.44772 1 1v8c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-8c.0000096-.55228.44772-.99999 1-1zm6 3v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-1-1h-1v-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/VisibleOnScreenEnabler3D.svg b/editor/icons/VisibleOnScreenEnabler3D.svg index 6923bcb46b..1c24a348a5 100644 --- a/editor/icons/VisibleOnScreenEnabler3D.svg +++ b/editor/icons/VisibleOnScreenEnabler3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v3h1v-2h2v-1zm11 0v1h2v2h1v-3zm-4 1c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-7 6v3h3v-1h-2v-2zm13 0v2h-2v1h3v-3z" fill="#fc7f7f" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v3h1v-2h2v-1zm11 0v1h2v2h1v-3zm-4 1c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-7 6v3h3v-1h-2v-2zm13 0v2h-2v1h3v-3z" fill="#fc7f7f" fill-rule="evenodd"/></svg> diff --git a/editor/icons/VisibleOnScreenNotifier3D.svg b/editor/icons/VisibleOnScreenNotifier3D.svg index 2fdf784701..f731ae99a2 100644 --- a/editor/icons/VisibleOnScreenNotifier3D.svg +++ b/editor/icons/VisibleOnScreenNotifier3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1v6h2v-6zm-4 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-.65207 4.7109-2h-.71094-2v-.54102a4 4 0 0 1 -2 .54102 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 2 .54102v-2.1816c-.68312-.23834-1.3644-.35938-2-.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4 2v2h2v-2z" fill="#fc7f7f" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1v6h2v-6zm-4 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-.65207 4.7109-2h-.71094-2v-.54102a4 4 0 0 1 -2 .54102 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 2 .54102v-2.1816c-.68312-.23834-1.3644-.35938-2-.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4 2v2h2v-2z" fill="#fc7f7f" fill-rule="evenodd"/></svg> diff --git a/editor/icons/VisualScriptComment.svg b/editor/icons/VisualScriptComment.svg deleted file mode 100644 index 3887853b58..0000000000 --- a/editor/icons/VisualScriptComment.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m3 1v2h-2v2h2v4h-2v2h2v2h2v-2h4v2h2v-2h2v-2h-2v-4h2v-2h-2v-2h-2v2h-4v-2zm2 4h4v4h-4z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/VisualScriptExpression.svg b/editor/icons/VisualScriptExpression.svg deleted file mode 100644 index d6a3c2d9a8..0000000000 --- a/editor/icons/VisualScriptExpression.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m4.859536 3.0412379c-2.0539867 0-3.7190721 1.6650852-3.7190721 3.719072v6.1984521h2.4793814v-2.479381h2.4793814v-2.4793803h-2.4793814v-1.2396908c0-.6846622.5550285-1.2396907 1.2396907-1.2396907h1.2396907v-2.4793813z"/><path d="m7.5889175 3.0000003 2.5000005 4.9999997-2.5000005 5h2.5000005l1.135249-2.727 1.36475 2.727h2.499999l-2.499999-5 2.499999-4.9999997h-2.499999l-1.13525 2.7269998-1.364749-2.7269998zm7.4999985 9.9999997v-6.25z"/></g></svg> diff --git a/editor/icons/VoxelGI.svg b/editor/icons/VoxelGI.svg index f5e1025260..58567569af 100644 --- a/editor/icons/VoxelGI.svg +++ b/editor/icons/VoxelGI.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4v-2h-3v-10h9v-2zm9 3a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.459v.54102c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1v-.54102a4 4 0 0 0 2-3.459 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-1 8v1h2v-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4v-2h-3v-10h9v-2zm9 3a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.459v.54102c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1v-.54102a4 4 0 0 0 2-3.459 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-1 8v1h2v-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/WorldEnvironment.svg b/editor/icons/WorldEnvironment.svg index d26ec52034..6c7e34657f 100644 --- a/editor/icons/WorldEnvironment.svg +++ b/editor/icons/WorldEnvironment.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-1.7305 2.3125c-.83125 1.5372-1.2685 3.1037-1.2695 4.6816-.64057-.11251-1.3005-.27158-1.9766-.47266a5 5 0 0 1 3.2461-4.209zm3.4629.0039062a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm-1.7324.0078126c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.96392.096801-1.9566.1103-2.9844.027344-.0016335-.063192-.0078125-.12632-.0078125-.18945 0-1.5333.48744-3.0828 1.5-4.6758zm4.8789 5.7578a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039zm-9.7461.033203c.68377.18153 1.3555.33345 2.0098.43164.18781 1.0551.56647 2.1026 1.125 3.1367a5 5 0 0 1 -3.1348-3.5684zm6.168.55469c-.22615.98866-.65424 1.9884-1.3008 3.0059-.63811-1.0042-1.0645-1.9908-1.293-2.9668.89027.054126 1.7517.029377 2.5938-.039062z" fill="#fc7f7f" fill-opacity=".99608"/><path d="m8 1v2.3242c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.4894.049148-.98713.077552-1.4922.082031v1.4922c.43915-.0075968.87287-.031628 1.3008-.066406-.22615.98866-.65424 1.9884-1.3008 3.0059v2.3242a7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm1.7324 2.3164a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm3.1465 5.7656a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039z" fill="#8da5f3"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-1.7305 2.3125c-.83125 1.5372-1.2685 3.1037-1.2695 4.6816-.64057-.11251-1.3005-.27158-1.9766-.47266a5 5 0 0 1 3.2461-4.209zm3.4629.0039062a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm-1.7324.0078126c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.96392.096801-1.9566.1103-2.9844.027344-.0016335-.063192-.0078125-.12632-.0078125-.18945 0-1.5333.48744-3.0828 1.5-4.6758zm4.8789 5.7578a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039zm-9.7461.033203c.68377.18153 1.3555.33345 2.0098.43164.18781 1.0551.56647 2.1026 1.125 3.1367a5 5 0 0 1 -3.1348-3.5684zm6.168.55469c-.22615.98866-.65424 1.9884-1.3008 3.0059-.63811-1.0042-1.0645-1.9908-1.293-2.9668.89027.054126 1.7517.029377 2.5938-.039062z" fill="#fc7f7f"/><path d="m8 1v2.3242c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.4894.049148-.98713.077552-1.4922.082031v1.4922c.43915-.0075968.87287-.031628 1.3008-.066406-.22615.98866-.65424 1.9884-1.3008 3.0059v2.3242a7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm1.7324 2.3164a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm3.1465 5.7656a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039z" fill="#8da5f3"/></g></svg> diff --git a/editor/icons/Zoom.svg b/editor/icons/Zoom.svg index fc0102f0e3..6e6462af35 100644 --- a/editor/icons/Zoom.svg +++ b/editor/icons/Zoom.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 2.752-.83398l4.3184 4.3184 1.4141-1.4141-4.3184-4.3184a5 5 0 0 0 .41016-.75195h-.57617v-2h-1a3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3 3 3 0 0 1 2 .76758v-1.7676h.99023a5 5 0 0 0 -2.9902-1zm5 0v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 2.752-.83398l4.3184 4.3184 1.4141-1.4141-4.3184-4.3184a5 5 0 0 0 .41016-.75195h-.57617v-2h-1a3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3 3 3 0 0 1 2 .76758v-1.7676h.99023a5 5 0 0 0 -2.9902-1zm5 0v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#e0e0e0"/></svg> diff --git a/editor/import/audio_stream_import_settings.cpp b/editor/import/audio_stream_import_settings.cpp index e3da82a5cb..f635c74547 100644 --- a/editor/import/audio_stream_import_settings.cpp +++ b/editor/import/audio_stream_import_settings.cpp @@ -32,6 +32,7 @@ #include "editor/audio_stream_preview.h" #include "editor/editor_file_system.h" #include "editor/editor_scale.h" +#include "scene/gui/check_box.h" AudioStreamImportSettings *AudioStreamImportSettings::singleton = nullptr; @@ -76,7 +77,7 @@ void AudioStreamImportSettings::_notification(int p_what) { void AudioStreamImportSettings::_draw_preview() { Rect2 rect = _preview->get_rect(); - Size2 size = rect.size; + Size2 rect_size = rect.size; Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream); float preview_offset = zoom_bar->get_value(); @@ -85,7 +86,7 @@ void AudioStreamImportSettings::_draw_preview() { Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts")); int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")); Vector<Vector2> lines; - lines.resize(size.width * 2); + lines.resize(rect_size.width * 2); Color color_active = get_theme_color(SNAME("contrast_color_2"), SNAME("Editor")); Color color_inactive = color_active; color_inactive.a *= 0.5; @@ -107,9 +108,9 @@ void AudioStreamImportSettings::_draw_preview() { } } - for (int i = 0; i < size.width; i++) { - float ofs = preview_offset + i * preview_len / size.width; - float ofs_n = preview_offset + (i + 1) * preview_len / size.width; + for (int i = 0; i < rect_size.width; i++) { + float ofs = preview_offset + i * preview_len / rect_size.width; + float ofs_n = preview_offset + (i + 1) * preview_len / rect_size.width; float max = preview->get_max(ofs, ofs_n) * 0.5 + 0.5; float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5; @@ -139,8 +140,8 @@ void AudioStreamImportSettings::_draw_preview() { int bar_beats = stream->get_bar_beats(); int last_text_end_x = 0; - for (int i = 0; i < size.width; i++) { - float ofs = preview_offset + i * preview_len / size.width; + for (int i = 0; i < rect_size.width; i++) { + float ofs = preview_offset + i * preview_len / rect_size.width; int beat = int(ofs / beat_size); if (beat != prev_beat) { String text = itos(beat); @@ -287,17 +288,15 @@ void AudioStreamImportSettings::_draw_indicator() { float preview_len = zoom_bar->get_page(); float beat_size = 60 / float(stream->get_bpm()); int prev_beat = 0; - int last_text_end_x = 0; for (int i = 0; i < rect.size.width; i++) { float ofs = preview_offset + i * preview_len / rect.size.width; int beat = int(ofs / beat_size); if (beat != prev_beat) { String text = itos(beat); int text_w = beat_font->get_string_size(text).width; - if (i - text_w / 2 > last_text_end_x + 2 * EDSCALE && beat == _hovering_beat) { + if (i - text_w / 2 > 2 * EDSCALE && beat == _hovering_beat) { int x_ofs = i - text_w / 2; _indicator->draw_string(beat_font, Point2(x_ofs, 2 * EDSCALE + beat_font->get_ascent(main_size)), text, HORIZONTAL_ALIGNMENT_LEFT, rect.size.width - x_ofs, Font::DEFAULT_FONT_SIZE, color); - last_text_end_x = i + text_w / 2; break; } prev_beat = beat; diff --git a/editor/import/audio_stream_import_settings.h b/editor/import/audio_stream_import_settings.h index 5e399237ca..fc756c6524 100644 --- a/editor/import/audio_stream_import_settings.h +++ b/editor/import/audio_stream_import_settings.h @@ -34,9 +34,12 @@ #include "editor/editor_plugin.h" #include "scene/audio/audio_stream_player.h" #include "scene/gui/color_rect.h" +#include "scene/gui/dialogs.h" #include "scene/gui/spin_box.h" #include "scene/resources/texture.h" +class CheckBox; + class AudioStreamImportSettings : public ConfirmationDialog { GDCLASS(AudioStreamImportSettings, ConfirmationDialog); diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp index 5d8e453395..c54b10842f 100644 --- a/editor/import/collada.cpp +++ b/editor/import/collada.cpp @@ -848,6 +848,8 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam CurveData &curvedata = state.curve_data_map[p_id]; curvedata.name = p_name; + String closed = parser.get_attribute_value_safe("closed").to_lower(); + curvedata.closed = closed == "true" || closed == "1"; COLLADA_PRINT("curve name: " + p_name); @@ -2036,11 +2038,7 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) { ERR_CONTINUE(!state.scene_map.has(nodeid)); //weird, it should have it... -#ifdef NO_SAFE_CAST - NodeJoint *nj = static_cast<NodeJoint *>(state.scene_map[nodeid]); -#else NodeJoint *nj = dynamic_cast<NodeJoint *>(state.scene_map[nodeid]); -#endif ERR_CONTINUE(!nj); //broken collada ERR_CONTINUE(!nj->owner); //weird, node should have a skeleton owner @@ -2197,11 +2195,7 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L String nodeid = ng->skeletons[0]; ERR_FAIL_COND_V(!state.scene_map.has(nodeid), false); //weird, it should have it... -#ifdef NO_SAFE_CAST - NodeJoint *nj = static_cast<NodeJoint *>(state.scene_map[nodeid]); -#else NodeJoint *nj = dynamic_cast<NodeJoint *>(state.scene_map[nodeid]); -#endif ERR_FAIL_COND_V(!nj, false); ERR_FAIL_COND_V(!nj->owner, false); //weird, node should have a skeleton owner diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp index d1f37179f3..0aa77f6ea0 100644 --- a/editor/import/dynamic_font_import_settings.cpp +++ b/editor/import/dynamic_font_import_settings.cpp @@ -30,6 +30,7 @@ #include "dynamic_font_import_settings.h" +#include "core/config/project_settings.h" #include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_inspector.h" @@ -302,6 +303,7 @@ static UniRange unicode_ranges[] = { { 0x10D00, 0x10D3F, U"Hanifi Rohingya" }, { 0x10E60, 0x10E7F, U"Rumi Numeral Symbols" }, { 0x10E80, 0x10EBF, U"Yezidi" }, + { 0x10EC0, 0x10EFF, U"Arabic Extended-C" }, { 0x10F00, 0x10F2F, U"Old Sogdian" }, { 0x10F30, 0x10F6F, U"Sogdian" }, { 0x10F70, 0x10FAF, U"Old Uyghur" }, @@ -333,11 +335,13 @@ static UniRange unicode_ranges[] = { { 0x11A50, 0x11AAF, U"Soyombo" }, { 0x11AB0, 0x11ABF, U"Unified Canadian Aboriginal Syllabics Extended-A" }, { 0x11AC0, 0x11AFF, U"Pau Cin Hau" }, + { 0x11B00, 0x11B5F, U"Devanagari Extended-A" }, { 0x11C00, 0x11C6F, U"Bhaiksuki" }, { 0x11C70, 0x11CBF, U"Marchen" }, { 0x11D00, 0x11D5F, U"Masaram Gondi" }, { 0x11D60, 0x11DAF, U"Gunjala Gondi" }, { 0x11EE0, 0x11EFF, U"Makasar" }, + { 0x11F00, 0x11F5F, U"Kawi" }, { 0x11FB0, 0x11FBF, U"Lisu Supplement" }, { 0x11FC0, 0x11FFF, U"Tamil Supplement" }, { 0x12000, 0x123FF, U"Cuneiform" }, @@ -370,6 +374,7 @@ static UniRange unicode_ranges[] = { { 0x1D000, 0x1D0FF, U"Byzantine Musical Symbols" }, { 0x1D100, 0x1D1FF, U"Musical Symbols" }, { 0x1D200, 0x1D24F, U"Ancient Greek Musical Notation" }, + { 0x1D2C0, 0x1D2DF, U"Kaktovik Numerals" }, { 0x1D2E0, 0x1D2FF, U"Mayan Numerals" }, { 0x1D300, 0x1D35F, U"Tai Xuan Jing Symbols" }, { 0x1D360, 0x1D37F, U"Counting Rod Numerals" }, @@ -377,9 +382,11 @@ static UniRange unicode_ranges[] = { { 0x1D800, 0x1DAAF, U"Sutton SignWriting" }, { 0x1DF00, 0x1DFFF, U"Latin Extended-G" }, { 0x1E000, 0x1E02F, U"Glagolitic Supplement" }, + { 0x1E030, 0x1E08F, U"Cyrillic Extended-D" }, { 0x1E100, 0x1E14F, U"Nyiakeng Puachue Hmong" }, { 0x1E290, 0x1E2BF, U"Toto" }, { 0x1E2C0, 0x1E2FF, U"Wancho" }, + { 0x1E4D0, 0x1E4FF, U"Nag Mundari" }, { 0x1E7E0, 0x1E7FF, U"Ethiopic Extended-B" }, { 0x1E800, 0x1E8DF, U"Mende Kikakui" }, { 0x1E900, 0x1E95F, U"Adlam" }, @@ -409,6 +416,7 @@ static UniRange unicode_ranges[] = { { 0x2CEB0, 0x2EBEF, U"CJK Unified Ideographs Extension F" }, { 0x2F800, 0x2FA1F, U"CJK Compatibility Ideographs Supplement" }, { 0x30000, 0x3134F, U"CJK Unified Ideographs Extension G" }, + { 0x31350, 0x323AF, U"CJK Unified Ideographs Extension H" }, //{ 0xE0000, 0xE007F, U"Tags" }, //{ 0xE0100, 0xE01EF, U"Variation Selectors Supplement" }, { 0xF0000, 0xFFFFF, U"Supplementary Private Use Area-A" }, @@ -485,9 +493,9 @@ void DynamicFontImportSettings::_variation_add() { TreeItem *vars_item = vars_list->create_item(vars_list_root); ERR_FAIL_NULL(vars_item); - vars_item->set_text(0, TTR("New configuration")); + vars_item->set_text(0, TTR("New Configuration")); vars_item->set_editable(0, true); - vars_item->add_button(1, vars_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); + vars_item->add_button(1, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75)); Ref<DynamicFontImportSettingsData> import_variation_data; @@ -521,6 +529,12 @@ void DynamicFontImportSettings::_variation_selected() { label_glyphs->set_text(TTR("Preloaded glyphs: ") + itos(import_variation_data->selected_glyphs.size())); _range_selected(); _change_text_opts(); + + btn_fill->set_disabled(false); + btn_fill_locales->set_disabled(false); + } else { + btn_fill->set_disabled(true); + btn_fill_locales->set_disabled(true); } } @@ -544,6 +558,15 @@ void DynamicFontImportSettings::_variation_remove(Object *p_item, int p_column, } _variations_validate(); + + vars_item = vars_list->get_selected(); + if (vars_item) { + btn_fill->set_disabled(false); + btn_fill_locales->set_disabled(false); + } else { + btn_fill->set_disabled(true); + btn_fill_locales->set_disabled(true); + } } void DynamicFontImportSettings::_variation_changed(const String &p_edited_property) { @@ -575,10 +598,10 @@ void DynamicFontImportSettings::_variations_validate() { } } if ((TextServer::FontAntialiasing)(int)import_settings_data->get("antialiasing") == TextServer::FONT_ANTIALIASING_LCD) { - warn += "\n" + TTR("Note: LCD sub-pixel anti-aliasing is selected, each of the glyphs will be pre-rendered for all supported sub-pixel layouts (5x)."); + warn += "\n" + TTR("Note: LCD Subpixel antialiasing is selected, each of the glyphs will be pre-rendered for all supported subpixel layouts (5x)."); } if ((TextServer::SubpixelPositioning)(int)import_settings_data->get("subpixel_positioning") != TextServer::SUBPIXEL_POSITIONING_DISABLED) { - warn += "\n" + TTR("Note: Sub-pixel positioning is selected, each of the glyphs might be pre-rendered for multiple sub-pixel offsets (up to 4x)."); + warn += "\n" + TTR("Note: Subpixel positioning is selected, each of the glyphs might be pre-rendered for multiple subpixel offsets (up to 4x)."); } if (warn.is_empty()) { label_warn->set_text(""); @@ -616,6 +639,27 @@ void DynamicFontImportSettings::_change_text_opts() { text_edit->add_theme_font_override("font", font_main_text); } +void DynamicFontImportSettings::_glyph_update_lbl() { + Ref<DynamicFontImportSettingsData> import_variation_data; + + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return; + } + + int linked_glyphs = 0; + for (const char32_t &c : import_variation_data->selected_chars) { + if (import_variation_data->selected_glyphs.has(font_main->get_glyph_index(16, c))) { + linked_glyphs++; + } + } + int unlinked_glyphs = import_variation_data->selected_glyphs.size() - linked_glyphs; + label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(unlinked_glyphs + import_variation_data->selected_chars.size())); +} + void DynamicFontImportSettings::_glyph_clear() { Ref<DynamicFontImportSettingsData> import_variation_data; @@ -628,7 +672,7 @@ void DynamicFontImportSettings::_glyph_clear() { } import_variation_data->selected_glyphs.clear(); - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size())); + _glyph_update_lbl(); _range_selected(); } @@ -655,7 +699,7 @@ void DynamicFontImportSettings::_glyph_text_selected() { } } TS->free_rid(text_rid); - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size())); + _glyph_update_lbl(); } _range_selected(); } @@ -692,7 +736,7 @@ void DynamicFontImportSettings::_glyph_selected() { item->clear_custom_bg_color(glyph_table->get_selected_column()); } } - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size())); + _glyph_update_lbl(); item = glyph_tree->get_selected(); ERR_FAIL_NULL(item); @@ -793,7 +837,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { col = 0; } } - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(import_variation_data->selected_glyphs.size())); + _glyph_update_lbl(); } bool DynamicFontImportSettings::_char_update(int32_t p_char) { @@ -878,7 +922,7 @@ void DynamicFontImportSettings::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - add_var->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + add_var->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } break; } } @@ -940,13 +984,76 @@ void DynamicFontImportSettings::_re_import() { EditorFileSystem::get_singleton()->reimport_file_with_custom_parameters(base_path, "font_data_dynamic", main_settings); } +void DynamicFontImportSettings::_locale_edited() { + TreeItem *item = locale_tree->get_selected(); + ERR_FAIL_NULL(item); + item->set_checked(0, !item->is_checked(0)); +} + +void DynamicFontImportSettings::_process_locales() { + Ref<DynamicFontImportSettingsData> import_variation_data; + + TreeItem *vars_item = vars_list->get_selected(); + if (vars_item) { + import_variation_data = vars_item->get_metadata(0); + } + if (import_variation_data.is_null()) { + return; + } + + for (int i = 0; i < locale_root->get_child_count(); i++) { + TreeItem *item = locale_root->get_child(i); + if (item) { + if (item->is_checked(0)) { + String locale = item->get_text(0); + Ref<Translation> tr = ResourceLoader::load(locale); + if (tr.is_valid()) { + Vector<String> messages = tr->get_translated_message_list(); + for (const String &E : messages) { + RID text_rid = TS->create_shaped_text(); + if (text_rid.is_valid()) { + TS->shaped_text_add_string(text_rid, E, font_main->get_rids(), 16, Dictionary(), tr->get_locale()); + TS->shaped_text_shape(text_rid); + const Glyph *gl = TS->shaped_text_get_glyphs(text_rid); + const int gl_size = TS->shaped_text_get_glyph_count(text_rid); + + for (int j = 0; j < gl_size; j++) { + if (gl[j].font_rid.is_valid() && gl[j].index != 0) { + import_variation_data->selected_glyphs.insert(gl[j].index); + } + } + TS->free_rid(text_rid); + } + } + } + } + } + } + + _glyph_update_lbl(); + _range_selected(); +} + void DynamicFontImportSettings::open_settings(const String &p_path) { // Load base font data. - Vector<uint8_t> data = FileAccess::get_file_as_array(p_path); + Vector<uint8_t> font_data = FileAccess::get_file_as_array(p_path); + + // Load project locale list. + locale_tree->clear(); + locale_root = locale_tree->create_item(); + ERR_FAIL_NULL(locale_root); + + Vector<String> translations = GLOBAL_GET("internationalization/locale/translations"); + for (const String &E : translations) { + TreeItem *item = locale_tree->create_item(locale_root); + ERR_FAIL_NULL(item); + item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + item->set_text(0, E); + } // Load font for preview. font_preview.instantiate(); - font_preview->set_data(data); + font_preview->set_data(font_data); String font_name = vformat("%s (%s)", font_preview->get_font_name(), font_preview->get_font_style_name()); String sample; @@ -969,7 +1076,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { // Load second copy of font with MSDF disabled for the glyph table and metadata extraction. font_main.instantiate(); - font_main->set_data(data); + font_main->set_data(font_data); font_main->set_multichannel_signed_distance_field(false); text_edit->add_theme_font_override("font", font_main); @@ -996,12 +1103,14 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { int gww = get_theme_font(SNAME("font"))->get_string_size("00000").x + 50; glyph_table->set_column_custom_minimum_width(0, gww); - glyph_table->clear(); vars_list->clear(); + glyph_tree->set_selected(glyph_root->get_child(0)); + vars_list_root = vars_list->create_item(); + import_settings_data->settings.clear(); import_settings_data->defaults.clear(); for (List<ResourceImporter::ImportOption>::Element *E = options_general.front(); E; E = E->next()) { import_settings_data->defaults[E->get().option.name] = E->get().default_value; @@ -1028,7 +1137,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { double embolden = preload_config.has("variation_embolden") ? preload_config["variation_embolden"].operator double() : 0; int face_index = preload_config.has("variation_face_index") ? preload_config["variation_face_index"].operator int() : 0; Transform2D transform = preload_config.has("variation_transform") ? preload_config["variation_transform"].operator Transform2D() : Transform2D(); - Vector2i size = preload_config.has("size") ? preload_config["size"].operator Vector2i() : Vector2i(16, 0); + Vector2i font_size = preload_config.has("size") ? preload_config["size"].operator Vector2i() : Vector2i(16, 0); String cfg_name = preload_config.has("name") ? preload_config["name"].operator String() : vformat("Configuration %d", i); TreeItem *vars_item = vars_list->create_item(vars_list_root); @@ -1036,7 +1145,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { vars_item->set_text(0, cfg_name); vars_item->set_editable(0, true); - vars_item->add_button(1, vars_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); + vars_item->add_button(1, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75)); Ref<DynamicFontImportSettingsData> import_variation_data_custom; @@ -1053,8 +1162,8 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { import_variation_data_custom->options = options_variations; vars_item->set_metadata(0, import_variation_data_custom); - import_variation_data_custom->set("size", size.x); - import_variation_data_custom->set("outline_size", size.y); + import_variation_data_custom->set("size", font_size.x); + import_variation_data_custom->set("outline_size", font_size.y); import_variation_data_custom->set("variation_opentype", variation); import_variation_data_custom->set("variation_embolden", embolden); import_variation_data_custom->set("variation_face_index", face_index); @@ -1072,6 +1181,10 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { import_variation_data_custom->selected_glyphs.insert(c); } } + if (preload_configurations.is_empty()) { + _variation_add(); // Add default variation. + } + vars_list->set_selected(vars_list_root->get_child(0)); } else { Variant value = config->get_value("params", key); import_settings_data->defaults[key] = value; @@ -1114,14 +1227,14 @@ DynamicFontImportSettings::DynamicFontImportSettings() { options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); - options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel"), 1)); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD Subpixel"), 1)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "generate_mipmaps"), false)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_RANGE, "1,100,1"), 8)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_RANGE, "1,250,1"), 48)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1)); - options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), 1)); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel"), 1)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0)); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Metadata Overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); @@ -1130,7 +1243,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_features"), Dictionary())); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Fallbacks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); - options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array())); + options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), Array())); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::NIL, "Compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); options_general.push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "compress", PROPERTY_HINT_NONE, ""), false)); @@ -1211,7 +1324,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { // Page 2 layout: Configurations VBoxContainer *page2_vb = memnew(VBoxContainer); - page2_vb->set_name(TTR("Pre-render configurations")); + page2_vb->set_name(TTR("Pre-render Configurations")); main_pages->add_child(page2_vb); page2_description = memnew(Label); @@ -1240,7 +1353,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_var = memnew(Button); page2_hb_vars->add_child(add_var); add_var->set_tooltip_text(TTR("Add configuration")); - add_var->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + add_var->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_var->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_variation_add)); vars_list = memnew(Tree); @@ -1261,11 +1374,57 @@ DynamicFontImportSettings::DynamicFontImportSettings() { inspector_vars->connect("property_edited", callable_mp(this, &DynamicFontImportSettings::_variation_changed)); page2_side_vb->add_child(inspector_vars); + VBoxContainer *preload_pages_vb = memnew(VBoxContainer); + page2_hb->add_child(preload_pages_vb); + preload_pages = memnew(TabContainer); preload_pages->set_tab_alignment(TabBar::ALIGNMENT_CENTER); preload_pages->set_v_size_flags(Control::SIZE_EXPAND_FILL); preload_pages->set_h_size_flags(Control::SIZE_EXPAND_FILL); - page2_hb->add_child(preload_pages); + preload_pages_vb->add_child(preload_pages); + + HBoxContainer *gl_hb = memnew(HBoxContainer); + preload_pages_vb->add_child(gl_hb); + gl_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + + label_glyphs = memnew(Label); + gl_hb->add_child(label_glyphs); + label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(0)); + label_glyphs->set_custom_minimum_size(Size2(50 * EDSCALE, 0)); + + Button *btn_clear = memnew(Button); + gl_hb->add_child(btn_clear); + btn_clear->set_text(TTR("Clear Glyph List")); + btn_clear->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_glyph_clear)); + + VBoxContainer *page2_0_vb = memnew(VBoxContainer); + page2_0_vb->set_name(TTR("Glyphs from the Translations")); + preload_pages->add_child(page2_0_vb); + + page2_0_description = memnew(Label); + page2_0_description->set_text(TTR("Select translations to add all required glyphs to pre-render list:")); + page2_0_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); + page2_0_description->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART); + page2_0_vb->add_child(page2_0_description); + + locale_tree = memnew(Tree); + page2_0_vb->add_child(locale_tree); + locale_tree->set_columns(1); + locale_tree->set_hide_root(true); + locale_tree->set_column_expand(0, true); + locale_tree->connect("item_activated", callable_mp(this, &DynamicFontImportSettings::_locale_edited)); + locale_tree->set_column_custom_minimum_width(0, 120 * EDSCALE); + locale_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); + locale_root = locale_tree->create_item(); + + HBoxContainer *locale_hb = memnew(HBoxContainer); + page2_0_vb->add_child(locale_hb); + locale_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + + btn_fill_locales = memnew(Button); + locale_hb->add_child(btn_fill_locales); + btn_fill_locales->set_text(TTR("Shape all Strings in the Translations and Add Glyphs")); + btn_fill_locales->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_process_locales)); // Page 2.1 layout: Text to select glyphs VBoxContainer *page2_1_vb = memnew(VBoxContainer); @@ -1273,7 +1432,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { preload_pages->add_child(page2_1_vb); page2_1_description = memnew(Label); - page2_1_description->set_text(TTR("Enter a text to shape and add all required glyphs to pre-render list:")); + page2_1_description->set_text(TTR("Enter a text and select OpenType features to shape and add all required glyphs to pre-render list:")); page2_1_description->set_h_size_flags(Control::SIZE_EXPAND_FILL); page2_1_description->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART); page2_1_vb->add_child(page2_1_description); @@ -1299,21 +1458,11 @@ DynamicFontImportSettings::DynamicFontImportSettings() { page2_1_vb->add_child(text_hb); text_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); - label_glyphs = memnew(Label); - text_hb->add_child(label_glyphs); - label_glyphs->set_text(TTR("Preloaded glyphs:") + " " + itos(0)); - label_glyphs->set_custom_minimum_size(Size2(50 * EDSCALE, 0)); - - Button *btn_fill = memnew(Button); + btn_fill = memnew(Button); text_hb->add_child(btn_fill); - btn_fill->set_text(TTR("Shape text and add glyphs")); + btn_fill->set_text(TTR("Shape Text and Add Glyphs")); btn_fill->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_glyph_text_selected)); - Button *btn_clear = memnew(Button); - text_hb->add_child(btn_clear); - btn_clear->set_text(TTR("Clear glyph list")); - btn_clear->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_glyph_clear)); - // Page 2.2 layout: Character map VBoxContainer *page2_2_vb = memnew(VBoxContainer); page2_2_vb->set_name(TTR("Glyphs from the Character Map")); diff --git a/editor/import/dynamic_font_import_settings.h b/editor/import/dynamic_font_import_settings.h index a1f763b445..386e9896dc 100644 --- a/editor/import/dynamic_font_import_settings.h +++ b/editor/import/dynamic_font_import_settings.h @@ -118,18 +118,30 @@ class DynamicFontImportSettings : public ConfirmationDialog { TabContainer *preload_pages = nullptr; + Label *label_glyphs = nullptr; + void _glyph_clear(); + void _glyph_update_lbl(); + + // Page 2.0 layout: Translations + Label *page2_0_description = nullptr; + Tree *locale_tree = nullptr; + TreeItem *locale_root = nullptr; + Button *btn_fill_locales = nullptr; + + void _locale_edited(); + void _process_locales(); + // Page 2.1 layout: Text to select glyphs Label *page2_1_description = nullptr; - Label *label_glyphs = nullptr; TextEdit *text_edit = nullptr; EditorInspector *inspector_text = nullptr; + Button *btn_fill = nullptr; List<ResourceImporter::ImportOption> options_text; Ref<DynamicFontImportSettingsData> text_settings_data; void _change_text_opts(); void _glyph_text_selected(); - void _glyph_clear(); // Page 2.2 layout: Character map Label *page2_2_description = nullptr; diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 8d44329022..c335655d4e 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -65,7 +65,7 @@ struct ColladaImport { bool force_make_tangents = false; bool apply_mesh_xform_to_vertices = true; bool use_mesh_builtin_materials = false; - float bake_fps = 15; + float bake_fps = 30; HashMap<String, NodeMap> node_map; //map from collada node to engine node HashMap<String, String> node_name_map; //map from collada node to engine node @@ -1090,6 +1090,12 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres c->set_point_tilt(i, tilts->array[i]); } } + if (cd.closed && pc > 1) { + Vector3 pos = c->get_point_position(0); + Vector3 in = c->get_point_in(0); + Vector3 out = c->get_point_out(0); + c->add_point(pos, in, out, -1); + } curve_cache[ng->source] = c; path->set_curve(c); @@ -1754,7 +1760,7 @@ void EditorSceneFormatImporterCollada::get_extensions(List<String> *r_extensions r_extensions->push_back("dae"); } -Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { +Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err) { if (r_err) { *r_err = OK; } @@ -1765,7 +1771,7 @@ Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint3 } state.use_mesh_builtin_materials = true; - state.bake_fps = p_bake_fps; + state.bake_fps = (float)p_options["animation/fps"]; Error err = state.load(p_path, flags, p_flags & EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, false); diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h index a75b0a903f..ec30c91c1b 100644 --- a/editor/import/editor_import_collada.h +++ b/editor/import/editor_import_collada.h @@ -39,7 +39,7 @@ class EditorSceneFormatImporterCollada : public EditorSceneFormatImporter { public: virtual uint32_t get_import_flags() const override; virtual void get_extensions(List<String> *r_extensions) const override; - virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr) override; + virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr) override; EditorSceneFormatImporterCollada(); }; diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp index 5211f003c1..5d684fc5db 100644 --- a/editor/import/editor_import_plugin.cpp +++ b/editor/import/editor_import_plugin.cpp @@ -154,7 +154,7 @@ bool EditorImportPlugin::get_option_visibility(const String &p_path, const Strin d[E->key] = E->value; ++E; } - bool visible; + bool visible = false; if (GDVIRTUAL_CALL(_get_option_visibility, p_path, p_option, d, visible)) { return visible; } @@ -172,7 +172,7 @@ Error EditorImportPlugin::import(const String &p_source_file, const String &p_sa ++E; } - int err; + int err = 0; if (GDVIRTUAL_CALL(_import, p_source_file, p_save_path, options, platform_variants, gen_files, err)) { Error ret_err = Error(err); diff --git a/editor/import/post_import_plugin_skeleton_renamer.cpp b/editor/import/post_import_plugin_skeleton_renamer.cpp index 72ccb832c7..c2694329c2 100644 --- a/editor/import/post_import_plugin_skeleton_renamer.cpp +++ b/editor/import/post_import_plugin_skeleton_renamer.cpp @@ -44,100 +44,164 @@ void PostImportPluginSkeletonRenamer::get_internal_import_options(InternalImport } } -void PostImportPluginSkeletonRenamer::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) { - if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { - // Prepare objects. - Object *map = p_options["retarget/bone_map"].get_validated_object(); - if (!map || !bool(p_options["retarget/bone_renamer/rename_bones"])) { - return; - } - BoneMap *bone_map = Object::cast_to<BoneMap>(map); - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node); +void PostImportPluginSkeletonRenamer::_internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options, HashMap<String, String> p_rename_map) { + // Prepare objects. + Object *map = p_options["retarget/bone_map"].get_validated_object(); + if (!map || !bool(p_options["retarget/bone_renamer/rename_bones"])) { + return; + } + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node); - // Rename bones in Skeleton3D. - { - int len = skeleton->get_bone_count(); - for (int i = 0; i < len; i++) { - StringName bn = bone_map->find_profile_bone_name(skeleton->get_bone_name(i)); - if (bn) { - skeleton->set_bone_name(i, bn); - } + // Rename bones in Skeleton3D. + { + int len = skeleton->get_bone_count(); + for (int i = 0; i < len; i++) { + StringName bn = p_rename_map[skeleton->get_bone_name(i)]; + if (bn) { + skeleton->set_bone_name(i, bn); } } + } - // Rename bones in Skin. - { - TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D"); - while (nodes.size()) { - ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back()); - Ref<Skin> skin = mi->get_skin(); - if (skin.is_valid()) { - Node *node = mi->get_node(mi->get_skeleton_path()); - if (node) { - Skeleton3D *mesh_skeleton = Object::cast_to<Skeleton3D>(node); - if (mesh_skeleton && node == skeleton) { - int len = skin->get_bind_count(); - for (int i = 0; i < len; i++) { - StringName bn = bone_map->find_profile_bone_name(skin->get_bind_name(i)); - if (bn) { - skin->set_bind_name(i, bn); - } + // Rename bones in Skin. + { + TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D"); + while (nodes.size()) { + ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back()); + Ref<Skin> skin = mi->get_skin(); + if (skin.is_valid()) { + Node *node = mi->get_node(mi->get_skeleton_path()); + if (node) { + Skeleton3D *mesh_skeleton = Object::cast_to<Skeleton3D>(node); + if (mesh_skeleton && node == skeleton) { + int len = skin->get_bind_count(); + for (int i = 0; i < len; i++) { + StringName bn = p_rename_map[skin->get_bind_name(i)]; + if (bn) { + skin->set_bind_name(i, bn); } } } } } } + } - // Rename bones in AnimationPlayer. - { - TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); - while (nodes.size()) { - AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); - List<StringName> anims; - ap->get_animation_list(&anims); - for (const StringName &name : anims) { - Ref<Animation> anim = ap->get_animation(name); - int len = anim->get_track_count(); - for (int i = 0; i < len; i++) { - if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { - continue; - } - String track_path = String(anim->track_get_path(i).get_concatenated_names()); - Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); - if (node) { - Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); - if (track_skeleton && track_skeleton == skeleton) { - StringName bn = bone_map->find_profile_bone_name(anim->track_get_path(i).get_subname(0)); - if (bn) { - anim->track_set_path(i, track_path + ":" + bn); - } + // Rename bones in AnimationPlayer. + { + TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + int len = anim->get_track_count(); + for (int i = 0; i < len; i++) { + if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { + continue; + } + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); + if (node) { + Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); + if (track_skeleton && track_skeleton == skeleton) { + StringName bn = p_rename_map[anim->track_get_path(i).get_subname(0)]; + if (bn) { + anim->track_set_path(i, track_path + ":" + bn); } } } } } } + } + + // Rename bones in all Nodes by calling method. + { + Vector<Variant> vargs; + vargs.push_back(p_base_scene); + vargs.push_back(skeleton); + Dictionary rename_map_dict; + for (HashMap<String, String>::Iterator E = p_rename_map.begin(); E; ++E) { + rename_map_dict[E->key] = E->value; + } + vargs.push_back(rename_map_dict); + const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * vargs.size()); + const Variant *args = vargs.ptr(); + uint32_t argcount = vargs.size(); + for (uint32_t i = 0; i < argcount; i++) { + argptrs[i] = &args[i]; + } + + TypedArray<Node> nodes = p_base_scene->find_children("*"); + while (nodes.size()) { + Node *nd = Object::cast_to<Node>(nodes.pop_back()); + Callable::CallError ce; + nd->callp("_notify_skeleton_bones_renamed", argptrs, argcount, ce); + } + } +} + +void PostImportPluginSkeletonRenamer::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) { + if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { + // Prepare objects. + Object *map = p_options["retarget/bone_map"].get_validated_object(); + if (!map || !bool(p_options["retarget/bone_renamer/rename_bones"])) { + return; + } + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node); + BoneMap *bone_map = Object::cast_to<BoneMap>(map); + int len = skeleton->get_bone_count(); + + // First, prepare main rename map. + HashMap<String, String> main_rename_map; + for (int i = 0; i < len; i++) { + String bone_name = skeleton->get_bone_name(i); + String target_name = bone_map->find_profile_bone_name(bone_name); + if (target_name.is_empty()) { + continue; + } + main_rename_map.insert(bone_name, target_name); + } - // Rename bones in all Nodes by calling method. + // Preprocess of renaming bones to avoid to conflict with original bone name. + HashMap<String, String> pre_rename_map; // HashMap<skeleton bone name, target(profile) bone name> { - Vector<Variant> vargs; - vargs.push_back(p_base_scene); - vargs.push_back(skeleton); - vargs.push_back(bone_map); - const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * vargs.size()); - const Variant *args = vargs.ptr(); - uint32_t argcount = vargs.size(); - for (uint32_t i = 0; i < argcount; i++) { - argptrs[i] = &args[i]; + Vector<String> solved_name_stack; + for (int i = 0; i < len; i++) { + String bone_name = skeleton->get_bone_name(i); + String target_name = bone_map->find_profile_bone_name(bone_name); + if (target_name.is_empty() || bone_name == target_name || skeleton->find_bone(target_name) == -1) { + continue; // No conflicting. + } + + // Solve conflicting. + Ref<SkeletonProfile> profile = bone_map->get_profile(); + String solved_name = target_name; + for (int j = 2; skeleton->find_bone(solved_name) >= 0 || profile->find_bone(solved_name) >= 0 || solved_name_stack.has(solved_name); j++) { + solved_name = target_name + itos(j); + } + solved_name_stack.push_back(solved_name); + pre_rename_map.insert(target_name, solved_name); } + _internal_process(p_category, p_base_scene, p_node, p_resource, p_options, pre_rename_map); + } - TypedArray<Node> nodes = p_base_scene->find_children("*"); - while (nodes.size()) { - Node *nd = Object::cast_to<Node>(nodes.pop_back()); - Callable::CallError ce; - nd->callp("_notify_skeleton_bones_renamed", argptrs, argcount, ce); + // Main process of renaming bones. + { + // Apply pre-renaming result to prepared main rename map. + Vector<String> remove_queue; + for (HashMap<String, String>::Iterator E = main_rename_map.begin(); E; ++E) { + if (pre_rename_map.has(E->key)) { + remove_queue.push_back(E->key); + } + } + for (int i = 0; i < remove_queue.size(); i++) { + main_rename_map.insert(pre_rename_map[remove_queue[i]], main_rename_map[remove_queue[i]]); + main_rename_map.erase(remove_queue[i]); } + _internal_process(p_category, p_base_scene, p_node, p_resource, p_options, main_rename_map); } // Make unique skeleton. diff --git a/editor/import/post_import_plugin_skeleton_renamer.h b/editor/import/post_import_plugin_skeleton_renamer.h index 73cbabd1c5..b430f49ff4 100644 --- a/editor/import/post_import_plugin_skeleton_renamer.h +++ b/editor/import/post_import_plugin_skeleton_renamer.h @@ -40,6 +40,8 @@ public: virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) override; virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override; + void _internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options, HashMap<String, String> p_rename_map); + PostImportPluginSkeletonRenamer(); }; diff --git a/editor/import/resource_importer_bmfont.cpp b/editor/import/resource_importer_bmfont.cpp index 14b5638755..4fb1b726bd 100644 --- a/editor/import/resource_importer_bmfont.cpp +++ b/editor/import/resource_importer_bmfont.cpp @@ -60,7 +60,7 @@ bool ResourceImporterBMFont::get_option_visibility(const String &p_path, const S } void ResourceImporterBMFont::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { - r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array())); + r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), Array())); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true)); } diff --git a/editor/import/resource_importer_dynamic_font.cpp b/editor/import/resource_importer_dynamic_font.cpp index c822cd0fec..44440a92bd 100644 --- a/editor/import/resource_importer_dynamic_font.cpp +++ b/editor/import/resource_importer_dynamic_font.cpp @@ -76,6 +76,9 @@ bool ResourceImporterDynamicFont::get_option_visibility(const String &p_path, co if (p_option == "msdf_size" && !bool(p_options["multichannel_signed_distance_field"])) { return false; } + if (p_option == "antialiasing" && bool(p_options["multichannel_signed_distance_field"])) { + return false; + } if (p_option == "oversampling" && bool(p_options["multichannel_signed_distance_field"])) { return false; } @@ -105,7 +108,7 @@ void ResourceImporterDynamicFont::get_import_options(const String &p_path, List< r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Rendering", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel"), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD Subpixel"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate_mipmaps"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), (msdf) ? true : false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_RANGE, "1,100,1"), 8)); @@ -113,11 +116,11 @@ void ResourceImporterDynamicFont::get_import_options(const String &p_path, List< r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force_autohinter"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), 1)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0)); r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Fallbacks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); - r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array())); + r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), Array())); r_options->push_back(ImportOption(PropertyInfo(Variant::NIL, "Compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP), Variant())); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true)); diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp index 58c2061051..eb4916663e 100644 --- a/editor/import/resource_importer_imagefont.cpp +++ b/editor/import/resource_importer_imagefont.cpp @@ -63,9 +63,10 @@ void ResourceImporterImageFont::get_import_options(const String &p_path, List<Im r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "character_ranges"), Vector<String>())); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "columns"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "rows"), 1)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "font_size"), 14)); + r_options->push_back(ImportOption(PropertyInfo(Variant::RECT2I, "image_margin"), Rect2i())); + r_options->push_back(ImportOption(PropertyInfo(Variant::RECT2I, "character_margin"), Rect2i())); - r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), Array())); + r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), Array())); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true)); } @@ -93,33 +94,39 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin int columns = p_options["columns"]; int rows = p_options["rows"]; - int base_size = p_options["font_size"]; Vector<String> ranges = p_options["character_ranges"]; Array fallbacks = p_options["fallbacks"]; + Rect2i img_margin = p_options["image_margin"]; + Rect2i char_margin = p_options["character_margin"]; + + Ref<Image> img; + img.instantiate(); + Error err = ImageLoader::load_image(p_source_file, img); + ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture:") + " \"" + p_source_file + "\"."); + + int count = columns * rows; + int chr_cell_width = (img->get_width() - img_margin.position.x - img_margin.size.x) / columns; + int chr_cell_height = (img->get_height() - img_margin.position.y - img_margin.size.y) / rows; + ERR_FAIL_COND_V_MSG(chr_cell_width <= 0 || chr_cell_height <= 0, ERR_FILE_CANT_READ, TTR("Image margin too big.")); + + int chr_width = chr_cell_width - char_margin.position.x - char_margin.size.x; + int chr_height = chr_cell_height - char_margin.position.y - char_margin.size.y; + ERR_FAIL_COND_V_MSG(chr_width <= 0 || chr_height <= 0, ERR_FILE_CANT_READ, TTR("Character margin too bit.")); Ref<FontFile> font; font.instantiate(); font->set_antialiasing(TextServer::FONT_ANTIALIASING_NONE); font->set_generate_mipmaps(false); font->set_multichannel_signed_distance_field(false); - font->set_fixed_size(base_size); + font->set_fixed_size(chr_height); font->set_subpixel_positioning(TextServer::SUBPIXEL_POSITIONING_DISABLED); font->set_force_autohinter(false); font->set_hinting(TextServer::HINTING_NONE); font->set_oversampling(1.0f); font->set_fallbacks(fallbacks); + font->set_texture_image(0, Vector2i(chr_height, 0), 0, img); - Ref<Image> img; - img.instantiate(); - Error err = ImageLoader::load_image(p_source_file, img); - ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture:") + " \"" + p_source_file + "\"."); - font->set_texture_image(0, Vector2i(base_size, 0), 0, img); - - int count = columns * rows; - int chr_width = img->get_width() / columns; - int chr_height = img->get_height() / rows; int pos = 0; - for (int i = 0; i < ranges.size(); i++) { int32_t start, end; Vector<String> tokens = ranges[i].split("-"); @@ -141,17 +148,17 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin for (int32_t idx = start; idx <= end; idx++) { int x = pos % columns; int y = pos / columns; - font->set_glyph_advance(0, base_size, idx, Vector2(chr_width, 0)); - font->set_glyph_offset(0, Vector2i(base_size, 0), idx, Vector2(0, -0.5 * chr_height)); - font->set_glyph_size(0, Vector2i(base_size, 0), idx, Vector2(chr_width, chr_height)); - font->set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, Rect2(chr_width * x, chr_height * y, chr_width, chr_height)); - font->set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, 0); + font->set_glyph_advance(0, chr_height, idx, Vector2(chr_width, 0)); + font->set_glyph_offset(0, Vector2i(chr_height, 0), idx, Vector2(0, -0.5 * chr_height)); + font->set_glyph_size(0, Vector2i(chr_height, 0), idx, Vector2(chr_width, chr_height)); + font->set_glyph_uv_rect(0, Vector2i(chr_height, 0), idx, Rect2(img_margin.position.x + chr_cell_width * x + char_margin.position.x, img_margin.position.y + chr_cell_height * y + char_margin.position.y, chr_width, chr_height)); + font->set_glyph_texture_idx(0, Vector2i(chr_height, 0), idx, 0); pos++; - ERR_FAIL_COND_V_MSG(pos >= count, ERR_CANT_CREATE, "Too many characters in range."); + ERR_FAIL_COND_V_MSG(pos >= count, ERR_CANT_CREATE, "Too many characters in range, should be " + itos(columns * rows)); } } - font->set_cache_ascent(0, base_size, 0.5 * chr_height); - font->set_cache_descent(0, base_size, 0.5 * chr_height); + font->set_cache_ascent(0, chr_height, 0.5 * chr_height); + font->set_cache_descent(0, chr_height, 0.5 * chr_height); int flg = 0; if ((bool)p_options["compress"]) { diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index ed83535421..9adabfb5d1 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -135,7 +135,7 @@ String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const { } void ResourceImporterLayeredTexture::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless (PNG),Lossy (WebP),Video RAM (S3TC/ETC/BPTC),Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,VRAM Compressed,VRAM Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0)); @@ -186,9 +186,7 @@ void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, cons int mm_d = MAX(1, d >> 1); for (int i = 0; i < mm_d; i++) { - Ref<Image> mm; - mm.instantiate(); - mm->create(mm_w, mm_h, false, p_images[0]->get_format()); + Ref<Image> mm = Image::create_empty(mm_w, mm_h, false, p_images[0]->get_format()); Vector3 pos; pos.z = float(i) * float(d) / float(mm_d) + 0.5; for (int x = 0; x < mm_w; x++) { @@ -370,7 +368,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const for (int j = 0; j < hslices; j++) { int x = slice_w * j; int y = slice_h * i; - Ref<Image> slice = image->get_rect(Rect2i(x, y, slice_w, slice_h)); + Ref<Image> slice = image->get_region(Rect2i(x, y, slice_w, slice_h)); ERR_CONTINUE(slice.is_null() || slice->is_empty()); if (slice->get_width() != slice_w || slice->get_height() != slice_h) { slice->resize(slice_w, slice_h); @@ -396,12 +394,12 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const texture_import->used_channels = used_channels; _check_compress_ctex(p_source_file, texture_import); if (r_metadata) { - Dictionary metadata; - metadata["vram_texture"] = compress_mode == COMPRESS_VRAM_COMPRESSED; + Dictionary meta; + meta["vram_texture"] = compress_mode == COMPRESS_VRAM_COMPRESSED; if (formats_imported.size()) { - metadata["imported_formats"] = formats_imported; + meta["imported_formats"] = formats_imported; } - *r_metadata = metadata; + *r_metadata = meta; } return OK; @@ -420,7 +418,7 @@ String ResourceImporterLayeredTexture::get_import_settings_string() const { int index = 0; while (compression_formats[index]) { String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]); - bool test = ProjectSettings::get_singleton()->get(setting_path); + bool test = GLOBAL_GET(setting_path); if (test) { s += String(compression_formats[index]); } @@ -432,27 +430,27 @@ String ResourceImporterLayeredTexture::get_import_settings_string() const { bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_path) const { //will become invalid if formats are missing to import - Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path); + Dictionary meta = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path); - if (!metadata.has("vram_texture")) { + if (!meta.has("vram_texture")) { return false; } - bool vram = metadata["vram_texture"]; + bool vram = meta["vram_texture"]; if (!vram) { return true; //do not care about non vram } Vector<String> formats_imported; - if (metadata.has("imported_formats")) { - formats_imported = metadata["imported_formats"]; + if (meta.has("imported_formats")) { + formats_imported = meta["imported_formats"]; } int index = 0; bool valid = true; while (compression_formats[index]) { String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]); - bool test = ProjectSettings::get_singleton()->get(setting_path); + bool test = GLOBAL_GET(setting_path); if (test) { if (!formats_imported.has(compression_formats[index])) { valid = false; @@ -486,7 +484,7 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source // Must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc). // Android, GLES 2.x - bool can_bptc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc"); + bool can_bptc = GLOBAL_GET("rendering/textures/vram_compression/import_bptc"); if (can_bptc) { r_texture_import->formats_imported.push_back("bptc"); // BPTC needs to be added anyway. } @@ -494,7 +492,7 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source ERR_FAIL_NULL(r_texture_import->image); bool is_hdr = (r_texture_import->image->get_format() >= Image::FORMAT_RF && r_texture_import->image->get_format() <= Image::FORMAT_RGBE9995); bool is_ldr = (r_texture_import->image->get_format() >= Image::FORMAT_L8 && r_texture_import->image->get_format() <= Image::FORMAT_RGB565); - bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_s3tc"); + bool can_s3tc = GLOBAL_GET("rendering/textures/vram_compression/import_s3tc"); ERR_FAIL_NULL(r_texture_import->slices); // Can compress hdr, but hdr with alpha is not compressible. if (r_texture_import->hdr_compression == 2) { @@ -532,7 +530,7 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source } } if (!(r_texture_import->used_channels == Image::USED_CHANNELS_LA || r_texture_import->used_channels == Image::USED_CHANNELS_RGBA)) { - if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2")) { + if (GLOBAL_GET("rendering/textures/vram_compression/import_etc2")) { _save_tex(*r_texture_import->slices, r_texture_import->save_path + ".etc2." + extension, r_texture_import->compress_mode, r_texture_import->lossy, Image::COMPRESS_ETC2, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true); r_texture_import->platform_variants->push_back("etc2"); r_texture_import->formats_imported.push_back("etc2"); diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index fe70fd58b5..f19b4dbe56 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -422,7 +422,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ return OK; } -Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { +Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err) { List<Ref<Mesh>> meshes; Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, false, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps); diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h index 4dfac90fa1..121d8e6d36 100644 --- a/editor/import/resource_importer_obj.h +++ b/editor/import/resource_importer_obj.h @@ -39,7 +39,7 @@ class EditorOBJImporter : public EditorSceneFormatImporter { public: virtual uint32_t get_import_flags() const override; virtual void get_extensions(List<String> *r_extensions) const override; - virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; + virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err = nullptr) override; EditorOBJImporter(); }; diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index b5798a5784..a9ce6e9f88 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -74,13 +74,13 @@ void EditorSceneFormatImporter::get_extensions(List<String> *r_extensions) const ERR_FAIL(); } -Node *EditorSceneFormatImporter::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { +Node *EditorSceneFormatImporter::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err) { Dictionary options_dict; for (const KeyValue<StringName, Variant> &elem : p_options) { options_dict[elem.key] = elem.value; } Object *ret = nullptr; - if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, options_dict, p_bake_fps, ret)) { + if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, options_dict, ret)) { return Object::cast_to<Node>(ret); } @@ -100,7 +100,7 @@ Variant EditorSceneFormatImporter::get_option_visibility(const String &p_path, b void EditorSceneFormatImporter::_bind_methods() { GDVIRTUAL_BIND(_get_import_flags); GDVIRTUAL_BIND(_get_extensions); - GDVIRTUAL_BIND(_import_scene, "path", "flags", "options", "bake_fps"); + GDVIRTUAL_BIND(_import_scene, "path", "flags", "options"); GDVIRTUAL_BIND(_get_import_options, "path"); GDVIRTUAL_BIND(_get_option_visibility, "path", "for_animation", "option"); @@ -355,7 +355,7 @@ static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r ERR_FAIL_NULL_MSG(mesh, "Cannot generate shape list with null mesh value"); ERR_FAIL_NULL_MSG(mesh->get_mesh(), "Cannot generate shape list with null mesh value"); if (!p_convex) { - Ref<Shape3D> shape = mesh->create_trimesh_shape(); + Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape(); r_shape_list.push_back(shape); } else { Vector<Ref<Shape3D>> cd; @@ -402,7 +402,7 @@ void _rescale_importer_mesh(Vector3 p_scale, Ref<ImporterMesh> p_mesh, bool is_s const int fmt_compress_flags = p_mesh->get_surface_format(surf_idx); Array arr = p_mesh->get_surface_arrays(surf_idx); String name = p_mesh->get_surface_name(surf_idx); - Dictionary lods = Dictionary(); + Dictionary lods; Ref<Material> mat = p_mesh->get_surface_material(surf_idx); { Vector<Vector3> vertex_array = arr[ArrayMesh::ARRAY_VERTEX]; @@ -953,43 +953,49 @@ Node *ResourceImporterScene::_pre_fix_animations(Node *p_node, Node *p_root, con if (Object::cast_to<AnimationPlayer>(p_node)) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); + List<StringName> anims; + ap->get_animation_list(&anims); - Array animation_clips; - { - int clip_count = node_settings["clips/amount"]; + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + Array animation_slices; - for (int i = 0; i < clip_count; i++) { - String name = node_settings["clip_" + itos(i + 1) + "/name"]; - int from_frame = node_settings["clip_" + itos(i + 1) + "/start_frame"]; - int end_frame = node_settings["clip_" + itos(i + 1) + "/end_frame"]; - Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)node_settings["clip_" + itos(i + 1) + "/loop_mode"]); - bool save_to_file = node_settings["clip_" + itos(i + 1) + "/save_to_file/enabled"]; - bool save_to_path = node_settings["clip_" + itos(i + 1) + "/save_to_file/path"]; - bool save_to_file_keep_custom = node_settings["clip_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"]; + if (p_animation_data.has(name)) { + Dictionary anim_settings = p_animation_data[name]; + int slices_count = anim_settings["slices/amount"]; + + for (int i = 0; i < slices_count; i++) { + String slice_name = anim_settings["slice_" + itos(i + 1) + "/name"]; + int from_frame = anim_settings["slice_" + itos(i + 1) + "/start_frame"]; + int end_frame = anim_settings["slice_" + itos(i + 1) + "/end_frame"]; + Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)anim_settings["slice_" + itos(i + 1) + "/loop_mode"]); + bool save_to_file = anim_settings["slice_" + itos(i + 1) + "/save_to_file/enabled"]; + bool save_to_path = anim_settings["slice_" + itos(i + 1) + "/save_to_file/path"]; + bool save_to_file_keep_custom = anim_settings["slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"]; + + animation_slices.push_back(slice_name); + animation_slices.push_back(from_frame / p_animation_fps); + animation_slices.push_back(end_frame / p_animation_fps); + animation_slices.push_back(loop_mode); + animation_slices.push_back(save_to_file); + animation_slices.push_back(save_to_path); + animation_slices.push_back(save_to_file_keep_custom); + } + } - animation_clips.push_back(name); - animation_clips.push_back(from_frame / p_animation_fps); - animation_clips.push_back(end_frame / p_animation_fps); - animation_clips.push_back(loop_mode); - animation_clips.push_back(save_to_file); - animation_clips.push_back(save_to_path); - animation_clips.push_back(save_to_file_keep_custom); + if (animation_slices.size() > 0) { + _create_slices(ap, anim, animation_slices, true); } } - if (animation_clips.size()) { - _create_clips(ap, animation_clips, true); - } else { - List<StringName> anims; - ap->get_animation_list(&anims); - AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = { - AnimationImportTracks(int(node_settings["import_tracks/position"])), - AnimationImportTracks(int(node_settings["import_tracks/rotation"])), - AnimationImportTracks(int(node_settings["import_tracks/scale"])) - }; - if (anims.size() > 1 && (import_tracks_mode[0] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[1] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[2] != ANIMATION_IMPORT_TRACKS_IF_PRESENT)) { - _optimize_track_usage(ap, import_tracks_mode); - } + AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = { + AnimationImportTracks(int(node_settings["import_tracks/position"])), + AnimationImportTracks(int(node_settings["import_tracks/rotation"])), + AnimationImportTracks(int(node_settings["import_tracks/scale"])) + }; + + if (anims.size() > 1 && (import_tracks_mode[0] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[1] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[2] != ANIMATION_IMPORT_TRACKS_IF_PRESENT)) { + _optimize_track_usage(ap, import_tracks_mode); } } @@ -1270,14 +1276,12 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap< } break; } - int idx = 0; for (const Ref<Shape3D> &E : shapes) { CollisionShape3D *cshape = memnew(CollisionShape3D); cshape->set_shape(E); base->add_child(cshape, true); cshape->set_owner(base->get_owner()); - idx++; } } } @@ -1367,7 +1371,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap< } for (int i = 0; i < post_importer_plugins.size(); i++) { - post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION, p_root, p_node, anim, node_settings); + post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION, p_root, p_node, anim, anim_settings); } } } @@ -1408,144 +1412,138 @@ Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> ani return anim; } -void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all) { - if (!anim->has_animation("default")) { - ERR_FAIL_COND_MSG(p_clips.size() > 0, "To create clips, animations must be named \"default\"."); - return; - } - - Ref<Animation> default_anim = anim->get_animation("default"); - Ref<AnimationLibrary> al = anim->get_animation_library(anim->find_animation(default_anim)); +void ResourceImporterScene::_create_slices(AnimationPlayer *ap, Ref<Animation> anim, const Array &p_slices, bool p_bake_all) { + Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim)); - for (int i = 0; i < p_clips.size(); i += 7) { - String name = p_clips[i]; - float from = p_clips[i + 1]; - float to = p_clips[i + 2]; - Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)p_clips[i + 3]); - bool save_to_file = p_clips[i + 4]; - String save_to_path = p_clips[i + 5]; - bool keep_current = p_clips[i + 6]; + for (int i = 0; i < p_slices.size(); i += 7) { + String name = p_slices[i]; + float from = p_slices[i + 1]; + float to = p_slices[i + 2]; + Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)p_slices[i + 3]); + bool save_to_file = p_slices[i + 4]; + String save_to_path = p_slices[i + 5]; + bool keep_current = p_slices[i + 6]; if (from >= to) { continue; } Ref<Animation> new_anim = memnew(Animation); - for (int j = 0; j < default_anim->get_track_count(); j++) { + for (int j = 0; j < anim->get_track_count(); j++) { List<float> keys; - int kc = default_anim->track_get_key_count(j); + int kc = anim->track_get_key_count(j); int dtrack = -1; for (int k = 0; k < kc; k++) { - float kt = default_anim->track_get_key_time(j, k); + float kt = anim->track_get_key_time(j, k); if (kt >= from && kt < to) { //found a key within range, so create track if (dtrack == -1) { - new_anim->add_track(default_anim->track_get_type(j)); + new_anim->add_track(anim->track_get_type(j)); dtrack = new_anim->get_track_count() - 1; - new_anim->track_set_path(dtrack, default_anim->track_get_path(j)); + new_anim->track_set_path(dtrack, anim->track_get_path(j)); if (kt > (from + 0.01) && k > 0) { - if (default_anim->track_get_type(j) == Animation::TYPE_POSITION_3D) { + if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) { Vector3 p; - default_anim->position_track_interpolate(j, from, &p); + anim->position_track_interpolate(j, from, &p); new_anim->position_track_insert_key(dtrack, 0, p); - } else if (default_anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) { + } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) { Quaternion r; - default_anim->rotation_track_interpolate(j, from, &r); + anim->rotation_track_interpolate(j, from, &r); new_anim->rotation_track_insert_key(dtrack, 0, r); - } else if (default_anim->track_get_type(j) == Animation::TYPE_SCALE_3D) { + } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) { Vector3 s; - default_anim->scale_track_interpolate(j, from, &s); + anim->scale_track_interpolate(j, from, &s); new_anim->scale_track_insert_key(dtrack, 0, s); - } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) { - Variant var = default_anim->value_track_interpolate(j, from); + } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) { + Variant var = anim->value_track_interpolate(j, from); new_anim->track_insert_key(dtrack, 0, var); - } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { + } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { float interp; - default_anim->blend_shape_track_interpolate(j, from, &interp); + anim->blend_shape_track_interpolate(j, from, &interp); new_anim->blend_shape_track_insert_key(dtrack, 0, interp); } } } - if (default_anim->track_get_type(j) == Animation::TYPE_POSITION_3D) { + if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) { Vector3 p; - default_anim->position_track_get_key(j, k, &p); + anim->position_track_get_key(j, k, &p); new_anim->position_track_insert_key(dtrack, kt - from, p); - } else if (default_anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) { + } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) { Quaternion r; - default_anim->rotation_track_get_key(j, k, &r); + anim->rotation_track_get_key(j, k, &r); new_anim->rotation_track_insert_key(dtrack, kt - from, r); - } else if (default_anim->track_get_type(j) == Animation::TYPE_SCALE_3D) { + } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) { Vector3 s; - default_anim->scale_track_get_key(j, k, &s); + anim->scale_track_get_key(j, k, &s); new_anim->scale_track_insert_key(dtrack, kt - from, s); - } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) { - Variant var = default_anim->track_get_key_value(j, k); + } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) { + Variant var = anim->track_get_key_value(j, k); new_anim->track_insert_key(dtrack, kt - from, var); - } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { + } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { float interp; - default_anim->blend_shape_track_get_key(j, k, &interp); + anim->blend_shape_track_get_key(j, k, &interp); new_anim->blend_shape_track_insert_key(dtrack, kt - from, interp); } } if (dtrack != -1 && kt >= to) { - if (default_anim->track_get_type(j) == Animation::TYPE_POSITION_3D) { + if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) { Vector3 p; - default_anim->position_track_interpolate(j, to, &p); + anim->position_track_interpolate(j, to, &p); new_anim->position_track_insert_key(dtrack, to - from, p); - } else if (default_anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) { + } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) { Quaternion r; - default_anim->rotation_track_interpolate(j, to, &r); + anim->rotation_track_interpolate(j, to, &r); new_anim->rotation_track_insert_key(dtrack, to - from, r); - } else if (default_anim->track_get_type(j) == Animation::TYPE_SCALE_3D) { + } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) { Vector3 s; - default_anim->scale_track_interpolate(j, to, &s); + anim->scale_track_interpolate(j, to, &s); new_anim->scale_track_insert_key(dtrack, to - from, s); - } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) { - Variant var = default_anim->value_track_interpolate(j, to); + } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) { + Variant var = anim->value_track_interpolate(j, to); new_anim->track_insert_key(dtrack, to - from, var); - } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { + } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { float interp; - default_anim->blend_shape_track_interpolate(j, to, &interp); + anim->blend_shape_track_interpolate(j, to, &interp); new_anim->blend_shape_track_insert_key(dtrack, to - from, interp); } } } if (dtrack == -1 && p_bake_all) { - new_anim->add_track(default_anim->track_get_type(j)); + new_anim->add_track(anim->track_get_type(j)); dtrack = new_anim->get_track_count() - 1; - new_anim->track_set_path(dtrack, default_anim->track_get_path(j)); - if (default_anim->track_get_type(j) == Animation::TYPE_POSITION_3D) { + new_anim->track_set_path(dtrack, anim->track_get_path(j)); + if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) { Vector3 p; - default_anim->position_track_interpolate(j, from, &p); + anim->position_track_interpolate(j, from, &p); new_anim->position_track_insert_key(dtrack, 0, p); - default_anim->position_track_interpolate(j, to, &p); + anim->position_track_interpolate(j, to, &p); new_anim->position_track_insert_key(dtrack, to - from, p); - } else if (default_anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) { + } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) { Quaternion r; - default_anim->rotation_track_interpolate(j, from, &r); + anim->rotation_track_interpolate(j, from, &r); new_anim->rotation_track_insert_key(dtrack, 0, r); - default_anim->rotation_track_interpolate(j, to, &r); + anim->rotation_track_interpolate(j, to, &r); new_anim->rotation_track_insert_key(dtrack, to - from, r); - } else if (default_anim->track_get_type(j) == Animation::TYPE_SCALE_3D) { + } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) { Vector3 s; - default_anim->scale_track_interpolate(j, from, &s); + anim->scale_track_interpolate(j, from, &s); new_anim->scale_track_insert_key(dtrack, 0, s); - default_anim->scale_track_interpolate(j, to, &s); + anim->scale_track_interpolate(j, to, &s); new_anim->scale_track_insert_key(dtrack, to - from, s); - } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) { - Variant var = default_anim->value_track_interpolate(j, from); + } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) { + Variant var = anim->value_track_interpolate(j, from); new_anim->track_insert_key(dtrack, 0, var); - Variant to_var = default_anim->value_track_interpolate(j, to); + Variant to_var = anim->value_track_interpolate(j, to); new_anim->track_insert_key(dtrack, to - from, to_var); - } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { + } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) { float interp; - default_anim->blend_shape_track_interpolate(j, from, &interp); + anim->blend_shape_track_interpolate(j, from, &interp); new_anim->blend_shape_track_insert_key(dtrack, 0, interp); - default_anim->blend_shape_track_interpolate(j, to, &interp); + anim->blend_shape_track_interpolate(j, to, &interp); new_anim->blend_shape_track_insert_key(dtrack, to - from, interp); } } @@ -1562,7 +1560,7 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ } } - al->remove_animation("default"); // Remove default (no longer needed). + al->remove_animation(ap->find_animation(anim)); // Remove original animation (no longer needed). } void ResourceImporterScene::_optimize_animations(AnimationPlayer *anim, float p_max_vel_error, float p_max_ang_error, int p_prc_error) { @@ -1642,6 +1640,17 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.tres"), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/keep_custom_tracks"), "")); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0)); + + for (int i = 0; i < 256; i++) { + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/name"), "")); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/start_frame"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/end_frame"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/path", PROPERTY_HINT_SAVE_FILE, ".res,*.tres"), "")); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"), false)); + } } break; case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); @@ -1654,17 +1663,6 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/position", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/rotation", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/scale", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0)); - - for (int i = 0; i < 256; i++) { - r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/name"), "")); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/start_frame"), 0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/end_frame"), 0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/path", PROPERTY_HINT_SAVE_FILE, ".res,*.tres"), "")); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"), false)); - } } break; case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); @@ -1767,6 +1765,13 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor if (p_option == "save_to_file/path" || p_option == "save_to_file/keep_custom_tracks") { return p_options["save_to_file/enabled"]; } + if (p_option.begins_with("slice_")) { + int max_slice = p_options["slices/amount"]; + int slice = p_option.get_slice("_", 1).to_int() - 1; + if (slice >= max_slice) { + return false; + } + } } break; case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: { if (p_option.begins_with("optimizer/") && p_option != "optimizer/enabled" && !bool(p_options["optimizer/enabled"])) { @@ -1775,14 +1780,6 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor if (p_option.begins_with("compression/") && p_option != "compression/enabled" && !bool(p_options["compression/enabled"])) { return false; } - - if (p_option.begins_with("slice_")) { - int max_slice = p_options["slices/amount"]; - int slice = p_option.get_slice("_", 1).to_int() - 1; - if (slice >= max_slice) { - return false; - } - } } break; case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: { const bool use_retarget = p_options["retarget/bone_map"].get_validated_object() != nullptr; @@ -1867,6 +1864,7 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 30)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/trimming"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Dictionary())); @@ -2284,13 +2282,8 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashM ERR_FAIL_COND_V(!importer.is_valid(), nullptr); - int bake_fps = 30; - if (p_options.has(SNAME("animation/fps"))) { - bake_fps = p_options[SNAME("animation/fps")]; - } - Error err = OK; - Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, p_options, bake_fps, nullptr, &err); + Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, p_options, nullptr, &err); if (!scene || err != OK) { return nullptr; } @@ -2329,8 +2322,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p ERR_FAIL_COND_V(!importer.is_valid(), ERR_FILE_UNRECOGNIZED); - float fps = p_options["animation/fps"]; - int import_flags = 0; if (animation_importer) { @@ -2353,7 +2344,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p Error err = OK; List<String> missing_deps; // for now, not much will be done with this - Node *scene = importer->import_scene(src_path, import_flags, p_options, fps, &missing_deps, &err); + Node *scene = importer->import_scene(src_path, import_flags, p_options, &missing_deps, &err); if (!scene || err != OK) { return err; } @@ -2401,6 +2392,10 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p post_importer_plugins.write[i]->pre_process(scene, p_options); } + float fps = 30; + if (p_options.has(SNAME("animation/fps"))) { + fps = (float)p_options[SNAME("animation/fps")]; + } _pre_fix_animations(scene, scene, node_data, animation_data, fps); _post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps); _post_fix_animations(scene, scene, node_data, animation_data, fps); @@ -2615,7 +2610,7 @@ void EditorSceneFormatImporterESCN::get_extensions(List<String> *r_extensions) c r_extensions->push_back("escn"); } -Node *EditorSceneFormatImporterESCN::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { +Node *EditorSceneFormatImporterESCN::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err) { Error error; Ref<PackedScene> ps = ResourceFormatLoaderText::singleton->load(p_path, p_path, &error); ERR_FAIL_COND_V_MSG(!ps.is_valid(), nullptr, "Cannot load scene as text resource from path '" + p_path + "'."); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 77bc06533c..678251372b 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -35,11 +35,13 @@ #include "core/io/resource_importer.h" #include "core/variant/dictionary.h" #include "scene/3d/importer_mesh_instance_3d.h" -#include "scene/3d/node_3d.h" #include "scene/resources/animation.h" +#include "scene/resources/box_shape_3d.h" +#include "scene/resources/capsule_shape_3d.h" +#include "scene/resources/cylinder_shape_3d.h" #include "scene/resources/mesh.h" #include "scene/resources/shape_3d.h" -#include "scene/resources/skin.h" +#include "scene/resources/sphere_shape_3d.h" class Material; class AnimationPlayer; @@ -51,12 +53,12 @@ class EditorSceneFormatImporter : public RefCounted { protected: static void _bind_methods(); - Node *import_scene_wrapper(const String &p_path, uint32_t p_flags, Dictionary p_options, int p_bake_fps); - Ref<Animation> import_animation_wrapper(const String &p_path, uint32_t p_flags, Dictionary p_options, int p_bake_fps); + Node *import_scene_wrapper(const String &p_path, uint32_t p_flags, Dictionary p_options); + Ref<Animation> import_animation_wrapper(const String &p_path, uint32_t p_flags, Dictionary p_options); GDVIRTUAL0RC(int, _get_import_flags) GDVIRTUAL0RC(Vector<String>, _get_extensions) - GDVIRTUAL4R(Object *, _import_scene, String, uint32_t, Dictionary, uint32_t) + GDVIRTUAL3R(Object *, _import_scene, String, uint32_t, Dictionary) GDVIRTUAL1(_get_import_options, String) GDVIRTUAL3RC(Variant, _get_option_visibility, String, bool, String) @@ -72,7 +74,7 @@ public: virtual uint32_t get_import_flags() const; virtual void get_extensions(List<String> *r_extensions) const; - virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr); + virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err = nullptr); virtual void get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options); virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const HashMap<StringName, Variant> &p_options); @@ -281,7 +283,7 @@ public: Node *_post_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps); Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks); - void _create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all); + void _create_slices(AnimationPlayer *ap, Ref<Animation> anim, const Array &p_clips, bool p_bake_all); void _optimize_animations(AnimationPlayer *anim, float p_max_vel_error, float p_max_ang_error, int p_prc_error); void _compress_animations(AnimationPlayer *anim, int p_page_size_kb); @@ -308,14 +310,9 @@ class EditorSceneFormatImporterESCN : public EditorSceneFormatImporter { public: virtual uint32_t get_import_flags() const override; virtual void get_extensions(List<String> *r_extensions) const override; - virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; + virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err = nullptr) override; }; -#include "scene/resources/box_shape_3d.h" -#include "scene/resources/capsule_shape_3d.h" -#include "scene/resources/cylinder_shape_3d.h" -#include "scene/resources/sphere_shape_3d.h" - template <class M> Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options) { ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX; @@ -477,7 +474,7 @@ Transform3D ResourceImporterScene::get_collision_shapes_transform(const M &p_opt } if (p_options.has(SNAME("primitive/rotation"))) { - transform.basis.set_euler((p_options[SNAME("primitive/rotation")].operator Vector3() / 180.0) * Math_PI); + transform.basis = Basis::from_euler(p_options[SNAME("primitive/rotation")].operator Vector3() * (Math_PI / 180.0)); } } return transform; diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index c06756ff0b..54ad840f3d 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -192,7 +192,7 @@ bool ResourceImporterTexture::get_option_visibility(const String &p_path, const if (compress_mode < COMPRESS_VRAM_COMPRESSED) { return false; } - if (!ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc")) { + if (!GLOBAL_GET("rendering/textures/vram_compression/import_bptc")) { return false; } } @@ -233,7 +233,8 @@ void ResourceImporterTexture::get_import_options(const String &p_path, List<Impo r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "detect_3d/compress_to", PROPERTY_HINT_ENUM, "Disabled,VRAM Compressed,Basis Universal"), (p_preset == PRESET_DETECT) ? 1 : 0)); - if (p_path.get_extension() == "svg") { + // Do path based customization only if a path was passed. + if (p_path.is_empty() || p_path.get_extension() == "svg") { r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0)); // Editor use only, applies to SVG. @@ -245,7 +246,7 @@ void ResourceImporterTexture::get_import_options(const String &p_path, List<Impo void ResourceImporterTexture::save_to_ctex_format(Ref<FileAccess> f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality) { switch (p_compress_mode) { case COMPRESS_LOSSLESS: { - bool lossless_force_png = ProjectSettings::get_singleton()->get("rendering/textures/lossless_compression/force_png") || + bool lossless_force_png = GLOBAL_GET("rendering/textures/lossless_compression/force_png") || !Image::_webp_mem_loader_func; // WebP module disabled. bool use_webp = !lossless_force_png && p_image->get_width() <= 16383 && p_image->get_height() <= 16383; // WebP has a size limit f->store_32(use_webp ? CompressedTexture2D::DATA_FORMAT_WEBP : CompressedTexture2D::DATA_FORMAT_PNG); @@ -598,8 +599,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String const bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995); bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGB565); - const bool can_bptc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc"); - const bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_s3tc"); + const bool can_bptc = GLOBAL_GET("rendering/textures/vram_compression/import_bptc"); + const bool can_s3tc = GLOBAL_GET("rendering/textures/vram_compression/import_s3tc"); if (can_bptc) { // Add to the list anyway. @@ -644,13 +645,13 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String formats_imported.push_back("s3tc"); } - if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2")) { + if (GLOBAL_GET("rendering/textures/vram_compression/import_etc2")) { _save_ctex(image, p_save_path + ".etc2.ctex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("etc2"); formats_imported.push_back("etc2"); } - if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc")) { + if (GLOBAL_GET("rendering/textures/vram_compression/import_etc")) { _save_ctex(image, p_save_path + ".etc.ctex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel); r_platform_variants->push_back("etc"); formats_imported.push_back("etc"); @@ -669,23 +670,23 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String } if (r_metadata) { - Dictionary metadata; - metadata["vram_texture"] = compress_mode == COMPRESS_VRAM_COMPRESSED; + Dictionary meta; + meta["vram_texture"] = compress_mode == COMPRESS_VRAM_COMPRESSED; if (formats_imported.size()) { - metadata["imported_formats"] = formats_imported; + meta["imported_formats"] = formats_imported; } if (editor_image.is_valid()) { - metadata["has_editor_variant"] = true; + meta["has_editor_variant"] = true; if (use_editor_scale) { - metadata["editor_scale"] = EDSCALE; + meta["editor_scale"] = EDSCALE; } if (convert_editor_colors) { - metadata["editor_dark_theme"] = EditorSettings::get_singleton()->is_dark_theme(); + meta["editor_dark_theme"] = EditorSettings::get_singleton()->is_dark_theme(); } } - *r_metadata = metadata; + *r_metadata = meta; } return OK; } @@ -703,7 +704,7 @@ String ResourceImporterTexture::get_import_settings_string() const { int index = 0; while (compression_formats[index]) { String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]); - bool test = ProjectSettings::get_singleton()->get(setting_path); + bool test = GLOBAL_GET(setting_path); if (test) { s += String(compression_formats[index]); } @@ -715,36 +716,36 @@ String ResourceImporterTexture::get_import_settings_string() const { bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) const { //will become invalid if formats are missing to import - Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path); + Dictionary meta = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path); - if (metadata.has("has_editor_variant")) { - if (metadata.has("editor_scale") && (float)metadata["editor_scale"] != EDSCALE) { + if (meta.has("has_editor_variant")) { + if (meta.has("editor_scale") && (float)meta["editor_scale"] != EDSCALE) { return false; } - if (metadata.has("editor_dark_theme") && (bool)metadata["editor_dark_theme"] != EditorSettings::get_singleton()->is_dark_theme()) { + if (meta.has("editor_dark_theme") && (bool)meta["editor_dark_theme"] != EditorSettings::get_singleton()->is_dark_theme()) { return false; } } - if (!metadata.has("vram_texture")) { + if (!meta.has("vram_texture")) { return false; } - bool vram = metadata["vram_texture"]; + bool vram = meta["vram_texture"]; if (!vram) { return true; // Do not care about non-VRAM. } Vector<String> formats_imported; - if (metadata.has("imported_formats")) { - formats_imported = metadata["imported_formats"]; + if (meta.has("imported_formats")) { + formats_imported = meta["imported_formats"]; } int index = 0; bool valid = true; while (compression_formats[index]) { String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]); - bool test = ProjectSettings::get_singleton()->get(setting_path); + bool test = GLOBAL_GET(setting_path); if (test) { if (!formats_imported.has(compression_formats[index])) { valid = false; diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp index 9171f04f42..bf22a9377e 100644 --- a/editor/import/resource_importer_texture_atlas.cpp +++ b/editor/import/resource_importer_texture_atlas.cpp @@ -273,9 +273,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file EditorAtlasPacker::chart_pack(charts, atlas_width, atlas_height); //blit the atlas - Ref<Image> new_atlas; - new_atlas.instantiate(); - new_atlas->create(atlas_width, atlas_height, false, Image::FORMAT_RGBA8); + Ref<Image> new_atlas = Image::create_empty(atlas_width, atlas_height, false, Image::FORMAT_RGBA8); for (int i = 0; i < pack_data_files.size(); i++) { PackData &pack_data = pack_data_files.write[i]; diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 1dcae2841b..f5a0f0abcf 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -107,7 +107,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s file->get_buffer((uint8_t *)&riff, 4); //RIFF if (riff[0] != 'R' || riff[1] != 'I' || riff[2] != 'F' || riff[3] != 'F') { - ERR_FAIL_V(ERR_FILE_UNRECOGNIZED); + ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("Not a WAV file. File should start with 'RIFF', but found '%s', in file of size %d bytes", riff, file->get_length())); } /* GET FILESIZE */ @@ -115,12 +115,12 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s /* CHECK WAVE */ - char wave[4]; - - file->get_buffer((uint8_t *)&wave, 4); //RIFF + char wave[5]; + wave[4] = 0; + file->get_buffer((uint8_t *)&wave, 4); //WAVE if (wave[0] != 'W' || wave[1] != 'A' || wave[2] != 'V' || wave[3] != 'E') { - ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Not a WAV file (no WAVE RIFF header)."); + ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("Not a WAV file. Header should contain 'WAVE', but found '%s', in file of size %d bytes", wave, file->get_length())); } // Let users override potential loop points from the WAV. diff --git a/editor/import_defaults_editor.cpp b/editor/import_defaults_editor.cpp index a70f5225e9..a801a678fc 100644 --- a/editor/import_defaults_editor.cpp +++ b/editor/import_defaults_editor.cpp @@ -140,7 +140,7 @@ void ImportDefaultsEditor::_update_importer() { importer->get_import_options("", &options); Dictionary d; if (ProjectSettings::get_singleton()->has_setting("importer_defaults/" + importer->get_importer_name())) { - d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); + d = GLOBAL_GET("importer_defaults/" + importer->get_importer_name()); } for (const ResourceImporter::ImportOption &E : options) { diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index 4732268256..e6ba19172f 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -384,7 +384,7 @@ void ImportDock::_preset_selected(int p_idx) { case ITEM_LOAD_DEFAULT: { ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting("importer_defaults/" + params->importer->get_importer_name())); - Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + params->importer->get_importer_name()); + Dictionary d = GLOBAL_GET("importer_defaults/" + params->importer->get_importer_name()); List<Variant> v; d.get_key_list(&v); diff --git a/editor/input_event_configuration_dialog.cpp b/editor/input_event_configuration_dialog.cpp new file mode 100644 index 0000000000..cb2a8205c2 --- /dev/null +++ b/editor/input_event_configuration_dialog.cpp @@ -0,0 +1,633 @@ +/*************************************************************************/ +/* input_event_configuration_dialog.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor/input_event_configuration_dialog.h" +#include "core/input/input_map.h" +#include "editor/editor_scale.h" +#include "editor/event_listener_line_edit.h" +#include "scene/gui/check_box.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/option_button.h" +#include "scene/gui/separator.h" +#include "scene/gui/tree.h" + +void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, bool p_update_input_list_selection) { + if (p_event.is_valid()) { + event = p_event; + + // If the event is changed to something which is not the same as the listener, + // clear out the event from the listener text box to avoid confusion. + const Ref<InputEvent> listener_event = event_listener->get_event(); + if (listener_event.is_valid() && !listener_event->is_match(p_event)) { + event_listener->clear_event(); + } + + // Update Label + event_as_text->set_text(EventListenerLineEdit::get_event_text(event, true)); + + Ref<InputEventKey> k = p_event; + Ref<InputEventMouseButton> mb = p_event; + Ref<InputEventJoypadButton> joyb = p_event; + Ref<InputEventJoypadMotion> joym = p_event; + Ref<InputEventWithModifiers> mod = p_event; + + // Update option values and visibility + bool show_mods = false; + bool show_device = false; + bool show_phys_key = false; + + if (mod.is_valid()) { + show_mods = true; + mod_checkboxes[MOD_ALT]->set_pressed(mod->is_alt_pressed()); + mod_checkboxes[MOD_SHIFT]->set_pressed(mod->is_shift_pressed()); + mod_checkboxes[MOD_CTRL]->set_pressed(mod->is_ctrl_pressed()); + mod_checkboxes[MOD_META]->set_pressed(mod->is_meta_pressed()); + + autoremap_command_or_control_checkbox->set_pressed(mod->is_command_or_control_autoremap()); + } + + if (k.is_valid()) { + show_phys_key = true; + physical_key_checkbox->set_pressed(k->get_physical_keycode() != Key::NONE && k->get_keycode() == Key::NONE); + + } else if (joyb.is_valid() || joym.is_valid() || mb.is_valid()) { + show_device = true; + _set_current_device(event->get_device()); + } + + mod_container->set_visible(show_mods); + device_container->set_visible(show_device); + physical_key_checkbox->set_visible(show_phys_key); + additional_options_container->show(); + + // Update selected item in input list. + if (p_update_input_list_selection && (k.is_valid() || joyb.is_valid() || joym.is_valid() || mb.is_valid())) { + TreeItem *category = input_list_tree->get_root()->get_first_child(); + while (category) { + TreeItem *input_item = category->get_first_child(); + + if (input_item != nullptr) { + // input_type should always be > 0, unless the tree structure has been misconfigured. + int input_type = input_item->get_parent()->get_meta("__type", 0); + if (input_type == 0) { + return; + } + + // If event type matches input types of this category. + if ((k.is_valid() && input_type == INPUT_KEY) || (joyb.is_valid() && input_type == INPUT_JOY_BUTTON) || (joym.is_valid() && input_type == INPUT_JOY_MOTION) || (mb.is_valid() && input_type == INPUT_MOUSE_BUTTON)) { + // Loop through all items of this category until one matches. + while (input_item) { + bool key_match = k.is_valid() && (Variant(k->get_keycode()) == input_item->get_meta("__keycode") || Variant(k->get_physical_keycode()) == input_item->get_meta("__keycode")); + bool joyb_match = joyb.is_valid() && Variant(joyb->get_button_index()) == input_item->get_meta("__index"); + bool joym_match = joym.is_valid() && Variant(joym->get_axis()) == input_item->get_meta("__axis") && joym->get_axis_value() == (float)input_item->get_meta("__value"); + bool mb_match = mb.is_valid() && Variant(mb->get_button_index()) == input_item->get_meta("__index"); + if (key_match || joyb_match || joym_match || mb_match) { + category->set_collapsed(false); + input_item->select(0); + input_list_tree->ensure_cursor_is_visible(); + return; + } + input_item = input_item->get_next(); + } + } + } + + category->set_collapsed(true); // Event not in this category, so collapse; + category = category->get_next(); + } + } + } else { + // Event is not valid, reset dialog + event = p_event; + event_listener->clear_event(); + event_as_text->set_text(TTR("No Event Configured")); + + additional_options_container->hide(); + input_list_tree->deselect_all(); + _update_input_list(); + } +} + +void InputEventConfigurationDialog::_on_listen_input_changed(const Ref<InputEvent> &p_event) { + // Ignore if invalid, echo or not pressed + if (p_event.is_null() || p_event->is_echo() || !p_event->is_pressed()) { + return; + } + + // Create an editable reference + Ref<InputEvent> received_event = p_event; + // Check what the type is and if it is allowed. + Ref<InputEventKey> k = received_event; + Ref<InputEventJoypadButton> joyb = received_event; + Ref<InputEventJoypadMotion> joym = received_event; + Ref<InputEventMouseButton> mb = received_event; + + int type = 0; + if (k.is_valid()) { + type = INPUT_KEY; + } else if (joyb.is_valid()) { + type = INPUT_JOY_BUTTON; + } else if (joym.is_valid()) { + type = INPUT_JOY_MOTION; + } else if (mb.is_valid()) { + type = INPUT_MOUSE_BUTTON; + } + + if (!(allowed_input_types & type)) { + return; + } + + if (joym.is_valid()) { + joym->set_axis_value(SIGN(joym->get_axis_value())); + } + + if (k.is_valid()) { + k->set_pressed(false); // To avoid serialisation of 'pressed' property - doesn't matter for actions anyway. + // Maintain physical keycode option state + if (physical_key_checkbox->is_pressed()) { + k->set_keycode(Key::NONE); + } else { + k->set_physical_keycode(Key::NONE); + } + } + + Ref<InputEventWithModifiers> mod = received_event; + if (mod.is_valid()) { + mod->set_window_id(0); + } + + // Maintain device selection. + received_event->set_device(_get_current_device()); + + _set_event(received_event); +} + +void InputEventConfigurationDialog::_on_listen_focus_changed() { + if (event_listener->has_focus()) { + set_close_on_escape(false); + } else { + set_close_on_escape(true); + } +} + +void InputEventConfigurationDialog::_search_term_updated(const String &) { + _update_input_list(); +} + +void InputEventConfigurationDialog::_update_input_list() { + input_list_tree->clear(); + + TreeItem *root = input_list_tree->create_item(); + String search_term = input_list_search->get_text(); + + bool collapse = input_list_search->get_text().is_empty(); + + if (allowed_input_types & INPUT_KEY) { + TreeItem *kb_root = input_list_tree->create_item(root); + kb_root->set_text(0, TTR("Keyboard Keys")); + kb_root->set_icon(0, icon_cache.keyboard); + kb_root->set_collapsed(collapse); + kb_root->set_meta("__type", INPUT_KEY); + + for (int i = 0; i < keycode_get_count(); i++) { + String name = keycode_get_name_by_index(i); + + if (!search_term.is_empty() && name.findn(search_term) == -1) { + continue; + } + + TreeItem *item = input_list_tree->create_item(kb_root); + item->set_text(0, name); + item->set_meta("__keycode", keycode_get_value_by_index(i)); + } + } + + if (allowed_input_types & INPUT_MOUSE_BUTTON) { + TreeItem *mouse_root = input_list_tree->create_item(root); + mouse_root->set_text(0, TTR("Mouse Buttons")); + mouse_root->set_icon(0, icon_cache.mouse); + mouse_root->set_collapsed(collapse); + mouse_root->set_meta("__type", INPUT_MOUSE_BUTTON); + + MouseButton mouse_buttons[9] = { MouseButton::LEFT, MouseButton::RIGHT, MouseButton::MIDDLE, MouseButton::WHEEL_UP, MouseButton::WHEEL_DOWN, MouseButton::WHEEL_LEFT, MouseButton::WHEEL_RIGHT, MouseButton::MB_XBUTTON1, MouseButton::MB_XBUTTON2 }; + for (int i = 0; i < 9; i++) { + Ref<InputEventMouseButton> mb; + mb.instantiate(); + mb->set_button_index(mouse_buttons[i]); + String desc = EventListenerLineEdit::get_event_text(mb, false); + + if (!search_term.is_empty() && desc.findn(search_term) == -1) { + continue; + } + + TreeItem *item = input_list_tree->create_item(mouse_root); + item->set_text(0, desc); + item->set_meta("__index", mouse_buttons[i]); + } + } + + if (allowed_input_types & INPUT_JOY_BUTTON) { + TreeItem *joyb_root = input_list_tree->create_item(root); + joyb_root->set_text(0, TTR("Joypad Buttons")); + joyb_root->set_icon(0, icon_cache.joypad_button); + joyb_root->set_collapsed(collapse); + joyb_root->set_meta("__type", INPUT_JOY_BUTTON); + + for (int i = 0; i < (int)JoyButton::MAX; i++) { + Ref<InputEventJoypadButton> joyb; + joyb.instantiate(); + joyb->set_button_index((JoyButton)i); + String desc = EventListenerLineEdit::get_event_text(joyb, false); + + if (!search_term.is_empty() && desc.findn(search_term) == -1) { + continue; + } + + TreeItem *item = input_list_tree->create_item(joyb_root); + item->set_text(0, desc); + item->set_meta("__index", i); + } + } + + if (allowed_input_types & INPUT_JOY_MOTION) { + TreeItem *joya_root = input_list_tree->create_item(root); + joya_root->set_text(0, TTR("Joypad Axes")); + joya_root->set_icon(0, icon_cache.joypad_axis); + joya_root->set_collapsed(collapse); + joya_root->set_meta("__type", INPUT_JOY_MOTION); + + for (int i = 0; i < (int)JoyAxis::MAX * 2; i++) { + int axis = i / 2; + int direction = (i & 1) ? 1 : -1; + Ref<InputEventJoypadMotion> joym; + joym.instantiate(); + joym->set_axis((JoyAxis)axis); + joym->set_axis_value(direction); + String desc = EventListenerLineEdit::get_event_text(joym, false); + + if (!search_term.is_empty() && desc.findn(search_term) == -1) { + continue; + } + + TreeItem *item = input_list_tree->create_item(joya_root); + item->set_text(0, desc); + item->set_meta("__axis", i >> 1); + item->set_meta("__value", (i & 1) ? 1 : -1); + } + } +} + +void InputEventConfigurationDialog::_mod_toggled(bool p_checked, int p_index) { + Ref<InputEventWithModifiers> ie = event; + + // Not event with modifiers + if (ie.is_null()) { + return; + } + + if (p_index == 0) { + ie->set_alt_pressed(p_checked); + } else if (p_index == 1) { + ie->set_shift_pressed(p_checked); + } else if (p_index == 2) { + if (!autoremap_command_or_control_checkbox->is_pressed()) { + ie->set_ctrl_pressed(p_checked); + } + } else if (p_index == 3) { + if (!autoremap_command_or_control_checkbox->is_pressed()) { + ie->set_meta_pressed(p_checked); + } + } + + _set_event(ie); +} + +void InputEventConfigurationDialog::_autoremap_command_or_control_toggled(bool p_checked) { + Ref<InputEventWithModifiers> ie = event; + if (ie.is_valid()) { + ie->set_command_or_control_autoremap(p_checked); + _set_event(ie); + } + + if (p_checked) { + mod_checkboxes[MOD_META]->hide(); + mod_checkboxes[MOD_CTRL]->hide(); + } else { + mod_checkboxes[MOD_META]->show(); + mod_checkboxes[MOD_CTRL]->show(); + } +} + +void InputEventConfigurationDialog::_physical_keycode_toggled(bool p_checked) { + Ref<InputEventKey> k = event; + + if (k.is_null()) { + return; + } + + if (p_checked) { + k->set_physical_keycode(k->get_keycode()); + k->set_keycode(Key::NONE); + } else { + k->set_keycode((Key)k->get_physical_keycode()); + k->set_physical_keycode(Key::NONE); + } + + _set_event(k); +} + +void InputEventConfigurationDialog::_input_list_item_selected() { + TreeItem *selected = input_list_tree->get_selected(); + + // Invalid tree selection - type only exists on the "category" items, which are not a valid selection. + if (selected->has_meta("__type")) { + return; + } + + InputType input_type = (InputType)(int)selected->get_parent()->get_meta("__type"); + + switch (input_type) { + case INPUT_KEY: { + Key keycode = (Key)(int)selected->get_meta("__keycode"); + Ref<InputEventKey> k; + k.instantiate(); + + if (physical_key_checkbox->is_pressed()) { + k->set_physical_keycode(keycode); + k->set_keycode(Key::NONE); + } else { + k->set_physical_keycode(Key::NONE); + k->set_keycode(keycode); + } + + // Maintain modifier state from checkboxes + k->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed()); + k->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed()); + if (autoremap_command_or_control_checkbox->is_pressed()) { + k->set_command_or_control_autoremap(true); + } else { + k->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed()); + k->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed()); + } + + _set_event(k, false); + } break; + case INPUT_MOUSE_BUTTON: { + MouseButton idx = (MouseButton)(int)selected->get_meta("__index"); + Ref<InputEventMouseButton> mb; + mb.instantiate(); + mb->set_button_index(idx); + // Maintain modifier state from checkboxes + mb->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed()); + mb->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed()); + if (autoremap_command_or_control_checkbox->is_pressed()) { + mb->set_command_or_control_autoremap(true); + } else { + mb->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed()); + mb->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed()); + } + + // Maintain selected device + mb->set_device(_get_current_device()); + + _set_event(mb, false); + } break; + case INPUT_JOY_BUTTON: { + JoyButton idx = (JoyButton)(int)selected->get_meta("__index"); + Ref<InputEventJoypadButton> jb = InputEventJoypadButton::create_reference(idx); + + // Maintain selected device + jb->set_device(_get_current_device()); + + _set_event(jb, false); + } break; + case INPUT_JOY_MOTION: { + JoyAxis axis = (JoyAxis)(int)selected->get_meta("__axis"); + int value = selected->get_meta("__value"); + + Ref<InputEventJoypadMotion> jm; + jm.instantiate(); + jm->set_axis(axis); + jm->set_axis_value(value); + + // Maintain selected device + jm->set_device(_get_current_device()); + + _set_event(jm, false); + } break; + } +} + +void InputEventConfigurationDialog::_device_selection_changed(int p_option_button_index) { + // Subtract 1 as option index 0 corresponds to "All Devices" (value of -1) + // and option index 1 corresponds to device 0, etc... + event->set_device(p_option_button_index - 1); + event_as_text->set_text(EventListenerLineEdit::get_event_text(event, true)); +} + +void InputEventConfigurationDialog::_set_current_device(int p_device) { + device_id_option->select(p_device + 1); +} + +int InputEventConfigurationDialog::_get_current_device() const { + return device_id_option->get_selected() - 1; +} + +void InputEventConfigurationDialog::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_VISIBILITY_CHANGED: { + event_listener->grab_focus(); + } break; + + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + input_list_search->set_right_icon(input_list_search->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); + + physical_key_checkbox->set_icon(get_theme_icon(SNAME("KeyboardPhysical"), SNAME("EditorIcons"))); + + icon_cache.keyboard = get_theme_icon(SNAME("Keyboard"), SNAME("EditorIcons")); + icon_cache.mouse = get_theme_icon(SNAME("Mouse"), SNAME("EditorIcons")); + icon_cache.joypad_button = get_theme_icon(SNAME("JoyButton"), SNAME("EditorIcons")); + icon_cache.joypad_axis = get_theme_icon(SNAME("JoyAxis"), SNAME("EditorIcons")); + + _update_input_list(); + } break; + } +} + +void InputEventConfigurationDialog::popup_and_configure(const Ref<InputEvent> &p_event) { + if (p_event.is_valid()) { + _set_event(p_event); + } else { + // Clear Event + _set_event(p_event); + + // Clear Checkbox Values + for (int i = 0; i < MOD_MAX; i++) { + mod_checkboxes[i]->set_pressed(false); + } + + // Enable the Physical Key checkbox by default to encourage its use. + // Physical Key should be used for most game inputs as it allows keys to work + // on non-QWERTY layouts out of the box. + // This is especially important for WASD movement layouts. + physical_key_checkbox->set_pressed(true); + + autoremap_command_or_control_checkbox->set_pressed(false); + + // Select "All Devices" by default. + device_id_option->select(0); + } + + popup_centered(Size2(0, 400) * EDSCALE); +} + +Ref<InputEvent> InputEventConfigurationDialog::get_event() const { + return event; +} + +void InputEventConfigurationDialog::set_allowed_input_types(int p_type_masks) { + allowed_input_types = p_type_masks; +} + +InputEventConfigurationDialog::InputEventConfigurationDialog() { + allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION; + + set_title(TTR("Event Configuration")); + set_min_size(Size2i(550 * EDSCALE, 0)); // Min width + + VBoxContainer *main_vbox = memnew(VBoxContainer); + add_child(main_vbox); + + event_as_text = memnew(Label); + event_as_text->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART); + event_as_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + event_as_text->add_theme_font_override("font", get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); + event_as_text->add_theme_font_size_override("font_size", 18 * EDSCALE); + main_vbox->add_child(event_as_text); + + event_listener = memnew(EventListenerLineEdit); + event_listener->set_h_size_flags(Control::SIZE_EXPAND_FILL); + event_listener->set_stretch_ratio(0.75); + event_listener->connect("event_changed", callable_mp(this, &InputEventConfigurationDialog::_on_listen_input_changed)); + event_listener->connect("focus_entered", callable_mp(this, &InputEventConfigurationDialog::_on_listen_focus_changed)); + event_listener->connect("focus_exited", callable_mp(this, &InputEventConfigurationDialog::_on_listen_focus_changed)); + main_vbox->add_child(event_listener); + + main_vbox->add_child(memnew(HSeparator)); + + // List of all input options to manually select from. + VBoxContainer *manual_vbox = memnew(VBoxContainer); + manual_vbox->set_name(TTR("Manual Selection")); + manual_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL); + main_vbox->add_child(manual_vbox); + + input_list_search = memnew(LineEdit); + input_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL); + input_list_search->set_placeholder(TTR("Filter Inputs")); + input_list_search->set_clear_button_enabled(true); + input_list_search->connect("text_changed", callable_mp(this, &InputEventConfigurationDialog::_search_term_updated)); + manual_vbox->add_child(input_list_search); + + input_list_tree = memnew(Tree); + input_list_tree->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); // Min height for tree + input_list_tree->connect("item_selected", callable_mp(this, &InputEventConfigurationDialog::_input_list_item_selected)); + input_list_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); + manual_vbox->add_child(input_list_tree); + + input_list_tree->set_hide_root(true); + input_list_tree->set_columns(1); + + _update_input_list(); + + // Additional Options + additional_options_container = memnew(VBoxContainer); + additional_options_container->hide(); + + Label *opts_label = memnew(Label); + opts_label->set_theme_type_variation("HeaderSmall"); + opts_label->set_text(TTR("Additional Options")); + additional_options_container->add_child(opts_label); + + // Device Selection + device_container = memnew(HBoxContainer); + device_container->set_h_size_flags(Control::SIZE_EXPAND_FILL); + + Label *device_label = memnew(Label); + device_label->set_theme_type_variation("HeaderSmall"); + device_label->set_text(TTR("Device:")); + device_container->add_child(device_label); + + device_id_option = memnew(OptionButton); + device_id_option->set_h_size_flags(Control::SIZE_EXPAND_FILL); + for (int i = -1; i < 8; i++) { + device_id_option->add_item(EventListenerLineEdit::get_device_string(i)); + } + device_id_option->connect("item_selected", callable_mp(this, &InputEventConfigurationDialog::_device_selection_changed)); + _set_current_device(InputMap::ALL_DEVICES); + device_container->add_child(device_id_option); + + device_container->hide(); + additional_options_container->add_child(device_container); + + // Modifier Selection + mod_container = memnew(HBoxContainer); + for (int i = 0; i < MOD_MAX; i++) { + String name = mods[i]; + mod_checkboxes[i] = memnew(CheckBox); + mod_checkboxes[i]->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_mod_toggled).bind(i)); + mod_checkboxes[i]->set_text(name); + mod_checkboxes[i]->set_tooltip_text(TTR(mods_tip[i])); + mod_container->add_child(mod_checkboxes[i]); + } + + mod_container->add_child(memnew(VSeparator)); + + autoremap_command_or_control_checkbox = memnew(CheckBox); + autoremap_command_or_control_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_autoremap_command_or_control_toggled)); + autoremap_command_or_control_checkbox->set_pressed(false); + autoremap_command_or_control_checkbox->set_text(TTR("Command / Control (auto)")); + autoremap_command_or_control_checkbox->set_tooltip_text(TTR("Automatically remaps between 'Meta' ('Command') and 'Control' depending on current platform.")); + mod_container->add_child(autoremap_command_or_control_checkbox); + + mod_container->hide(); + additional_options_container->add_child(mod_container); + + // Physical Key Checkbox + + physical_key_checkbox = memnew(CheckBox); + physical_key_checkbox->set_text(TTR("Use Physical Keycode")); + physical_key_checkbox->set_tooltip_text(TTR("Stores the physical position of the key on the keyboard rather than the key's value. Used for compatibility with non-latin layouts.\nThis should generally be enabled for most game shortcuts, but not in non-game applications.")); + physical_key_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_physical_keycode_toggled)); + physical_key_checkbox->hide(); + additional_options_container->add_child(physical_key_checkbox); + + main_vbox->add_child(additional_options_container); +} diff --git a/editor/input_event_configuration_dialog.h b/editor/input_event_configuration_dialog.h new file mode 100644 index 0000000000..eb6eb485ea --- /dev/null +++ b/editor/input_event_configuration_dialog.h @@ -0,0 +1,122 @@ +/*************************************************************************/ +/* input_event_configuration_dialog.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef INPUT_EVENT_CONFIGURATION_DIALOG_H +#define INPUT_EVENT_CONFIGURATION_DIALOG_H + +#include "scene/gui/dialogs.h" + +class OptionButton; +class Tree; +class EventListenerLineEdit; +class CheckBox; + +// Confirmation Dialog used when configuring an input event. +// Separate from ActionMapEditor for code cleanliness and separation of responsibilities. +class InputEventConfigurationDialog : public ConfirmationDialog { + GDCLASS(InputEventConfigurationDialog, ConfirmationDialog) +private: + struct IconCache { + Ref<Texture2D> keyboard; + Ref<Texture2D> mouse; + Ref<Texture2D> joypad_button; + Ref<Texture2D> joypad_axis; + } icon_cache; + + Ref<InputEvent> event = Ref<InputEvent>(); + + // Listening for input + EventListenerLineEdit *event_listener = nullptr; + Label *event_as_text = nullptr; + + // List of All Key/Mouse/Joypad input options. + int allowed_input_types; + Tree *input_list_tree = nullptr; + LineEdit *input_list_search = nullptr; + + // Additional Options, shown depending on event selected + VBoxContainer *additional_options_container = nullptr; + + HBoxContainer *device_container = nullptr; + OptionButton *device_id_option = nullptr; + + HBoxContainer *mod_container = nullptr; // Contains the subcontainer and the store command checkbox. + + enum ModCheckbox { + MOD_ALT, + MOD_SHIFT, + MOD_CTRL, + MOD_META, + MOD_MAX + }; +#if defined(MACOS_ENABLED) + String mods[MOD_MAX] = { "Option", "Shift", "Ctrl", "Command" }; +#elif defined(WINDOWS_ENABLED) + String mods[MOD_MAX] = { "Alt", "Shift", "Ctrl", "Windows" }; +#else + String mods[MOD_MAX] = { "Alt", "Shift", "Ctrl", "Meta" }; +#endif + String mods_tip[MOD_MAX] = { "Alt or Option key", "Shift key", "Control key", "Meta/Windows or Command key" }; + + CheckBox *mod_checkboxes[MOD_MAX]; + CheckBox *autoremap_command_or_control_checkbox = nullptr; + + CheckBox *physical_key_checkbox = nullptr; + + void _set_event(const Ref<InputEvent> &p_event, bool p_update_input_list_selection = true); + void _on_listen_input_changed(const Ref<InputEvent> &p_event); + void _on_listen_focus_changed(); + + void _search_term_updated(const String &p_term); + void _update_input_list(); + void _input_list_item_selected(); + + void _mod_toggled(bool p_checked, int p_index); + void _autoremap_command_or_control_toggled(bool p_checked); + void _physical_keycode_toggled(bool p_checked); + + void _device_selection_changed(int p_option_button_index); + void _set_current_device(int p_device); + int _get_current_device() const; + +protected: + void _notification(int p_what); + +public: + // Pass an existing event to configure it. Alternatively, pass no event to start with a blank configuration. + void popup_and_configure(const Ref<InputEvent> &p_event = Ref<InputEvent>()); + Ref<InputEvent> get_event() const; + + void set_allowed_input_types(int p_type_masks); + + InputEventConfigurationDialog(); +}; + +#endif // INPUT_EVENT_CONFIGURATION_DIALOG_H diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 74fdbdebd7..8cb0e4e8d7 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -34,6 +34,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" #include "editor/plugins/script_editor_plugin.h" InspectorDock *InspectorDock::singleton = nullptr; @@ -227,7 +228,7 @@ void InspectorDock::_load_resource(const String &p_type) { load_resource_dialog->add_filter("*." + extensions[i], extensions[i].to_upper()); } - const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); for (int i = 0; i < textfile_ext.size(); i++) { load_resource_dialog->add_filter("*." + textfile_ext[i], textfile_ext[i].to_upper()); } @@ -240,7 +241,7 @@ void InspectorDock::_resource_file_selected(String p_file) { if (ResourceLoader::exists(p_file, "")) { res = ResourceLoader::load(p_file); } else { - const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); if (textfile_ext.has(p_file.get_extension())) { res = ScriptEditor::get_singleton()->open_file(p_file); } @@ -255,8 +256,8 @@ void InspectorDock::_resource_file_selected(String p_file) { } void InspectorDock::_save_resource(bool save_as) { - ObjectID current = EditorNode::get_singleton()->get_editor_selection_history()->get_current(); - Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; + ObjectID current_id = EditorNode::get_singleton()->get_editor_selection_history()->get_current(); + Object *current_obj = current_id.is_valid() ? ObjectDB::get_instance(current_id) : nullptr; ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); @@ -270,8 +271,8 @@ void InspectorDock::_save_resource(bool save_as) { } void InspectorDock::_unref_resource() { - ObjectID current = EditorNode::get_singleton()->get_editor_selection_history()->get_current(); - Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; + ObjectID current_id = EditorNode::get_singleton()->get_editor_selection_history()->get_current(); + Object *current_obj = current_id.is_valid() ? ObjectDB::get_instance(current_id) : nullptr; ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); @@ -281,8 +282,8 @@ void InspectorDock::_unref_resource() { } void InspectorDock::_copy_resource() { - ObjectID current = EditorNode::get_singleton()->get_editor_selection_history()->get_current(); - Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; + ObjectID current_id = EditorNode::get_singleton()->get_editor_selection_history()->get_current(); + Object *current_obj = current_id.is_valid() ? ObjectDB::get_instance(current_id) : nullptr; ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)); @@ -364,7 +365,7 @@ void InspectorDock::_select_history(int p_idx) { } void InspectorDock::_resource_created() { - Variant c = new_resource_dialog->instance_selected(); + Variant c = new_resource_dialog->instantiate_selected(); ERR_FAIL_COND(!c); Resource *r = Object::cast_to<Resource>(c); @@ -610,8 +611,8 @@ void InspectorDock::apply_script_properties(Object *p_object) { } for (const Pair<StringName, Variant> &E : stored_properties) { - Variant current; - if (si->get(E.first, current) && current.get_type() == E.second.get_type()) { + Variant current_prop; + if (si->get(E.first, current_prop) && current_prop.get_type() == E.second.get_type()) { si->set(E.first, E.second); } } @@ -669,14 +670,14 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) { backward_button = memnew(Button); backward_button->set_flat(true); general_options_hb->add_child(backward_button); - backward_button->set_tooltip_text(TTR("Go to the previous edited object in history.")); + backward_button->set_tooltip_text(TTR("Go to previous edited object in history.")); backward_button->set_disabled(true); backward_button->connect("pressed", callable_mp(this, &InspectorDock::_edit_back)); forward_button = memnew(Button); forward_button->set_flat(true); general_options_hb->add_child(forward_button); - forward_button->set_tooltip_text(TTR("Go to the next edited object in history.")); + forward_button->set_tooltip_text(TTR("Go to next edited object in history.")); forward_button->set_disabled(true); forward_button->connect("pressed", callable_mp(this, &InspectorDock::_edit_forward)); @@ -769,7 +770,6 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) { inspector->set_property_name_style(EditorPropertyNameProcessor::get_default_inspector_style()); inspector->set_use_folding(!bool(EDITOR_GET("interface/inspector/disable_folding"))); inspector->register_text_enter(search); - inspector->set_undo_redo(editor_data->get_undo_redo()); inspector->set_use_filter(true); // TODO: check me diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index 683481ecc1..4b8257969c 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -73,7 +73,7 @@ void LocalizationEditor::add_translation(const String &p_translation) { } void LocalizationEditor::_translation_add(const PackedStringArray &p_paths) { - PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations"); + PackedStringArray translations = GLOBAL_GET("internationalization/locale/translations"); for (int i = 0; i < p_paths.size(); i++) { if (!translations.has(p_paths[i])) { // Don't add duplicate translation paths. @@ -81,9 +81,10 @@ void LocalizationEditor::_translation_add(const PackedStringArray &p_paths) { } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Add %d Translations"), p_paths.size())); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", translations); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", ProjectSettings::get_singleton()->get("internationalization/locale/translations")); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", GLOBAL_GET("internationalization/locale/translations")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -105,15 +106,16 @@ void LocalizationEditor::_translation_delete(Object *p_item, int p_column, int p int idx = ti->get_metadata(0); - PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations"); + PackedStringArray translations = GLOBAL_GET("internationalization/locale/translations"); ERR_FAIL_INDEX(idx, translations.size()); translations.remove_at(idx); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Translation")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", translations); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", ProjectSettings::get_singleton()->get("internationalization/locale/translations")); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", GLOBAL_GET("internationalization/locale/translations")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -130,7 +132,7 @@ void LocalizationEditor::_translation_res_add(const PackedStringArray &p_paths) Dictionary remaps; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { - remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); prev = remaps; } @@ -141,6 +143,7 @@ void LocalizationEditor::_translation_res_add(const PackedStringArray &p_paths) } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Translation Resource Remap: Add %d Path(s)"), p_paths.size())); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", prev); @@ -158,7 +161,7 @@ void LocalizationEditor::_translation_res_option_file_open() { void LocalizationEditor::_translation_res_option_add(const PackedStringArray &p_paths) { ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")); - Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); TreeItem *k = translation_remap->get_selected(); ERR_FAIL_COND(!k); @@ -172,9 +175,10 @@ void LocalizationEditor::_translation_res_option_add(const PackedStringArray &p_ } remaps[key] = r; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Translation Resource Remap: Add %d Remap(s)"), p_paths.size())); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps")); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", GLOBAL_GET("internationalization/locale/translation_remaps")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -216,7 +220,7 @@ void LocalizationEditor::_translation_res_option_changed() { return; } - Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); TreeItem *k = translation_remap->get_selected(); ERR_FAIL_COND(!k); @@ -234,9 +238,11 @@ void LocalizationEditor::_translation_res_option_changed() { remaps[key] = r; updating_translations = true; + + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Resource Remap Language")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps")); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", GLOBAL_GET("internationalization/locale/translation_remaps")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -258,7 +264,7 @@ void LocalizationEditor::_translation_res_delete(Object *p_item, int p_column, i return; } - Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); TreeItem *k = Object::cast_to<TreeItem>(p_item); @@ -267,9 +273,10 @@ void LocalizationEditor::_translation_res_delete(Object *p_item, int p_column, i remaps.erase(key); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Resource Remap")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps")); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", GLOBAL_GET("internationalization/locale/translation_remaps")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -290,7 +297,7 @@ void LocalizationEditor::_translation_res_option_delete(Object *p_item, int p_co return; } - Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); TreeItem *k = translation_remap->get_selected(); ERR_FAIL_COND(!k); @@ -306,9 +313,10 @@ void LocalizationEditor::_translation_res_option_delete(Object *p_item, int p_co r.remove_at(idx); remaps[key] = r; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Resource Remap Option")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps")); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", GLOBAL_GET("internationalization/locale/translation_remaps")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -317,16 +325,17 @@ void LocalizationEditor::_translation_res_option_delete(Object *p_item, int p_co } void LocalizationEditor::_pot_add(const PackedStringArray &p_paths) { - PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); + PackedStringArray pot_translations = GLOBAL_GET("internationalization/locale/translations_pot_files"); for (int i = 0; i < p_paths.size(); i++) { if (!pot_translations.has(p_paths[i])) { pot_translations.push_back(p_paths[i]); } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Add %d file(s) for POT generation"), p_paths.size())); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", pot_translations); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files")); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", GLOBAL_GET("internationalization/locale/translations_pot_files")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -344,15 +353,16 @@ void LocalizationEditor::_pot_delete(Object *p_item, int p_column, int p_button, int idx = ti->get_metadata(0); - PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); + PackedStringArray pot_translations = GLOBAL_GET("internationalization/locale/translations_pot_files"); ERR_FAIL_INDEX(idx, pot_translations.size()); pot_translations.remove_at(idx); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove file from POT generation")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", pot_translations); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files")); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", GLOBAL_GET("internationalization/locale/translations_pot_files")); undo_redo->add_do_method(this, "update_translations"); undo_redo->add_undo_method(this, "update_translations"); undo_redo->add_do_method(this, "emit_signal", localization_changed); @@ -392,7 +402,7 @@ void LocalizationEditor::_filesystem_files_moved(const String &p_old_file, const bool remaps_changed = false; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { - remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); } // Check for the keys. @@ -442,7 +452,7 @@ void LocalizationEditor::_filesystem_file_removed(const String &p_file) { Dictionary remaps; if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { - remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); } bool remaps_changed = remaps.has(p_file); @@ -481,7 +491,7 @@ void LocalizationEditor::update_translations() { TreeItem *root = translation_list->create_item(nullptr); translation_list->set_hide_root(true); if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translations")) { - PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations"); + PackedStringArray translations = GLOBAL_GET("internationalization/locale/translations"); for (int i = 0; i < translations.size(); i++) { TreeItem *t = translation_list->create_item(root); t->set_editable(0, false); @@ -507,7 +517,7 @@ void LocalizationEditor::update_translations() { translation_res_option_add_button->set_disabled(true); if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) { - Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); + Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); List<Variant> rk; remaps.get_key_list(&rk); Vector<String> keys; @@ -568,7 +578,7 @@ void LocalizationEditor::update_translations() { root = translation_pot_list->create_item(nullptr); translation_pot_list->set_hide_root(true); if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translations_pot_files")) { - PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); + PackedStringArray pot_translations = GLOBAL_GET("internationalization/locale/translations_pot_files"); for (int i = 0; i < pot_translations.size(); i++) { TreeItem *t = translation_pot_list->create_item(root); t->set_editable(0, false); @@ -592,7 +602,6 @@ void LocalizationEditor::_bind_methods() { } LocalizationEditor::LocalizationEditor() { - undo_redo = EditorNode::get_undo_redo(); localization_changed = "localization_changed"; TabContainer *translations = memnew(TabContainer); diff --git a/editor/localization_editor.h b/editor/localization_editor.h index ecac171fe3..5fa6d9519a 100644 --- a/editor/localization_editor.h +++ b/editor/localization_editor.h @@ -31,7 +31,6 @@ #ifndef LOCALIZATION_EDITOR_H #define LOCALIZATION_EDITOR_H -#include "core/object/undo_redo.h" #include "editor/editor_locale_dialog.h" #include "scene/gui/tree.h" @@ -56,7 +55,6 @@ class LocalizationEditor : public VBoxContainer { EditorFileDialog *pot_file_open_dialog = nullptr; EditorFileDialog *pot_generate_dialog = nullptr; - Ref<EditorUndoRedoManager> undo_redo; bool updating_translations = false; String localization_changed; diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp index 55fa2f22dd..266b265819 100644 --- a/editor/node_dock.cpp +++ b/editor/node_dock.cpp @@ -117,13 +117,11 @@ NodeDock::NodeDock() { groups_button->connect("pressed", callable_mp(this, &NodeDock::show_groups)); connections = memnew(ConnectionsDock); - connections->set_undo_redo(EditorNode::get_undo_redo()); add_child(connections); connections->set_v_size_flags(SIZE_EXPAND_FILL); connections->hide(); groups = memnew(GroupsEditor); - groups->set_undo_redo(EditorNode::get_undo_redo()); add_child(groups); groups->set_v_size_flags(SIZE_EXPAND_FILL); groups->hide(); diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp index 71ff77e9bc..affb31945d 100644 --- a/editor/plugin_config_dialog.cpp +++ b/editor/plugin_config_dialog.cpp @@ -36,6 +36,7 @@ #include "editor/editor_plugin.h" #include "editor/editor_scale.h" #include "editor/project_settings_editor.h" +#include "scene/gui/grid_container.h" void PluginConfigDialog::_clear_fields() { name_edit->set_text(""); @@ -80,11 +81,11 @@ void PluginConfigDialog::_on_confirmed() { if (!templates.is_empty()) { template_content = templates[0].content; } - Ref<Script> script = ScriptServer::get_language(lang_idx)->make_template(template_content, class_name, "EditorPlugin"); - script->set_path(script_path, true); - ResourceSaver::save(script); + Ref<Script> scr = ScriptServer::get_language(lang_idx)->make_template(template_content, class_name, "EditorPlugin"); + scr->set_path(script_path, true); + ResourceSaver::save(scr); - emit_signal(SNAME("plugin_ready"), script.ptr(), active_edit->is_pressed() ? _to_absolute_plugin_path(_get_subfolder()) : ""); + emit_signal(SNAME("plugin_ready"), scr.ptr(), active_edit->is_pressed() ? _to_absolute_plugin_path(_get_subfolder()) : ""); } else { EditorNode::get_singleton()->get_project_settings()->update_plugins(); } diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index c928b95642..ecb4837695 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -91,6 +91,7 @@ void AbstractPolygon2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) void AbstractPolygon2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) { Node2D *node = _get_node(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(node, "set_polygon", p_polygon); undo_redo->add_undo_method(node, "set_polygon", p_previous); } @@ -100,6 +101,7 @@ Vector2 AbstractPolygon2DEditor::_get_offset(int p_idx) const { } void AbstractPolygon2DEditor::_commit_action() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); undo_redo->commit_action(); @@ -203,6 +205,7 @@ void AbstractPolygon2DEditor::_wip_close() { if (_is_line()) { _set_polygon(0, wip); } else if (wip.size() >= (_is_line() ? 2 : 3)) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Create Polygon")); _action_add_polygon(wip); if (_has_uv()) { @@ -254,6 +257,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) return false; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); Ref<InputEventMouseButton> mb = p_event; if (!_has_resource()) { @@ -561,8 +565,8 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl const Vector2 p = (vertex == edited_point) ? edited_point.pos : (points[i] + offset); const Vector2 point = xform.xform(p); - const Color modulate = vertex == active_point ? Color(0.5, 1, 2) : Color(1, 1, 1); - p_overlay->draw_texture(handle, point - handle->get_size() * 0.5, modulate); + const Color overlay_modulate = vertex == active_point ? Color(0.5, 1, 2) : Color(1, 1, 1); + p_overlay->draw_texture(handle, point - handle->get_size() * 0.5, overlay_modulate); if (vertex == hover_point) { Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); @@ -611,6 +615,7 @@ void AbstractPolygon2DEditor::_bind_methods() { } void AbstractPolygon2DEditor::remove_point(const Vertex &p_vertex) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); Vector<Vector2> vertices = _get_polygon(p_vertex.polygon); if (vertices.size() > (_is_line() ? 2 : 3)) { @@ -706,8 +711,6 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c } AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) { - undo_redo = EditorNode::get_undo_redo(); - edited_point = PosVertex(); wip_destructive = p_wip_destructive; diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index 1fbbe67c8d..8414945223 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -36,7 +36,7 @@ #include "scene/gui/box_container.h" class CanvasItemEditor; -class EditorUndoRedoManager; +class ConfirmationDialog; class AbstractPolygon2DEditor : public HBoxContainer { GDCLASS(AbstractPolygon2DEditor, HBoxContainer); @@ -100,8 +100,6 @@ protected: int mode = MODE_EDIT; - Ref<EditorUndoRedoManager> undo_redo; - virtual void _menu_option(int p_option); void _wip_changed(); void _wip_close(); diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 0e941ad433..e64b80abbd 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -37,6 +37,8 @@ #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "scene/animation/animation_blend_tree.h" +#include "scene/gui/check_box.h" +#include "scene/gui/panel_container.h" StringName AnimationNodeBlendSpace1DEditor::get_blend_position_path() const { StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + "blend_position"; @@ -69,7 +71,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven menu->add_submenu_item(TTR("Add Animation"), "animations"); - AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_tree(); + AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_animation_tree(); ERR_FAIL_COND(!gp); if (gp->has_node(gp->get_animation_player())) { @@ -153,6 +155,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Move Node Point")); undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, point); undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); @@ -177,7 +180,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); blend_pos += blend_space->get_min_space(); - AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); + AnimationTreeEditor::get_singleton()->get_animation_tree()->set(get_blend_position_path(), blend_pos); blend_space_draw->queue_redraw(); } @@ -200,7 +203,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven blend_pos *= blend_space->get_max_space() - blend_space->get_min_space(); blend_pos += blend_space->get_min_space(); - AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); + AnimationTreeEditor::get_singleton()->get_animation_tree()->set(get_blend_position_path(), blend_pos); blend_space_draw->queue_redraw(); } @@ -298,7 +301,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() { color.a *= 0.5; } - float point = AnimationTreeEditor::get_singleton()->get_tree()->get(get_blend_position_path()); + float point = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(get_blend_position_path()); point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); point *= s.width; @@ -341,6 +344,7 @@ void AnimationNodeBlendSpace1DEditor::_config_changed(double) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change BlendSpace1D Config")); undo_redo->add_do_method(blend_space.ptr(), "set_max_space", max_value->get_value()); undo_redo->add_undo_method(blend_space.ptr(), "set_max_space", blend_space->get_max_space()); @@ -364,6 +368,7 @@ void AnimationNodeBlendSpace1DEditor::_labels_changed(String) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change BlendSpace1D Labels"), UndoRedo::MERGE_ENDS); undo_redo->add_do_method(blend_space.ptr(), "set_value_label", label_value->get_text()); undo_redo->add_undo_method(blend_space.ptr(), "set_value_label", blend_space->get_value_label()); @@ -381,6 +386,8 @@ void AnimationNodeBlendSpace1DEditor::_file_opened(const String &p_file) { file_loaded = ResourceLoader::load(p_file); if (file_loaded.is_valid()) { _add_menu_type(MENU_LOAD_FILE_CONFIRM); + } else { + EditorNode::get_singleton()->show_warning(TTR("This type of node can't be used. Only animation nodes are allowed.")); } } @@ -417,6 +424,7 @@ void AnimationNodeBlendSpace1DEditor::_add_menu_type(int p_index) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Node Point")); undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", node, add_point_pos); undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count()); @@ -435,6 +443,7 @@ void AnimationNodeBlendSpace1DEditor::_add_animation_type(int p_index) { anim->set_animation(animations_to_add[p_index]); updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Animation Point")); undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", anim, add_point_pos); undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count()); @@ -508,6 +517,7 @@ void AnimationNodeBlendSpace1DEditor::_erase_selected() { if (selected_point != -1) { updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove BlendSpace1D Point")); undo_redo->add_do_method(blend_space.ptr(), "remove_blend_point", selected_point); undo_redo->add_undo_method(blend_space.ptr(), "add_blend_point", blend_space->get_blend_point_node(selected_point), blend_space->get_blend_point_position(selected_point), selected_point); @@ -527,6 +537,7 @@ void AnimationNodeBlendSpace1DEditor::_edit_point_pos(double) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Move BlendSpace1D Node Point")); undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, edit_value->get_value()); undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); @@ -566,10 +577,10 @@ void AnimationNodeBlendSpace1DEditor::_notification(int p_what) { case NOTIFICATION_PROCESS: { String error; - if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) { + if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->is_active()) { error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails."); - } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) { - error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason(); + } else if (AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) { + error = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_invalid_state_reason(); } if (error != error_label->get_text()) { @@ -760,8 +771,6 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { error_panel->add_child(error_label); error_label->set_text("hmmm"); - undo_redo = EditorNode::get_undo_redo(); - menu = memnew(PopupMenu); add_child(menu); menu->connect("id_pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_add_menu_type)); @@ -776,7 +785,6 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { open_file->set_title(TTR("Open Animation Node")); open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_file_opened)); - undo_redo = EditorNode::get_undo_redo(); set_custom_minimum_size(Size2(0, 150 * EDSCALE)); } diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h index c8b01cb54b..ec07678b27 100644 --- a/editor/plugins/animation_blend_space_1d_editor.h +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -40,7 +40,8 @@ #include "scene/gui/separator.h" #include "scene/gui/tree.h" -class EditorUndoRedoManager; +class CheckBox; +class PanelContainer; class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin { GDCLASS(AnimationNodeBlendSpace1DEditor, AnimationTreeNodeEditorPlugin); @@ -79,8 +80,6 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin { bool updating = false; - Ref<EditorUndoRedoManager> undo_redo; - static AnimationNodeBlendSpace1DEditor *singleton; void _blend_space_gui_input(const Ref<InputEvent> &p_event); diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index f75dcdf2d6..4d8e972883 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -42,8 +42,12 @@ #include "editor/editor_undo_redo_manager.h" #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" +#include "scene/gui/check_box.h" +#include "scene/gui/grid_container.h" #include "scene/gui/menu_button.h" +#include "scene/gui/option_button.h" #include "scene/gui/panel.h" +#include "scene/gui/panel_container.h" #include "scene/main/window.h" bool AnimationNodeBlendSpace2DEditor::can_edit(const Ref<AnimationNode> &p_node) { @@ -114,7 +118,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); menu->add_submenu_item(TTR("Add Animation"), "animations"); - AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_tree(); + AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_animation_tree(); ERR_FAIL_COND(!gp); if (gp && gp->has_node(gp->get_animation_player())) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); @@ -221,6 +225,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Triangle")); undo_redo->add_do_method(blend_space.ptr(), "add_triangle", making_triangle[0], making_triangle[1], making_triangle[2]); undo_redo->add_undo_method(blend_space.ptr(), "remove_triangle", blend_space->get_triangle_count()); @@ -246,6 +251,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven if (!read_only) { updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Move Node Point")); undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, point); undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); @@ -269,7 +275,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); blend_pos += blend_space->get_min_space(); - AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); + AnimationTreeEditor::get_singleton()->get_animation_tree()->set(get_blend_position_path(), blend_pos); blend_space_draw->queue_redraw(); } @@ -305,7 +311,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space()); blend_pos += blend_space->get_min_space(); - AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); + AnimationTreeEditor::get_singleton()->get_animation_tree()->set(get_blend_position_path(), blend_pos); blend_space_draw->queue_redraw(); } @@ -315,6 +321,8 @@ void AnimationNodeBlendSpace2DEditor::_file_opened(const String &p_file) { file_loaded = ResourceLoader::load(p_file); if (file_loaded.is_valid()) { _add_menu_type(MENU_LOAD_FILE_CONFIRM); + } else { + EditorNode::get_singleton()->show_warning(TTR("This type of node can't be used. Only animation nodes are allowed.")); } } @@ -351,6 +359,7 @@ void AnimationNodeBlendSpace2DEditor::_add_menu_type(int p_index) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Node Point")); undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", node, add_point_pos); undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count()); @@ -369,6 +378,7 @@ void AnimationNodeBlendSpace2DEditor::_add_animation_type(int p_index) { anim->set_animation(animations_to_add[p_index]); updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Animation Point")); undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", anim, add_point_pos); undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count()); @@ -406,11 +416,11 @@ void AnimationNodeBlendSpace2DEditor::_tool_switch(int p_tool) { making_triangle.clear(); if (p_tool == 2) { - Vector<Vector2> points; + Vector<Vector2> bl_points; for (int i = 0; i < blend_space->get_blend_point_count(); i++) { - points.push_back(blend_space->get_blend_point_position(i)); + bl_points.push_back(blend_space->get_blend_point_position(i)); } - Vector<Delaunay2D::Triangle> tr = Delaunay2D::triangulate(points); + Vector<Delaunay2D::Triangle> tr = Delaunay2D::triangulate(bl_points); for (int i = 0; i < tr.size(); i++) { blend_space->add_triangle(tr[i].points[0], tr[i].points[1], tr[i].points[2]); } @@ -494,8 +504,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { //triangles first for (int i = 0; i < blend_space->get_triangle_count(); i++) { - Vector<Vector2> points; - points.resize(3); + Vector<Vector2> bl_points; + bl_points.resize(3); for (int j = 0; j < 3; j++) { int point_idx = blend_space->get_triangle_point(i, j); @@ -509,11 +519,11 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); point *= s; point.y = s.height - point.y; - points.write[j] = point; + bl_points.write[j] = point; } for (int j = 0; j < 3; j++) { - blend_space_draw->draw_line(points[j], points[(j + 1) % 3], linecolor, Math::round(EDSCALE), true); + blend_space_draw->draw_line(bl_points[j], bl_points[(j + 1) % 3], linecolor, Math::round(EDSCALE), true); } Color color; @@ -530,7 +540,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { color, color }; - blend_space_draw->draw_primitive(points, colors, Vector<Vector2>()); + blend_space_draw->draw_primitive(bl_points, colors, Vector<Vector2>()); } points.clear(); @@ -560,19 +570,19 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { } if (making_triangle.size()) { - Vector<Vector2> points; + Vector<Vector2> bl_points; for (int i = 0; i < making_triangle.size(); i++) { Vector2 point = blend_space->get_blend_point_position(making_triangle[i]); point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); point *= s; point.y = s.height - point.y; - points.push_back(point); + bl_points.push_back(point); } - for (int i = 0; i < points.size() - 1; i++) { - blend_space_draw->draw_line(points[i], points[i + 1], linecolor, Math::round(2 * EDSCALE), true); + for (int i = 0; i < bl_points.size() - 1; i++) { + blend_space_draw->draw_line(bl_points[i], bl_points[i + 1], linecolor, Math::round(2 * EDSCALE), true); } - blend_space_draw->draw_line(points[points.size() - 1], blend_space_draw->get_local_mouse_position(), linecolor, Math::round(2 * EDSCALE), true); + blend_space_draw->draw_line(bl_points[bl_points.size() - 1], blend_space_draw->get_local_mouse_position(), linecolor, Math::round(2 * EDSCALE), true); } ///draw cursor position @@ -586,7 +596,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { color.a *= 0.5; } - Vector2 blend_pos = AnimationTreeEditor::get_singleton()->get_tree()->get(get_blend_position_path()); + Vector2 blend_pos = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(get_blend_position_path()); Vector2 point = blend_pos; point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space()); @@ -658,6 +668,7 @@ void AnimationNodeBlendSpace2DEditor::_config_changed(double) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change BlendSpace2D Config")); undo_redo->add_do_method(blend_space.ptr(), "set_max_space", Vector2(max_x_value->get_value(), max_y_value->get_value())); undo_redo->add_undo_method(blend_space.ptr(), "set_max_space", blend_space->get_max_space()); @@ -683,6 +694,7 @@ void AnimationNodeBlendSpace2DEditor::_labels_changed(String) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change BlendSpace2D Labels"), UndoRedo::MERGE_ENDS); undo_redo->add_do_method(blend_space.ptr(), "set_x_label", label_x->get_text()); undo_redo->add_undo_method(blend_space.ptr(), "set_x_label", blend_space->get_x_label()); @@ -695,6 +707,7 @@ void AnimationNodeBlendSpace2DEditor::_labels_changed(String) { } void AnimationNodeBlendSpace2DEditor::_erase_selected() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (selected_point != -1) { updating = true; undo_redo->create_action(TTR("Remove BlendSpace2D Point")); @@ -757,6 +770,7 @@ void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) { return; } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Move Node Point")); undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, Vector2(edit_x->get_value(), edit_y->get_value())); undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point)); @@ -794,12 +808,12 @@ void AnimationNodeBlendSpace2DEditor::_notification(int p_what) { case NOTIFICATION_PROCESS: { String error; - if (!AnimationTreeEditor::get_singleton()->get_tree()) { + if (!AnimationTreeEditor::get_singleton()->get_animation_tree()) { error = TTR("BlendSpace2D does not belong to an AnimationTree node."); - } else if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) { + } else if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->is_active()) { error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails."); - } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) { - error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason(); + } else if (AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) { + error = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_invalid_state_reason(); } else if (blend_space->get_triangle_count() == 0) { error = TTR("No triangles exist, so no blending can take place."); } @@ -833,6 +847,7 @@ void AnimationNodeBlendSpace2DEditor::_removed_from_graph() { } void AnimationNodeBlendSpace2DEditor::_auto_triangles_toggled() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Toggle Auto Triangles")); undo_redo->add_do_method(blend_space.ptr(), "set_auto_triangles", auto_triangles->is_pressed()); undo_redo->add_undo_method(blend_space.ptr(), "set_auto_triangles", blend_space->get_auto_triangles()); @@ -1056,8 +1071,6 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { error_panel->add_child(error_label); error_label->set_text("eh"); - undo_redo = EditorNode::get_undo_redo(); - set_custom_minimum_size(Size2(0, 300 * EDSCALE)); menu = memnew(PopupMenu); @@ -1074,7 +1087,6 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { open_file->set_title(TTR("Open Animation Node")); open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_file_opened)); - undo_redo = EditorNode::get_undo_redo(); selected_point = -1; selected_triangle = -1; diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h index 1f015a1804..60873e5473 100644 --- a/editor/plugins/animation_blend_space_2d_editor.h +++ b/editor/plugins/animation_blend_space_2d_editor.h @@ -40,7 +40,9 @@ #include "scene/gui/separator.h" #include "scene/gui/tree.h" -class EditorUndoRedoManager; +class CheckBox; +class OptionButton; +class PanelContainer; class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin { GDCLASS(AnimationNodeBlendSpace2DEditor, AnimationTreeNodeEditorPlugin); @@ -85,8 +87,6 @@ class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin { bool updating; - Ref<EditorUndoRedoManager> undo_redo; - static AnimationNodeBlendSpace2DEditor *singleton; void _blend_space_gui_input(const Ref<InputEvent> &p_event); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index ca7b2d0015..0f67663948 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -41,9 +41,11 @@ #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "scene/animation/animation_player.h" +#include "scene/gui/check_box.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "scene/gui/progress_bar.h" +#include "scene/gui/separator.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" @@ -96,8 +98,9 @@ Size2 AnimationNodeBlendTreeEditor::get_minimum_size() const { } void AnimationNodeBlendTreeEditor::_property_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) { - AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_tree(); + AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree(); updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Parameter Changed:") + " " + String(p_property), UndoRedo::MERGE_ENDS); undo_redo->add_do_property(tree, p_property, p_value); undo_redo->add_undo_property(tree, p_property, tree->get(p_property)); @@ -153,7 +156,8 @@ void AnimationNodeBlendTreeEditor::update_graph() { node->add_child(name); node->set_slot(0, false, 0, Color(), true, read_only ? -1 : 0, get_theme_color(SNAME("font_color"), SNAME("Label"))); name->connect("text_submitted", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed).bind(agnode), CONNECT_DEFERRED); - name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out).bind(name, agnode), CONNECT_DEFERRED); + name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out).bind(agnode), CONNECT_DEFERRED); + name->connect("text_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_rename_lineedit_changed), CONNECT_DEFERRED); base = 1; node->set_show_close_button(true); node->connect("close_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_request).bind(E), CONNECT_DEFERRED); @@ -173,10 +177,10 @@ void AnimationNodeBlendTreeEditor::update_graph() { continue; } String base_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E) + "/" + F.name; - EditorProperty *prop = EditorInspector::instantiate_property_editor(AnimationTreeEditor::get_singleton()->get_tree(), F.type, base_path, F.hint, F.hint_string, F.usage); + EditorProperty *prop = EditorInspector::instantiate_property_editor(AnimationTreeEditor::get_singleton()->get_animation_tree(), F.type, base_path, F.hint, F.hint_string, F.usage); if (prop) { prop->set_read_only(read_only); - prop->set_object_and_property(AnimationTreeEditor::get_singleton()->get_tree(), base_path); + prop->set_object_and_property(AnimationTreeEditor::get_singleton()->get_animation_tree(), base_path); prop->update_property(); prop->set_name_split_ratio(0); prop->connect("property_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_property_changed)); @@ -224,7 +228,7 @@ void AnimationNodeBlendTreeEditor::update_graph() { ProgressBar *pb = memnew(ProgressBar); - AnimationTree *player = AnimationTreeEditor::get_singleton()->get_tree(); + AnimationTree *player = AnimationTreeEditor::get_singleton()->get_animation_tree(); if (player->has_node(player->get_animation_player())) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(player->get_node(player->get_animation_player())); if (ap) { @@ -262,10 +266,10 @@ void AnimationNodeBlendTreeEditor::update_graph() { node->add_theme_color_override("resizer_color", c); } - List<AnimationNodeBlendTree::NodeConnection> connections; - blend_tree->get_node_connections(&connections); + List<AnimationNodeBlendTree::NodeConnection> node_connections; + blend_tree->get_node_connections(&node_connections); - for (const AnimationNodeBlendTree::NodeConnection &E : connections) { + for (const AnimationNodeBlendTree::NodeConnection &E : node_connections) { StringName from = E.output_node; StringName to = E.input_node; int to_idx = E.input_index; @@ -273,9 +277,9 @@ void AnimationNodeBlendTreeEditor::update_graph() { graph->connect_node(from, 0, to, to_idx); } - float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + float graph_minimap_opacity = EDITOR_GET("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); - float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + float graph_lines_curvature = EDITOR_GET("editors/visual_editors/lines_curvature"); graph->set_connection_lines_curvature(graph_lines_curvature); } @@ -283,6 +287,8 @@ void AnimationNodeBlendTreeEditor::_file_opened(const String &p_file) { file_loaded = ResourceLoader::load(p_file); if (file_loaded.is_valid()) { _add_node(MENU_LOAD_FILE_CONFIRM); + } else { + EditorNode::get_singleton()->show_warning(TTR("This type of node can't be used. Only animation nodes are allowed.")); } } @@ -293,9 +299,9 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) { if (p_idx == MENU_LOAD_FILE) { open_file->clear_filters(); - List<String> filters; - ResourceLoader::get_recognized_extensions_for_type("AnimationNode", &filters); - for (const String &E : filters) { + List<String> ext_filters; + ResourceLoader::get_recognized_extensions_for_type("AnimationNode", &ext_filters); + for (const String &E : ext_filters) { open_file->add_filter("*." + E); } open_file->popup_file_dialog(); @@ -350,6 +356,7 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) { name = base_name + " " + itos(base); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Node to BlendTree")); undo_redo->add_do_method(blend_tree.ptr(), "add_node", name, anode, instance_pos / EDSCALE); undo_redo->add_undo_method(blend_tree.ptr(), "remove_node", name); @@ -413,6 +420,7 @@ void AnimationNodeBlendTreeEditor::_connection_from_empty(const String &p_to, in void AnimationNodeBlendTreeEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, const StringName &p_which) { updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Node Moved")); undo_redo->add_do_method(blend_tree.ptr(), "set_node_position", p_which, p_to / EDSCALE); undo_redo->add_undo_method(blend_tree.ptr(), "set_node_position", p_which, p_from / EDSCALE); @@ -434,6 +442,7 @@ void AnimationNodeBlendTreeEditor::_connection_request(const String &p_from, int return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Nodes Connected")); undo_redo->add_do_method(blend_tree.ptr(), "connect_node", p_to, p_to_index, p_from); undo_redo->add_undo_method(blend_tree.ptr(), "disconnect_node", p_to, p_to_index); @@ -450,6 +459,7 @@ void AnimationNodeBlendTreeEditor::_disconnection_request(const String &p_from, graph->disconnect_node(p_from, p_from_index, p_to, p_to_index); updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Nodes Disconnected")); undo_redo->add_do_method(blend_tree.ptr(), "disconnect_node", p_to, p_to_index); undo_redo->add_undo_method(blend_tree.ptr(), "connect_node", p_to, p_to_index, p_from); @@ -465,6 +475,7 @@ void AnimationNodeBlendTreeEditor::_anim_selected(int p_index, Array p_options, Ref<AnimationNodeAnimation> anim = blend_tree->get_node(p_node); ERR_FAIL_COND(!anim.is_valid()); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Animation")); undo_redo->add_do_method(anim.ptr(), "set_animation", option); undo_redo->add_undo_method(anim.ptr(), "set_animation", anim->get_animation()); @@ -478,6 +489,7 @@ void AnimationNodeBlendTreeEditor::_delete_request(const String &p_which) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete Node")); undo_redo->add_do_method(blend_tree.ptr(), "remove_node", p_which); undo_redo->add_undo_method(blend_tree.ptr(), "add_node", p_which, blend_tree->get_node(p_which), blend_tree.ptr()->get_node_position(p_which)); @@ -522,6 +534,7 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request(const TypedArray<String return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete Node(s)")); for (const StringName &F : to_erase) { @@ -555,6 +568,7 @@ void AnimationNodeBlendTreeEditor::_open_in_editor(const String &p_which) { void AnimationNodeBlendTreeEditor::_filter_toggled() { updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Toggle Filter On/Off")); undo_redo->add_do_method(_filter_edit.ptr(), "set_filter_enabled", filter_enabled->is_pressed()); undo_redo->add_undo_method(_filter_edit.ptr(), "set_filter_enabled", _filter_edit->is_filter_enabled()); @@ -572,6 +586,7 @@ void AnimationNodeBlendTreeEditor::_filter_edited() { bool filtered = edited->is_checked(0); updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Filter")); undo_redo->add_do_method(_filter_edit.ptr(), "set_filter_path", edited_path, filtered); undo_redo->add_undo_method(_filter_edit.ptr(), "set_filter_path", edited_path, _filter_edit->is_path_filtered(edited_path)); @@ -586,14 +601,14 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano return false; } - NodePath player_path = AnimationTreeEditor::get_singleton()->get_tree()->get_animation_player(); + NodePath player_path = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_animation_player(); - if (!AnimationTreeEditor::get_singleton()->get_tree()->has_node(player_path)) { + if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->has_node(player_path)) { EditorNode::get_singleton()->show_warning(TTR("No animation player set, so unable to retrieve track names.")); return false; } - AnimationPlayer *player = Object::cast_to<AnimationPlayer>(AnimationTreeEditor::get_singleton()->get_tree()->get_node(player_path)); + AnimationPlayer *player = Object::cast_to<AnimationPlayer>(AnimationTreeEditor::get_singleton()->get_animation_tree()->get_node(player_path)); if (!player) { EditorNode::get_singleton()->show_warning(TTR("Player path set is invalid, so unable to retrieve track names.")); return false; @@ -611,10 +626,10 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano HashSet<String> paths; HashMap<String, RBSet<String>> types; { - List<StringName> animations; - player->get_animation_list(&animations); + List<StringName> animation_list; + player->get_animation_list(&animation_list); - for (const StringName &E : animations) { + for (const StringName &E : animation_list) { Ref<Animation> anim = player->get_animation(E); for (int i = 0; i < anim->get_track_count(); i++) { String track_path = anim->track_get_path(i); @@ -795,8 +810,8 @@ void AnimationNodeBlendTreeEditor::_removed_from_graph() { } void AnimationNodeBlendTreeEditor::_update_editor_settings() { - graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); - graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning"))); + graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); + graph->set_warped_panning(bool(EDITOR_GET("editors/panning/warped_mouse_panning"))); } void AnimationNodeBlendTreeEditor::_update_theme() { @@ -826,10 +841,10 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { case NOTIFICATION_PROCESS: { String error; - if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) { + if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->is_active()) { error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails."); - } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) { - error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason(); + } else if (AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) { + error = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_invalid_state_reason(); } if (error != error_label->get_text()) { @@ -846,13 +861,13 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { for (const AnimationNodeBlendTree::NodeConnection &E : conns) { float activity = 0; StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node; - if (AnimationTreeEditor::get_singleton()->get_tree() && !AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) { - activity = AnimationTreeEditor::get_singleton()->get_tree()->get_connection_activity(path, E.input_index); + if (AnimationTreeEditor::get_singleton()->get_animation_tree() && !AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) { + activity = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_connection_activity(path, E.input_index); } graph->set_connection_activity(E.output_node, 0, E.input_node, E.input_index, activity); } - AnimationTree *graph_player = AnimationTreeEditor::get_singleton()->get_tree(); + AnimationTree *graph_player = AnimationTreeEditor::get_singleton()->get_animation_tree(); AnimationPlayer *player = nullptr; if (graph_player->has_node(graph_player->get_animation_player())) { player = Object::cast_to<AnimationPlayer>(graph_player->get_node(graph_player->get_animation_player())); @@ -868,7 +883,7 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { E.value->set_max(anim->get_length()); //StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node; StringName time_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E.key) + "/time"; - E.value->set_value(AnimationTreeEditor::get_singleton()->get_tree()->get(time_path)); + E.value->set_value(AnimationTreeEditor::get_singleton()->get_animation_tree()->get(time_path)); } } } @@ -946,11 +961,12 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima String base_path = AnimationTreeEditor::get_singleton()->get_base_path(); updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Node Renamed")); undo_redo->add_do_method(blend_tree.ptr(), "rename_node", prev_name, name); undo_redo->add_undo_method(blend_tree.ptr(), "rename_node", name, prev_name); - undo_redo->add_do_method(AnimationTreeEditor::get_singleton()->get_tree(), "rename_parameter", base_path + prev_name, base_path + name); - undo_redo->add_undo_method(AnimationTreeEditor::get_singleton()->get_tree(), "rename_parameter", base_path + name, base_path + prev_name); + undo_redo->add_do_method(AnimationTreeEditor::get_singleton()->get_animation_tree(), "rename_parameter", base_path + prev_name, base_path + name); + undo_redo->add_undo_method(AnimationTreeEditor::get_singleton()->get_animation_tree(), "rename_parameter", base_path + name, base_path + prev_name); undo_redo->add_do_method(this, "update_graph"); undo_redo->add_undo_method(this, "update_graph"); undo_redo->commit_action(); @@ -970,10 +986,10 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima //recreate connections graph->clear_connections(); - List<AnimationNodeBlendTree::NodeConnection> connections; - blend_tree->get_node_connections(&connections); + List<AnimationNodeBlendTree::NodeConnection> node_connections; + blend_tree->get_node_connections(&node_connections); - for (const AnimationNodeBlendTree::NodeConnection &E : connections) { + for (const AnimationNodeBlendTree::NodeConnection &E : node_connections) { StringName from = E.output_node; StringName to = E.input_node; int to_idx = E.input_index; @@ -991,13 +1007,18 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima } update_graph(); // Needed to update the signal connections with the new name. + current_node_rename_text = String(); } -void AnimationNodeBlendTreeEditor::_node_renamed_focus_out(Node *le, Ref<AnimationNode> p_node) { - if (le == nullptr) { +void AnimationNodeBlendTreeEditor::_node_renamed_focus_out(Ref<AnimationNode> p_node) { + if (current_node_rename_text.is_empty()) { return; // The text_submitted signal triggered the graph update and freed the LineEdit. } - _node_renamed(le->call("get_text"), p_node); + _node_renamed(current_node_rename_text, p_node); +} + +void AnimationNodeBlendTreeEditor::_node_rename_lineedit_changed(const String &p_text) { + current_node_rename_text = p_text; } bool AnimationNodeBlendTreeEditor::can_edit(const Ref<AnimationNode> &p_node) { @@ -1048,9 +1069,9 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { graph->connect("popup_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_popup_request)); graph->connect("connection_to_empty", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_to_empty)); graph->connect("connection_from_empty", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_from_empty)); - float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + float graph_minimap_opacity = EDITOR_GET("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); - float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + float graph_lines_curvature = EDITOR_GET("editors/visual_editors/lines_curvature"); graph->set_connection_lines_curvature(graph_lines_curvature); VSeparator *vs = memnew(VSeparator); @@ -1109,5 +1130,4 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { open_file->set_title(TTR("Open Animation Node")); open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendTreeEditor::_file_opened)); - undo_redo = EditorNode::get_undo_redo(); } diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h index 46e0d18c69..fb19cce147 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.h +++ b/editor/plugins/animation_blend_tree_editor_plugin.h @@ -31,17 +31,21 @@ #ifndef ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H #define ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H -#include "editor/editor_plugin.h" #include "editor/plugins/animation_tree_editor_plugin.h" #include "scene/animation/animation_blend_tree.h" #include "scene/gui/button.h" #include "scene/gui/graph_edit.h" +#include "scene/gui/panel_container.h" #include "scene/gui/popup.h" #include "scene/gui/tree.h" +class AcceptDialog; +class CheckBox; class ProgressBar; class EditorFileDialog; -class EditorUndoRedoManager; +class EditorProperty; +class MenuButton; +class PanelContainer; class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin { GDCLASS(AnimationNodeBlendTreeEditor, AnimationTreeNodeEditorPlugin); @@ -58,8 +62,6 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin { PanelContainer *error_panel = nullptr; Label *error_label = nullptr; - Ref<EditorUndoRedoManager> undo_redo; - AcceptDialog *filter_dialog = nullptr; Tree *filters = nullptr; CheckBox *filter_enabled = nullptr; @@ -92,9 +94,11 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin { void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, const StringName &p_which); void _node_renamed(const String &p_text, Ref<AnimationNode> p_node); - void _node_renamed_focus_out(Node *le, Ref<AnimationNode> p_node); + void _node_renamed_focus_out(Ref<AnimationNode> p_node); + void _node_rename_lineedit_changed(const String &p_text); void _node_changed(const StringName &p_node_name); + String current_node_rename_text; bool updating; void _connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index); diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp index 2d20c0cca7..10b5271fc8 100644 --- a/editor/plugins/animation_library_editor.cpp +++ b/editor/plugins/animation_library_editor.cpp @@ -32,6 +32,7 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" void AnimationLibraryEditor::set_animation_player(Object *p_player) { @@ -93,7 +94,7 @@ void AnimationLibraryEditor::_add_library_validate(const String &p_name) { void AnimationLibraryEditor::_add_library_confirm() { if (adding_animation) { String anim_name = add_library_name->get_text(); - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); Ref<AnimationLibrary> al = player->call("get_animation_library", adding_animation_to_library); ERR_FAIL_COND(!al.is_valid()); @@ -110,7 +111,7 @@ void AnimationLibraryEditor::_add_library_confirm() { } else { String lib_name = add_library_name->get_text(); - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); Ref<AnimationLibrary> al; al.instantiate(); @@ -210,7 +211,7 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) { ald->add_animation(animation_name, animation); } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Make Animation Library Unique: %s"), lib_name)); undo_redo->add_do_method(player, "remove_animation_library", lib_name); undo_redo->add_do_method(player, "add_animation_library", lib_name, ald); @@ -279,7 +280,7 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) { Ref<Animation> animd = anim->duplicate(); - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Make Animation Unique: %s"), anim_name)); undo_redo->add_do_method(al.ptr(), "remove_animation", anim_name); undo_redo->add_do_method(al.ptr(), "add_animation", anim_name, animd); @@ -327,7 +328,7 @@ void AnimationLibraryEditor::_load_file(String p_path) { name = p_path.get_file().get_basename() + " " + itos(attempt); } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Add Animation Library: %s"), name)); undo_redo->add_do_method(player, "add_animation_library", name, al); @@ -365,7 +366,7 @@ void AnimationLibraryEditor::_load_file(String p_path) { name = p_path.get_file().get_basename() + " " + itos(attempt); } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Load Animation into Library: %s"), name)); undo_redo->add_do_method(al.ptr(), "add_animation", name, anim); @@ -381,7 +382,7 @@ void AnimationLibraryEditor::_load_file(String p_path) { EditorNode::get_singleton()->save_resource_in_path(al, p_path); if (al->get_path() != prev_path) { // Save successful. - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Save Animation library to File: %s"), file_dialog_library)); undo_redo->add_do_method(al.ptr(), "set_path", al->get_path()); @@ -402,7 +403,7 @@ void AnimationLibraryEditor::_load_file(String p_path) { String prev_path = anim->get_path(); EditorNode::get_singleton()->save_resource_in_path(anim, p_path); if (anim->get_path() != prev_path) { // Save successful. - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Save Animation to File: %s"), file_dialog_animation)); undo_redo->add_do_method(anim.ptr(), "set_path", anim->get_path()); @@ -420,7 +421,7 @@ void AnimationLibraryEditor::_item_renamed() { String text = ti->get_text(0); String old_text = ti->get_metadata(0); bool restore_text = false; - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); if (String(text).contains("/") || String(text).contains(":") || String(text).contains(",") || String(text).contains("[")) { restore_text = true; @@ -534,7 +535,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int name = base_name + " (" + itos(attempt) + ")"; } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Add Animation to Library: %s"), name)); undo_redo->add_do_method(al.ptr(), "add_animation", name, anim); @@ -560,7 +561,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int file_dialog_library = lib_name; } break; case LIB_BUTTON_DELETE: { - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Remove Animation Library: %s"), lib_name)); undo_redo->add_do_method(player, "remove_animation_library", lib_name); undo_redo->add_undo_method(player, "add_animation_library", lib_name, al); @@ -601,7 +602,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int } break; case ANIM_BUTTON_DELETE: { - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(vformat(TTR("Remove Animation from Library: %s"), anim_name)); undo_redo->add_do_method(al.ptr(), "remove_animation", anim_name); undo_redo->add_undo_method(al.ptr(), "add_animation", anim_name, anim); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 5406aada09..f8ebd377d1 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -39,9 +39,12 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" +#include "editor/inspector_dock.h" #include "editor/plugins/canvas_item_editor_plugin.h" // For onion skinning. #include "editor/plugins/node_3d_editor_plugin.h" // For onion skinning. #include "editor/scene_tree_dock.h" +#include "scene/gui/separator.h" #include "scene/main/window.h" #include "scene/resources/animation.h" #include "scene/scene_string_names.h" @@ -128,14 +131,11 @@ void AnimationPlayerEditor::_notification(int p_what) { { Ref<Image> autoplay_img = autoplay_icon->get_image(); Ref<Image> reset_img = reset_icon->get_image(); - Ref<Image> autoplay_reset_img; Size2 icon_size = autoplay_img->get_size(); - autoplay_reset_img.instantiate(); - autoplay_reset_img->create(icon_size.x * 2, icon_size.y, false, autoplay_img->get_format()); + Ref<Image> autoplay_reset_img = Image::create_empty(icon_size.x * 2, icon_size.y, false, autoplay_img->get_format()); autoplay_reset_img->blit_rect(autoplay_img, Rect2i(Point2i(), icon_size), Point2i()); autoplay_reset_img->blit_rect(reset_img, Rect2i(Point2i(), icon_size), Point2i(icon_size.x, 0)); - autoplay_reset_icon.instantiate(); - autoplay_reset_icon->set_image(autoplay_reset_img); + autoplay_reset_icon = ImageTexture::create_from_image(autoplay_reset_img); } stop->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); @@ -170,6 +170,7 @@ void AnimationPlayerEditor::_autoplay_pressed() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); String current = animation->get_item_text(animation->get_selected()); if (player->get_autoplay() == current) { //unset @@ -302,6 +303,8 @@ void AnimationPlayerEditor::_animation_selected(int p_which) { AnimationPlayerEditor::get_singleton()->get_track_editor()->update_keying(); _animation_key_editor_seek(timeline_position, false); + + emit_signal("animation_selected", current); } void AnimationPlayerEditor::_animation_new() { @@ -384,6 +387,7 @@ void AnimationPlayerEditor::_animation_remove_confirmed() { if (current.contains("/")) { current = current.get_slice("/", 1); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Animation")); if (player->get_autoplay() == current) { undo_redo->add_do_method(player, "set_autoplay", ""); @@ -459,6 +463,7 @@ void AnimationPlayerEditor::_animation_name_edited() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (name_dialog_op) { case TOOL_RENAME_ANIM: { String current = animation->get_item_text(animation->get_selected()); @@ -593,6 +598,7 @@ void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) { String current = animation->get_item_text(animation->get_selected()); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Blend Next Changed")); undo_redo->add_do_method(player, "animation_set_next", current, blend_editor.next->get_item_text(p_idx)); undo_redo->add_undo_method(player, "animation_set_next", current, player->animation_get_next(current)); @@ -679,6 +685,7 @@ void AnimationPlayerEditor::_blend_edited() { float blend_time = selected->get_range(1); float prev_blend_time = player->get_blend_time(current, to); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Blend Time")); undo_redo->add_do_method(player, "set_blend_time", current, to, blend_time); undo_redo->add_undo_method(player, "set_blend_time", current, to, prev_blend_time); @@ -720,7 +727,18 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) { if (p_state.has("player")) { Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]); if (Object::cast_to<AnimationPlayer>(n) && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) { + if (player) { + if (player->is_connected("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated))) { + player->disconnect("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated)); + } + } player = Object::cast_to<AnimationPlayer>(n); + if (player) { + if (!player->is_connected("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated))) { + player->connect("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated)); + } + } + _update_player(); EditorNode::get_singleton()->make_bottom_panel_item_visible(this); set_process(true); @@ -826,13 +844,13 @@ void AnimationPlayerEditor::_update_player() { } // Check if the global library is foreign since we want to disable options for adding/remove/renaming animations if it is. - Ref<AnimationLibrary> library = player->get_animation_library(K); + Ref<AnimationLibrary> anim_library = player->get_animation_library(K); if (K == "") { - foreign_global_anim_lib = EditorNode::get_singleton()->is_resource_read_only(library); + foreign_global_anim_lib = EditorNode::get_singleton()->is_resource_read_only(anim_library); } List<StringName> animlist; - library->get_animation_list(&animlist); + anim_library->get_animation_list(&animlist); for (const StringName &E : animlist) { String path = K; @@ -874,6 +892,11 @@ void AnimationPlayerEditor::_update_player() { onion_toggle->set_disabled(no_anims_found); onion_skinning->set_disabled(no_anims_found); + if (hack_disable_onion_skinning) { + onion_toggle->set_disabled(true); + onion_skinning->set_disabled(true); + } + _update_animation_list_icons(); updating = false; @@ -908,19 +931,19 @@ void AnimationPlayerEditor::_update_player() { void AnimationPlayerEditor::_update_animation_list_icons() { for (int i = 0; i < animation->get_item_count(); i++) { - String name = animation->get_item_text(i); + String anim_name = animation->get_item_text(i); if (animation->is_item_disabled(i) || animation->is_item_separator(i)) { continue; } Ref<Texture2D> icon; - if (name == player->get_autoplay()) { - if (name == SceneStringNames::get_singleton()->RESET) { + if (anim_name == player->get_autoplay()) { + if (anim_name == SceneStringNames::get_singleton()->RESET) { icon = autoplay_reset_icon; } else { icon = autoplay_icon; } - } else if (name == SceneStringNames::get_singleton()->RESET) { + } else if (anim_name == SceneStringNames::get_singleton()->RESET) { icon = reset_icon; } @@ -929,7 +952,7 @@ void AnimationPlayerEditor::_update_animation_list_icons() { } void AnimationPlayerEditor::_update_name_dialog_library_dropdown() { - StringName current_library_name = StringName(); + StringName current_library_name; if (animation->has_selectable_items()) { String current_animation_name = animation->get_item_text(animation->get_selected()); Ref<Animation> current_animation = player->get_animation(current_animation_name); @@ -969,17 +992,22 @@ void AnimationPlayerEditor::_update_name_dialog_library_dropdown() { } } -void AnimationPlayerEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void AnimationPlayerEditor::edit(AnimationPlayer *p_player) { if (player && pin->is_pressed()) { return; // Ignore, pinned. } + + if (player) { + if (player->is_connected("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated))) { + player->disconnect("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated)); + } + } player = p_player; if (player) { + if (!player->is_connected("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated))) { + player->connect("animation_libraries_updated", callable_mp(this, &AnimationPlayerEditor::_animation_libraries_updated)); + } _update_player(); if (onion.enabled) { @@ -1146,6 +1174,10 @@ void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) { } } +void AnimationPlayerEditor::_animation_libraries_updated() { + _animation_player_changed(player); +} + void AnimationPlayerEditor::_list_changed() { if (is_visible_in_tree()) { _update_player(); @@ -1351,8 +1383,8 @@ void AnimationPlayerEditor::_free_onion_layers() { void AnimationPlayerEditor::_prepare_onion_layers_1() { // This would be called per viewport and we want to act once only. - int64_t frame = get_tree()->get_frame(); - if (frame == onion.last_frame) { + int64_t cur_frame = get_tree()->get_frame(); + if (cur_frame == onion.last_frame) { return; } @@ -1361,7 +1393,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_1() { return; } - onion.last_frame = frame; + onion.last_frame = cur_frame; // Refresh viewports with no onion layers overlaid. onion.can_overlay = false; @@ -1540,6 +1572,7 @@ void AnimationPlayerEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_animation_edit"), &AnimationPlayerEditor::_animation_edit); ClassDB::bind_method(D_METHOD("_animation_resource_edit"), &AnimationPlayerEditor::_animation_resource_edit); ClassDB::bind_method(D_METHOD("_animation_player_changed"), &AnimationPlayerEditor::_animation_player_changed); + ClassDB::bind_method(D_METHOD("_animation_libraries_updated"), &AnimationPlayerEditor::_animation_libraries_updated); ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed); ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate); @@ -1547,6 +1580,8 @@ void AnimationPlayerEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_prepare_onion_layers_2"), &AnimationPlayerEditor::_prepare_onion_layers_2); ClassDB::bind_method(D_METHOD("_start_onion_skinning"), &AnimationPlayerEditor::_start_onion_skinning); ClassDB::bind_method(D_METHOD("_stop_onion_skinning"), &AnimationPlayerEditor::_stop_onion_skinning); + + ADD_SIGNAL(MethodInfo("animation_selected", PropertyInfo(Variant::STRING, "name"))); } AnimationPlayerEditor *AnimationPlayerEditor::singleton = nullptr; @@ -1678,6 +1713,16 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug onion_skinning->get_popup()->add_check_item(TTR("Include Gizmos (3D)"), ONION_SKINNING_INCLUDE_GIZMOS); hb->add_child(onion_skinning); + // FIXME: Onion skinning disabled for now as it's broken and triggers fast + // flickering red/blue modulation (GH-53870). + if (hack_disable_onion_skinning) { + onion_toggle->set_disabled(true); + onion_toggle->set_tooltip_text(TTR("Onion Skinning temporarily disabled due to rendering bug.")); + + onion_skinning->set_disabled(true); + onion_skinning->set_tooltip_text(TTR("Onion Skinning temporarily disabled due to rendering bug.")); + } + hb->add_child(memnew(VSeparator)); pin = memnew(Button); @@ -1853,7 +1898,6 @@ void AnimationPlayerEditorPlugin::_update_keying() { } void AnimationPlayerEditorPlugin::edit(Object *p_object) { - anim_editor->set_undo_redo(get_undo_redo()); if (!p_object) { return; } @@ -1874,7 +1918,6 @@ void AnimationPlayerEditorPlugin::make_visible(bool p_visible) { AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin() { anim_editor = memnew(AnimationPlayerEditor(this)); - anim_editor->set_undo_redo(EditorNode::get_undo_redo()); EditorNode::get_singleton()->add_bottom_panel_item(TTR("Animation"), anim_editor); } diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index a37a9debef..6370b00ea8 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -41,7 +41,6 @@ #include "scene/gui/texture_button.h" #include "scene/gui/tree.h" -class EditorUndoRedoManager; class AnimationPlayerEditorPlugin; class AnimationPlayerEditor : public VBoxContainer { @@ -101,7 +100,6 @@ class AnimationPlayerEditor : public VBoxContainer { LineEdit *name = nullptr; OptionButton *library = nullptr; Label *name_title = nullptr; - Ref<EditorUndoRedoManager> undo_redo; Ref<Texture2D> autoplay_icon; Ref<Texture2D> reset_icon; @@ -131,6 +129,8 @@ class AnimationPlayerEditor : public VBoxContainer { AnimationTrackEditor *track_editor = nullptr; static AnimationPlayerEditor *singleton; + bool hack_disable_onion_skinning = true; // Temporary hack for GH-53870. + // Onion skinning. struct { // Settings. @@ -193,6 +193,7 @@ class AnimationPlayerEditor : public VBoxContainer { void _blend_edited(); void _animation_player_changed(Object *p_pl); + void _animation_libraries_updated(); void _animation_key_editor_seek(float p_pos, bool p_drag, bool p_timeline_only = false); void _animation_key_editor_anim_len_changed(float p_len); @@ -234,7 +235,6 @@ public: void ensure_visibility(); - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); void edit(AnimationPlayer *p_player); void forward_force_draw_over_viewport(Control *p_overlay); @@ -264,7 +264,7 @@ public: virtual void make_visible(bool p_visible) override; virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); } - virtual void forward_spatial_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); } + virtual void forward_3d_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); } AnimationPlayerEditorPlugin(); ~AnimationPlayerEditorPlugin(); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 461326a47b..ef9477abea 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -43,7 +43,10 @@ #include "scene/animation/animation_blend_tree.h" #include "scene/animation/animation_player.h" #include "scene/gui/menu_button.h" +#include "scene/gui/option_button.h" #include "scene/gui/panel.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/separator.h" #include "scene/gui/tree.h" #include "scene/main/viewport.h" #include "scene/main/window.h" @@ -76,7 +79,7 @@ void AnimationNodeStateMachineEditor::edit(const Ref<AnimationNode> &p_node) { } void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEvent> &p_event) { - Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); + Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); if (playback.is_null()) { return; } @@ -238,6 +241,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv Ref<AnimationNode> an = state_machine->get_node(selected_node); updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Move Node")); for (int i = 0; i < node_rects.size(); i++) { @@ -420,7 +424,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (mm.is_valid()) { state_machine_draw->grab_focus(); - String new_over_node = StringName(); + String new_over_node; int new_over_node_what = -1; if (tool_select->is_pressed()) { for (int i = node_rects.size() - 1; i >= 0; i--) { // Inverse to draw order. @@ -534,6 +538,7 @@ void AnimationNodeStateMachineEditor::_group_selected_nodes() { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action("Group"); // Move selected nodes to the new state machine @@ -648,6 +653,7 @@ void AnimationNodeStateMachineEditor::_ungroup_selected_nodes() { Vector<TransitionUR> transitions_ur; updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action("Ungroup"); // Move all child nodes to current state machine @@ -739,7 +745,7 @@ void AnimationNodeStateMachineEditor::_open_menu(const Vector2 &p_position) { ClassDB::get_inheriters_from_class("AnimationRootNode", &classes); menu->add_submenu_item(TTR("Add Animation"), "animations"); - AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_tree(); + AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_animation_tree(); ERR_FAIL_COND(!gp); if (gp && gp->has_node(gp->get_animation_player())) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player())); @@ -921,6 +927,7 @@ void AnimationNodeStateMachineEditor::_stop_connecting() { void AnimationNodeStateMachineEditor::_delete_selected() { TreeItem *item = delete_tree->get_next_selected(nullptr); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); while (item) { if (!updating) { updating = true; @@ -948,6 +955,7 @@ void AnimationNodeStateMachineEditor::_delete_all() { selected_multi_transition = TransitionLine(); updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action("Transition(s) Removed"); _erase_selected(true); for (int i = 0; i < multi_transitions.size(); i++) { @@ -974,6 +982,8 @@ void AnimationNodeStateMachineEditor::_file_opened(const String &p_file) { file_loaded = ResourceLoader::load(p_file); if (file_loaded.is_valid()) { _add_menu_type(MENU_LOAD_FILE_CONFIRM); + } else { + EditorNode::get_singleton()->show_warning(TTR("This type of node can't be used. Only animation nodes are allowed.")); } } @@ -1025,6 +1035,7 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Node and Transition")); undo_redo->add_do_method(state_machine.ptr(), "add_node", name, node, add_node_pos); undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name); @@ -1051,6 +1062,7 @@ void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Node and Transition")); undo_redo->add_do_method(state_machine.ptr(), "add_node", name, anim, add_node_pos); undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name); @@ -1079,6 +1091,7 @@ void AnimationNodeStateMachineEditor::_add_transition(const bool p_nested_action tr.instantiate(); tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected())); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (!p_nested_action) { updating = true; undo_redo->create_action(TTR("Add Transition")); @@ -1179,7 +1192,7 @@ void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(const Vector2 &p_fr } void AnimationNodeStateMachineEditor::_state_machine_draw() { - Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); + Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); Ref<StyleBoxFlat> style = get_theme_stylebox(SNAME("state_machine_frame"), SNAME("GraphNode")); Ref<StyleBoxFlat> style_selected = get_theme_stylebox(SNAME("state_machine_selected_frame"), SNAME("GraphNode")); @@ -1367,7 +1380,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } StringName fullpath = AnimationTreeEditor::get_singleton()->get_base_path() + String(tl.advance_condition_name); - if (tl.advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_tree()->get(fullpath))) { + if (tl.advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_animation_tree()->get(fullpath))) { tl.advance_condition_state = true; tl.auto_advance = true; } @@ -1482,7 +1495,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { } void AnimationNodeStateMachineEditor::_state_machine_pos_draw() { - Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); + Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); if (!playback.is_valid() || !playback->is_playing()) { return; @@ -1576,15 +1589,15 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { case NOTIFICATION_PROCESS: { String error; - Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); + Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback"); if (error_time > 0) { error = error_text; error_time -= get_process_delta_time(); - } else if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) { + } else if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->is_active()) { error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails."); - } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) { - error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason(); + } else if (AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) { + error = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_invalid_state_reason(); /*} else if (state_machine->get_parent().is_valid() && state_machine->get_parent()->is_class("AnimationNodeStateMachine")) { if (state_machine->get_start_node() == StringName() || state_machine->get_end_node() == StringName()) { error = TTR("Start and end nodes are needed for a sub-transition."); @@ -1636,7 +1649,7 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { break; } - bool acstate = transition_lines[i].advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + String(transition_lines[i].advance_condition_name))); + bool acstate = transition_lines[i].advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + String(transition_lines[i].advance_condition_name))); if (transition_lines[i].advance_condition_state != acstate) { state_machine_draw->queue_redraw(); @@ -1691,7 +1704,7 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { Ref<AnimationNodeStateMachinePlayback> current_node_playback; while (anodesm.is_valid()) { - current_node_playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + next + "/playback"); + current_node_playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + next + "/playback"); next += "/" + current_node_playback->get_current_node(); anodesm = anodesm->get_node(current_node_playback->get_current_node()); } @@ -1743,6 +1756,7 @@ void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) { } updating = true; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Node Renamed")); undo_redo->add_do_method(state_machine.ptr(), "rename_node", prev_name, name); undo_redo->add_undo_method(state_machine.ptr(), "rename_node", name, prev_name); @@ -1777,6 +1791,7 @@ void AnimationNodeStateMachineEditor::_erase_selected(const bool p_nested_action if (!p_nested_action) { updating = true; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Node Removed")); for (int i = 0; i < node_rects.size(); i++) { @@ -1845,6 +1860,7 @@ void AnimationNodeStateMachineEditor::_erase_selected(const bool p_nested_action if (!p_nested_action) { updating = true; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Transition Removed")); undo_redo->add_do_method(state_machine.ptr(), "remove_transition", selected_transition_from, selected_transition_to); undo_redo->add_undo_method(state_machine.ptr(), "add_transition", selected_transition_from, selected_transition_to, tr); @@ -2011,8 +2027,6 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { error_panel->add_child(error_label); error_panel->hide(); - undo_redo = EditorNode::get_undo_redo(); - set_custom_minimum_size(Size2(0, 300 * EDSCALE)); menu = memnew(PopupMenu); @@ -2053,7 +2067,6 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() { open_file->set_title(TTR("Open Animation Node")); open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); open_file->connect("file_selected", callable_mp(this, &AnimationNodeStateMachineEditor::_file_opened)); - undo_redo = EditorNode::get_undo_redo(); delete_window = memnew(ConfirmationDialog); delete_window->set_flag(Window::FLAG_RESIZE_DISABLED, true); diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h index d0828a5f52..5edf803c41 100644 --- a/editor/plugins/animation_state_machine_editor.h +++ b/editor/plugins/animation_state_machine_editor.h @@ -31,16 +31,16 @@ #ifndef ANIMATION_STATE_MACHINE_EDITOR_H #define ANIMATION_STATE_MACHINE_EDITOR_H -#include "editor/editor_plugin.h" #include "editor/plugins/animation_tree_editor_plugin.h" #include "scene/animation/animation_node_state_machine.h" -#include "scene/gui/button.h" #include "scene/gui/graph_edit.h" #include "scene/gui/popup.h" #include "scene/gui/tree.h" +class ConfirmationDialog; class EditorFileDialog; -class EditorUndoRedoManager; +class OptionButton; +class PanelContainer; class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { GDCLASS(AnimationNodeStateMachineEditor, AnimationTreeNodeEditorPlugin); @@ -79,8 +79,6 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin { bool updating = false; - Ref<EditorUndoRedoManager> undo_redo; - static AnimationNodeStateMachineEditor *singleton; void _state_machine_gui_input(const Ref<InputEvent> &p_event); diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 1de4fbaabc..61aa861a3f 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -74,6 +74,12 @@ void AnimationTreeEditor::edit(AnimationTree *p_tree) { edit_path(path); } +void AnimationTreeEditor::_node_removed(Node *p_node) { + if (p_node == tree) { + tree = nullptr; + } +} + void AnimationTreeEditor::_path_button_pressed(int p_path) { edited_path.clear(); for (int i = 0; i <= p_path; i++) { @@ -167,6 +173,9 @@ void AnimationTreeEditor::enter_editor(const String &p_path) { void AnimationTreeEditor::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + get_tree()->connect("node_removed", callable_mp(this, &AnimationTreeEditor::_node_removed)); + } break; case NOTIFICATION_PROCESS: { ObjectID root; if (tree && tree->get_tree_root().is_valid()) { @@ -181,6 +190,9 @@ void AnimationTreeEditor::_notification(int p_what) { edit_path(edited_path); } } break; + case NOTIFICATION_EXIT_TREE: { + get_tree()->disconnect("node_removed", callable_mp(this, &AnimationTreeEditor::_node_removed)); + } break; } } diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h index 9ef9fff8cd..e1d9536f03 100644 --- a/editor/plugins/animation_tree_editor_plugin.h +++ b/editor/plugins/animation_tree_editor_plugin.h @@ -35,8 +35,6 @@ #include "scene/animation/animation_tree.h" #include "scene/gui/button.h" #include "scene/gui/graph_edit.h" -#include "scene/gui/popup.h" -#include "scene/gui/tree.h" class EditorFileDialog; @@ -71,12 +69,13 @@ class AnimationTreeEditor : public VBoxContainer { protected: void _notification(int p_what); + void _node_removed(Node *p_node); static void _bind_methods(); static AnimationTreeEditor *singleton; public: - AnimationTree *get_tree() { return tree; } + AnimationTree *get_animation_tree() { return tree; } void add_plugin(AnimationTreeNodeEditorPlugin *p_editor); void remove_plugin(AnimationTreeNodeEditorPlugin *p_editor); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 3c9486cdaa..7c3ecd5d4e 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -41,6 +41,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/project_settings_editor.h" +#include "scene/gui/menu_button.h" static inline void setup_http_request(HTTPRequest *request) { request->set_use_threads(EDITOR_DEF("asset_library/use_threads", true)); @@ -65,13 +66,13 @@ void EditorAssetLibraryItem::set_image(int p_type, int p_index, const Ref<Textur ERR_FAIL_COND(p_type != EditorAssetLibrary::IMAGE_QUEUE_ICON); ERR_FAIL_COND(p_index != 0); - icon->set_normal_texture(p_image); + icon->set_texture_normal(p_image); } void EditorAssetLibraryItem::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - icon->set_normal_texture(get_theme_icon(SNAME("ProjectIconLoading"), SNAME("EditorIcons"))); + icon->set_texture_normal(get_theme_icon(SNAME("ProjectIconLoading"), SNAME("EditorIcons"))); category->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5)); author->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5)); price->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5)); @@ -243,19 +244,19 @@ void EditorAssetLibraryItemDescription::configure(const String &p_title, int p_a } void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, const String &p_url) { - Preview preview; - preview.id = p_id; - preview.video_link = p_url; - preview.is_video = p_video; - preview.button = memnew(Button); - preview.button->set_icon(previews->get_theme_icon(SNAME("ThumbnailWait"), SNAME("EditorIcons"))); - preview.button->set_toggle_mode(true); - preview.button->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDescription::_preview_click).bind(p_id)); - preview_hb->add_child(preview.button); + Preview new_preview; + new_preview.id = p_id; + new_preview.video_link = p_url; + new_preview.is_video = p_video; + new_preview.button = memnew(Button); + new_preview.button->set_icon(previews->get_theme_icon(SNAME("ThumbnailWait"), SNAME("EditorIcons"))); + new_preview.button->set_toggle_mode(true); + new_preview.button->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDescription::_preview_click).bind(p_id)); + preview_hb->add_child(new_preview.button); if (!p_video) { - preview.image = previews->get_theme_icon(SNAME("ThumbnailWait"), SNAME("EditorIcons")); + new_preview.image = previews->get_theme_icon(SNAME("ThumbnailWait"), SNAME("EditorIcons")); } - preview_images.push_back(preview); + preview_images.push_back(new_preview); if (preview_images.size() == 1 && !p_video) { _preview_click(p_id); } @@ -402,7 +403,7 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("AssetLib"))); status->add_theme_color_override("font_color", get_theme_color(SNAME("status_color"), SNAME("AssetLib"))); - dismiss_button->set_normal_texture(get_theme_icon(SNAME("dismiss"), SNAME("AssetLib"))); + dismiss_button->set_texture_normal(get_theme_icon(SNAME("dismiss"), SNAME("AssetLib"))); } break; case NOTIFICATION_PROCESS: { @@ -460,7 +461,7 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) { void EditorAssetLibraryItemDownload::_close() { // Clean up downloaded file. DirAccess::remove_file_or_error(download->get_download_file()); - queue_delete(); + queue_free(); } bool EditorAssetLibraryItemDownload::can_install() const { @@ -832,7 +833,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons } } - image_queue[p_queue_id].request->queue_delete(); + image_queue[p_queue_id].request->queue_free(); image_queue.erase(p_queue_id); _update_image_queue(); @@ -868,7 +869,7 @@ void EditorAssetLibrary::_update_image_queue() { } while (to_delete.size()) { - image_queue[to_delete.front()->get()].request->queue_delete(); + image_queue[to_delete.front()->get()].request->queue_free(); image_queue.erase(to_delete.front()->get()); to_delete.pop_front(); } diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index 070d25e29f..2795892c2e 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -50,6 +50,9 @@ #include "scene/gui/texture_button.h" #include "scene/main/http_request.h" +class EditorFileDialog; +class MenuButton; + class EditorAssetLibraryItem : public PanelContainer { GDCLASS(EditorAssetLibraryItem, PanelContainer); diff --git a/editor/plugins/audio_stream_randomizer_editor_plugin.cpp b/editor/plugins/audio_stream_randomizer_editor_plugin.cpp index d670197c53..e21a50a434 100644 --- a/editor/plugins/audio_stream_randomizer_editor_plugin.cpp +++ b/editor/plugins/audio_stream_randomizer_editor_plugin.cpp @@ -44,8 +44,8 @@ void AudioStreamRandomizerEditorPlugin::make_visible(bool p_visible) { } void AudioStreamRandomizerEditorPlugin::_move_stream_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) { - Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); - ERR_FAIL_COND(undo_redo.is_null()); + Ref<EditorUndoRedoManager> undo_redo_man = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); + ERR_FAIL_COND(undo_redo_man.is_null()); AudioStreamRandomizer *randomizer = Object::cast_to<AudioStreamRandomizer>(p_edited); if (!randomizer) { @@ -76,12 +76,12 @@ void AudioStreamRandomizerEditorPlugin::_move_stream_array_element(Object *p_und end = MIN(MAX(p_from_index, p_to_pos) + 1, end); } -#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property)); +#define ADD_UNDO(obj, property) undo_redo_man->add_undo_property(obj, property, obj->get(property)); // Save layers' properties. if (p_from_index < 0) { - undo_redo->add_undo_method(randomizer, "remove_stream", p_to_pos < 0 ? randomizer->get_streams_count() : p_to_pos); + undo_redo_man->add_undo_method(randomizer, "remove_stream", p_to_pos < 0 ? randomizer->get_streams_count() : p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_undo_method(randomizer, "add_stream", p_from_index); + undo_redo_man->add_undo_method(randomizer, "add_stream", p_from_index); } List<PropertyInfo> properties; @@ -107,11 +107,11 @@ void AudioStreamRandomizerEditorPlugin::_move_stream_array_element(Object *p_und #undef ADD_UNDO if (p_from_index < 0) { - undo_redo->add_do_method(randomizer, "add_stream", p_to_pos); + undo_redo_man->add_do_method(randomizer, "add_stream", p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_do_method(randomizer, "remove_stream", p_from_index); + undo_redo_man->add_do_method(randomizer, "remove_stream", p_from_index); } else { - undo_redo->add_do_method(randomizer, "move_stream", p_from_index, p_to_pos); + undo_redo_man->add_do_method(randomizer, "move_stream", p_from_index, p_to_pos); } } diff --git a/editor/plugins/bit_map_editor_plugin.cpp b/editor/plugins/bit_map_editor_plugin.cpp index 657c5a36b6..8d9b3147a9 100644 --- a/editor/plugins/bit_map_editor_plugin.cpp +++ b/editor/plugins/bit_map_editor_plugin.cpp @@ -31,6 +31,8 @@ #include "bit_map_editor_plugin.h" #include "editor/editor_scale.h" +#include "scene/gui/label.h" +#include "scene/gui/texture_rect.h" void BitMapEditor::setup(const Ref<BitMap> &p_bitmap) { texture_rect->set_texture(ImageTexture::create_from_image(p_bitmap->convert_to_image())); diff --git a/editor/plugins/bit_map_editor_plugin.h b/editor/plugins/bit_map_editor_plugin.h index b045f8c751..8c65b1b6f1 100644 --- a/editor/plugins/bit_map_editor_plugin.h +++ b/editor/plugins/bit_map_editor_plugin.h @@ -31,9 +31,12 @@ #ifndef BIT_MAP_EDITOR_PLUGIN_H #define BIT_MAP_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "scene/resources/bit_map.h" +class TextureRect; + class BitMapEditor : public VBoxContainer { GDCLASS(BitMapEditor, VBoxContainer); diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index 46e2fe41af..4bf11f0627 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -31,16 +31,20 @@ #include "bone_map_editor_plugin.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/import/post_import_plugin_skeleton_renamer.h" #include "editor/import/post_import_plugin_skeleton_rest_fixer.h" #include "editor/import/post_import_plugin_skeleton_track_organizer.h" #include "editor/import/scene_import_settings.h" +#include "scene/gui/aspect_ratio_container.h" +#include "scene/gui/separator.h" +#include "scene/gui/texture_rect.h" void BoneMapperButton::fetch_textures() { if (selected) { - set_normal_texture(get_theme_icon(SNAME("BoneMapperHandleSelected"), SNAME("EditorIcons"))); + set_texture_normal(get_theme_icon(SNAME("BoneMapperHandleSelected"), SNAME("EditorIcons"))); } else { - set_normal_texture(get_theme_icon(SNAME("BoneMapperHandle"), SNAME("EditorIcons"))); + set_texture_normal(get_theme_icon(SNAME("BoneMapperHandle"), SNAME("EditorIcons"))); } set_offset(SIDE_LEFT, 0); set_offset(SIDE_RIGHT, 0); @@ -63,16 +67,16 @@ StringName BoneMapperButton::get_profile_bone_name() const { void BoneMapperButton::set_state(BoneMapState p_state) { switch (p_state) { case BONE_MAP_STATE_UNSET: { - circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/unset")); + circle->set_modulate(EDITOR_GET("editors/bone_mapper/handle_colors/unset")); } break; case BONE_MAP_STATE_SET: { - circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/set")); + circle->set_modulate(EDITOR_GET("editors/bone_mapper/handle_colors/set")); } break; case BONE_MAP_STATE_MISSING: { - circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/missing")); + circle->set_modulate(EDITOR_GET("editors/bone_mapper/handle_colors/missing")); } break; case BONE_MAP_STATE_ERROR: { - circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/error")); + circle->set_modulate(EDITOR_GET("editors/bone_mapper/handle_colors/error")); } break; default: { } break; @@ -742,7 +746,6 @@ void BoneMapper::auto_mapping_process(Ref<BoneMap> &p_bone_map) { } else { p_bone_map->_set_skeleton_bone_name("LeftEye", skeleton->get_bone_name(bone_idx)); } - bone_idx = -1; bone_idx = search_bone_by_name(skeleton, picklist, BONE_SEGREGATION_RIGHT, neck_or_head); if (bone_idx == -1) { @@ -750,7 +753,6 @@ void BoneMapper::auto_mapping_process(Ref<BoneMap> &p_bone_map) { } else { p_bone_map->_set_skeleton_bone_name("RightEye", skeleton->get_bone_name(bone_idx)); } - bone_idx = -1; picklist.clear(); // 4-2. Guess Jaw @@ -1309,7 +1311,7 @@ void BoneMapEditor::create_editors() { void BoneMapEditor::fetch_objects() { skeleton = nullptr; - // Hackey... but it may be the easist way to get a selected object from "ImporterScene". + // Hackey... but it may be the easiest way to get a selected object from "ImporterScene". SceneImportSettings *si = SceneImportSettings::get_singleton(); if (!si) { return; diff --git a/editor/plugins/bone_map_editor_plugin.h b/editor/plugins/bone_map_editor_plugin.h index 55261ab477..e6a35d1120 100644 --- a/editor/plugins/bone_map_editor_plugin.h +++ b/editor/plugins/bone_map_editor_plugin.h @@ -41,11 +41,14 @@ #endif #include "scene/3d/skeleton_3d.h" +#include "scene/gui/box_container.h" #include "scene/gui/color_rect.h" #include "scene/gui/dialogs.h" #include "scene/resources/bone_map.h" #include "scene/resources/texture.h" +class AspectRatioContainer; + class BoneMapperButton : public TextureButton { GDCLASS(BoneMapperButton, TextureButton); @@ -206,7 +209,6 @@ class BoneMapEditor : public VBoxContainer { BoneMapper *bone_mapper = nullptr; void fetch_objects(); - void clear_editors(); void create_editors(); protected: diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 070834b33b..8cb9a6712d 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -32,15 +32,14 @@ #include "core/config/project_settings.h" #include "core/input/input.h" -#include "core/math/geometry_2d.h" #include "core/os/keyboard.h" -#include "core/string/print_string.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_toaster.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/editor_zoom_widget.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/scene_tree_dock.h" @@ -55,6 +54,7 @@ #include "scene/gui/grid_container.h" #include "scene/gui/nine_patch_rect.h" #include "scene/gui/separator.h" +#include "scene/gui/split_container.h" #include "scene/gui/subviewport_container.h" #include "scene/gui/view_panner.h" #include "scene/main/canvas_layer.h" @@ -116,6 +116,7 @@ public: grid_offset_x->set_allow_greater(true); grid_offset_x->set_suffix("px"); grid_offset_x->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_offset_x->set_select_all_on_focus(true); child_container->add_child(grid_offset_x); grid_offset_y = memnew(SpinBox); @@ -125,6 +126,7 @@ public: grid_offset_y->set_allow_greater(true); grid_offset_y->set_suffix("px"); grid_offset_y->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_offset_y->set_select_all_on_focus(true); child_container->add_child(grid_offset_y); label = memnew(Label); @@ -138,6 +140,7 @@ public: grid_step_x->set_allow_greater(true); grid_step_x->set_suffix("px"); grid_step_x->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_step_x->set_select_all_on_focus(true); child_container->add_child(grid_step_x); grid_step_y = memnew(SpinBox); @@ -146,6 +149,7 @@ public: grid_step_y->set_allow_greater(true); grid_step_y->set_suffix("px"); grid_step_y->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_step_y->set_select_all_on_focus(true); child_container->add_child(grid_step_y); child_container = memnew(GridContainer); @@ -164,6 +168,7 @@ public: primary_grid_steps->set_allow_greater(true); primary_grid_steps->set_suffix(TTR("steps")); primary_grid_steps->set_h_size_flags(Control::SIZE_EXPAND_FILL); + primary_grid_steps->set_select_all_on_focus(true); child_container->add_child(primary_grid_steps); container->add_child(memnew(HSeparator)); @@ -184,6 +189,7 @@ public: rotation_offset->set_max(SPIN_BOX_ROTATION_RANGE); rotation_offset->set_suffix("deg"); rotation_offset->set_h_size_flags(Control::SIZE_EXPAND_FILL); + rotation_offset->set_select_all_on_focus(true); child_container->add_child(rotation_offset); label = memnew(Label); @@ -196,6 +202,7 @@ public: rotation_step->set_max(SPIN_BOX_ROTATION_RANGE); rotation_step->set_suffix("deg"); rotation_step->set_h_size_flags(Control::SIZE_EXPAND_FILL); + rotation_step->set_select_all_on_focus(true); child_container->add_child(rotation_step); container->add_child(memnew(HSeparator)); @@ -214,6 +221,7 @@ public: scale_step->set_allow_greater(true); scale_step->set_h_size_flags(Control::SIZE_EXPAND_FILL); scale_step->set_step(0.01f); + scale_step->set_select_all_on_focus(true); child_container->add_child(scale_step); } @@ -304,7 +312,7 @@ void CanvasItemEditor::_snap_other_nodes( Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2], const SnapTarget p_snap_target, List<const CanvasItem *> p_exceptions, const Node *p_current) { - const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_current); + const CanvasItem *ci = Object::cast_to<CanvasItem>(p_current); // Check if the element is in the exception bool exception = false; @@ -315,12 +323,12 @@ void CanvasItemEditor::_snap_other_nodes( } }; - if (canvas_item && !exception) { - Transform2D ci_transform = canvas_item->get_global_transform_with_canvas(); + if (ci && !exception) { + Transform2D ci_transform = ci->get_global_transform_with_canvas(); if (fmod(ci_transform.get_rotation() - p_transform_to_snap.get_rotation(), (real_t)360.0) == 0.0) { - if (canvas_item->_edit_use_rect()) { - Point2 begin = ci_transform.xform(canvas_item->_edit_get_rect().get_position()); - Point2 end = ci_transform.xform(canvas_item->_edit_get_rect().get_position() + canvas_item->_edit_get_rect().get_size()); + if (ci->_edit_use_rect()) { + Point2 begin = ci_transform.xform(ci->_edit_get_rect().get_position()); + Point2 end = ci_transform.xform(ci->_edit_get_rect().get_position() + ci->_edit_get_rect().get_size()); _snap_if_closer_point(p_value, r_current_snap, r_current_snap_target, begin, p_snap_target, ci_transform.get_rotation()); _snap_if_closer_point(p_value, r_current_snap, r_current_snap_target, end, p_snap_target, ci_transform.get_rotation()); @@ -404,7 +412,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig // Other nodes sides if ((is_snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) { - Transform2D to_snap_transform = Transform2D(); + Transform2D to_snap_transform; List<const CanvasItem *> exceptions = List<const CanvasItem *>(); for (const CanvasItem *E : p_other_nodes_exceptions) { exceptions.push_back(E); @@ -528,14 +536,14 @@ Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List<CanvasItem *> p_li ERR_FAIL_COND_V(p_list.is_empty(), Rect2()); // Handles the first element - CanvasItem *canvas_item = p_list.front()->get(); - Rect2 rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_rect().get_center()), Size2()); + CanvasItem *ci = p_list.front()->get(); + Rect2 rect = Rect2(ci->get_global_transform_with_canvas().xform(ci->_edit_get_rect().get_center()), Size2()); // Expand with the other ones - for (CanvasItem *canvas_item2 : p_list) { - Transform2D xform = canvas_item2->get_global_transform_with_canvas(); + for (CanvasItem *ci2 : p_list) { + Transform2D xform = ci2->get_global_transform_with_canvas(); - Rect2 current_rect = canvas_item2->_edit_get_rect(); + Rect2 current_rect = ci2->_edit_get_rect(); rect.expand_to(xform.xform(current_rect.position)); rect.expand_to(xform.xform(current_rect.position + Vector2(current_rect.size.x, 0))); rect.expand_to(xform.xform(current_rect.position + current_rect.size)); @@ -553,24 +561,24 @@ void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, c return; } - const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); + const CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - if (canvas_item && !canvas_item->is_set_as_top_level()) { - _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + if (ci && !ci->is_set_as_top_level()) { + _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, p_parent_xform * ci->get_transform(), p_canvas_xform); } else { - const CanvasLayer *canvas_layer = Object::cast_to<CanvasLayer>(p_node); - _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, Transform2D(), canvas_layer ? canvas_layer->get_transform() : p_canvas_xform); + const CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); + _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, Transform2D(), cl ? cl->get_transform() : p_canvas_xform); } } - if (canvas_item && canvas_item->is_visible_in_tree() && (include_locked_nodes || !_is_node_locked(canvas_item))) { + if (ci && ci->is_visible_in_tree() && (include_locked_nodes || !_is_node_locked(ci))) { Transform2D xform = p_canvas_xform; - if (!canvas_item->is_set_as_top_level()) { + if (!ci->is_set_as_top_level()) { xform *= p_parent_xform; } - xform *= canvas_item->get_transform(); - Rect2 rect = canvas_item->_edit_get_rect(); + xform *= ci->get_transform(); + Rect2 rect = ci->_edit_get_rect(); if (r_first) { r_rect = Rect2(xform.xform(rect.get_center()), Size2()); r_first = false; @@ -599,14 +607,14 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no } const real_t grab_distance = EDITOR_GET("editors/polygon_editor/point_grab_radius"); - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); + CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - if (canvas_item) { - if (!canvas_item->is_set_as_top_level()) { - _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + if (ci) { + if (!ci->is_set_as_top_level()) { + _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_parent_xform * ci->get_transform(), p_canvas_xform); } else { - _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, canvas_item->get_transform(), p_canvas_xform); + _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, ci->get_transform(), p_canvas_xform); } } else { CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); @@ -614,18 +622,18 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no } } - if (canvas_item && canvas_item->is_visible_in_tree()) { + if (ci && ci->is_visible_in_tree()) { Transform2D xform = p_canvas_xform; - if (!canvas_item->is_set_as_top_level()) { + if (!ci->is_set_as_top_level()) { xform *= p_parent_xform; } - xform = (xform * canvas_item->get_transform()).affine_inverse(); + xform = (xform * ci->get_transform()).affine_inverse(); const real_t local_grab_distance = xform.basis_xform(Vector2(grab_distance, 0)).length() / zoom; - if (canvas_item->_edit_is_selected_on_click(xform.xform(p_pos), local_grab_distance)) { - Node2D *node = Object::cast_to<Node2D>(canvas_item); + if (ci->_edit_is_selected_on_click(xform.xform(p_pos), local_grab_distance)) { + Node2D *node = Object::cast_to<Node2D>(ci); _SelectResult res; - res.item = canvas_item; + res.item = ci; res.z_index = node ? node->get_z_index() : 0; res.has_z = node; r_items.push_back(res); @@ -647,13 +655,13 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel node = scene->get_deepest_editable_node(node); } - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(node); + CanvasItem *ci = Object::cast_to<CanvasItem>(node); if (!p_allow_locked) { // Replace the node by the group if grouped while (node && node != scene->get_parent()) { - CanvasItem *canvas_item_tmp = Object::cast_to<CanvasItem>(node); - if (canvas_item_tmp && node->has_meta("_edit_group_")) { - canvas_item = canvas_item_tmp; + CanvasItem *ci_tmp = Object::cast_to<CanvasItem>(node); + if (ci_tmp && node->has_meta("_edit_group_")) { + ci = ci_tmp; } node = node->get_parent(); } @@ -662,18 +670,18 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel // Check if the canvas item is already in the list (for groups or scenes) bool duplicate = false; for (int j = 0; j < i; j++) { - if (r_items[j].item == canvas_item) { + if (r_items[j].item == ci) { duplicate = true; break; } } //Remove the item if invalid - if (!canvas_item || duplicate || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner())) || (!p_allow_locked && _is_node_locked(canvas_item))) { + if (!ci || duplicate || (ci != scene && ci->get_owner() != scene && !scene->is_editable_instance(ci->get_owner())) || (!p_allow_locked && _is_node_locked(ci))) { r_items.remove_at(i); i--; } else { - r_items.write[i].item = canvas_item; + r_items.write[i].item = ci; } } } @@ -686,7 +694,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n return; } - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); + CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); Node *scene = EditorNode::get_singleton()->get_edited_scene(); bool editable = p_node == scene || p_node->get_owner() == scene || p_node == scene->get_deepest_editable_node(p_node); @@ -695,37 +703,37 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n if (!lock_children || !editable) { for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - if (canvas_item) { - if (!canvas_item->is_set_as_top_level()) { - _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + if (ci) { + if (!ci->is_set_as_top_level()) { + _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * ci->get_transform(), p_canvas_xform); } else { - _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, canvas_item->get_transform(), p_canvas_xform); + _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, ci->get_transform(), p_canvas_xform); } } else { - CanvasLayer *canvas_layer = Object::cast_to<CanvasLayer>(p_node); - _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, Transform2D(), canvas_layer ? canvas_layer->get_transform() : p_canvas_xform); + CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); + _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, Transform2D(), cl ? cl->get_transform() : p_canvas_xform); } } } - if (canvas_item && canvas_item->is_visible_in_tree() && !locked && editable) { + if (ci && ci->is_visible_in_tree() && !locked && editable) { Transform2D xform = p_canvas_xform; - if (!canvas_item->is_set_as_top_level()) { + if (!ci->is_set_as_top_level()) { xform *= p_parent_xform; } - xform *= canvas_item->get_transform(); + xform *= ci->get_transform(); - if (canvas_item->_edit_use_rect()) { - Rect2 rect = canvas_item->_edit_get_rect(); + if (ci->_edit_use_rect()) { + Rect2 rect = ci->_edit_get_rect(); if (p_rect.has_point(xform.xform(rect.position)) && p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, 0))) && p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, rect.size.y))) && p_rect.has_point(xform.xform(rect.position + Vector2(0, rect.size.y)))) { - r_items->push_back(canvas_item); + r_items->push_back(ci); } } else { if (p_rect.has_point(xform.xform(Point2()))) { - r_items->push_back(canvas_item); + r_items->push_back(ci); } } } @@ -765,11 +773,11 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool retrieve_locked, bool remove_canvas_item_if_parent_in_selection) { List<CanvasItem *> selection; for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); - if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retrieve_locked || !_is_node_locked(canvas_item))) { - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + CanvasItem *ci = Object::cast_to<CanvasItem>(E.key); + if (ci && ci->is_visible_in_tree() && ci->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retrieve_locked || !_is_node_locked(ci))) { + CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci); if (se) { - selection.push_back(canvas_item); + selection.push_back(ci); } } } @@ -805,7 +813,7 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 Rect2 parent_rect = p_control->get_parent_anchorable_rect(); - Vector2 output = Vector2(); + Vector2 output; if (p_control->is_layout_rtl()) { output.x = (parent_rect.size.x == 0) ? 0.0 : (parent_rect.size.x - p_control->get_transform().xform(position).x - parent_rect.position.x) / parent_rect.size.x; } else { @@ -819,18 +827,18 @@ void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items original_transform = Transform2D(); bool transform_stored = false; - for (CanvasItem *canvas_item : p_canvas_items) { - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + for (CanvasItem *ci : p_canvas_items) { + CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci); if (se) { if (!transform_stored) { - original_transform = canvas_item->get_global_transform(); + original_transform = ci->get_global_transform(); transform_stored = true; } - se->undo_state = canvas_item->_edit_get_state(); - se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); - if (canvas_item->_edit_use_rect()) { - se->pre_drag_rect = canvas_item->_edit_get_rect(); + se->undo_state = ci->_edit_get_state(); + se->pre_drag_xform = ci->get_global_transform_with_canvas(); + if (ci->_edit_use_rect()) { + se->pre_drag_rect = ci->_edit_get_rect(); } else { se->pre_drag_rect = Rect2(); } @@ -839,20 +847,20 @@ void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items } void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones) { - for (CanvasItem *canvas_item : drag_selection) { - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - canvas_item->_edit_set_state(se->undo_state); + for (CanvasItem *ci : drag_selection) { + CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci); + ci->_edit_set_state(se->undo_state); } } void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones) { List<CanvasItem *> modified_canvas_items; - for (CanvasItem *canvas_item : p_canvas_items) { - Dictionary old_state = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item)->undo_state; - Dictionary new_state = canvas_item->_edit_get_state(); + for (CanvasItem *ci : p_canvas_items) { + Dictionary old_state = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci)->undo_state; + Dictionary new_state = ci->_edit_get_state(); if (old_state.hash() != new_state.hash()) { - modified_canvas_items.push_back(canvas_item); + modified_canvas_items.push_back(ci); } } @@ -860,17 +868,18 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(action_name); - for (CanvasItem *canvas_item : modified_canvas_items) { - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + for (CanvasItem *ci : modified_canvas_items) { + CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci); if (se) { - undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); - undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state); + undo_redo->add_do_method(ci, "_edit_set_state", ci->_edit_get_state()); + undo_redo->add_undo_method(ci, "_edit_set_state", se->undo_state); if (commit_bones) { for (const Dictionary &F : se->pre_drag_bones_undo_state) { - canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent()); - undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); - undo_redo->add_undo_method(canvas_item, "_edit_set_state", F); + ci = Object::cast_to<CanvasItem>(ci->get_parent()); + undo_redo->add_do_method(ci, "_edit_set_state", ci->_edit_get_state()); + undo_redo->add_undo_method(ci, "_edit_set_state", F); } } } @@ -919,13 +928,12 @@ void CanvasItemEditor::_add_node_pressed(int p_result) { [[fallthrough]]; } case ADD_MOVE: { - if (p_result == ADD_MOVE) { - nodes_to_move = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list(); - } + nodes_to_move = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list(); if (nodes_to_move.is_empty()) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Move Node(s) to Position")); for (Node *node : nodes_to_move) { CanvasItem *ci = Object::cast_to<CanvasItem>(node); @@ -1014,6 +1022,7 @@ void CanvasItemEditor::_on_grid_menu_id_pressed(int p_id) { } bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_event) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); Ref<InputEventMouseButton> b = p_event; Ref<InputEventMouseMotion> m = p_event; @@ -1318,9 +1327,9 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { // Filters the selection with nodes that allow setting the pivot drag_selection = List<CanvasItem *>(); - for (CanvasItem *canvas_item : selection) { - if (canvas_item->_edit_use_pivot()) { - drag_selection.push_back(canvas_item); + for (CanvasItem *ci : selection) { + if (ci->_edit_use_pivot()) { + drag_selection.push_back(ci); } } @@ -1334,8 +1343,8 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { } else { new_pos = snap_point(drag_from, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, nullptr, drag_selection); } - for (CanvasItem *canvas_item : drag_selection) { - canvas_item->_edit_set_pivot(canvas_item->get_global_transform_with_canvas().affine_inverse().xform(new_pos)); + for (CanvasItem *ci : drag_selection) { + ci->_edit_set_pivot(ci->get_global_transform_with_canvas().affine_inverse().xform(new_pos)); } drag_type = DRAG_PIVOT; @@ -1355,8 +1364,8 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { } else { new_pos = snap_point(drag_to, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL); } - for (CanvasItem *canvas_item : drag_selection) { - canvas_item->_edit_set_pivot(canvas_item->get_global_transform_with_canvas().affine_inverse().xform(new_pos)); + for (CanvasItem *ci : drag_selection) { + ci->_edit_set_pivot(ci->get_global_transform_with_canvas().affine_inverse().xform(new_pos)); } return true; } @@ -1408,11 +1417,11 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { if (drag_selection.size() > 0) { drag_type = DRAG_ROTATE; drag_from = transform.affine_inverse().xform(b->get_position()); - CanvasItem *canvas_item = drag_selection[0]; - if (canvas_item->_edit_use_pivot()) { - drag_rotation_center = canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_pivot()); + CanvasItem *ci = drag_selection[0]; + if (ci->_edit_use_pivot()) { + drag_rotation_center = ci->get_global_transform_with_canvas().xform(ci->_edit_get_pivot()); } else { - drag_rotation_center = canvas_item->get_global_transform_with_canvas().get_origin(); + drag_rotation_center = ci->get_global_transform_with_canvas().get_origin(); } _save_canvas_item_state(drag_selection); return true; @@ -1425,11 +1434,11 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { // Rotate the node if (m.is_valid()) { _restore_canvas_item_state(drag_selection); - for (CanvasItem *canvas_item : drag_selection) { + for (CanvasItem *ci : drag_selection) { drag_to = transform.affine_inverse().xform(m->get_position()); //Rotate the opposite way if the canvas item's compounded scale has an uneven number of negative elements - bool opposite = (canvas_item->get_global_transform().get_scale().sign().dot(canvas_item->get_transform().get_scale().sign()) == 0); - canvas_item->_edit_set_rotation(snap_angle(canvas_item->_edit_get_rotation() + (opposite ? -1 : 1) * (drag_from - drag_rotation_center).angle_to(drag_to - drag_rotation_center), canvas_item->_edit_get_rotation())); + bool opposite = (ci->get_global_transform().get_scale().sign().dot(ci->get_transform().get_scale().sign()) == 0); + ci->_edit_set_rotation(snap_angle(ci->_edit_get_rotation() + (opposite ? -1 : 1) * (drag_from - drag_rotation_center).angle_to(drag_to - drag_rotation_center), ci->_edit_get_rotation())); viewport->queue_redraw(); } return true; @@ -1477,9 +1486,9 @@ bool CanvasItemEditor::_gui_input_open_scene_on_double_click(const Ref<InputEven if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() && b->is_double_click() && tool == TOOL_SELECT) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { - CanvasItem *canvas_item = selection[0]; - if (!canvas_item->get_scene_file_path().is_empty() && canvas_item != EditorNode::get_singleton()->get_edited_scene()) { - EditorNode::get_singleton()->open_request(canvas_item->get_scene_file_path()); + CanvasItem *ci = selection[0]; + if (!ci->get_scene_file_path().is_empty() && ci != EditorNode::get_singleton()->get_edited_scene()) { + EditorNode::get_singleton()->open_request(ci->get_scene_file_path()); return true; } } @@ -1641,10 +1650,10 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() && tool == TOOL_SELECT) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { - CanvasItem *canvas_item = selection[0]; - if (canvas_item->_edit_use_rect() && _is_node_movable(canvas_item)) { - Rect2 rect = canvas_item->_edit_get_rect(); - Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); + CanvasItem *ci = selection[0]; + if (ci->_edit_use_rect() && _is_node_movable(ci)) { + Rect2 rect = ci->_edit_get_rect(); + Transform2D xform = transform * ci->get_global_transform_with_canvas(); const Vector2 endpoints[4] = { xform.xform(rect.position), @@ -1689,7 +1698,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { drag_type = resize_drag; drag_from = transform.affine_inverse().xform(b->get_position()); drag_selection = List<CanvasItem *>(); - drag_selection.push_back(canvas_item); + drag_selection.push_back(ci); _save_canvas_item_state(drag_selection); return true; } @@ -1702,40 +1711,34 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { drag_type == DRAG_TOP_LEFT || drag_type == DRAG_TOP_RIGHT || drag_type == DRAG_BOTTOM_LEFT || drag_type == DRAG_BOTTOM_RIGHT) { // Resize the node if (m.is_valid()) { - CanvasItem *canvas_item = drag_selection[0]; - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + CanvasItem *ci = drag_selection[0]; + CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci); //Reset state - canvas_item->_edit_set_state(se->undo_state); + ci->_edit_set_state(se->undo_state); bool uniform = m->is_shift_pressed(); bool symmetric = m->is_alt_pressed(); - Rect2 local_rect = canvas_item->_edit_get_rect(); + Rect2 local_rect = ci->_edit_get_rect(); real_t aspect = local_rect.get_size().y / local_rect.get_size().x; Point2 current_begin = local_rect.get_position(); Point2 current_end = local_rect.get_position() + local_rect.get_size(); - Point2 max_begin = (symmetric) ? (current_begin + current_end - canvas_item->_edit_get_minimum_size()) / 2.0 : current_end - canvas_item->_edit_get_minimum_size(); - Point2 min_end = (symmetric) ? (current_begin + current_end + canvas_item->_edit_get_minimum_size()) / 2.0 : current_begin + canvas_item->_edit_get_minimum_size(); + Point2 max_begin = (symmetric) ? (current_begin + current_end - ci->_edit_get_minimum_size()) / 2.0 : current_end - ci->_edit_get_minimum_size(); + Point2 min_end = (symmetric) ? (current_begin + current_end + ci->_edit_get_minimum_size()) / 2.0 : current_begin + ci->_edit_get_minimum_size(); Point2 center = (current_begin + current_end) / 2.0; drag_to = transform.affine_inverse().xform(m->get_position()); - Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse(); + Transform2D xform = ci->get_global_transform_with_canvas(); Point2 drag_to_snapped_begin; Point2 drag_to_snapped_end; - // last call decides which snapping lines are drawn - if (drag_type == DRAG_LEFT || drag_type == DRAG_TOP || drag_type == DRAG_TOP_LEFT) { - drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); - drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); - } else { - drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); - drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); - } + drag_to_snapped_end = snap_point(xform.xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, ci); + drag_to_snapped_begin = snap_point(xform.xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, ci); - Point2 drag_begin = xform.xform(drag_to_snapped_begin); - Point2 drag_end = xform.xform(drag_to_snapped_end); + Point2 drag_begin = xform.affine_inverse().xform(drag_to_snapped_begin); + Point2 drag_end = xform.affine_inverse().xform(drag_to_snapped_end); // Horizontal resize if (drag_type == DRAG_LEFT || drag_type == DRAG_TOP_LEFT || drag_type == DRAG_BOTTOM_LEFT) { @@ -1787,7 +1790,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { current_begin.y = 2.0 * center.y - current_end.y; } } - canvas_item->_edit_set_rect(Rect2(current_begin, current_end - current_begin)); + ci->_edit_set_rect(Rect2(current_begin, current_end - current_begin)); return true; } @@ -1850,11 +1853,11 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() && ((b->is_alt_pressed() && b->is_ctrl_pressed()) || tool == TOOL_SCALE)) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { - CanvasItem *canvas_item = selection[0]; + CanvasItem *ci = selection[0]; - if (_is_node_movable(canvas_item)) { - Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); - Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); + if (_is_node_movable(ci)) { + Transform2D xform = transform * ci->get_global_transform_with_canvas(); + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; drag_type = DRAG_SCALE_BOTH; @@ -1873,7 +1876,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { drag_from = transform.affine_inverse().xform(b->get_position()); drag_selection = List<CanvasItem *>(); - drag_selection.push_back(canvas_item); + drag_selection.push_back(ci); _save_canvas_item_state(drag_selection); return true; } @@ -1885,12 +1888,12 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { // Resize the node if (m.is_valid()) { _restore_canvas_item_state(drag_selection); - CanvasItem *canvas_item = drag_selection[0]; + CanvasItem *ci = drag_selection[0]; drag_to = transform.affine_inverse().xform(m->get_position()); - Transform2D parent_xform = canvas_item->get_global_transform_with_canvas() * canvas_item->get_transform().affine_inverse(); - Transform2D unscaled_transform = (transform * parent_xform * canvas_item->_edit_get_transform()).orthonormalized(); + Transform2D parent_xform = ci->get_global_transform_with_canvas() * ci->get_transform().affine_inverse(); + Transform2D unscaled_transform = (transform * parent_xform * ci->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform; bool uniform = m->is_shift_pressed(); @@ -1900,7 +1903,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { Point2 drag_to_local = simple_xform.xform(drag_to); Point2 offset = drag_to_local - drag_from_local; - Size2 scale = canvas_item->_edit_get_scale(); + Size2 scale = ci->_edit_get_scale(); Size2 original_scale = scale; real_t ratio = scale.y / scale.x; if (drag_type == DRAG_SCALE_BOTH) { @@ -1938,7 +1941,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { } } - canvas_item->_edit_set_scale(scale); + ci->_edit_set_scale(scale); return true; } @@ -1999,9 +2002,9 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (selection.size() > 0) { drag_type = DRAG_MOVE; - CanvasItem *canvas_item = selection[0]; - Transform2D parent_xform = canvas_item->get_global_transform_with_canvas() * canvas_item->get_transform().affine_inverse(); - Transform2D unscaled_transform = (transform * parent_xform * canvas_item->_edit_get_transform()).orthonormalized(); + CanvasItem *ci = selection[0]; + Transform2D parent_xform = ci->get_global_transform_with_canvas() * ci->get_transform().affine_inverse(); + Transform2D unscaled_transform = (transform * parent_xform * ci->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; if (show_transformation_gizmos) { @@ -2057,12 +2060,9 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } } - int index = 0; - for (CanvasItem *canvas_item : drag_selection) { - Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); - - canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); - index++; + for (CanvasItem *ci : drag_selection) { + Transform2D xform = ci->get_global_transform_with_canvas().affine_inverse() * ci->get_transform(); + ci->_edit_set_position(ci->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); } return true; } @@ -2180,12 +2180,9 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { new_pos = previous_pos + (drag_to - drag_from); } - int index = 0; - for (CanvasItem *canvas_item : drag_selection) { - Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); - - canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); - index++; + for (CanvasItem *ci : drag_selection) { + Transform2D xform = ci->get_global_transform_with_canvas().affine_inverse() * ci->get_transform(); + ci->_edit_set_position(ci->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); } } return true; @@ -2263,15 +2260,15 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { Node *node = item; while (node && node != scene->get_parent()) { - CanvasItem *canvas_item_tmp = Object::cast_to<CanvasItem>(node); - if (canvas_item_tmp && node->has_meta("_edit_group_")) { + CanvasItem *ci_tmp = Object::cast_to<CanvasItem>(node); + if (ci_tmp && node->has_meta("_edit_group_")) { locked = 2; } node = node->get_parent(); } } - String suffix = String(); + String suffix; if (locked == 1) { suffix = " (" + TTR("Locked") + ")"; } else if (locked == 2) { @@ -2325,16 +2322,16 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { } // Find the item to select - CanvasItem *canvas_item = nullptr; + CanvasItem *ci = nullptr; Vector<_SelectResult> selection = Vector<_SelectResult>(); // Retrieve the canvas items _get_canvas_items_at_pos(click, selection); if (!selection.is_empty()) { - canvas_item = selection[0].item; + ci = selection[0].item; } - if (!canvas_item) { + if (!ci) { // Start a box selection if (!b->is_shift_pressed()) { // Clear the selection if not additive @@ -2348,7 +2345,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { box_selecting_to = drag_from; return true; } else { - bool still_selected = _select_click_on_item(canvas_item, click, b->is_shift_pressed()); + bool still_selected = _select_click_on_item(ci, click, b->is_shift_pressed()); // Start dragging if (still_selected) { // Drag the node(s) if requested @@ -2488,16 +2485,16 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) { // Compute the nodes names and icon position Vector<_HoverResult> hovering_results_tmp; for (int i = 0; i < hovering_results_items.size(); i++) { - CanvasItem *canvas_item = hovering_results_items[i].item; + CanvasItem *ci = hovering_results_items[i].item; - if (canvas_item->_edit_use_rect()) { + if (ci->_edit_use_rect()) { continue; } _HoverResult hover_result; - hover_result.position = canvas_item->get_global_transform_with_canvas().get_origin(); - hover_result.icon = EditorNode::get_singleton()->get_object_icon(canvas_item); - hover_result.name = canvas_item->get_name(); + hover_result.position = ci->get_global_transform_with_canvas().get_origin(); + hover_result.icon = EditorNode::get_singleton()->get_object_icon(ci); + hover_result.name = ci->get_name(); hovering_results_tmp.push_back(hover_result); } @@ -2534,31 +2531,33 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; bool release_lmb = (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT); // Required to properly release some stuff (e.g. selection box) while panning. - if (EditorSettings::get_singleton()->get("editors/panning/simple_panning") || !pan_pressed || release_lmb) { - if ((accepted = _gui_input_rulers_and_guides(p_event))) { + if (EDITOR_GET("editors/panning/simple_panning") || !pan_pressed || release_lmb) { + accepted = true; + if (_gui_input_rulers_and_guides(p_event)) { // print_line("Rulers and guides"); - } else if ((accepted = EditorNode::get_singleton()->get_editor_plugins_over()->forward_gui_input(p_event))) { + } else if (EditorNode::get_singleton()->get_editor_plugins_over()->forward_gui_input(p_event)) { // print_line("Plugin"); - } else if ((accepted = _gui_input_open_scene_on_double_click(p_event))) { + } else if (_gui_input_open_scene_on_double_click(p_event)) { // print_line("Open scene on double click"); - } else if ((accepted = _gui_input_scale(p_event))) { + } else if (_gui_input_scale(p_event)) { // print_line("Set scale"); - } else if ((accepted = _gui_input_pivot(p_event))) { + } else if (_gui_input_pivot(p_event)) { // print_line("Set pivot"); - } else if ((accepted = _gui_input_resize(p_event))) { + } else if (_gui_input_resize(p_event)) { // print_line("Resize"); - } else if ((accepted = _gui_input_rotate(p_event))) { + } else if (_gui_input_rotate(p_event)) { // print_line("Rotate"); - } else if ((accepted = _gui_input_move(p_event))) { + } else if (_gui_input_move(p_event)) { // print_line("Move"); - } else if ((accepted = _gui_input_anchors(p_event))) { + } else if (_gui_input_anchors(p_event)) { // print_line("Anchors"); - } else if ((accepted = _gui_input_select(p_event))) { + } else if (_gui_input_select(p_event)) { // print_line("Selection"); - } else if ((accepted = _gui_input_ruler_tool(p_event))) { + } else if (_gui_input_ruler_tool(p_event)) { // print_line("Measure"); } else { // print_line("Not accepted"); + accepted = false; } } @@ -2720,7 +2719,7 @@ void CanvasItemEditor::_draw_focus() { } void CanvasItemEditor::_draw_guides() { - Color guide_color = EditorSettings::get_singleton()->get("editors/2d/guides_color"); + Color guide_color = EDITOR_GET("editors/2d/guides_color"); Transform2D xform = viewport_scrollable->get_transform() * transform; // Guides already there. @@ -2769,7 +2768,7 @@ void CanvasItemEditor::_draw_guides() { } void CanvasItemEditor::_draw_smart_snapping() { - Color line_color = EditorSettings::get_singleton()->get("editors/2d/smart_snapping_line_color"); + Color line_color = EDITOR_GET("editors/2d/smart_snapping_line_color"); if (snap_target[0] != SNAP_TARGET_NONE && snap_target[0] != SNAP_TARGET_GRID) { viewport->draw_set_transform_matrix(viewport->get_transform() * transform * snap_transform); viewport->draw_line(Point2(0, -1.0e+10F), Point2(0, 1.0e+10F), line_color); @@ -2791,7 +2790,7 @@ void CanvasItemEditor::_draw_rulers() { int font_size = get_theme_font_size(SNAME("rulers_size"), SNAME("EditorFonts")); // The rule transform - Transform2D ruler_transform = Transform2D(); + Transform2D ruler_transform; if (grid_snap_active || _is_grid_visible()) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (snap_relative && selection.size() > 0) { @@ -2817,11 +2816,11 @@ void CanvasItemEditor::_draw_rulers() { // Subdivisions int major_subdivision = 2; - Transform2D major_subdivide = Transform2D(); + Transform2D major_subdivide; major_subdivide.scale(Size2(1.0 / major_subdivision, 1.0 / major_subdivision)); int minor_subdivision = 5; - Transform2D minor_subdivide = Transform2D(); + Transform2D minor_subdivide; minor_subdivide.scale(Size2(1.0 / minor_subdivision, 1.0 / minor_subdivision)); // First and last graduations to draw (in the ruler space) @@ -2887,7 +2886,7 @@ void CanvasItemEditor::_draw_grid() { // Draw a "primary" line every several lines to make measurements easier. // The step is configurable in the Configure Snap dialog. - const Color secondary_grid_color = EditorSettings::get_singleton()->get("editors/2d/grid_color"); + const Color secondary_grid_color = EDITOR_GET("editors/2d/grid_color"); const Color primary_grid_color = Color(secondary_grid_color.r, secondary_grid_color.g, secondary_grid_color.b, secondary_grid_color.a * 2.5); @@ -3033,7 +3032,7 @@ void CanvasItemEditor::_draw_ruler_tool() { viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.y)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color); - Point2 v_angle_text_pos = Point2(); + Point2 v_angle_text_pos; v_angle_text_pos.x = CLAMP(begin.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width); v_angle_text_pos.y = begin.y < end.y ? MIN(text_pos2.y - 2 * text_height, begin.y - text_height * 0.5) : MAX(text_pos2.y + text_height * 3, begin.y + text_height * 1.5); viewport->draw_string_outline(font, v_angle_text_pos, TS->format_number(vformat(String::utf8("%d°"), vertical_angle)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); @@ -3044,7 +3043,7 @@ void CanvasItemEditor::_draw_ruler_tool() { viewport->draw_string_outline(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, outline_size, outline_color); viewport->draw_string(font, text_pos2, TS->format_number(vformat("%.1f px", length_vector.x)), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_secondary_color); - Point2 h_angle_text_pos = Point2(); + Point2 h_angle_text_pos; h_angle_text_pos.x = CLAMP(end.x - angle_text_width / 2, angle_text_width / 2, viewport->get_rect().size.x - angle_text_width); if (begin.y < end.y) { h_angle_text_pos.y = end.y + text_height * 1.5; @@ -3310,16 +3309,16 @@ void CanvasItemEditor::_draw_selection() { Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")); Ref<Texture2D> previous_position_icon = get_theme_icon(SNAME("EditorPositionPrevious"), SNAME("EditorIcons")); - RID ci = viewport->get_canvas_item(); + RID vp_ci = viewport->get_canvas_item(); List<CanvasItem *> selection = _get_edited_canvas_items(true, false); bool single = selection.size() == 1; for (CanvasItem *E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + CanvasItem *ci = Object::cast_to<CanvasItem>(E); + CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci); - bool item_locked = canvas_item->has_meta("_edit_lock_"); + bool item_locked = ci->has_meta("_edit_lock_"); // Draw the previous position if we are dragging the node if (show_helpers && @@ -3329,7 +3328,7 @@ void CanvasItemEditor::_draw_selection() { const Transform2D pre_drag_xform = transform * se->pre_drag_xform; const Color pre_drag_color = Color(0.4, 0.6, 1, 0.7); - if (canvas_item->_edit_use_rect()) { + if (ci->_edit_use_rect()) { Vector2 pre_drag_endpoints[4] = { pre_drag_xform.xform(se->pre_drag_rect.position), pre_drag_xform.xform(se->pre_drag_rect.position + Vector2(se->pre_drag_rect.size.x, 0)), @@ -3345,11 +3344,11 @@ void CanvasItemEditor::_draw_selection() { } } - Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); + Transform2D xform = transform * ci->get_global_transform_with_canvas(); // Draw the selected items position / surrounding boxes - if (canvas_item->_edit_use_rect()) { - Rect2 rect = canvas_item->_edit_get_rect(); + if (ci->_edit_use_rect()) { + Rect2 rect = ci->_edit_get_rect(); const Vector2 endpoints[4] = { xform.xform(rect.position), xform.xform(rect.position + Vector2(rect.size.x, 0)), @@ -3367,7 +3366,7 @@ void CanvasItemEditor::_draw_selection() { viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, Math::round(2 * EDSCALE)); } } else { - Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; viewport->draw_set_transform_matrix(simple_xform); viewport->draw_texture(position_icon, -(position_icon->get_size() / 2)); @@ -3376,9 +3375,9 @@ void CanvasItemEditor::_draw_selection() { if (single && !item_locked && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks // Draw the pivot - if (canvas_item->_edit_use_pivot()) { + if (ci->_edit_use_pivot()) { // Draw the node's pivot - Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; viewport->draw_set_transform_matrix(simple_xform); @@ -3387,15 +3386,15 @@ void CanvasItemEditor::_draw_selection() { } // Draw control-related helpers - Control *control = Object::cast_to<Control>(canvas_item); + Control *control = Object::cast_to<Control>(ci); if (control && _is_node_movable(control)) { _draw_control_anchors(control); _draw_control_helpers(control); } // Draw the resize handles - if (tool == TOOL_SELECT && canvas_item->_edit_use_rect() && _is_node_movable(canvas_item)) { - Rect2 rect = canvas_item->_edit_get_rect(); + if (tool == TOOL_SELECT && ci->_edit_use_rect() && _is_node_movable(ci)) { + Rect2 rect = ci->_edit_get_rect(); const Vector2 endpoints[4] = { xform.xform(rect.position), xform.xform(rect.position + Vector2(rect.size.x, 0)), @@ -3409,12 +3408,12 @@ void CanvasItemEditor::_draw_selection() { Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); ofs *= Math_SQRT2 * (select_handle->get_size().width / 2); - select_handle->draw(ci, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor()); + select_handle->draw(vp_ci, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor()); ofs = (endpoints[i] + endpoints[next]) / 2; ofs += (endpoints[next] - endpoints[i]).orthogonal().normalized() * (select_handle->get_size().width / 2); - select_handle->draw(ci, (ofs - (select_handle->get_size() / 2)).floor()); + select_handle->draw(vp_ci, (ofs - (select_handle->get_size() / 2)).floor()); } } @@ -3422,8 +3421,8 @@ void CanvasItemEditor::_draw_selection() { bool is_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL); bool is_alt = Input::get_singleton()->is_key_pressed(Key::ALT); if (tool == TOOL_MOVE && show_transformation_gizmos) { - if (_is_node_movable(canvas_item)) { - Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); + if (_is_node_movable(ci)) { + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE); @@ -3452,8 +3451,8 @@ void CanvasItemEditor::_draw_selection() { // Draw the rescale handles if (show_transformation_gizmos && ((is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y)) { - if (_is_node_movable(canvas_item)) { - Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); + if (_is_node_movable(ci)) { + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); @@ -3563,9 +3562,9 @@ void CanvasItemEditor::_draw_axis() { if (show_viewport) { RID ci = viewport->get_canvas_item(); - Color area_axis_color = EditorSettings::get_singleton()->get("editors/2d/viewport_border_color"); + Color area_axis_color = EDITOR_GET("editors/2d/viewport_border_color"); - Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); + Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height")); Vector2 screen_endpoints[4] = { transform.xform(Vector2(0, 0)), @@ -3587,16 +3586,16 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) { return; } - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); - if (canvas_item && !canvas_item->is_visible_in_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); + if (ci && !ci->is_visible_in_tree()) { return; } Transform2D parent_xform = p_parent_xform; Transform2D canvas_xform = p_canvas_xform; - if (canvas_item && !canvas_item->is_set_as_top_level()) { - parent_xform = parent_xform * canvas_item->get_transform(); + if (ci && !ci->is_set_as_top_level()) { + parent_xform = parent_xform * ci->get_transform(); } else { CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); parent_xform = Transform2D(); @@ -3607,12 +3606,12 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans _draw_invisible_nodes_positions(p_node->get_child(i), parent_xform, canvas_xform); } - if (canvas_item && !canvas_item->_edit_use_rect() && (!editor_selection->is_selected(canvas_item) || _is_node_locked(canvas_item))) { + if (ci && !ci->_edit_use_rect() && (!editor_selection->is_selected(ci) || _is_node_locked(ci))) { Transform2D xform = transform * canvas_xform * parent_xform; // Draw the node's position Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPositionUnselected"), SNAME("EditorIcons")); - Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = viewport->get_transform() * unscaled_transform; viewport->draw_set_transform_matrix(simple_xform); viewport->draw_texture(position_icon, -position_icon->get_size() / 2, Color(1.0, 1.0, 1.0, 0.5)); @@ -3718,16 +3717,16 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) { return; } - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); - if (canvas_item && !canvas_item->is_visible_in_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); + if (ci && !ci->is_visible_in_tree()) { return; } Transform2D parent_xform = p_parent_xform; Transform2D canvas_xform = p_canvas_xform; - if (canvas_item && !canvas_item->is_set_as_top_level()) { - parent_xform = parent_xform * canvas_item->get_transform(); + if (ci && !ci->is_set_as_top_level()) { + parent_xform = parent_xform * ci->get_transform(); } else { CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); parent_xform = Transform2D(); @@ -3738,19 +3737,19 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p _draw_locks_and_groups(p_node->get_child(i), parent_xform, canvas_xform); } - RID viewport_canvas_item = viewport->get_canvas_item(); - if (canvas_item) { + RID viewport_ci = viewport->get_canvas_item(); + if (ci) { real_t offset = 0; Ref<Texture2D> lock = get_theme_icon(SNAME("LockViewport"), SNAME("EditorIcons")); if (p_node->has_meta("_edit_lock_") && show_edit_locks) { - lock->draw(viewport_canvas_item, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0)); + lock->draw(viewport_ci, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0)); offset += lock->get_size().x; } Ref<Texture2D> group = get_theme_icon(SNAME("GroupViewport"), SNAME("EditorIcons")); - if (canvas_item->has_meta("_edit_group_") && show_edit_locks) { - group->draw(viewport_canvas_item, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0)); + if (ci->has_meta("_edit_group_") && show_edit_locks) { + group->draw(viewport_ci, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0)); //offset += group->get_size().x; } } @@ -3869,9 +3868,9 @@ void CanvasItemEditor::_update_editor_settings() { context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles"))); - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); - pan_speed = int(EditorSettings::get_singleton()->get("editors/panning/2d_editor_pan_speed")); - warped_panning = bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning")); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); + pan_speed = int(EDITOR_GET("editors/panning/2d_editor_pan_speed")); + warped_panning = bool(EDITOR_GET("editors/panning/warped_mouse_panning")); } void CanvasItemEditor::_notification(int p_what) { @@ -3883,16 +3882,16 @@ void CanvasItemEditor::_notification(int p_what) { // Update the viewport if the canvas_item changes List<CanvasItem *> selection = _get_edited_canvas_items(true); - for (CanvasItem *canvas_item : selection) { - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + for (CanvasItem *ci : selection) { + CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci); Rect2 rect; - if (canvas_item->_edit_use_rect()) { - rect = canvas_item->_edit_get_rect(); + if (ci->_edit_use_rect()) { + rect = ci->_edit_get_rect(); } else { rect = Rect2(); } - Transform2D xform = canvas_item->get_transform(); + Transform2D xform = ci->get_transform(); if (rect != se->prev_rect || xform != se->prev_xform) { viewport->queue_redraw(); @@ -3900,7 +3899,7 @@ void CanvasItemEditor::_notification(int p_what) { se->prev_xform = xform; } - Control *control = Object::cast_to<Control>(canvas_item); + Control *control = Object::cast_to<Control>(ci); if (control) { real_t anchors[4]; Vector2 pivot; @@ -3921,7 +3920,7 @@ void CanvasItemEditor::_notification(int p_what) { } } - if (canvas_item->_edit_use_pivot()) { + if (ci->_edit_use_pivot()) { nb_having_pivot++; } } @@ -3990,10 +3989,6 @@ void CanvasItemEditor::_selection_changed() { selected_from_canvas = false; } -void CanvasItemEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void CanvasItemEditor::edit(CanvasItem *p_canvas_item) { Array selection = editor_selection->get_selected_nodes(); if (selection.size() != 1 || Object::cast_to<Node>(selection[0]) != p_canvas_item) { @@ -4017,7 +4012,7 @@ void CanvasItemEditor::_update_scrollbars() { Size2 vmin = v_scroll->get_minimum_size(); // Get the visible frame. - Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); + Size2 screen_rect = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height")); Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height)); // Calculate scrollable area. @@ -4034,7 +4029,7 @@ void CanvasItemEditor::_update_scrollbars() { Size2 size = viewport->get_size(); Point2 begin = canvas_item_rect.position; Point2 end = canvas_item_rect.position + canvas_item_rect.size - local_rect.size / zoom; - bool constrain_editor_view = bool(EditorSettings::get_singleton()->get("editors/2d/constrain_editor_view")); + bool constrain_editor_view = bool(EDITOR_GET("editors/2d/constrain_editor_view")); if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) { real_t centered = -(size.y / 2) / zoom + screen_rect.y / 2; @@ -4182,17 +4177,17 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, AnimationTrackEditor *te = AnimationPlayerEditor::get_singleton()->get_track_editor(); te->make_insert_queue(); for (const KeyValue<Node *, Object *> &E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); - if (!canvas_item || !canvas_item->is_visible_in_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(E.key); + if (!ci || !ci->is_visible_in_tree()) { continue; } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { + if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { continue; } - if (Object::cast_to<Node2D>(canvas_item)) { - Node2D *n2d = Object::cast_to<Node2D>(canvas_item); + if (Object::cast_to<Node2D>(ci)) { + Node2D *n2d = Object::cast_to<Node2D>(ci); if (key_pos && p_location) { te->insert_node_value_key(n2d, "position", n2d->get_position(), p_on_existing); @@ -4239,8 +4234,8 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, } } - } else if (Object::cast_to<Control>(canvas_item)) { - Control *ctrl = Object::cast_to<Control>(canvas_item); + } else if (Object::cast_to<Control>(ci)) { + Control *ctrl = Object::cast_to<Control>(ci); if (key_pos) { te->insert_node_value_key(ctrl, "position", ctrl->get_position(), p_on_existing); @@ -4268,6 +4263,7 @@ void CanvasItemEditor::_update_override_camera_button(bool p_game_running) { } void CanvasItemEditor::_popup_callback(int p_op) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); last_option = MenuOption(p_op); switch (p_op) { case SHOW_ORIGIN: { @@ -4388,16 +4384,16 @@ void CanvasItemEditor::_popup_callback(int p_op) { List<Node *> selection = editor_selection->get_selected_node_list(); for (Node *E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); - if (!canvas_item || !canvas_item->is_inside_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(E); + if (!ci || !ci->is_inside_tree()) { continue; } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { + if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { continue; } - undo_redo->add_do_method(canvas_item, "set_meta", "_edit_lock_", true); - undo_redo->add_undo_method(canvas_item, "remove_meta", "_edit_lock_"); + undo_redo->add_do_method(ci, "set_meta", "_edit_lock_", true); + undo_redo->add_undo_method(ci, "remove_meta", "_edit_lock_"); undo_redo->add_do_method(this, "emit_signal", "item_lock_status_changed"); undo_redo->add_undo_method(this, "emit_signal", "item_lock_status_changed"); } @@ -4410,16 +4406,16 @@ void CanvasItemEditor::_popup_callback(int p_op) { List<Node *> selection = editor_selection->get_selected_node_list(); for (Node *E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); - if (!canvas_item || !canvas_item->is_inside_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(E); + if (!ci || !ci->is_inside_tree()) { continue; } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { + if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { continue; } - undo_redo->add_do_method(canvas_item, "remove_meta", "_edit_lock_"); - undo_redo->add_undo_method(canvas_item, "set_meta", "_edit_lock_", true); + undo_redo->add_do_method(ci, "remove_meta", "_edit_lock_"); + undo_redo->add_undo_method(ci, "set_meta", "_edit_lock_", true); undo_redo->add_do_method(this, "emit_signal", "item_lock_status_changed"); undo_redo->add_undo_method(this, "emit_signal", "item_lock_status_changed"); } @@ -4432,16 +4428,16 @@ void CanvasItemEditor::_popup_callback(int p_op) { List<Node *> selection = editor_selection->get_selected_node_list(); for (Node *E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); - if (!canvas_item || !canvas_item->is_inside_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(E); + if (!ci || !ci->is_inside_tree()) { continue; } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { + if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { continue; } - undo_redo->add_do_method(canvas_item, "set_meta", "_edit_group_", true); - undo_redo->add_undo_method(canvas_item, "remove_meta", "_edit_group_"); + undo_redo->add_do_method(ci, "set_meta", "_edit_group_", true); + undo_redo->add_undo_method(ci, "remove_meta", "_edit_group_"); undo_redo->add_do_method(this, "emit_signal", "item_group_status_changed"); undo_redo->add_undo_method(this, "emit_signal", "item_group_status_changed"); } @@ -4454,16 +4450,16 @@ void CanvasItemEditor::_popup_callback(int p_op) { List<Node *> selection = editor_selection->get_selected_node_list(); for (Node *E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E); - if (!canvas_item || !canvas_item->is_inside_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(E); + if (!ci || !ci->is_inside_tree()) { continue; } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { + if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { continue; } - undo_redo->add_do_method(canvas_item, "remove_meta", "_edit_group_"); - undo_redo->add_undo_method(canvas_item, "set_meta", "_edit_group_", true); + undo_redo->add_do_method(ci, "remove_meta", "_edit_group_"); + undo_redo->add_undo_method(ci, "set_meta", "_edit_group_", true); undo_redo->add_do_method(this, "emit_signal", "item_group_status_changed"); undo_redo->add_undo_method(this, "emit_signal", "item_group_status_changed"); } @@ -4494,17 +4490,17 @@ void CanvasItemEditor::_popup_callback(int p_op) { const HashMap<Node *, Object *> &selection = editor_selection->get_selection(); for (const KeyValue<Node *, Object *> &E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); - if (!canvas_item || !canvas_item->is_visible_in_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(E.key); + if (!ci || !ci->is_visible_in_tree()) { continue; } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { + if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { continue; } - if (Object::cast_to<Node2D>(canvas_item)) { - Node2D *n2d = Object::cast_to<Node2D>(canvas_item); + if (Object::cast_to<Node2D>(ci)) { + Node2D *n2d = Object::cast_to<Node2D>(ci); PoseClipboard pc; pc.pos = n2d->get_position(); pc.rot = n2d->get_rotation(); @@ -4540,17 +4536,17 @@ void CanvasItemEditor::_popup_callback(int p_op) { HashMap<Node *, Object *> &selection = editor_selection->get_selection(); for (const KeyValue<Node *, Object *> &E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); - if (!canvas_item || !canvas_item->is_visible_in_tree()) { + CanvasItem *ci = Object::cast_to<CanvasItem>(E.key); + if (!ci || !ci->is_visible_in_tree()) { continue; } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { + if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { continue; } - if (Object::cast_to<Node2D>(canvas_item)) { - Node2D *n2d = Object::cast_to<Node2D>(canvas_item); + if (Object::cast_to<Node2D>(ci)) { + Node2D *n2d = Object::cast_to<Node2D>(ci); if (key_pos) { n2d->set_position(Vector2()); @@ -4561,8 +4557,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { if (key_scale) { n2d->set_scale(Vector2(1, 1)); } - } else if (Object::cast_to<Control>(canvas_item)) { - Control *ctrl = Object::cast_to<Control>(canvas_item); + } else if (Object::cast_to<Control>(ci)) { + Control *ctrl = Object::cast_to<Control>(ci); if (key_pos) { ctrl->set_position(Point2()); @@ -4656,28 +4652,28 @@ void CanvasItemEditor::_focus_selection(int p_op) { const HashMap<Node *, Object *> &selection = editor_selection->get_selection(); for (const KeyValue<Node *, Object *> &E : selection) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); - if (!canvas_item) { + CanvasItem *ci = Object::cast_to<CanvasItem>(E.key); + if (!ci) { continue; } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { + if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { continue; } // counting invisible items, for now - //if (!canvas_item->is_visible_in_tree()) continue; + //if (!ci->is_visible_in_tree()) continue; ++count; Rect2 item_rect; - if (canvas_item->_edit_use_rect()) { - item_rect = canvas_item->_edit_get_rect(); + if (ci->_edit_use_rect()) { + item_rect = ci->_edit_get_rect(); } else { item_rect = Rect2(); } - Vector2 pos = canvas_item->get_global_transform().get_origin(); - Vector2 scale = canvas_item->get_global_transform().get_scale(); - real_t angle = canvas_item->get_global_transform().get_rotation(); + Vector2 pos = ci->get_global_transform().get_origin(); + Vector2 scale = ci->get_global_transform().get_scale(); + real_t angle = ci->get_global_transform().get_rotation(); Transform2D t(angle, Vector2(0.f, 0.f)); item_rect = t.xform(item_rect); @@ -4715,12 +4711,10 @@ void CanvasItemEditor::_reset_drag() { } void CanvasItemEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_update_override_camera_button", "game_running"), &CanvasItemEditor::_update_override_camera_button); ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data); ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state); ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport); - ClassDB::bind_method(D_METHOD("_zoom_on_position"), &CanvasItemEditor::_zoom_on_position); ClassDB::bind_method("_set_owner_for_node_and_children", &CanvasItemEditor::_set_owner_for_node_and_children); @@ -4975,7 +4969,6 @@ CanvasItemEditor::CanvasItemEditor() { snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; - undo_redo = EditorNode::get_singleton()->get_undo_redo(); editor_selection = EditorNode::get_singleton()->get_editor_selection(); editor_selection->add_editor_plugin(this); editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); @@ -4984,8 +4977,8 @@ CanvasItemEditor::CanvasItemEditor() { SceneTreeDock::get_singleton()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); SceneTreeDock::get_singleton()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position)); - EditorNode::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", Callable(this, "_update_override_camera_button").bind(true)); - EditorNode::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", Callable(this, "_update_override_camera_button").bind(false)); + EditorNode::get_singleton()->call_deferred(SNAME("connect"), callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(true)); + EditorNode::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(false)); // A fluid container for all toolbars. HFlowContainer *main_flow = memnew(HFlowContainer); @@ -5060,6 +5053,7 @@ CanvasItemEditor::CanvasItemEditor() { zoom_widget = memnew(EditorZoomWidget); controls_vb->add_child(zoom_widget); zoom_widget->set_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE); + zoom_widget->set_shortcut_context(this); zoom_widget->connect("zoom_changed", callable_mp(this, &CanvasItemEditor::_update_zoom)); panner.instantiate(); @@ -5316,7 +5310,7 @@ CanvasItemEditor::CanvasItemEditor() { p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KeyModifierMask::SHIFT | Key::F), VIEW_FRAME_TO_SELECTION); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/clear_guides", TTR("Clear Guides")), CLEAR_GUIDES); p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KeyModifierMask::SHIFT | KeyModifierMask::CMD_OR_CTRL | Key::P), PREVIEW_CANVAS_SCALE); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale")), PREVIEW_CANVAS_SCALE); main_menu_hbox->add_child(memnew(VSeparator)); @@ -5425,7 +5419,6 @@ CanvasItemEditor::CanvasItemEditor() { CanvasItemEditor *CanvasItemEditor::singleton = nullptr; void CanvasItemEditorPlugin::edit(Object *p_object) { - canvas_item_editor->set_undo_redo(EditorNode::get_undo_redo()); canvas_item_editor->edit(Object::cast_to<CanvasItem>(p_object)); } @@ -5454,6 +5447,15 @@ void CanvasItemEditorPlugin::set_state(const Dictionary &p_state) { canvas_item_editor->set_state(p_state); } +void CanvasItemEditorPlugin::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + connect("scene_changed", callable_mp((CanvasItem *)canvas_item_editor->get_viewport_control(), &CanvasItem::queue_redraw).unbind(1)); + connect("scene_closed", callable_mp((CanvasItem *)canvas_item_editor->get_viewport_control(), &CanvasItem::queue_redraw).unbind(1)); + } break; + } +} + CanvasItemEditorPlugin::CanvasItemEditorPlugin() { canvas_item_editor = memnew(CanvasItemEditor); canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -5533,7 +5535,7 @@ void CanvasItemEditorViewport::_remove_preview() { if (preview_node->get_parent()) { for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { Node *node = preview_node->get_child(i); - node->queue_delete(); + node->queue_free(); preview_node->remove_child(node); } EditorNode::get_singleton()->get_scene_root()->remove_child(preview_node); @@ -5563,37 +5565,38 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & String name = path.get_file().get_basename(); child->set_name(Node::adjust_name_casing(name)); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); Ref<Texture2D> texture = ResourceCache::get_ref(path); if (parent) { - editor_data->get_undo_redo()->add_do_method(parent, "add_child", child, true); - editor_data->get_undo_redo()->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene()); - editor_data->get_undo_redo()->add_do_reference(child); - editor_data->get_undo_redo()->add_undo_method(parent, "remove_child", child); + undo_redo->add_do_method(parent, "add_child", child, true); + undo_redo->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene()); + undo_redo->add_do_reference(child); + undo_redo->add_undo_method(parent, "remove_child", child); } else { // If no parent is selected, set as root node of the scene. - editor_data->get_undo_redo()->add_do_method(EditorNode::get_singleton(), "set_edited_scene", child); - editor_data->get_undo_redo()->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene()); - editor_data->get_undo_redo()->add_do_reference(child); - editor_data->get_undo_redo()->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr); + undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", child); + undo_redo->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene()); + undo_redo->add_do_reference(child); + undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr); } if (parent) { String new_name = parent->validate_child_name(child); EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); - editor_data->get_undo_redo()->add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), child->get_class(), new_name); - editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); + undo_redo->add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), child->get_class(), new_name); + undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); } if (Object::cast_to<TouchScreenButton>(child) || Object::cast_to<TextureButton>(child)) { - editor_data->get_undo_redo()->add_do_property(child, "texture_normal", texture); + undo_redo->add_do_property(child, "texture_normal", texture); } else { - editor_data->get_undo_redo()->add_do_property(child, "texture", texture); + undo_redo->add_do_property(child, "texture", texture); } // make visible for certain node type if (Object::cast_to<Control>(child)) { Size2 texture_size = texture->get_size(); - editor_data->get_undo_redo()->add_do_property(child, "rect_size", texture_size); + undo_redo->add_do_property(child, "rect_size", texture_size); } else if (Object::cast_to<Polygon2D>(child)) { Size2 texture_size = texture->get_size(); Vector<Vector2> list = { @@ -5602,7 +5605,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & Vector2(texture_size.width, texture_size.height), Vector2(0, texture_size.height) }; - editor_data->get_undo_redo()->add_do_property(child, "polygon", list); + undo_redo->add_do_property(child, "polygon", list); } // Compute the global position @@ -5611,7 +5614,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & // there's nothing to be used as source position so snapping will work as absolute if enabled target_position = canvas_item_editor->snap_point(target_position); - editor_data->get_undo_redo()->add_do_method(child, "set_global_position", target_position); + undo_redo->add_do_method(child, "set_global_position", target_position); } bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) { @@ -5621,13 +5624,13 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons } Node *instantiated_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); - if (!instantiated_scene) { // error on instancing + if (!instantiated_scene) { // Error on instantiation. return false; } Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); - if (!edited_scene->get_scene_file_path().is_empty()) { // cyclical instancing + if (!edited_scene->get_scene_file_path().is_empty()) { // Cyclic instantiation. if (_cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) { memdelete(instantiated_scene); return false; @@ -5636,15 +5639,16 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path)); - editor_data->get_undo_redo()->add_do_method(parent, "add_child", instantiated_scene, true); - editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_owner", edited_scene); - editor_data->get_undo_redo()->add_do_reference(instantiated_scene); - editor_data->get_undo_redo()->add_undo_method(parent, "remove_child", instantiated_scene); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->add_do_method(parent, "add_child", instantiated_scene, true); + undo_redo->add_do_method(instantiated_scene, "set_owner", edited_scene); + undo_redo->add_do_reference(instantiated_scene); + undo_redo->add_undo_method(parent, "remove_child", instantiated_scene); String new_name = parent->validate_child_name(instantiated_scene); EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); - editor_data->get_undo_redo()->add_do_method(ed, "live_debug_instance_node", edited_scene->get_path_to(parent), path, new_name); - editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + new_name)); + undo_redo->add_do_method(ed, "live_debug_instantiate_node", edited_scene->get_path_to(parent), path, new_name); + undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + new_name)); CanvasItem *instance_ci = Object::cast_to<CanvasItem>(instantiated_scene); if (instance_ci) { @@ -5658,7 +5662,7 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons // Preserve instance position of the original scene. target_pos += instance_ci->_edit_get_position(); - editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_position", target_pos); + undo_redo->add_do_method(instantiated_scene, "set_position", target_pos); } return true; @@ -5676,7 +5680,8 @@ void CanvasItemEditorViewport::_perform_drop_data() { Vector<String> error_files; - editor_data->get_undo_redo()->create_action(TTR("Create Node")); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Create Node")); for (int i = 0; i < selected_files.size(); i++) { String path = selected_files[i]; @@ -5707,7 +5712,7 @@ void CanvasItemEditorViewport::_perform_drop_data() { } } - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); if (error_files.size() > 0) { String files_str; @@ -5715,7 +5720,7 @@ void CanvasItemEditorViewport::_perform_drop_data() { files_str += error_files[i].get_file().get_basename() + ","; } files_str = files_str.substr(0, files_str.length() - 1); - accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.get_data())); + accept->set_text(vformat(TTR("Error instantiating scene from %s"), files_str.get_data())); accept->popup_centered(); } } @@ -5733,8 +5738,10 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian ResourceLoader::get_recognized_extensions_for_type("Texture2D", &texture_extensions); for (int i = 0; i < files.size(); i++) { + String extension = files[i].get_extension().to_lower(); + // Check if dragged files with texture or scene extension can be created at least once. - if (texture_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { + if (texture_extensions.find(extension) || scene_extensions.find(extension)) { Ref<Resource> res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; @@ -5883,9 +5890,6 @@ void CanvasItemEditorViewport::_notification(int p_what) { } } -void CanvasItemEditorViewport::_bind_methods() { -} - CanvasItemEditorViewport::CanvasItemEditorViewport(CanvasItemEditor *p_canvas_item_editor) { default_texture_node_type = "Sprite2D"; // Node2D @@ -5901,7 +5905,6 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(CanvasItemEditor *p_canvas_it texture_node_types.push_back("NinePatchRect"); target_node = nullptr; - editor_data = SceneTreeDock::get_singleton()->get_editor_data(); canvas_item_editor = p_canvas_item_editor; preview_node = memnew(Control); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 0a840d6fd6..9c7d0fbe6f 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -32,20 +32,21 @@ #define CANVAS_ITEM_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "editor/editor_zoom_widget.h" +#include "scene/gui/base_button.h" #include "scene/gui/box_container.h" -#include "scene/gui/check_box.h" -#include "scene/gui/label.h" -#include "scene/gui/panel_container.h" -#include "scene/gui/spin_box.h" -#include "scene/gui/split_container.h" -#include "scene/gui/texture_rect.h" -#include "scene/main/canvas_item.h" -class EditorData; +class AcceptDialog; class CanvasItemEditorViewport; +class ConfirmationDialog; +class EditorData; +class EditorZoomWidget; +class HScrollBar; +class HSplitContainer; +class MenuButton; +class PanelContainer; class ViewPanner; -class EditorUndoRedoManager; +class VScrollBar; +class VSplitContainer; class CanvasItemEditorSelectedItem : public Object { GDCLASS(CanvasItemEditorSelectedItem, Object); @@ -337,12 +338,12 @@ private: Point2 drag_start_origin; DragType drag_type = DRAG_NONE; - Point2 drag_from = Vector2(); - Point2 drag_to = Vector2(); + Point2 drag_from; + Point2 drag_to; Point2 drag_rotation_center; List<CanvasItem *> drag_selection; int dragged_guide_index = -1; - Point2 dragged_guide_pos = Point2(); + Point2 dragged_guide_pos; bool is_hovering_h_guide = false; bool is_hovering_v_guide = false; @@ -401,8 +402,6 @@ private: void _prepare_grid_menu(); void _on_grid_menu_id_pressed(int p_id); - Ref<EditorUndoRedoManager> undo_redo; - List<CanvasItem *> _get_edited_canvas_items(bool retrieve_locked = false, bool remove_canvas_item_if_parent_in_selection = true); Rect2 _get_encompassing_rect_from_list(List<CanvasItem *> p_list); void _expand_encompassing_rect_using_children(Rect2 &r_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D(), bool include_locked_nodes = true); @@ -548,7 +547,6 @@ public: Tool get_current_tool() { return tool; } void set_current_tool(Tool p_tool); - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); void edit(CanvasItem *p_canvas_item); void focus_selection(); @@ -563,6 +561,9 @@ class CanvasItemEditorPlugin : public EditorPlugin { CanvasItemEditor *canvas_item_editor = nullptr; +protected: + void _notification(int p_what); + public: virtual String get_name() const override { return "2D"; } bool has_main_screen() const override { return true; } @@ -590,7 +591,6 @@ class CanvasItemEditorViewport : public Control { Node *target_node = nullptr; Point2 drop_pos; - EditorData *editor_data = nullptr; CanvasItemEditor *canvas_item_editor = nullptr; Control *preview_node = nullptr; AcceptDialog *accept = nullptr; @@ -618,8 +618,6 @@ class CanvasItemEditorViewport : public Control { void _show_resource_type_selector(); void _update_theme(); - static void _bind_methods(); - protected: void _notification(int p_what); diff --git a/editor/plugins/cast_2d_editor_plugin.cpp b/editor/plugins/cast_2d_editor_plugin.cpp index a8d255f997..d991cdf27f 100644 --- a/editor/plugins/cast_2d_editor_plugin.cpp +++ b/editor/plugins/cast_2d_editor_plugin.cpp @@ -77,6 +77,7 @@ bool Cast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return false; } } else if (pressed) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set target_position")); undo_redo->add_do_property(node, "target_position", target_position); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); @@ -130,10 +131,6 @@ void Cast2DEditor::edit(Node2D *p_node) { canvas_item_editor->update_viewport(); } -Cast2DEditor::Cast2DEditor() { - undo_redo = EditorNode::get_singleton()->get_undo_redo(); -} - /////////////////////// void Cast2DEditorPlugin::edit(Object *p_object) { diff --git a/editor/plugins/cast_2d_editor_plugin.h b/editor/plugins/cast_2d_editor_plugin.h index ceed9b9111..1165a301f6 100644 --- a/editor/plugins/cast_2d_editor_plugin.h +++ b/editor/plugins/cast_2d_editor_plugin.h @@ -35,12 +35,10 @@ #include "scene/2d/node_2d.h" class CanvasItemEditor; -class EditorUndoRedoManager; class Cast2DEditor : public Control { GDCLASS(Cast2DEditor, Control); - Ref<EditorUndoRedoManager> undo_redo; CanvasItemEditor *canvas_item_editor = nullptr; Node2D *node = nullptr; @@ -55,8 +53,6 @@ public: bool forward_canvas_gui_input(const Ref<InputEvent> &p_event); void forward_canvas_draw_over_viewport(Control *p_overlay); void edit(Node2D *p_node); - - Cast2DEditor(); }; class Cast2DEditorPlugin : public EditorPlugin { diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 11992ad10e..a7f842aa66 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -219,6 +219,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Handle")); switch (shape_type) { @@ -588,8 +589,6 @@ CollisionShape2DEditor::CollisionShape2DEditor() { node = nullptr; canvas_item_editor = nullptr; - undo_redo = EditorNode::get_singleton()->get_undo_redo(); - edit_handle = -1; pressed = false; diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index 49e0820ae9..51cdab7396 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -35,7 +35,6 @@ #include "scene/2d/collision_shape_2d.h" class CanvasItemEditor; -class EditorUndoRedoManager; class CollisionShape2DEditor : public Control { GDCLASS(CollisionShape2DEditor, Control); @@ -62,7 +61,6 @@ class CollisionShape2DEditor : public Control { Point2(1, -1), }; - Ref<EditorUndoRedoManager> undo_redo; CanvasItemEditor *canvas_item_editor = nullptr; CollisionShape2D *node = nullptr; diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp index bb6092755e..c18876b9ef 100644 --- a/editor/plugins/control_editor_plugin.cpp +++ b/editor/plugins/control_editor_plugin.cpp @@ -35,6 +35,7 @@ #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/canvas_item_editor_plugin.h" +#include "scene/gui/grid_container.h" #include "scene/gui/separator.h" // Inspector controls. @@ -720,6 +721,7 @@ void ControlEditorToolbar::_anchors_preset_selected(int p_preset) { LayoutPreset preset = (LayoutPreset)p_preset; List<Node *> selection = editor_selection->get_selected_node_list(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Anchors, Offsets, Grow Direction")); for (Node *E : selection) { @@ -739,6 +741,7 @@ void ControlEditorToolbar::_anchors_preset_selected(int p_preset) { void ControlEditorToolbar::_anchors_to_current_ratio() { List<Node *> selection = editor_selection->get_selected_node_list(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Anchors, Offsets (Keep Ratio)")); for (Node *E : selection) { @@ -789,6 +792,7 @@ void ControlEditorToolbar::_anchor_mode_toggled(bool p_status) { void ControlEditorToolbar::_container_flags_selected(int p_flags, bool p_vertical) { List<Node *> selection = editor_selection->get_selected_node_list(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (p_vertical) { undo_redo->create_action(TTR("Change Vertical Size Flags")); } else { @@ -810,25 +814,12 @@ void ControlEditorToolbar::_container_flags_selected(int p_flags, bool p_vertica undo_redo->commit_action(); } -Vector2 ControlEditorToolbar::_anchor_to_position(const Control *p_control, Vector2 anchor) { - ERR_FAIL_COND_V(!p_control, Vector2()); - - Transform2D parent_transform = p_control->get_transform().affine_inverse(); - Rect2 parent_rect = p_control->get_parent_anchorable_rect(); - - if (p_control->is_layout_rtl()) { - return parent_transform.xform(parent_rect.position + Vector2(parent_rect.size.x - parent_rect.size.x * anchor.x, parent_rect.size.y * anchor.y)); - } else { - return parent_transform.xform(parent_rect.position + Vector2(parent_rect.size.x * anchor.x, parent_rect.size.y * anchor.y)); - } -} - Vector2 ControlEditorToolbar::_position_to_anchor(const Control *p_control, Vector2 position) { ERR_FAIL_COND_V(!p_control, Vector2()); Rect2 parent_rect = p_control->get_parent_anchorable_rect(); - Vector2 output = Vector2(); + Vector2 output; if (p_control->is_layout_rtl()) { output.x = (parent_rect.size.x == 0) ? 0.0 : (parent_rect.size.x - p_control->get_transform().xform(position).x - parent_rect.position.x) / parent_rect.size.x; } else { @@ -1037,7 +1028,6 @@ ControlEditorToolbar::ControlEditorToolbar() { container_v_picker->connect("size_flags_selected", callable_mp(this, &ControlEditorToolbar::_container_flags_selected).bind(true)); // Editor connections. - undo_redo = EditorNode::get_singleton()->get_undo_redo(); editor_selection = EditorNode::get_singleton()->get_editor_selection(); editor_selection->add_editor_plugin(this); editor_selection->connect("selection_changed", callable_mp(this, &ControlEditorToolbar::_selection_changed)); diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h index 22267cbc04..cf2c6f4e20 100644 --- a/editor/plugins/control_editor_plugin.h +++ b/editor/plugins/control_editor_plugin.h @@ -31,6 +31,7 @@ #ifndef CONTROL_EDITOR_PLUGIN_H #define CONTROL_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" @@ -44,7 +45,7 @@ #include "scene/gui/separator.h" #include "scene/gui/texture_rect.h" -class EditorUndoRedoManager; +class GridContainer; // Inspector controls. class ControlPositioningWarning : public MarginContainer { @@ -205,7 +206,6 @@ public: class ControlEditorToolbar : public HBoxContainer { GDCLASS(ControlEditorToolbar, HBoxContainer); - Ref<EditorUndoRedoManager> undo_redo; EditorSelection *editor_selection = nullptr; ControlEditorPopupButton *anchors_button = nullptr; @@ -222,7 +222,6 @@ class ControlEditorToolbar : public HBoxContainer { void _anchor_mode_toggled(bool p_status); void _container_flags_selected(int p_flags, bool p_vertical); - Vector2 _anchor_to_position(const Control *p_control, Vector2 anchor); Vector2 _position_to_anchor(const Control *p_control, Vector2 position); bool _is_node_locked(const Node *p_node); List<Control *> _get_edited_controls(); diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp index e56fd5dfe3..36b51e0e0c 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp @@ -34,9 +34,12 @@ #include "core/io/image_loader.h" #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" -#include "editor/editor_undo_redo_manager.h" #include "scene/2d/cpu_particles_2d.h" +#include "scene/gui/check_box.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/option_button.h" #include "scene/gui/separator.h" +#include "scene/gui/spin_box.h" #include "scene/resources/particle_process_material.h" void CPUParticles2DEditorPlugin::edit(Object *p_object) { @@ -110,8 +113,8 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() { int vpc = 0; { - Vector<uint8_t> data = img->get_data(); - const uint8_t *r = data.ptr(); + Vector<uint8_t> img_data = img->get_data(); + const uint8_t *r = img_data.ptr(); for (int i = 0; i < s.width; i++) { for (int j = 0; j < s.height; j++) { @@ -239,7 +242,6 @@ void CPUParticles2DEditorPlugin::_bind_methods() { CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin() { particles = nullptr; - undo_redo = EditorNode::get_singleton()->get_undo_redo(); toolbar = memnew(HBoxContainer); add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar); diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.h b/editor/plugins/cpu_particles_2d_editor_plugin.h index 06ca208463..1fc9ed763c 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.h +++ b/editor/plugins/cpu_particles_2d_editor_plugin.h @@ -36,10 +36,12 @@ #include "scene/2d/cpu_particles_2d.h" #include "scene/gui/box_container.h" -class EditorPlugin; +class CheckBox; +class ConfirmationDialog; class SpinBox; class EditorFileDialog; -class EditorUndoRedoManager; +class MenuButton; +class OptionButton; class CPUParticles2DEditorPlugin : public EditorPlugin { GDCLASS(CPUParticles2DEditorPlugin, EditorPlugin); @@ -71,7 +73,6 @@ class CPUParticles2DEditorPlugin : public EditorPlugin { String source_emission_file; - Ref<EditorUndoRedoManager> undo_redo; void _file_selected(const String &p_file); void _menu_callback(int p_idx); void _generate_emission_mask(); diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 8d1df0b32c..c7bb6b79ef 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -37,6 +37,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" CurveEditor::CurveEditor() { _selected_point = -1; @@ -139,14 +140,13 @@ void CurveEditor::gui_input(const Ref<InputEvent> &p_event) { if (!mb.is_pressed() && _dragging && mb.get_button_index() == MouseButton::LEFT) { _dragging = false; if (_has_undo_data) { - Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo(); - - ur->create_action(_selected_tangent == TANGENT_NONE ? TTR("Modify Curve Point") : TTR("Modify Curve Tangent")); - ur->add_do_method(*_curve_ref, "_set_data", _curve_ref->get_data()); - ur->add_undo_method(*_curve_ref, "_set_data", _undo_data); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(_selected_tangent == TANGENT_NONE ? TTR("Modify Curve Point") : TTR("Modify Curve Tangent")); + undo_redo->add_do_method(*_curve_ref, "_set_data", _curve_ref->get_data()); + undo_redo->add_undo_method(*_curve_ref, "_set_data", _undo_data); // Note: this will trigger one more "changed" signal even if nothing changes, // but it's ok since it would have fired every frame during the drag anyways - ur->commit_action(); + undo_redo->commit_action(); _has_undo_data = false; } @@ -301,13 +301,11 @@ void CurveEditor::on_preset_item_selected(int preset_id) { break; } - Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo(); - ur->create_action(TTR("Load Curve Preset")); - - ur->add_do_method(&curve, "_set_data", curve.get_data()); - ur->add_undo_method(&curve, "_set_data", previous_data); - - ur->commit_action(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Load Curve Preset")); + undo_redo->add_do_method(&curve, "_set_data", curve.get_data()); + undo_redo->add_undo_method(&curve, "_set_data", previous_data); + undo_redo->commit_action(); } void CurveEditor::_curve_changed() { @@ -435,8 +433,8 @@ CurveEditor::TangentIndex CurveEditor::get_tangent_at(Vector2 pos) const { void CurveEditor::add_point(Vector2 pos) { ERR_FAIL_COND(_curve_ref.is_null()); - Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo(); - ur->create_action(TTR("Remove Curve Point")); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Remove Curve Point")); Vector2 point_pos = get_world_pos(pos); if (point_pos.y < 0.0) { @@ -449,22 +447,21 @@ void CurveEditor::add_point(Vector2 pos) { int i = _curve_ref->add_point(point_pos); _curve_ref->remove_point(i); - ur->add_do_method(*_curve_ref, "add_point", point_pos); - ur->add_undo_method(*_curve_ref, "remove_point", i); - - ur->commit_action(); + undo_redo->add_do_method(*_curve_ref, "add_point", point_pos); + undo_redo->add_undo_method(*_curve_ref, "remove_point", i); + undo_redo->commit_action(); } void CurveEditor::remove_point(int index) { ERR_FAIL_COND(_curve_ref.is_null()); - Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo(); - ur->create_action(TTR("Remove Curve Point")); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Remove Curve Point")); Curve::Point p = _curve_ref->get_point(index); - ur->add_do_method(*_curve_ref, "remove_point", index); - ur->add_undo_method(*_curve_ref, "add_point", p.position, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode); + undo_redo->add_do_method(*_curve_ref, "remove_point", index); + undo_redo->add_undo_method(*_curve_ref, "add_point", p.position, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode); if (index == _selected_point) { set_selected_point(-1); @@ -474,14 +471,14 @@ void CurveEditor::remove_point(int index) { set_hover_point_index(-1); } - ur->commit_action(); + undo_redo->commit_action(); } void CurveEditor::toggle_linear(TangentIndex tangent) { ERR_FAIL_COND(_curve_ref.is_null()); - Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo(); - ur->create_action(TTR("Toggle Curve Linear Tangent")); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Toggle Curve Linear Tangent")); if (tangent == TANGENT_NONE) { tangent = _selected_tangent; @@ -493,8 +490,8 @@ void CurveEditor::toggle_linear(TangentIndex tangent) { Curve::TangentMode prev_mode = _curve_ref->get_point_left_mode(_selected_point); Curve::TangentMode mode = is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR; - ur->add_do_method(*_curve_ref, "set_point_left_mode", _selected_point, mode); - ur->add_undo_method(*_curve_ref, "set_point_left_mode", _selected_point, prev_mode); + undo_redo->add_do_method(*_curve_ref, "set_point_left_mode", _selected_point, mode); + undo_redo->add_undo_method(*_curve_ref, "set_point_left_mode", _selected_point, prev_mode); } else { bool is_linear = _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR; @@ -502,11 +499,11 @@ void CurveEditor::toggle_linear(TangentIndex tangent) { Curve::TangentMode prev_mode = _curve_ref->get_point_right_mode(_selected_point); Curve::TangentMode mode = is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR; - ur->add_do_method(*_curve_ref, "set_point_right_mode", _selected_point, mode); - ur->add_undo_method(*_curve_ref, "set_point_right_mode", _selected_point, prev_mode); + undo_redo->add_do_method(*_curve_ref, "set_point_right_mode", _selected_point, mode); + undo_redo->add_undo_method(*_curve_ref, "set_point_right_mode", _selected_point, prev_mode); } - ur->commit_action(); + undo_redo->commit_action(); } void CurveEditor::set_selected_point(int index) { @@ -755,10 +752,10 @@ void CurveEditor::_draw() { float width = view_size.x - 60 * EDSCALE; if (_selected_point > 0 && _selected_point + 1 < curve.get_point_count()) { text_color.a *= 0.4; - draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_LEFT, width, -1, font_size, text_color); + draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_LEFT, width, font_size, -1, text_color); } else if (curve.get_point_count() == 0) { text_color.a *= 0.4; - draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HORIZONTAL_ALIGNMENT_LEFT, width, -1, font_size, text_color); + draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HORIZONTAL_ALIGNMENT_LEFT, width, font_size, -1, text_color); } } @@ -799,13 +796,13 @@ Ref<Texture2D> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, cons Curve &curve = **curve_ref; // FIXME: Should be ported to use p_size as done in b2633a97 - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + int thumbnail_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); thumbnail_size *= EDSCALE; Ref<Image> img_ref; img_ref.instantiate(); Image &im = **img_ref; - im.create(thumbnail_size, thumbnail_size / 2, false, Image::FORMAT_RGBA8); + im.initialize_data(thumbnail_size, thumbnail_size / 2, false, Image::FORMAT_RGBA8); Color bg_color(0.1, 0.1, 0.1, 1.0); diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h index 5cf3b16a06..5503ce96ff 100644 --- a/editor/plugins/curve_editor_plugin.h +++ b/editor/plugins/curve_editor_plugin.h @@ -31,6 +31,7 @@ #ifndef CURVE_EDITOR_PLUGIN_H #define CURVE_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "editor/editor_resource_preview.h" #include "scene/resources/curve.h" diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 40e7dfead2..7d04880fb7 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -47,7 +47,6 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) { ED_SHORTCUT("debugger/step_over", TTR("Step Over"), Key::F10); ED_SHORTCUT("debugger/break", TTR("Break")); ED_SHORTCUT("debugger/continue", TTR("Continue"), Key::F12); - ED_SHORTCUT("debugger/keep_debugger_open", TTR("Keep Debugger Open")); ED_SHORTCUT("debugger/debug_with_external_editor", TTR("Debug with External Editor")); // File Server for deploy with remote filesystem. @@ -69,7 +68,7 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) { debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, using one-click deploy for Android will only export an executable without the project data.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploying will use the USB cable for faster performance. This option speeds up testing for projects with large assets.")); debug_menu->add_separator(); - debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISONS); + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISIONS); debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, collision shapes and raycast nodes (for 2D and 3D) will be visible in the running project.")); debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_paths", TTR("Visible Paths")), RUN_DEBUG_PATHS); @@ -85,6 +84,9 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) { debug_menu->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Synchronize Script Changes")), RUN_RELOAD_SCRIPTS); debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, any script that is saved will be reloaded in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled.")); + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/keep_server_open", TTR("Keep Debug Server Open")), SERVER_KEEP_OPEN); + debug_menu->set_item_tooltip(-1, + TTR("When this option is enabled, the editor debug server will stay open and listen for new sessions started outside of the editor itself.")); // Multi-instance, start/stop instances_menu = memnew(PopupMenu); @@ -150,10 +152,10 @@ void DebuggerEditorPlugin::_menu_option(int p_option) { EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_deploy_remote_debug", !ischecked); } break; - case RUN_DEBUG_COLLISONS: { - bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_DEBUG_COLLISONS)); - debug_menu->set_item_checked(debug_menu->get_item_index(RUN_DEBUG_COLLISONS), !ischecked); - EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_collisons", !ischecked); + case RUN_DEBUG_COLLISIONS: { + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_DEBUG_COLLISIONS)); + debug_menu->set_item_checked(debug_menu->get_item_index(RUN_DEBUG_COLLISIONS), !ischecked); + EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_collisions", !ischecked); } break; case RUN_DEBUG_PATHS: { @@ -176,6 +178,14 @@ void DebuggerEditorPlugin::_menu_option(int p_option) { EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_reload_scripts", !ischecked); } break; + case SERVER_KEEP_OPEN: { + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(SERVER_KEEP_OPEN)); + debug_menu->set_item_checked(debug_menu->get_item_index(SERVER_KEEP_OPEN), !ischecked); + + EditorDebuggerNode::get_singleton()->set_keep_open(!ischecked); + EditorSettings::get_singleton()->set_project_metadata("debug_options", "server_keep_open", !ischecked); + + } break; } } @@ -190,11 +200,12 @@ void DebuggerEditorPlugin::_notification(int p_what) { void DebuggerEditorPlugin::_update_debug_options() { bool check_deploy_remote = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_deploy_remote_debug", false); bool check_file_server = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_file_server", false); - bool check_debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false); + bool check_debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisions", false); bool check_debug_paths = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_paths", false); bool check_debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false); bool check_live_debug = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_live_debug", true); bool check_reload_scripts = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_reload_scripts", true); + bool check_server_keep_open = EditorSettings::get_singleton()->get_project_metadata("debug_options", "server_keep_open", false); int instances = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_instances", 1); if (check_deploy_remote) { @@ -204,7 +215,7 @@ void DebuggerEditorPlugin::_update_debug_options() { _menu_option(RUN_FILE_SERVER); } if (check_debug_collisions) { - _menu_option(RUN_DEBUG_COLLISONS); + _menu_option(RUN_DEBUG_COLLISIONS); } if (check_debug_paths) { _menu_option(RUN_DEBUG_PATHS); @@ -218,6 +229,9 @@ void DebuggerEditorPlugin::_update_debug_options() { if (check_reload_scripts) { _menu_option(RUN_RELOAD_SCRIPTS); } + if (check_server_keep_open) { + _menu_option(SERVER_KEEP_OPEN); + } int len = instances_menu->get_item_count(); for (int idx = 0; idx < len; idx++) { diff --git a/editor/plugins/debugger_editor_plugin.h b/editor/plugins/debugger_editor_plugin.h index d8871128c3..5f682ed5e0 100644 --- a/editor/plugins/debugger_editor_plugin.h +++ b/editor/plugins/debugger_editor_plugin.h @@ -48,11 +48,12 @@ private: enum MenuOptions { RUN_FILE_SERVER, RUN_LIVE_DEBUG, - RUN_DEBUG_COLLISONS, + RUN_DEBUG_COLLISIONS, RUN_DEBUG_PATHS, RUN_DEBUG_NAVIGATION, RUN_DEPLOY_REMOTE_DEBUG, RUN_RELOAD_SCRIPTS, + SERVER_KEEP_OPEN, }; void _update_debug_options(); diff --git a/editor/plugins/editor_debugger_plugin.cpp b/editor/plugins/editor_debugger_plugin.cpp index 4ce3d7cfd5..5dd3038c0e 100644 --- a/editor/plugins/editor_debugger_plugin.cpp +++ b/editor/plugins/editor_debugger_plugin.cpp @@ -32,7 +32,7 @@ #include "editor/debugger/script_editor_debugger.h" -void EditorDebuggerPlugin::_breaked(bool p_really_did, bool p_can_debug, String p_message, bool p_has_stackdump) { +void EditorDebuggerSession::_breaked(bool p_really_did, bool p_can_debug, String p_message, bool p_has_stackdump) { if (p_really_did) { emit_signal(SNAME("breaked"), p_can_debug); } else { @@ -40,22 +40,22 @@ void EditorDebuggerPlugin::_breaked(bool p_really_did, bool p_can_debug, String } } -void EditorDebuggerPlugin::_started() { +void EditorDebuggerSession::_started() { emit_signal(SNAME("started")); } -void EditorDebuggerPlugin::_stopped() { +void EditorDebuggerSession::_stopped() { emit_signal(SNAME("stopped")); } -void EditorDebuggerPlugin::_bind_methods() { - ClassDB::bind_method(D_METHOD("send_message", "message", "data"), &EditorDebuggerPlugin::send_message); - ClassDB::bind_method(D_METHOD("register_message_capture", "name", "callable"), &EditorDebuggerPlugin::register_message_capture); - ClassDB::bind_method(D_METHOD("unregister_message_capture", "name"), &EditorDebuggerPlugin::unregister_message_capture); - ClassDB::bind_method(D_METHOD("has_capture", "name"), &EditorDebuggerPlugin::has_capture); - ClassDB::bind_method(D_METHOD("is_breaked"), &EditorDebuggerPlugin::is_breaked); - ClassDB::bind_method(D_METHOD("is_debuggable"), &EditorDebuggerPlugin::is_debuggable); - ClassDB::bind_method(D_METHOD("is_session_active"), &EditorDebuggerPlugin::is_session_active); +void EditorDebuggerSession::_bind_methods() { + ClassDB::bind_method(D_METHOD("send_message", "message", "data"), &EditorDebuggerSession::send_message, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("toggle_profiler", "profiler", "enable", "data"), &EditorDebuggerSession::toggle_profiler, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("is_breaked"), &EditorDebuggerSession::is_breaked); + ClassDB::bind_method(D_METHOD("is_debuggable"), &EditorDebuggerSession::is_debuggable); + ClassDB::bind_method(D_METHOD("is_active"), &EditorDebuggerSession::is_active); + ClassDB::bind_method(D_METHOD("add_session_tab", "control"), &EditorDebuggerSession::add_session_tab); + ClassDB::bind_method(D_METHOD("remove_session_tab", "control"), &EditorDebuggerSession::remove_session_tab); ADD_SIGNAL(MethodInfo("started")); ADD_SIGNAL(MethodInfo("stopped")); @@ -63,62 +63,131 @@ void EditorDebuggerPlugin::_bind_methods() { ADD_SIGNAL(MethodInfo("continued")); } -void EditorDebuggerPlugin::attach_debugger(ScriptEditorDebugger *p_debugger) { - debugger = p_debugger; - if (debugger) { - debugger->connect("started", callable_mp(this, &EditorDebuggerPlugin::_started)); - debugger->connect("stopped", callable_mp(this, &EditorDebuggerPlugin::_stopped)); - debugger->connect("breaked", callable_mp(this, &EditorDebuggerPlugin::_breaked)); - } +void EditorDebuggerSession::add_session_tab(Control *p_tab) { + ERR_FAIL_COND(!p_tab || !debugger); + debugger->add_debugger_tab(p_tab); + tabs.insert(p_tab); } -void EditorDebuggerPlugin::detach_debugger(bool p_call_debugger) { - if (debugger) { - debugger->disconnect("started", callable_mp(this, &EditorDebuggerPlugin::_started)); - debugger->disconnect("stopped", callable_mp(this, &EditorDebuggerPlugin::_stopped)); - debugger->disconnect("breaked", callable_mp(this, &EditorDebuggerPlugin::_breaked)); - if (p_call_debugger && get_script_instance()) { - debugger->remove_debugger_plugin(get_script_instance()->get_script()); - } - debugger = nullptr; - } +void EditorDebuggerSession::remove_session_tab(Control *p_tab) { + ERR_FAIL_COND(!p_tab || !debugger); + debugger->remove_debugger_tab(p_tab); + tabs.erase(p_tab); } -void EditorDebuggerPlugin::send_message(const String &p_message, const Array &p_args) { +void EditorDebuggerSession::send_message(const String &p_message, const Array &p_args) { ERR_FAIL_COND_MSG(!debugger, "Plugin is not attached to debugger"); debugger->send_message(p_message, p_args); } -void EditorDebuggerPlugin::register_message_capture(const StringName &p_name, const Callable &p_callable) { +void EditorDebuggerSession::toggle_profiler(const String &p_profiler, bool p_enable, const Array &p_data) { ERR_FAIL_COND_MSG(!debugger, "Plugin is not attached to debugger"); - debugger->register_message_capture(p_name, p_callable); + debugger->toggle_profiler(p_profiler, p_enable, p_data); } -void EditorDebuggerPlugin::unregister_message_capture(const StringName &p_name) { - ERR_FAIL_COND_MSG(!debugger, "Plugin is not attached to debugger"); - debugger->unregister_message_capture(p_name); -} - -bool EditorDebuggerPlugin::has_capture(const StringName &p_name) { - ERR_FAIL_COND_V_MSG(!debugger, false, "Plugin is not attached to debugger"); - return debugger->has_capture(p_name); -} - -bool EditorDebuggerPlugin::is_breaked() { +bool EditorDebuggerSession::is_breaked() { ERR_FAIL_COND_V_MSG(!debugger, false, "Plugin is not attached to debugger"); return debugger->is_breaked(); } -bool EditorDebuggerPlugin::is_debuggable() { +bool EditorDebuggerSession::is_debuggable() { ERR_FAIL_COND_V_MSG(!debugger, false, "Plugin is not attached to debugger"); return debugger->is_debuggable(); } -bool EditorDebuggerPlugin::is_session_active() { +bool EditorDebuggerSession::is_active() { ERR_FAIL_COND_V_MSG(!debugger, false, "Plugin is not attached to debugger"); return debugger->is_session_active(); } +void EditorDebuggerSession::detach_debugger() { + if (!debugger) { + return; + } + debugger->disconnect("started", callable_mp(this, &EditorDebuggerSession::_started)); + debugger->disconnect("stopped", callable_mp(this, &EditorDebuggerSession::_stopped)); + debugger->disconnect("breaked", callable_mp(this, &EditorDebuggerSession::_breaked)); + debugger->disconnect("tree_exited", callable_mp(this, &EditorDebuggerSession::_debugger_gone_away)); + for (Control *tab : tabs) { + debugger->remove_debugger_tab(tab); + } + tabs.clear(); + debugger = nullptr; +} + +void EditorDebuggerSession::_debugger_gone_away() { + debugger = nullptr; + tabs.clear(); +} + +EditorDebuggerSession::EditorDebuggerSession(ScriptEditorDebugger *p_debugger) { + ERR_FAIL_COND(!p_debugger); + debugger = p_debugger; + debugger->connect("started", callable_mp(this, &EditorDebuggerSession::_started)); + debugger->connect("stopped", callable_mp(this, &EditorDebuggerSession::_stopped)); + debugger->connect("breaked", callable_mp(this, &EditorDebuggerSession::_breaked)); + debugger->connect("tree_exited", callable_mp(this, &EditorDebuggerSession::_debugger_gone_away), CONNECT_ONE_SHOT); +} + +EditorDebuggerSession::~EditorDebuggerSession() { + detach_debugger(); +} + +/// EditorDebuggerPlugin + EditorDebuggerPlugin::~EditorDebuggerPlugin() { - detach_debugger(true); + clear(); +} + +void EditorDebuggerPlugin::clear() { + for (int i = 0; i < sessions.size(); i++) { + sessions[i]->detach_debugger(); + } + sessions.clear(); +} + +void EditorDebuggerPlugin::create_session(ScriptEditorDebugger *p_debugger) { + sessions.push_back(Ref<EditorDebuggerSession>(memnew(EditorDebuggerSession(p_debugger)))); + setup_session(sessions.size() - 1); +} + +void EditorDebuggerPlugin::setup_session(int p_idx) { + GDVIRTUAL_CALL(_setup_session, p_idx); +} + +Ref<EditorDebuggerSession> EditorDebuggerPlugin::get_session(int p_idx) { + ERR_FAIL_INDEX_V(p_idx, sessions.size(), nullptr); + return sessions[p_idx]; +} + +Array EditorDebuggerPlugin::get_sessions() { + Array ret; + for (int i = 0; i < sessions.size(); i++) { + ret.push_back(sessions[i]); + } + return ret; +} + +bool EditorDebuggerPlugin::has_capture(const String &p_message) const { + bool ret = false; + if (GDVIRTUAL_CALL(_has_capture, p_message, ret)) { + return ret; + } + return false; +} + +bool EditorDebuggerPlugin::capture(const String &p_message, const Array &p_data, int p_session_id) { + bool ret = false; + if (GDVIRTUAL_CALL(_capture, p_message, p_data, p_session_id, ret)) { + return ret; + } + return false; +} + +void EditorDebuggerPlugin::_bind_methods() { + GDVIRTUAL_BIND(_setup_session, "session_id"); + GDVIRTUAL_BIND(_has_capture, "capture"); + GDVIRTUAL_BIND(_capture, "message", "data", "session_id"); + ClassDB::bind_method(D_METHOD("get_session", "id"), &EditorDebuggerPlugin::get_session); + ClassDB::bind_method(D_METHOD("get_sessions"), &EditorDebuggerPlugin::get_sessions); } diff --git a/editor/plugins/editor_debugger_plugin.h b/editor/plugins/editor_debugger_plugin.h index b602c36912..46f8f17cc2 100644 --- a/editor/plugins/editor_debugger_plugin.h +++ b/editor/plugins/editor_debugger_plugin.h @@ -35,29 +35,62 @@ class ScriptEditorDebugger; -class EditorDebuggerPlugin : public Control { - GDCLASS(EditorDebuggerPlugin, Control); +class EditorDebuggerSession : public RefCounted { + GDCLASS(EditorDebuggerSession, RefCounted); private: + HashSet<Control *> tabs; + ScriptEditorDebugger *debugger = nullptr; void _breaked(bool p_really_did, bool p_can_debug, String p_message, bool p_has_stackdump); void _started(); void _stopped(); + void _debugger_gone_away(); protected: static void _bind_methods(); public: - void attach_debugger(ScriptEditorDebugger *p_debugger); - void detach_debugger(bool p_call_debugger); - void send_message(const String &p_message, const Array &p_args); - void register_message_capture(const StringName &p_name, const Callable &p_callable); - void unregister_message_capture(const StringName &p_name); - bool has_capture(const StringName &p_name); + void detach_debugger(); + + void add_session_tab(Control *p_tab); + void remove_session_tab(Control *p_tab); + void send_message(const String &p_message, const Array &p_args = Array()); + void toggle_profiler(const String &p_profiler, bool p_enable, const Array &p_data = Array()); bool is_breaked(); bool is_debuggable(); - bool is_session_active(); + bool is_active(); + + EditorDebuggerSession(ScriptEditorDebugger *p_debugger); + ~EditorDebuggerSession(); +}; + +class EditorDebuggerPlugin : public RefCounted { + GDCLASS(EditorDebuggerPlugin, RefCounted); + +private: + List<Ref<EditorDebuggerSession>> sessions; + +protected: + static void _bind_methods(); + +public: + void create_session(ScriptEditorDebugger *p_debugger); + void clear(); + + virtual void setup_session(int p_idx); + virtual bool capture(const String &p_message, const Array &p_data, int p_session); + virtual bool has_capture(const String &p_capture) const; + + Ref<EditorDebuggerSession> get_session(int p_session_id); + Array get_sessions(); + + GDVIRTUAL3R(bool, _capture, const String &, const Array &, int); + GDVIRTUAL1RC(bool, _has_capture, const String &); + GDVIRTUAL1(_setup_session, int); + + EditorDebuggerPlugin() {} ~EditorDebuggerPlugin(); }; diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 59b8f31720..5f9446c3b1 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -93,7 +93,7 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const Ref<Resource> &p_from, return Ref<Texture2D>(); } - img = atlas->get_rect(atex->get_region()); + img = atlas->get_region(atex->get_region()); } else { Ref<Texture2D> tex = p_from; if (tex.is_valid()) { @@ -210,9 +210,7 @@ Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const Ref<Resource> &p_from, } } - Ref<Image> img; - img.instantiate(); - img->create(bm->get_size().width, bm->get_size().height, false, Image::FORMAT_L8, data); + Ref<Image> img = Image::create_from_data(bm->get_size().width, bm->get_size().height, false, Image::FORMAT_L8, data); if (img->is_compressed()) { if (img->decompress() != OK) { @@ -483,17 +481,15 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from, int line = 0; int col = 0; - Ref<Image> img; - img.instantiate(); int thumbnail_size = MAX(p_size.x, p_size.y); - img->create(thumbnail_size, thumbnail_size, false, Image::FORMAT_RGBA8); + Ref<Image> img = Image::create_empty(thumbnail_size, thumbnail_size, false, Image::FORMAT_RGBA8); - Color bg_color = EditorSettings::get_singleton()->get("text_editor/theme/highlighting/background_color"); - Color keyword_color = EditorSettings::get_singleton()->get("text_editor/theme/highlighting/keyword_color"); - Color control_flow_keyword_color = EditorSettings::get_singleton()->get("text_editor/theme/highlighting/control_flow_keyword_color"); - Color text_color = EditorSettings::get_singleton()->get("text_editor/theme/highlighting/text_color"); - Color symbol_color = EditorSettings::get_singleton()->get("text_editor/theme/highlighting/symbol_color"); - Color comment_color = EditorSettings::get_singleton()->get("text_editor/theme/highlighting/comment_color"); + Color bg_color = EDITOR_GET("text_editor/theme/highlighting/background_color"); + Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); + Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color"); + Color text_color = EDITOR_GET("text_editor/theme/highlighting/text_color"); + Color symbol_color = EDITOR_GET("text_editor/theme/highlighting/symbol_color"); + Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color"); if (bg_color.a == 0) { bg_color = Color(0, 0, 0, 0); @@ -660,9 +656,7 @@ Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const Ref<Resource> &p_f //post_process_preview(img); - Ref<Image> image; - image.instantiate(); - image->create(w, h, false, Image::FORMAT_RGB8, img); + Ref<Image> image = Image::create_from_data(w, h, false, Image::FORMAT_RGB8, img); return ImageTexture::create_from_image(image); } diff --git a/editor/plugins/editor_resource_conversion_plugin.cpp b/editor/plugins/editor_resource_conversion_plugin.cpp index 91394dbac7..a5f12d1352 100644 --- a/editor/plugins/editor_resource_conversion_plugin.cpp +++ b/editor/plugins/editor_resource_conversion_plugin.cpp @@ -38,27 +38,18 @@ void EditorResourceConversionPlugin::_bind_methods() { String EditorResourceConversionPlugin::converts_to() const { String ret; - if (GDVIRTUAL_CALL(_converts_to, ret)) { - return ret; - } - - return ""; + GDVIRTUAL_CALL(_converts_to, ret); + return ret; } bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) const { - bool ret; - if (GDVIRTUAL_CALL(_handles, p_resource, ret)) { - return ret; - } - - return false; + bool ret = false; + GDVIRTUAL_CALL(_handles, p_resource, ret); + return ret; } Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const { Ref<Resource> ret; - if (GDVIRTUAL_CALL(_convert, p_resource, ret)) { - return ret; - } - - return Ref<Resource>(); + GDVIRTUAL_CALL(_convert, p_resource, ret); + return ret; } diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp index 2df951518e..4370d013be 100644 --- a/editor/plugins/font_config_plugin.cpp +++ b/editor/plugins/font_config_plugin.cpp @@ -31,6 +31,7 @@ #include "font_config_plugin.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/import/dynamic_font_import_settings.h" /*************************************************************************/ @@ -154,7 +155,7 @@ void EditorPropertyFontMetaOverride::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - if (Object::cast_to<Button>(button_add)) { + if (button_add) { button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } } break; @@ -260,7 +261,7 @@ void EditorPropertyFontMetaOverride::update_property() { } else { // Queue children for deletion, deleting immediately might cause errors. for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) { - property_vbox->get_child(i)->queue_delete(); + property_vbox->get_child(i)->queue_free(); } button_add = nullptr; } @@ -457,7 +458,7 @@ void EditorPropertyOTVariation::update_property() { } else { // Queue children for deletion, deleting immediately might cause errors. for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) { - property_vbox->get_child(i)->queue_delete(); + property_vbox->get_child(i)->queue_free(); } } @@ -549,7 +550,7 @@ void EditorPropertyOTFeatures::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - if (Object::cast_to<Button>(button_add)) { + if (button_add) { button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } } break; @@ -622,6 +623,16 @@ void EditorPropertyOTFeatures::update_property() { supported = fd->get_supported_feature_list(); } + if (supported.is_empty()) { + edit->set_text(vformat(TTR("No supported features"))); + if (container) { + set_bottom_editor(nullptr); + memdelete(container); + button_add = nullptr; + container = nullptr; + } + return; + } edit->set_text(vformat(TTR("Features (%d of %d set)"), dict.size(), supported.size())); bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property()); @@ -652,7 +663,7 @@ void EditorPropertyOTFeatures::update_property() { } else { // Queue children for deletion, deleting immediately might cause errors. for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) { - property_vbox->get_child(i)->queue_delete(); + property_vbox->get_child(i)->queue_free(); } button_add = nullptr; } diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h index e1d68d97b5..c5f7d2a047 100644 --- a/editor/plugins/gdextension_export_plugin.h +++ b/editor/plugins/gdextension_export_plugin.h @@ -107,7 +107,7 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p for (const String &E : p_features) { tags.append(E); } - ERR_FAIL_MSG(vformat("Couldn't export extension: %s. No suitable library found for export flags: %s", p_path, String(", ").join(tags))); + ERR_FAIL_MSG(vformat("No suitable library found. The libraries' tags referred to an invalid feature flag. Possible feature flags for your platform: %s", p_path, String(", ").join(tags))); } List<String> dependencies; diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp index e2d19c34e6..0fa3efba9a 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp @@ -37,6 +37,7 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/scene_tree_dock.h" #include "scene/2d/cpu_particles_2d.h" +#include "scene/gui/menu_button.h" #include "scene/gui/separator.h" #include "scene/resources/particle_process_material.h" @@ -160,6 +161,7 @@ void GPUParticles2DEditorPlugin::_generate_visibility_rect() { particles->set_emitting(false); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Generate Visibility Rect")); undo_redo->add_do_method(particles, "set_visibility_rect", rect); undo_redo->add_undo_method(particles, "set_visibility_rect", particles->get_visibility_rect()); @@ -207,8 +209,8 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() { int vpc = 0; { - Vector<uint8_t> data = img->get_data(); - const uint8_t *r = data.ptr(); + Vector<uint8_t> img_data = img->get_data(); + const uint8_t *r = img_data.ptr(); for (int i = 0; i < s.width; i++) { for (int j = 0; j < s.height; j++) { @@ -299,7 +301,7 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() { } img.instantiate(); - img->create(w, h, false, Image::FORMAT_RGF, texdata); + img->set_data(w, h, false, Image::FORMAT_RGF, texdata); pm->set_emission_point_texture(ImageTexture::create_from_image(img)); pm->set_emission_point_count(vpc); @@ -315,7 +317,7 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() { } img.instantiate(); - img->create(w, h, false, Image::FORMAT_RGBA8, colordata); + img->set_data(w, h, false, Image::FORMAT_RGBA8, colordata); pm->set_emission_color_texture(ImageTexture::create_from_image(img)); } @@ -335,7 +337,7 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() { } img.instantiate(); - img->create(w, h, false, Image::FORMAT_RGF, normdata); + img->set_data(w, h, false, Image::FORMAT_RGF, normdata); pm->set_emission_normal_texture(ImageTexture::create_from_image(img)); } else { @@ -359,7 +361,6 @@ void GPUParticles2DEditorPlugin::_bind_methods() { GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin() { particles = nullptr; - undo_redo = EditorNode::get_singleton()->get_undo_redo(); toolbar = memnew(HBoxContainer); add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar); diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.h b/editor/plugins/gpu_particles_2d_editor_plugin.h index 0229b57c10..34cadaf7de 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.h +++ b/editor/plugins/gpu_particles_2d_editor_plugin.h @@ -37,8 +37,11 @@ #include "scene/gui/box_container.h" #include "scene/gui/spin_box.h" +class CheckBox; +class ConfirmationDialog; class EditorFileDialog; -class EditorUndoRedoManager; +class MenuButton; +class OptionButton; class GPUParticles2DEditorPlugin : public EditorPlugin { GDCLASS(GPUParticles2DEditorPlugin, EditorPlugin); @@ -76,7 +79,6 @@ class GPUParticles2DEditorPlugin : public EditorPlugin { String source_emission_file; - Ref<EditorUndoRedoManager> undo_redo; void _file_selected(const String &p_file); void _menu_callback(int p_idx); void _generate_visibility_rect(); diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp index d91cbb6571..b2878244d0 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp @@ -36,6 +36,8 @@ #include "editor/plugins/node_3d_editor_plugin.h" #include "editor/scene_tree_dock.h" #include "scene/3d/cpu_particles_3d.h" +#include "scene/3d/mesh_instance_3d.h" +#include "scene/gui/menu_button.h" #include "scene/resources/particle_process_material.h" bool GPUParticles3DEditorBase::_generate(Vector<Vector3> &points, Vector<Vector3> &normals) { @@ -255,8 +257,8 @@ void GPUParticles3DEditor::_menu_option(int p_option) { } } break; case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: { - Ref<ParticleProcessMaterial> material = node->get_process_material(); - if (material.is_null()) { + Ref<ParticleProcessMaterial> mat = node->get_process_material(); + if (mat.is_null()) { EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticleProcessMaterial' is required.")); return; } @@ -366,13 +368,13 @@ void GPUParticles3DEditor::_generate_emission_points() { Ref<Image> image = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img)); Ref<ImageTexture> tex = ImageTexture::create_from_image(image); - Ref<ParticleProcessMaterial> material = node->get_process_material(); - ERR_FAIL_COND(material.is_null()); + Ref<ParticleProcessMaterial> mat = node->get_process_material(); + ERR_FAIL_COND(mat.is_null()); if (normals.size() > 0) { - material->set_emission_shape(ParticleProcessMaterial::EMISSION_SHAPE_DIRECTED_POINTS); - material->set_emission_point_count(point_count); - material->set_emission_point_texture(tex); + mat->set_emission_shape(ParticleProcessMaterial::EMISSION_SHAPE_DIRECTED_POINTS); + mat->set_emission_point_count(point_count); + mat->set_emission_point_texture(tex); Vector<uint8_t> point_img2; point_img2.resize(w * h * 3 * sizeof(float)); @@ -390,11 +392,11 @@ void GPUParticles3DEditor::_generate_emission_points() { } Ref<Image> image2 = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img2)); - material->set_emission_normal_texture(ImageTexture::create_from_image(image2)); + mat->set_emission_normal_texture(ImageTexture::create_from_image(image2)); } else { - material->set_emission_shape(ParticleProcessMaterial::EMISSION_SHAPE_POINTS); - material->set_emission_point_count(point_count); - material->set_emission_point_texture(tex); + mat->set_emission_shape(ParticleProcessMaterial::EMISSION_SHAPE_POINTS); + mat->set_emission_point_count(point_count); + mat->set_emission_point_texture(tex); } } diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.h b/editor/plugins/gpu_particles_3d_editor_plugin.h index 17bdfa6e3f..e5b264cfe4 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.h +++ b/editor/plugins/gpu_particles_3d_editor_plugin.h @@ -35,6 +35,10 @@ #include "scene/3d/gpu_particles_3d.h" #include "scene/gui/spin_box.h" +class ConfirmationDialog; +class HBoxContainer; +class MenuButton; +class OptionButton; class SceneTreeDialog; class GPUParticles3DEditorBase : public Control { diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h index 684279039a..2c1f49df29 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h @@ -37,6 +37,7 @@ struct EditorProgress; class EditorFileDialog; +class HBoxContainer; class GPUParticlesCollisionSDF3DEditorPlugin : public EditorPlugin { GDCLASS(GPUParticlesCollisionSDF3DEditorPlugin, EditorPlugin); diff --git a/editor/plugins/gradient_editor.cpp b/editor/plugins/gradient_editor.cpp index c13b162db6..c466a82f7d 100644 --- a/editor/plugins/gradient_editor.cpp +++ b/editor/plugins/gradient_editor.cpp @@ -57,7 +57,7 @@ int GradientEditor::_get_point_from_pos(int x) { for (int i = 0; i < points.size(); i++) { // Check if we clicked at point. float distance = ABS(x - points[i].offset * total_w); - float min = (draw_point_width / 2 * 1.7); //make it easier to grab + float min = (handle_width / 2 * 1.7); // Make it easier to grab. if (distance <= min && distance < min_distance) { result = i; min_distance = distance; @@ -90,8 +90,8 @@ void GradientEditor::_gradient_changed() { } editing = true; - Vector<Gradient::Point> points = gradient->get_points(); - set_points(points); + Vector<Gradient::Point> grad_points = gradient->get_points(); + set_points(grad_points); set_interpolation_mode(gradient->get_interpolation_mode()); queue_redraw(); editing = false; @@ -99,7 +99,7 @@ void GradientEditor::_gradient_changed() { void GradientEditor::_ramp_changed() { editing = true; - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Gradient Edited"), UndoRedo::MERGE_ENDS); undo_redo->add_do_method(gradient.ptr(), "set_offsets", get_offsets()); undo_redo->add_do_method(gradient.ptr(), "set_colors", get_colors()); @@ -203,6 +203,7 @@ void GradientEditor::gui_input(const Ref<InputEvent> &p_event) { grabbed = _get_point_from_pos(mb->get_position().x); _show_color_picker(); accept_event(); + return; } // Delete point on right click. @@ -396,7 +397,7 @@ void GradientEditor::_notification(int p_what) { } case NOTIFICATION_THEME_CHANGED: { draw_spacing = BASE_SPACING * get_theme_default_base_scale(); - draw_point_width = BASE_POINT_WIDTH * get_theme_default_base_scale(); + handle_width = BASE_HANDLE_WIDTH * get_theme_default_base_scale(); } break; case NOTIFICATION_DRAW: { @@ -407,32 +408,38 @@ void GradientEditor::_notification(int p_what) { return; // Safety check. We have division by 'h'. And in any case there is nothing to draw with such size. } - int total_w = get_size().width - get_size().height - draw_spacing; + int total_w = get_size().width - get_size().height - draw_spacing - handle_width; // Draw checker pattern for ramp. - draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(0, 0, total_w, h), true); + draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(handle_width / 2, 0, total_w, h), true); // Draw color ramp. gradient_cache->set_points(points); gradient_cache->set_interpolation_mode(interpolation_mode); preview_texture->set_gradient(gradient_cache); - draw_texture_rect(preview_texture, Rect2(0, 0, total_w, h)); + draw_texture_rect(preview_texture, Rect2(handle_width / 2, 0, total_w, h)); + + // Draw borders around color ramp if in focus. + if (has_focus()) { + draw_rect(Rect2(handle_width / 2, 0, total_w, h), Color(1, 1, 1, 0.9), false); + } // Draw point markers. for (int i = 0; i < points.size(); i++) { - Color col = points[i].color.inverted(); + Color col = points[i].color.get_v() > 0.5 ? Color(0, 0, 0) : Color(1, 1, 1); col.a = 0.9; - draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col); - Rect2 rect = Rect2(points[i].offset * total_w - draw_point_width / 2, h / 2, draw_point_width, h / 2); + draw_line(Vector2(points[i].offset * total_w + handle_width / 2, 0), Vector2(points[i].offset * total_w + handle_width / 2, h / 2), col); + Rect2 rect = Rect2(points[i].offset * total_w, h / 2, handle_width, h / 2); draw_rect(rect, points[i].color, true); draw_rect(rect, col, false); if (grabbed == i) { + const Color focus_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); rect = rect.grow(-1); if (has_focus()) { - draw_rect(rect, Color(1, 0, 0, 0.9), false); + draw_rect(rect, focus_color, false); } else { - draw_rect(rect, Color(0.6, 0, 0, 0.9), false); + draw_rect(rect, focus_color.darkened(0.4), false); } rect = rect.grow(-1); @@ -441,23 +448,16 @@ void GradientEditor::_notification(int p_what) { } // Draw "button" for color selector. - draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(total_w + draw_spacing, 0, h, h), true); + int button_offset = total_w + handle_width + draw_spacing; + draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(button_offset, 0, h, h), true); if (grabbed != -1) { // Draw with selection color. - draw_rect(Rect2(total_w + draw_spacing, 0, h, h), points[grabbed].color); + draw_rect(Rect2(button_offset, 0, h, h), points[grabbed].color); } else { // If no color selected draw grey color with 'X' on top. - draw_rect(Rect2(total_w + draw_spacing, 0, h, h), Color(0.5, 0.5, 0.5, 1)); - draw_line(Vector2(total_w + draw_spacing, 0), Vector2(total_w + draw_spacing + h, h), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + draw_spacing, h), Vector2(total_w + draw_spacing + h, 0), Color(1, 1, 1, 0.6)); - } - - // Draw borders around color ramp if in focus. - if (has_focus()) { - draw_line(Vector2(-1, -1), Vector2(total_w + 1, -1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + 1, -1), Vector2(total_w + 1, h + 1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); + draw_rect(Rect2(button_offset, 0, h, h), Color(0.5, 0.5, 0.5, 1)); + draw_line(Vector2(button_offset, 0), Vector2(button_offset + h, h), Color(1, 1, 1, 0.6)); + draw_line(Vector2(button_offset, h), Vector2(button_offset + h, 0), Color(1, 1, 1, 0.6)); } } break; diff --git a/editor/plugins/gradient_editor.h b/editor/plugins/gradient_editor.h index 816b539ba2..f27cd8a188 100644 --- a/editor/plugins/gradient_editor.h +++ b/editor/plugins/gradient_editor.h @@ -53,10 +53,10 @@ class GradientEditor : public Control { // Make sure to use the scaled value below. const int BASE_SPACING = 3; - const int BASE_POINT_WIDTH = 8; + const int BASE_HANDLE_WIDTH = 8; int draw_spacing = BASE_SPACING; - int draw_point_width = BASE_POINT_WIDTH; + int handle_width = BASE_HANDLE_WIDTH; void _gradient_changed(); void _ramp_changed(); diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h index ab191d83e2..f3859e74d3 100644 --- a/editor/plugins/gradient_editor_plugin.h +++ b/editor/plugins/gradient_editor_plugin.h @@ -31,6 +31,7 @@ #ifndef GRADIENT_EDITOR_PLUGIN_H #define GRADIENT_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "gradient_editor.h" diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp index dc01a52bb3..0591288c6e 100644 --- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp +++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp @@ -55,6 +55,7 @@ void GradientTexture2DEditorRect::_update_fill_position() { String property_name = handle == HANDLE_FILL_FROM ? "fill_from" : "fill_to"; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Set %s"), property_name), UndoRedo::MERGE_ENDS); undo_redo->add_do_property(texture.ptr(), property_name, percent); undo_redo->add_undo_property(texture.ptr(), property_name, handle == HANDLE_FILL_FROM ? texture->get_fill_from() : texture->get_fill_to()); @@ -121,13 +122,12 @@ void GradientTexture2DEditorRect::_notification(int p_what) { Size2 rect_size = get_size(); // Get the size and position to draw the texture and handles at. - size = Size2(texture->get_width() * rect_size.height / texture->get_height(), rect_size.height); - if (size.width > rect_size.width) { - size.width = rect_size.width; - size.height = texture->get_height() * size.width / texture->get_width(); - } - offset = ((rect_size - size + handle_size) / 2).round(); - size -= handle_size; + // Subtract handle sizes so they stay inside the preview, but keep the texture's aspect ratio. + Size2 available_size = rect_size - handle_size; + Size2 ratio = available_size / texture->get_size(); + size = MIN(ratio.x, ratio.y) * texture->get_size(); + offset = ((rect_size - size) / 2).round(); + checkerboard->set_rect(Rect2(offset, size)); draw_set_transform(offset); @@ -176,12 +176,11 @@ void GradientTexture2DEditorRect::_notification(int p_what) { } GradientTexture2DEditorRect::GradientTexture2DEditorRect() { - undo_redo = EditorNode::get_undo_redo(); - checkerboard = memnew(TextureRect); checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE); + checkerboard->set_ignore_texture_size(true); checkerboard->set_draw_behind_parent(true); - add_child(checkerboard); + add_child(checkerboard, false, INTERNAL_MODE_FRONT); set_custom_minimum_size(Size2(0, 250 * EDSCALE)); } @@ -189,6 +188,7 @@ GradientTexture2DEditorRect::GradientTexture2DEditorRect() { /////////////////////// void GradientTexture2DEditor::_reverse_button_pressed() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Swap GradientTexture2D Fill Points")); undo_redo->add_do_property(texture.ptr(), "fill_from", texture->get_fill_to()); undo_redo->add_do_property(texture.ptr(), "fill_to", texture->get_fill_from()); @@ -223,8 +223,6 @@ void GradientTexture2DEditor::_notification(int p_what) { } GradientTexture2DEditor::GradientTexture2DEditor() { - undo_redo = EditorNode::get_undo_redo(); - HFlowContainer *toolbar = memnew(HFlowContainer); add_child(toolbar); diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.h b/editor/plugins/gradient_texture_2d_editor_plugin.h index 9faf33152a..3172944ea8 100644 --- a/editor/plugins/gradient_texture_2d_editor_plugin.h +++ b/editor/plugins/gradient_texture_2d_editor_plugin.h @@ -31,11 +31,10 @@ #ifndef GRADIENT_TEXTURE_2D_EDITOR_PLUGIN_H #define GRADIENT_TEXTURE_2D_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "editor/editor_spin_slider.h" -class EditorUndoRedoManager; - class GradientTexture2DEditorRect : public Control { GDCLASS(GradientTexture2DEditorRect, Control); @@ -46,7 +45,6 @@ class GradientTexture2DEditorRect : public Control { }; Ref<GradientTexture2D> texture; - Ref<EditorUndoRedoManager> undo_redo; bool snap_enabled = false; float snap_size = 0; @@ -76,7 +74,6 @@ class GradientTexture2DEditor : public VBoxContainer { GDCLASS(GradientTexture2DEditor, VBoxContainer); Ref<GradientTexture2D> texture; - Ref<EditorUndoRedoManager> undo_redo; Button *reverse_button = nullptr; Button *snap_button = nullptr; diff --git a/editor/plugins/input_event_editor_plugin.cpp b/editor/plugins/input_event_editor_plugin.cpp index 153eab32d2..b67f0f6ad2 100644 --- a/editor/plugins/input_event_editor_plugin.cpp +++ b/editor/plugins/input_event_editor_plugin.cpp @@ -30,6 +30,9 @@ #include "input_event_editor_plugin.h" +#include "editor/event_listener_line_edit.h" +#include "editor/input_event_configuration_dialog.h" + void InputEventConfigContainer::_bind_methods() { } @@ -63,13 +66,13 @@ void InputEventConfigContainer::set_event(const Ref<InputEvent> &p_event) { Ref<InputEventJoypadMotion> jm = p_event; if (k.is_valid()) { - config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY); + config_dialog->set_allowed_input_types(INPUT_KEY); } else if (m.is_valid()) { - config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_MOUSE_BUTTON); + config_dialog->set_allowed_input_types(INPUT_MOUSE_BUTTON); } else if (jb.is_valid()) { - config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_JOY_BUTTON); + config_dialog->set_allowed_input_types(INPUT_JOY_BUTTON); } else if (jm.is_valid()) { - config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_JOY_MOTION); + config_dialog->set_allowed_input_types(INPUT_JOY_MOTION); } input_event = p_event; diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp index e7ef65c32b..f2c46cc9e8 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -30,6 +30,9 @@ #include "light_occluder_2d_editor_plugin.h" +#include "editor/editor_node.h" +#include "editor/editor_undo_redo_manager.h" + Ref<OccluderPolygon2D> LightOccluder2DEditor::_ensure_occluder() const { Ref<OccluderPolygon2D> occluder = node->get_occluder_polygon(); if (!occluder.is_valid()) { @@ -81,6 +84,7 @@ void LightOccluder2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) co void LightOccluder2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) { Ref<OccluderPolygon2D> occluder = _ensure_occluder(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(occluder.ptr(), "set_polygon", p_polygon); undo_redo->add_undo_method(occluder.ptr(), "set_polygon", p_previous); } @@ -94,6 +98,7 @@ void LightOccluder2DEditor::_create_resource() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Create Occluder Polygon")); undo_redo->add_do_method(node, "set_occluder_polygon", Ref<OccluderPolygon2D>(memnew(OccluderPolygon2D))); undo_redo->add_undo_method(node, "set_occluder_polygon", Variant(Ref<RefCounted>())); diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp index 31053f90b8..9182b23867 100644 --- a/editor/plugins/line_2d_editor_plugin.cpp +++ b/editor/plugins/line_2d_editor_plugin.cpp @@ -30,6 +30,9 @@ #include "line_2d_editor_plugin.h" +#include "editor/editor_node.h" +#include "editor/editor_undo_redo_manager.h" + Node2D *Line2DEditor::_get_node() const { return node; } @@ -51,9 +54,10 @@ void Line2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) const { } void Line2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) { - Node2D *node = _get_node(); - undo_redo->add_do_method(node, "set_points", p_polygon); - undo_redo->add_undo_method(node, "set_points", p_previous); + Node2D *_node = _get_node(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->add_do_method(_node, "set_points", p_polygon); + undo_redo->add_undo_method(_node, "set_points", p_previous); } Line2DEditor::Line2DEditor() {} diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index fe7713f175..759c1c967d 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -72,15 +72,15 @@ void MaterialEditor::_update_theme_item_cache() { void MaterialEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - light_1_switch->set_normal_texture(theme_cache.light_1_on); - light_1_switch->set_pressed_texture(theme_cache.light_1_off); - light_2_switch->set_normal_texture(theme_cache.light_2_on); - light_2_switch->set_pressed_texture(theme_cache.light_2_off); - - sphere_switch->set_normal_texture(theme_cache.sphere_off); - sphere_switch->set_pressed_texture(theme_cache.sphere_on); - box_switch->set_normal_texture(theme_cache.box_off); - box_switch->set_pressed_texture(theme_cache.box_on); + light_1_switch->set_texture_normal(theme_cache.light_1_on); + light_1_switch->set_texture_pressed(theme_cache.light_1_off); + light_2_switch->set_texture_normal(theme_cache.light_2_on); + light_2_switch->set_texture_pressed(theme_cache.light_2_off); + + sphere_switch->set_texture_normal(theme_cache.sphere_off); + sphere_switch->set_texture_pressed(theme_cache.sphere_on); + box_switch->set_texture_normal(theme_cache.box_off); + box_switch->set_texture_pressed(theme_cache.box_on); } break; case NOTIFICATION_DRAW: { diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 8e64434d8b..7d7d41785b 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -31,6 +31,7 @@ #ifndef MATERIAL_EDITOR_PLUGIN_H #define MATERIAL_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "editor/plugins/editor_resource_conversion_plugin.h" #include "scene/3d/camera_3d.h" @@ -40,12 +41,14 @@ #include "scene/resources/material.h" #include "scene/resources/primitive_meshes.h" +class SubViewport; class SubViewportContainer; +class TextureButton; class MaterialEditor : public Control { GDCLASS(MaterialEditor, Control); - Vector2 rot = Vector2(); + Vector2 rot; HBoxContainer *layout_2d = nullptr; ColorRect *rect_instance = nullptr; diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index be26baaea5..79fbf19f89 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -32,6 +32,8 @@ #include "core/config/project_settings.h" #include "editor/editor_scale.h" +#include "scene/gui/texture_button.h" +#include "scene/main/viewport.h" void MeshEditor::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); @@ -61,10 +63,10 @@ void MeshEditor::_update_theme_item_cache() { void MeshEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - light_1_switch->set_normal_texture(theme_cache.light_1_on); - light_1_switch->set_pressed_texture(theme_cache.light_1_off); - light_2_switch->set_normal_texture(theme_cache.light_2_on); - light_2_switch->set_pressed_texture(theme_cache.light_2_off); + light_1_switch->set_texture_normal(theme_cache.light_1_on); + light_1_switch->set_texture_pressed(theme_cache.light_1_off); + light_2_switch->set_texture_normal(theme_cache.light_2_on); + light_2_switch->set_texture_pressed(theme_cache.light_2_off); } break; } } diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h index 6394cb1171..8eecc909b6 100644 --- a/editor/plugins/mesh_editor_plugin.h +++ b/editor/plugins/mesh_editor_plugin.h @@ -31,6 +31,7 @@ #ifndef MESH_EDITOR_PLUGIN_H #define MESH_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "scene/3d/camera_3d.h" #include "scene/3d/light_3d.h" @@ -39,6 +40,9 @@ #include "scene/resources/camera_attributes.h" #include "scene/resources/material.h" +class SubViewport; +class TextureButton; + class MeshEditor : public SubViewportContainer { GDCLASS(MeshEditor, SubViewportContainer); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index c502d47669..57e8046f32 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -38,6 +38,9 @@ #include "scene/3d/navigation_region_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/gui/box_container.h" +#include "scene/gui/menu_button.h" +#include "scene/resources/concave_polygon_shape_3d.h" +#include "scene/resources/convex_polygon_shape_3d.h" void MeshInstance3DEditor::_node_removed(Node *p_node) { if (p_node == node) { @@ -66,7 +69,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { List<Node *> selection = editor_selection->get_selected_node_list(); if (selection.is_empty()) { - Ref<Shape3D> shape = mesh->create_trimesh_shape(); + Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape(); if (shape.is_null()) { err_dialog->set_text(TTR("Couldn't create a Trimesh collision shape.")); err_dialog->popup_centered(); @@ -105,7 +108,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { continue; } - Ref<Shape3D> shape = m->create_trimesh_shape(); + Ref<ConcavePolygonShape3D> shape = m->create_trimesh_shape(); if (shape.is_null()) { continue; } @@ -137,7 +140,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { return; } - Ref<Shape3D> shape = mesh->create_trimesh_shape(); + Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape(); if (shape.is_null()) { return; } @@ -171,7 +174,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { bool simplify = (p_option == MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE); - Ref<Shape3D> shape = mesh->create_convex_shape(true, simplify); + Ref<ConvexPolygonShape3D> shape = mesh->create_convex_shape(true, simplify); if (shape.is_null()) { err_dialog->set_text(TTR("Couldn't create a single convex collision shape.")); @@ -270,6 +273,24 @@ void MeshInstance3DEditor::_menu_option(int p_option) { case MENU_OPTION_CREATE_OUTLINE_MESH: { outline_dialog->popup_centered(Vector2(200, 90)); } break; + case MENU_OPTION_CREATE_DEBUG_TANGENTS: { + Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Create Debug Tangents")); + + MeshInstance3D *tangents = node->create_debug_tangents_node(); + + if (tangents) { + Node *owner = get_tree()->get_edited_scene_root(); + + ur->add_do_reference(tangents); + ur->add_do_method(node, "add_child", tangents, true); + ur->add_do_method(tangents, "set_owner", owner); + + ur->add_undo_method(node, "remove_child", tangents); + } + + ur->commit_action(); + } break; case MENU_OPTION_CREATE_UV2: { Ref<ArrayMesh> mesh2 = node->get_mesh(); if (!mesh2.is_valid()) { @@ -511,6 +532,7 @@ MeshInstance3DEditor::MeshInstance3DEditor() { options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Outline Mesh..."), MENU_OPTION_CREATE_OUTLINE_MESH); options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a static outline mesh. The outline mesh will have its normals flipped automatically.\nThis can be used instead of the StandardMaterial Grow property when using that property isn't possible.")); + options->get_popup()->add_item(TTR("Create Debug Tangents"), MENU_OPTION_CREATE_DEBUG_TANGENTS); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("View UV1"), MENU_OPTION_DEBUG_UV1); options->get_popup()->add_item(TTR("View UV2"), MENU_OPTION_DEBUG_UV2); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h index 7968176744..81ba263be0 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.h +++ b/editor/plugins/mesh_instance_3d_editor_plugin.h @@ -35,6 +35,10 @@ #include "scene/3d/mesh_instance_3d.h" #include "scene/gui/spin_box.h" +class AcceptDialog; +class ConfirmationDialog; +class MenuButton; + class MeshInstance3DEditor : public Control { GDCLASS(MeshInstance3DEditor, Control); @@ -46,6 +50,7 @@ class MeshInstance3DEditor : public Control { MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES, MENU_OPTION_CREATE_NAVMESH, MENU_OPTION_CREATE_OUTLINE_MESH, + MENU_OPTION_CREATE_DEBUG_TANGENTS, MENU_OPTION_CREATE_UV2, MENU_OPTION_DEBUG_UV1, MENU_OPTION_DEBUG_UV2, diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index 420ebe5942..4a8e5d9979 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -33,11 +33,13 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" +#include "editor/inspector_dock.h" #include "main/main.h" #include "node_3d_editor_plugin.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/navigation_region_3d.h" #include "scene/3d/physics_body_3d.h" +#include "scene/gui/menu_button.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" @@ -191,7 +193,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, } } - Vector<Ref<Texture2D>> textures = EditorInterface::get_singleton()->make_mesh_previews(meshes, &transforms, EditorSettings::get_singleton()->get("editors/grid_map/preview_size")); + Vector<Ref<Texture2D>> textures = EditorInterface::get_singleton()->make_mesh_previews(meshes, &transforms, EDITOR_GET("editors/grid_map/preview_size")); int j = 0; for (int i = 0; i < ids.size(); i++) { if (mesh_instances.find(ids[i])) { diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index b0e206b020..40fac060cd 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -35,6 +35,8 @@ #include "node_3d_editor_plugin.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/gui/box_container.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/option_button.h" void MultiMeshEditor::_node_removed(Node *p_node) { if (p_node == node) { diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h index 5773989d0d..76f86cfa5d 100644 --- a/editor/plugins/multimesh_editor_plugin.h +++ b/editor/plugins/multimesh_editor_plugin.h @@ -36,6 +36,10 @@ #include "scene/gui/slider.h" #include "scene/gui/spin_box.h" +class AcceptDialog; +class ConfirmationDialog; +class MenuButton; +class OptionButton; class SceneTreeDialog; class MultiMeshEditor : public Control { diff --git a/editor/plugins/navigation_link_2d_editor_plugin.cpp b/editor/plugins/navigation_link_2d_editor_plugin.cpp index b72f639fbf..560454e5d3 100644 --- a/editor/plugins/navigation_link_2d_editor_plugin.cpp +++ b/editor/plugins/navigation_link_2d_editor_plugin.cpp @@ -85,6 +85,7 @@ bool NavigationLink2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e end_grabbed = false; } } else { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (start_grabbed) { undo_redo->create_action(TTR("Set start_location")); undo_redo->add_do_method(node, "set_start_location", node->get_start_location()); @@ -165,10 +166,6 @@ void NavigationLink2DEditor::edit(NavigationLink2D *p_node) { canvas_item_editor->update_viewport(); } -NavigationLink2DEditor::NavigationLink2DEditor() { - undo_redo = EditorNode::get_undo_redo(); -} - /////////////////////// void NavigationLink2DEditorPlugin::edit(Object *p_object) { diff --git a/editor/plugins/navigation_link_2d_editor_plugin.h b/editor/plugins/navigation_link_2d_editor_plugin.h index 0a3d9b8810..fea9f58a40 100644 --- a/editor/plugins/navigation_link_2d_editor_plugin.h +++ b/editor/plugins/navigation_link_2d_editor_plugin.h @@ -35,12 +35,10 @@ #include "scene/2d/navigation_link_2d.h" class CanvasItemEditor; -class EditorUndoRedoManager; class NavigationLink2DEditor : public Control { GDCLASS(NavigationLink2DEditor, Control); - Ref<EditorUndoRedoManager> undo_redo; CanvasItemEditor *canvas_item_editor = nullptr; NavigationLink2D *node = nullptr; @@ -58,8 +56,6 @@ public: bool forward_canvas_gui_input(const Ref<InputEvent> &p_event); void forward_canvas_draw_over_viewport(Control *p_overlay); void edit(NavigationLink2D *p_node); - - NavigationLink2DEditor(); }; class NavigationLink2DEditorPlugin : public EditorPlugin { diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index 8f3553b8cf..664e18f555 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -30,6 +30,9 @@ #include "navigation_polygon_editor_plugin.h" +#include "editor/editor_node.h" +#include "editor/editor_undo_redo_manager.h" + Ref<NavigationPolygon> NavigationPolygonEditor::_ensure_navpoly() const { Ref<NavigationPolygon> navpoly = node->get_navigation_polygon(); if (!navpoly.is_valid()) { @@ -73,6 +76,7 @@ void NavigationPolygonEditor::_set_polygon(int p_idx, const Variant &p_polygon) void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) { Ref<NavigationPolygon> navpoly = _ensure_navpoly(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(navpoly.ptr(), "add_outline", p_polygon); undo_redo->add_undo_method(navpoly.ptr(), "remove_outline", navpoly->get_outline_count()); undo_redo->add_do_method(navpoly.ptr(), "make_polygons_from_outlines"); @@ -81,6 +85,7 @@ void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) { void NavigationPolygonEditor::_action_remove_polygon(int p_idx) { Ref<NavigationPolygon> navpoly = _ensure_navpoly(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(navpoly.ptr(), "remove_outline", p_idx); undo_redo->add_undo_method(navpoly.ptr(), "add_outline_at_index", navpoly->get_outline(p_idx), p_idx); undo_redo->add_do_method(navpoly.ptr(), "make_polygons_from_outlines"); @@ -89,6 +94,7 @@ void NavigationPolygonEditor::_action_remove_polygon(int p_idx) { void NavigationPolygonEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) { Ref<NavigationPolygon> navpoly = _ensure_navpoly(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(navpoly.ptr(), "set_outline", p_idx, p_polygon); undo_redo->add_undo_method(navpoly.ptr(), "set_outline", p_idx, p_previous); undo_redo->add_do_method(navpoly.ptr(), "make_polygons_from_outlines"); @@ -104,6 +110,7 @@ void NavigationPolygonEditor::_create_resource() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Create Navigation Polygon")); undo_redo->add_do_method(node, "set_navigation_polygon", Ref<NavigationPolygon>(memnew(NavigationPolygon))); undo_redo->add_undo_method(node, "set_navigation_polygon", Variant(Ref<RefCounted>())); diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index ec6ea7f39b..0af2a13df2 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -110,7 +110,9 @@ void EditorNode3DGizmo::clear() { collision_mesh = Ref<TriangleMesh>(); instances.clear(); handles.clear(); + handle_ids.clear(); secondary_handles.clear(); + secondary_handle_ids.clear(); } void EditorNode3DGizmo::redraw() { @@ -231,7 +233,7 @@ void EditorNode3DGizmo::commit_subgizmos(const Vector<int> &p_ids, const Vector< gizmo_plugin->commit_subgizmos(this, p_ids, p_restore, p_cancel); } -void EditorNode3DGizmo::set_spatial_node(Node3D *p_node) { +void EditorNode3DGizmo::set_node_3d(Node3D *p_node) { ERR_FAIL_NULL(p_node); spatial_node = p_node; } @@ -406,12 +408,15 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< return; } - ERR_FAIL_COND(!spatial_node); + ERR_FAIL_NULL(spatial_node); + + Vector<Vector3> &handle_list = p_secondary ? secondary_handles : handles; + Vector<int> &id_list = p_secondary ? secondary_handle_ids : handle_ids; if (p_ids.is_empty()) { - ERR_FAIL_COND_MSG((!handles.is_empty() && !handle_ids.is_empty()) || (!secondary_handles.is_empty() && !secondary_handle_ids.is_empty()), "Fail"); + ERR_FAIL_COND_MSG(!id_list.is_empty(), "IDs must be provided for all handles, as handles with IDs already exist."); } else { - ERR_FAIL_COND_MSG(handles.size() != handle_ids.size() || secondary_handles.size() != secondary_handle_ids.size(), "Fail"); + ERR_FAIL_COND_MSG(p_handles.size() != p_ids.size(), "The number of IDs should be the same as the number of handles."); } bool is_current_hover_gizmo = Node3DEditor::get_singleton()->get_current_hover_gizmo() == this; @@ -464,19 +469,17 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref< } instances.push_back(ins); - Vector<Vector3> &h = p_secondary ? secondary_handles : handles; - int current_size = h.size(); - h.resize(current_size + p_handles.size()); + int current_size = handle_list.size(); + handle_list.resize(current_size + p_handles.size()); for (int i = 0; i < p_handles.size(); i++) { - h.write[current_size + i] = p_handles[i]; + handle_list.write[current_size + i] = p_handles[i]; } if (!p_ids.is_empty()) { - Vector<int> &ids = p_secondary ? secondary_handle_ids : handle_ids; - current_size = ids.size(); - ids.resize(current_size + p_ids.size()); + current_size = id_list.size(); + id_list.resize(current_size + p_ids.size()); for (int i = 0; i < p_ids.size(); i++) { - ids.write[current_size + i] = p_ids[i]; + id_list.write[current_size + i] = p_ids[i]; } } } @@ -839,8 +842,8 @@ void EditorNode3DGizmo::_bind_methods() { ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles"), &EditorNode3DGizmo::add_collision_triangles); ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale", "modulate"), &EditorNode3DGizmo::add_unscaled_billboard, DEFVAL(1), DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("add_handles", "handles", "material", "ids", "billboard", "secondary"), &EditorNode3DGizmo::add_handles, DEFVAL(false), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorNode3DGizmo::_set_spatial_node); - ClassDB::bind_method(D_METHOD("get_spatial_node"), &EditorNode3DGizmo::get_spatial_node); + ClassDB::bind_method(D_METHOD("set_node_3d", "node"), &EditorNode3DGizmo::_set_node_3d); + ClassDB::bind_method(D_METHOD("get_node_3d"), &EditorNode3DGizmo::get_node_3d); ClassDB::bind_method(D_METHOD("get_plugin"), &EditorNode3DGizmo::get_plugin); ClassDB::bind_method(D_METHOD("clear"), &EditorNode3DGizmo::clear); ClassDB::bind_method(D_METHOD("set_hidden", "hidden"), &EditorNode3DGizmo::set_hidden); @@ -1039,7 +1042,7 @@ Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::get_gizmo(Node3D *p_spatial) { } ref->set_plugin(this); - ref->set_spatial_node(p_spatial); + ref->set_node_3d(p_spatial); ref->set_hidden(current_state == HIDDEN); current_gizmos.push_back(ref.ptr()); @@ -1078,11 +1081,9 @@ void EditorNode3DGizmoPlugin::_bind_methods() { } bool EditorNode3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { - bool success; - if (GDVIRTUAL_CALL(_has_gizmo, p_spatial, success)) { - return success; - } - return false; + bool success = false; + GDVIRTUAL_CALL(_has_gizmo, p_spatial, success); + return success; } Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::create_gizmo(Node3D *p_spatial) { @@ -1099,19 +1100,15 @@ Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::create_gizmo(Node3D *p_spatial) } bool EditorNode3DGizmoPlugin::can_be_hidden() const { - bool ret; - if (GDVIRTUAL_CALL(_can_be_hidden, ret)) { - return ret; - } - return true; + bool ret = true; + GDVIRTUAL_CALL(_can_be_hidden, ret); + return ret; } bool EditorNode3DGizmoPlugin::is_selectable_when_hidden() const { - bool ret; - if (GDVIRTUAL_CALL(_is_selectable_when_hidden, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_is_selectable_when_hidden, ret); + return ret; } void EditorNode3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { @@ -1119,27 +1116,21 @@ void EditorNode3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } bool EditorNode3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - bool ret; - if (GDVIRTUAL_CALL(_is_handle_highlighted, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_is_handle_highlighted, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret); + return ret; } String EditorNode3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { String ret; - if (GDVIRTUAL_CALL(_get_handle_name, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) { - return ret; - } - return ""; + GDVIRTUAL_CALL(_get_handle_name, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret); + return ret; } Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { Variant ret; - if (GDVIRTUAL_CALL(_get_handle_value, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) { - return ret; - } - return Variant(); + GDVIRTUAL_CALL(_get_handle_value, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret); + return ret; } void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { @@ -1151,34 +1142,26 @@ void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, in } int EditorNode3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const { - int ret; - if (GDVIRTUAL_CALL(_subgizmos_intersect_ray, Ref<EditorNode3DGizmo>(p_gizmo), p_camera, p_point, ret)) { - return ret; - } - return -1; + int ret = -1; + GDVIRTUAL_CALL(_subgizmos_intersect_ray, Ref<EditorNode3DGizmo>(p_gizmo), p_camera, p_point, ret); + return ret; } Vector<int> EditorNode3DGizmoPlugin::subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const { - TypedArray<Transform3D> frustum; + TypedArray<Plane> frustum; frustum.resize(p_frustum.size()); for (int i = 0; i < p_frustum.size(); i++) { frustum[i] = p_frustum[i]; } Vector<int> ret; - if (GDVIRTUAL_CALL(_subgizmos_intersect_frustum, Ref<EditorNode3DGizmo>(p_gizmo), p_camera, frustum, ret)) { - return ret; - } - - return Vector<int>(); + GDVIRTUAL_CALL(_subgizmos_intersect_frustum, Ref<EditorNode3DGizmo>(p_gizmo), p_camera, frustum, ret); + return ret; } Transform3D EditorNode3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const { Transform3D ret; - if (GDVIRTUAL_CALL(_get_subgizmo_transform, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) { - return ret; - } - - return Transform3D(); + GDVIRTUAL_CALL(_get_subgizmo_transform, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret); + return ret; } void EditorNode3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) { @@ -1217,7 +1200,7 @@ EditorNode3DGizmoPlugin::EditorNode3DGizmoPlugin() { EditorNode3DGizmoPlugin::~EditorNode3DGizmoPlugin() { for (int i = 0; i < current_gizmos.size(); ++i) { current_gizmos[i]->set_plugin(nullptr); - current_gizmos[i]->get_spatial_node()->remove_gizmo(current_gizmos[i]); + current_gizmos[i]->get_node_3d()->remove_gizmo(current_gizmos[i]); } if (Node3DEditor::get_singleton()) { Node3DEditor::get_singleton()->update_all_gizmos(); @@ -1261,7 +1244,7 @@ String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int } Variant Light3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); + Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_node_3d()); if (p_id == 0) { return light->get_param(Light3D::PARAM_RANGE); } @@ -1300,7 +1283,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec } void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); + Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_node_3d()); Transform3D gt = light->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -1344,7 +1327,7 @@ void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, } void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); + Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_node_3d()); if (p_cancel) { light->set_param(p_id == 0 ? Light3D::PARAM_RANGE : Light3D::PARAM_SPOT_ANGLE, p_restore); @@ -1364,7 +1347,7 @@ void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_i } void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); + Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_node_3d()); Color color = light->get_color().srgb_to_linear() * light->get_correlated_color().srgb_to_linear(); color = color.linear_to_srgb(); @@ -1526,12 +1509,12 @@ String AudioStreamPlayer3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo * } Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); + AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_node_3d()); return player->get_emission_angle(); } void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); + AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_node_3d()); Transform3D gt = player->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -1568,7 +1551,7 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo } void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); + AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_node_3d()); if (p_cancel) { player->set_emission_angle(p_restore); @@ -1583,7 +1566,7 @@ void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gi } void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - const AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); + const AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -1762,7 +1745,7 @@ int Camera3DGizmoPlugin::get_priority() const { } String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); + Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_node_3d()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { return "FOV"; @@ -1772,7 +1755,7 @@ String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, in } Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); + Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_node_3d()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { return camera->get_fov(); @@ -1782,7 +1765,7 @@ Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, } void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); + Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_node_3d()); Transform3D gt = camera->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -1811,7 +1794,7 @@ void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, } void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); + Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_node_3d()); if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { if (p_cancel) { @@ -1838,7 +1821,7 @@ void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_ } void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); + Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -1937,6 +1920,7 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { #undef ADD_QUAD p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); p_gizmo->add_handles(handles, get_material("handles")); } @@ -1962,7 +1946,7 @@ bool MeshInstance3DGizmoPlugin::can_be_hidden() const { } void MeshInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - MeshInstance3D *mesh = Object::cast_to<MeshInstance3D>(p_gizmo->get_spatial_node()); + MeshInstance3D *mesh = Object::cast_to<MeshInstance3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -1998,7 +1982,7 @@ int OccluderInstance3DGizmoPlugin::get_priority() const { } String OccluderInstance3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - const OccluderInstance3D *cs = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + const OccluderInstance3D *cs = Object::cast_to<OccluderInstance3D>(p_gizmo->get_node_3d()); Ref<Occluder3D> o = cs->get_occluder(); if (o.is_null()) { @@ -2017,7 +2001,7 @@ String OccluderInstance3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p } Variant OccluderInstance3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_node_3d()); Ref<Occluder3D> o = oi->get_occluder(); if (o.is_null()) { @@ -2043,7 +2027,7 @@ Variant OccluderInstance3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo } void OccluderInstance3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_node_3d()); Ref<Occluder3D> o = oi->get_occluder(); if (o.is_null()) { @@ -2130,7 +2114,7 @@ void OccluderInstance3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, } void OccluderInstance3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_node_3d()); Ref<Occluder3D> o = oi->get_occluder(); if (o.is_null()) { @@ -2181,7 +2165,7 @@ void OccluderInstance3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_giz } void OccluderInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - OccluderInstance3D *occluder_instance = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node()); + OccluderInstance3D *occluder_instance = Object::cast_to<OccluderInstance3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -2250,7 +2234,7 @@ bool Sprite3DGizmoPlugin::can_be_hidden() const { } void Sprite3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Sprite3D *sprite = Object::cast_to<Sprite3D>(p_gizmo->get_spatial_node()); + Sprite3D *sprite = Object::cast_to<Sprite3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -2282,7 +2266,7 @@ bool Label3DGizmoPlugin::can_be_hidden() const { } void Label3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Label3D *label = Object::cast_to<Label3D>(p_gizmo->get_spatial_node()); + Label3D *label = Object::cast_to<Label3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -2296,10 +2280,10 @@ void Label3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Marker3DGizmoPlugin::Marker3DGizmoPlugin() { pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); - cursor_points = Vector<Vector3>(); + Vector<Vector3> cursor_points; Vector<Color> cursor_colors; - const float cs = 0.25; + const float cs = 1.0; // Add more points to create a "hard stop" in the color gradient. cursor_points.push_back(Vector3(+cs, 0, 0)); cursor_points.push_back(Vector3()); @@ -2367,9 +2351,22 @@ int Marker3DGizmoPlugin::get_priority() const { } void Marker3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + const Marker3D *marker = Object::cast_to<Marker3D>(p_gizmo->get_node_3d()); + const real_t extents = marker->get_gizmo_extents(); + const Transform3D xform(Basis::from_scale(Vector3(extents, extents, extents))); + p_gizmo->clear(); - p_gizmo->add_mesh(pos3d_mesh); - p_gizmo->add_collision_segments(cursor_points); + p_gizmo->add_mesh(pos3d_mesh, Ref<Material>(), xform); + + const Vector<Vector3> points = { + Vector3(-extents, 0, 0), + Vector3(+extents, 0, 0), + Vector3(0, -extents, 0), + Vector3(0, +extents, 0), + Vector3(0, 0, -extents), + Vector3(0, 0, +extents), + }; + p_gizmo->add_collision_segments(points); } //// @@ -2393,7 +2390,7 @@ int PhysicalBone3DGizmoPlugin::get_priority() const { void PhysicalBone3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->clear(); - PhysicalBone3D *physical_bone = Object::cast_to<PhysicalBone3D>(p_gizmo->get_spatial_node()); + PhysicalBone3D *physical_bone = Object::cast_to<PhysicalBone3D>(p_gizmo->get_node_3d()); if (!physical_bone) { return; @@ -2528,7 +2525,7 @@ int RayCast3DGizmoPlugin::get_priority() const { } void RayCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - RayCast3D *raycast = Object::cast_to<RayCast3D>(p_gizmo->get_spatial_node()); + RayCast3D *raycast = Object::cast_to<RayCast3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -2566,7 +2563,7 @@ int ShapeCast3DGizmoPlugin::get_priority() const { } void ShapeCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - ShapeCast3D *shapecast = Object::cast_to<ShapeCast3D>(p_gizmo->get_spatial_node()); + ShapeCast3D *shapecast = Object::cast_to<ShapeCast3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -2584,7 +2581,7 @@ void ShapeCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { ///// void SpringArm3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - SpringArm3D *spring_arm = Object::cast_to<SpringArm3D>(p_gizmo->get_spatial_node()); + SpringArm3D *spring_arm = Object::cast_to<SpringArm3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -2636,7 +2633,7 @@ int VehicleWheel3DGizmoPlugin::get_priority() const { } void VehicleWheel3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - VehicleWheel3D *car_wheel = Object::cast_to<VehicleWheel3D>(p_gizmo->get_spatial_node()); + VehicleWheel3D *car_wheel = Object::cast_to<VehicleWheel3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -2712,7 +2709,7 @@ bool SoftBody3DGizmoPlugin::is_selectable_when_hidden() const { } void SoftBody3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); + SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -2753,17 +2750,17 @@ String SoftBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, } Variant SoftBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); + SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_node_3d()); return Variant(soft_body->is_point_pinned(p_id)); } void SoftBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); + SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_node_3d()); soft_body->pin_point_toggle(p_id); } bool SoftBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); + SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_node_3d()); return soft_body->is_point_pinned(p_id); } @@ -2809,12 +2806,12 @@ String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DG } Variant VisibleOnScreenNotifier3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); + VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_node_3d()); return notifier->get_aabb(); } void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); + VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_node_3d()); Transform3D gt = notifier->get_global_transform(); @@ -2866,7 +2863,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p } void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); + VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_node_3d()); if (p_cancel) { notifier->set_aabb(p_restore); @@ -2881,7 +2878,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo } void VisibleOnScreenNotifier3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node()); + VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -3001,12 +2998,12 @@ String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_giz } Variant GPUParticles3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); + GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d()); return particles->get_visibility_aabb(); } void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); + GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d()); Transform3D gt = particles->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -3057,7 +3054,7 @@ void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int } void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); + GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d()); if (p_cancel) { particles->set_visibility_aabb(p_restore); @@ -3072,7 +3069,7 @@ void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, } void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); + GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -3148,7 +3145,7 @@ int GPUParticlesCollision3DGizmoPlugin::get_priority() const { } String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - const Node3D *cs = p_gizmo->get_spatial_node(); + const Node3D *cs = p_gizmo->get_node_3d(); if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) { return "Radius"; @@ -3162,21 +3159,21 @@ String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGiz } Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - const Node3D *cs = p_gizmo->get_spatial_node(); + const Node3D *cs = p_gizmo->get_node_3d(); if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) { - return p_gizmo->get_spatial_node()->call("get_radius"); + return p_gizmo->get_node_3d()->call("get_radius"); } if (Object::cast_to<GPUParticlesCollisionBox3D>(cs) || Object::cast_to<GPUParticlesAttractorBox3D>(cs) || Object::cast_to<GPUParticlesAttractorVectorField3D>(cs) || Object::cast_to<GPUParticlesCollisionSDF3D>(cs) || Object::cast_to<GPUParticlesCollisionHeightField3D>(cs)) { - return Vector3(p_gizmo->get_spatial_node()->call("get_extents")); + return Vector3(p_gizmo->get_node_3d()->call("get_extents")); } return Variant(); } void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - Node3D *sn = p_gizmo->get_spatial_node(); + Node3D *sn = p_gizmo->get_node_3d(); Transform3D gt = sn->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -3222,7 +3219,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_g } void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - Node3D *sn = p_gizmo->get_spatial_node(); + Node3D *sn = p_gizmo->get_node_3d(); if (Object::cast_to<GPUParticlesCollisionSphere3D>(sn) || Object::cast_to<GPUParticlesAttractorSphere3D>(sn)) { if (p_cancel) { @@ -3252,7 +3249,7 @@ void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo * } void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Node3D *cs = p_gizmo->get_spatial_node(); + Node3D *cs = p_gizmo->get_node_3d(); p_gizmo->clear(); @@ -3430,12 +3427,12 @@ String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gi } Variant ReflectionProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); + ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d()); return AABB(probe->get_extents(), probe->get_origin_offset()); } void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); + ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d()); Transform3D gt = probe->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -3492,7 +3489,7 @@ void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, in } void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); + ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d()); AABB restore = p_restore; @@ -3512,7 +3509,7 @@ void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, } void ReflectionProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); + ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -3609,12 +3606,12 @@ String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p } Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); + Decal *decal = Object::cast_to<Decal>(p_gizmo->get_node_3d()); return decal->get_extents(); } void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); + Decal *decal = Object::cast_to<Decal>(p_gizmo->get_node_3d()); Transform3D gt = decal->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -3645,7 +3642,7 @@ void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bo } void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); + Decal *decal = Object::cast_to<Decal>(p_gizmo->get_node_3d()); Vector3 restore = p_restore; @@ -3662,7 +3659,7 @@ void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, } void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); + Decal *decal = Object::cast_to<Decal>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -3749,12 +3746,12 @@ String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int } Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); + VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d()); return probe->get_extents(); } void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); + VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d()); Transform3D gt = probe->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -3785,7 +3782,7 @@ void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, } void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); + VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d()); Vector3 restore = p_restore; @@ -3802,7 +3799,7 @@ void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_i } void VoxelGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); + VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d()); Ref<Material> material = get_material("voxel_gi_material", p_gizmo); Ref<Material> icon = get_material("voxel_gi_icon", p_gizmo); @@ -3913,7 +3910,7 @@ int LightmapGIGizmoPlugin::get_priority() const { void LightmapGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Ref<Material> icon = get_material("baked_indirect_light_icon", p_gizmo); - LightmapGI *baker = Object::cast_to<LightmapGI>(p_gizmo->get_spatial_node()); + LightmapGI *baker = Object::cast_to<LightmapGI>(p_gizmo->get_node_3d()); Ref<LightmapGIData> data = baker->get_light_data(); p_gizmo->add_unscaled_billboard(icon, 0.05); @@ -4163,13 +4160,13 @@ int CollisionObject3DGizmoPlugin::get_priority() const { } void CollisionObject3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_gizmo->get_spatial_node()); + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); - List<uint32_t> owners; - co->get_shape_owners(&owners); - for (uint32_t &owner_id : owners) { + List<uint32_t> owner_ids; + co->get_shape_owners(&owner_ids); + for (uint32_t &owner_id : owner_ids) { Transform3D xform = co->shape_owner_get_transform(owner_id); Object *owner = co->shape_owner_get_owner(owner_id); // Exclude CollisionShape3D and CollisionPolygon3D as they have their gizmo. @@ -4214,7 +4211,7 @@ int CollisionShape3DGizmoPlugin::get_priority() const { } String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - const CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); + const CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_node_3d()); Ref<Shape3D> s = cs->get_shape(); if (s.is_null()) { @@ -4245,7 +4242,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g } Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); + CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_node_3d()); Ref<Shape3D> s = cs->get_shape(); if (s.is_null()) { @@ -4281,7 +4278,7 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p } void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); + CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_node_3d()); Ref<Shape3D> s = cs->get_shape(); if (s.is_null()) { @@ -4395,7 +4392,7 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i } void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); + CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_node_3d()); Ref<Shape3D> s = cs->get_shape(); if (s.is_null()) { @@ -4499,7 +4496,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo } void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node()); + CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -4751,9 +4748,9 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (err == OK) { Vector<Vector3> points2; points2.resize(md.edges.size() * 2); - for (int i = 0; i < md.edges.size(); i++) { - points2.write[i * 2 + 0] = md.vertices[md.edges[i].a]; - points2.write[i * 2 + 1] = md.vertices[md.edges[i].b]; + for (uint32_t i = 0; i < md.edges.size(); i++) { + points2.write[i * 2 + 0] = md.vertices[md.edges[i].vertex_a]; + points2.write[i * 2 + 1] = md.vertices[md.edges[i].vertex_b]; } p_gizmo->add_lines(points2, material); @@ -4814,7 +4811,7 @@ int CollisionPolygon3DGizmoPlugin::get_priority() const { } void CollisionPolygon3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - CollisionPolygon3D *polygon = Object::cast_to<CollisionPolygon3D>(p_gizmo->get_spatial_node()); + CollisionPolygon3D *polygon = Object::cast_to<CollisionPolygon3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -4861,7 +4858,7 @@ int NavigationRegion3DGizmoPlugin::get_priority() const { } void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - NavigationRegion3D *navigationregion = Object::cast_to<NavigationRegion3D>(p_gizmo->get_spatial_node()); + NavigationRegion3D *navigationregion = Object::cast_to<NavigationRegion3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); Ref<NavigationMesh> navigationmesh = navigationregion->get_navigation_mesh(); @@ -5021,7 +5018,7 @@ int NavigationLink3DGizmoPlugin::get_priority() const { } void NavigationLink3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node()); + NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_node_3d()); RID nav_map = link->get_world_3d()->get_navigation_map(); real_t search_radius = NavigationServer3D::get_singleton()->map_get_link_connection_radius(nav_map); @@ -5106,12 +5103,12 @@ String NavigationLink3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g } Variant NavigationLink3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node()); + NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_node_3d()); return p_id == 0 ? link->get_start_location() : link->get_end_location(); } void NavigationLink3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node()); + NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_node_3d()); Transform3D gt = link->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -5144,7 +5141,7 @@ void NavigationLink3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i } void NavigationLink3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node()); + NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_node_3d()); if (p_cancel) { if (p_id == 0) { @@ -5444,7 +5441,7 @@ int Joint3DGizmoPlugin::get_priority() const { } void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Joint3D *joint = Object::cast_to<Joint3D>(p_gizmo->get_spatial_node()); + Joint3D *joint = Object::cast_to<Joint3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); @@ -5877,11 +5874,11 @@ String FogVolumeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, i } Variant FogVolumeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { - return Vector3(p_gizmo->get_spatial_node()->call("get_extents")); + return Vector3(p_gizmo->get_node_3d()->call("get_extents")); } void FogVolumeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) { - Node3D *sn = p_gizmo->get_spatial_node(); + Node3D *sn = p_gizmo->get_node_3d(); Transform3D gt = sn->get_global_transform(); Transform3D gi = gt.affine_inverse(); @@ -5910,7 +5907,7 @@ void FogVolumeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id } void FogVolumeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { - Node3D *sn = p_gizmo->get_spatial_node(); + Node3D *sn = p_gizmo->get_node_3d(); if (p_cancel) { sn->call("set_extents", p_restore); @@ -5925,11 +5922,11 @@ void FogVolumeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p } void FogVolumeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Node3D *cs = p_gizmo->get_spatial_node(); + Node3D *cs = p_gizmo->get_node_3d(); p_gizmo->clear(); - if (RS::FogVolumeShape(int(p_gizmo->get_spatial_node()->call("get_shape"))) != RS::FOG_VOLUME_SHAPE_WORLD) { + if (RS::FogVolumeShape(int(p_gizmo->get_node_3d()->call("get_shape"))) != RS::FOG_VOLUME_SHAPE_WORLD) { const Ref<Material> material = get_material("shape_material", p_gizmo); const Ref<Material> material_internal = diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index 5924f8571a..d7e3e03f61 100644 --- a/editor/plugins/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -72,7 +72,7 @@ class EditorNode3DGizmo : public Node3DGizmo { Vector<Instance> instances; Node3D *spatial_node = nullptr; - void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to<Node3D>(p_node)); } + void _set_node_3d(Node *p_node) { set_node_3d(Object::cast_to<Node3D>(p_node)); } protected: static void _bind_methods(); @@ -116,8 +116,8 @@ public: void set_selected(bool p_selected) { selected = p_selected; } bool is_selected() const { return selected; } - void set_spatial_node(Node3D *p_node); - Node3D *get_spatial_node() const { return spatial_node; } + void set_node_3d(Node3D *p_node); + Node3D *get_node_3d() const { return spatial_node; } Ref<EditorNode3DGizmoPlugin> get_plugin() const { return gizmo_plugin; } bool intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum); void handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id, bool &r_secondary); @@ -338,7 +338,6 @@ class Marker3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(Marker3DGizmoPlugin, EditorNode3DGizmoPlugin); Ref<ArrayMesh> pos3d_mesh; - Vector<Vector3> cursor_points; public: bool has_gizmo(Node3D *p_spatial) override; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index c8b49678d2..df1fd52b69 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -36,13 +36,12 @@ #include "core/math/math_funcs.h" #include "core/math/projection.h" #include "core/os/keyboard.h" -#include "core/templates/sort_array.h" #include "editor/debugger/editor_debugger_node.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/node_3d_editor_gizmos.h" -#include "editor/plugins/script_editor_plugin.h" #include "editor/scene_tree_dock.h" #include "scene/3d/camera_3d.h" #include "scene/3d/collision_shape_3d.h" @@ -53,9 +52,12 @@ #include "scene/3d/visual_instance_3d.h" #include "scene/3d/world_environment.h" #include "scene/gui/center_container.h" +#include "scene/gui/color_picker.h" #include "scene/gui/flow_container.h" +#include "scene/gui/split_container.h" #include "scene/gui/subviewport_container.h" #include "scene/resources/packed_scene.h" +#include "scene/resources/sky_material.h" #include "scene/resources/surface_tool.h" constexpr real_t DISTANCE_DEFAULT = 4; @@ -939,7 +941,7 @@ void Node3DEditorViewport::_compute_edit(const Point2 &p_point) { } static Key _get_key_modifier_setting(const String &p_property) { - switch (EditorSettings::get_singleton()->get(p_property).operator int()) { + switch (EDITOR_GET(p_property).operator int()) { case 0: return Key::NONE; case 1: @@ -1328,7 +1330,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { } } - String suffix = String(); + String suffix; if (locked == 1) { suffix = " (" + TTR("Locked") + ")"; } else if (locked == 2) { @@ -1356,7 +1358,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { EditorNode *en = EditorNode::get_singleton(); EditorPluginList *force_input_forwarding_list = en->get_editor_plugins_force_input_forwarding(); if (!force_input_forwarding_list->is_empty()) { - EditorPlugin::AfterGUIInput discard = force_input_forwarding_list->forward_spatial_gui_input(camera, p_event, true); + EditorPlugin::AfterGUIInput discard = force_input_forwarding_list->forward_3d_gui_input(camera, p_event, true); if (discard == EditorPlugin::AFTER_GUI_INPUT_STOP) { return; } @@ -1369,7 +1371,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { EditorNode *en = EditorNode::get_singleton(); EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); if (!over_plugin_list->is_empty()) { - EditorPlugin::AfterGUIInput discard = over_plugin_list->forward_spatial_gui_input(camera, p_event, false); + EditorPlugin::AfterGUIInput discard = over_plugin_list->forward_3d_gui_input(camera, p_event, false); if (discard == EditorPlugin::AFTER_GUI_INPUT_STOP) { return; } @@ -1401,7 +1403,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } break; case MouseButton::RIGHT: { - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); + NavigationScheme nav_scheme = (NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int(); if (b->is_pressed() && _edit.gizmo.is_valid()) { //restore @@ -1481,7 +1483,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { commit_transform(); break; // just commit the edit, stop processing the event so we don't deselect the object } - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); + NavigationScheme nav_scheme = (NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int(); if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->is_alt_pressed()) { break; } @@ -1650,12 +1652,12 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } se->gizmo->commit_subgizmos(ids, restore, false); - spatial_editor->update_transform_gizmo(); } else { commit_transform(); } _edit.mode = TRANSFORM_NONE; set_message(""); + spatial_editor->update_transform_gizmo(); } surface->queue_redraw(); } @@ -1709,7 +1711,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { _transform_gizmo_select(_edit.mouse_pos, true); } - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); + NavigationScheme nav_scheme = (NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int(); NavigationMode nav_mode = NAVIGATION_NONE; if (_edit.gizmo.is_valid()) { @@ -1782,7 +1784,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { nav_mode = NAVIGATION_PAN; } } - } else if (EditorSettings::get_singleton()->get("editors/3d/navigation/emulate_3_button_mouse")) { + } else if (EDITOR_GET("editors/3d/navigation/emulate_3_button_mouse")) { // Handle trackpad (no external mouse) use case const Key mod = _get_key_modifier(m); @@ -1835,7 +1837,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid()) { - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); + NavigationScheme nav_scheme = (NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int(); NavigationMode nav_mode = NAVIGATION_NONE; if (nav_scheme == NAVIGATION_GODOT) { @@ -1889,7 +1891,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { return; } - if (EditorSettings::get_singleton()->get("editors/3d/navigation/emulate_numpad")) { + if (EDITOR_GET("editors/3d/navigation/emulate_numpad")) { const Key code = k->get_physical_keycode(); if (code >= Key::KEY_0 && code <= Key::KEY_9) { k->set_keycode(code - Key::KEY_0 + Key::KP_0); @@ -2086,7 +2088,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) { - const NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); + const NavigationScheme nav_scheme = (NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int(); real_t pan_speed = 1 / 150.0; if (nav_scheme == NAVIGATION_MAYA && p_event->is_shift_pressed()) { @@ -2098,8 +2100,8 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const camera_transform.translate_local(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); - const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis"); - const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + const bool invert_x_axis = EDITOR_GET("editors/3d/navigation/invert_x_axis"); + const bool invert_y_axis = EDITOR_GET("editors/3d/navigation/invert_y_axis"); Vector3 translation( (invert_x_axis ? -1 : 1) * -p_relative.x * pan_speed, (invert_y_axis ? -1 : 1) * p_relative.y * pan_speed, @@ -2110,14 +2112,14 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const } void Node3DEditorViewport::_nav_zoom(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) { - const NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); + const NavigationScheme nav_scheme = (NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int(); real_t zoom_speed = 1 / 80.0; if (nav_scheme == NAVIGATION_MAYA && p_event->is_shift_pressed()) { zoom_speed *= 10; } - NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/navigation/zoom_style").operator int(); + NavigationZoomStyle zoom_style = (NavigationZoomStyle)EDITOR_GET("editors/3d/navigation/zoom_style").operator int(); if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) { if (p_relative.x > 0) { scale_cursor_distance(1 - p_relative.x * zoom_speed); @@ -2143,10 +2145,10 @@ void Node3DEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, cons _menu_option(VIEW_PERSPECTIVE); } - const real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); + const real_t degrees_per_pixel = EDITOR_GET("editors/3d/navigation_feel/orbit_sensitivity"); const real_t radians_per_pixel = Math::deg_to_rad(degrees_per_pixel); - const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); - const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis"); + const bool invert_y_axis = EDITOR_GET("editors/3d/navigation/invert_y_axis"); + const bool invert_x_axis = EDITOR_GET("editors/3d/navigation/invert_x_axis"); if (invert_y_axis) { cursor.x_rot -= p_relative.y * radians_per_pixel; @@ -2176,9 +2178,9 @@ void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const } // Scale mouse sensitivity with camera FOV scale when zoomed in to make it easier to point at things. - const real_t degrees_per_pixel = real_t(EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_sensitivity")) * MIN(1.0, cursor.fov_scale); + const real_t degrees_per_pixel = real_t(EDITOR_GET("editors/3d/freelook/freelook_sensitivity")) * MIN(1.0, cursor.fov_scale); const real_t radians_per_pixel = Math::deg_to_rad(degrees_per_pixel); - const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); + const bool invert_y_axis = EDITOR_GET("editors/3d/navigation/invert_y_axis"); // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag". const Transform3D prev_camera_transform = to_camera_transform(cursor); @@ -2215,9 +2217,9 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) { // Also sync the camera cursor, otherwise switching to freelook will be trippy if inertia is active camera_cursor.eye_pos = cursor.eye_pos; - if (EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_speed_zoom_link")) { + if (EDITOR_GET("editors/3d/freelook/freelook_speed_zoom_link")) { // Re-adjust freelook speed from the current zoom level - real_t base_speed = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_base_speed"); + real_t base_speed = EDITOR_GET("editors/3d/freelook/freelook_base_speed"); freelook_speed = base_speed * cursor.distance; } @@ -2299,7 +2301,7 @@ void Node3DEditorViewport::_update_freelook(real_t delta) { return; } - const FreelookNavigationScheme navigation_scheme = (FreelookNavigationScheme)EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_navigation_scheme").operator int(); + const FreelookNavigationScheme navigation_scheme = (FreelookNavigationScheme)EDITOR_GET("editors/3d/freelook/freelook_navigation_scheme").operator int(); Vector3 forward; if (navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) { @@ -2375,12 +2377,12 @@ void Node3DEditorPlugin::edited_scene_changed() { void Node3DEditorViewport::_project_settings_changed() { //update shadow atlas if changed - int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_size"); - bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_16_bits"); - int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_0_subdiv"); - int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_1_subdiv"); - int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_2_subdiv"); - int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_3_subdiv"); + int shadowmap_size = GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/atlas_size"); + bool shadowmap_16_bits = GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/atlas_16_bits"); + int atlas_q0 = GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_0_subdiv"); + int atlas_q1 = GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_1_subdiv"); + int atlas_q2 = GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_2_subdiv"); + int atlas_q3 = GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_3_subdiv"); viewport->set_positional_shadow_atlas_size(shadowmap_size); viewport->set_positional_shadow_atlas_16_bits(shadowmap_16_bits); @@ -2393,13 +2395,16 @@ void Node3DEditorViewport::_project_settings_changed() { // Update MSAA, screen-space AA and debanding if changed - const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/anti_aliasing/quality/msaa_3d"); + const int msaa_mode = GLOBAL_GET("rendering/anti_aliasing/quality/msaa_3d"); viewport->set_msaa_3d(Viewport::MSAA(msaa_mode)); const int ssaa_mode = GLOBAL_GET("rendering/anti_aliasing/quality/screen_space_aa"); viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); const bool use_taa = GLOBAL_GET("rendering/anti_aliasing/quality/use_taa"); viewport->set_use_taa(use_taa); + const bool transparent_background = GLOBAL_GET("rendering/transparent_background"); + viewport->set_transparent_background(transparent_background); + const bool use_debanding = GLOBAL_GET("rendering/anti_aliasing/quality/use_debanding"); viewport->set_use_debanding(use_debanding); @@ -2429,11 +2434,12 @@ void Node3DEditorViewport::_notification(int p_what) { } break; case NOTIFICATION_VISIBILITY_CHANGED: { - bool visible = is_visible_in_tree(); + bool vp_visible = is_visible_in_tree(); - set_process(visible); + set_process(vp_visible); + set_physics_process(vp_visible); - if (visible) { + if (vp_visible) { orthogonal = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL)); _update_name(); _update_camera(0); @@ -2441,7 +2447,7 @@ void Node3DEditorViewport::_notification(int p_what) { set_freelook_active(false); } call_deferred(SNAME("update_transform_gizmo_view")); - rotation_control->set_visible(EditorSettings::get_singleton()->get("editors/3d/navigation/show_viewport_rotation_gizmo")); + rotation_control->set_visible(EDITOR_GET("editors/3d/navigation/show_viewport_rotation_gizmo")); } break; case NOTIFICATION_RESIZED: { @@ -2655,6 +2661,21 @@ void Node3DEditorViewport::_notification(int p_what) { } } break; + case NOTIFICATION_PHYSICS_PROCESS: { + if (!update_preview_node) { + return; + } + if (preview_node->is_inside_tree()) { + preview_node_pos = spatial_editor->snap_point(_get_instance_position(preview_node_viewport_pos)); + Transform3D preview_gl_transform = Transform3D(Basis(), preview_node_pos); + preview_node->set_global_transform(preview_gl_transform); + if (!preview_node->is_visible()) { + preview_node->show(); + } + } + update_preview_node = false; + } break; + case NOTIFICATION_ENTER_TREE: { surface->connect("draw", callable_mp(this, &Node3DEditorViewport::_draw)); surface->connect("gui_input", callable_mp(this, &Node3DEditorViewport::_sinput)); @@ -2735,12 +2756,12 @@ static void draw_indicator_bar(Control &p_surface, real_t p_fill, const Ref<Text void Node3DEditorViewport::_draw() { EditorPluginList *over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_over(); if (!over_plugin_list->is_empty()) { - over_plugin_list->forward_spatial_draw_over_viewport(surface); + over_plugin_list->forward_3d_draw_over_viewport(surface); } EditorPluginList *force_over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_force_over(); if (!force_over_plugin_list->is_empty()) { - force_over_plugin_list->forward_spatial_force_draw_over_viewport(surface); + force_over_plugin_list->forward_3d_force_draw_over_viewport(surface); } if (surface->has_focus()) { @@ -2802,7 +2823,7 @@ void Node3DEditorViewport::_draw() { Math::round(2 * EDSCALE)); } if (previewing) { - Size2 ss = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); + Size2 ss = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height")); float aspect = ss.aspect(); Size2 s = get_size(); @@ -2879,6 +2900,7 @@ void Node3DEditorViewport::_draw() { } void Node3DEditorViewport::_menu_option(int p_option) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (p_option) { case VIEW_TOP: { cursor.y_rot = 0; @@ -2967,7 +2989,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { Transform3D xform; if (orthogonal) { xform = sp->get_global_transform(); - xform.basis.set_euler(camera_transform.basis.get_euler()); + xform.basis = Basis::from_euler(camera_transform.basis.get_euler()); } else { xform = camera_transform; xform.scale_basis(sp->get_scale()); @@ -3445,7 +3467,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { const real_t d1 = camera->unproject_position(camera_xform.origin + camz * gizmo_d + camy).y; const real_t dd = MAX(Math::abs(d0 - d1), CMP_EPSILON); - const real_t gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size"); + const real_t gizmo_size = EDITOR_GET("editors/3d/manipulator_gizmo_size"); // At low viewport heights, multiply the gizmo scale based on the viewport height. // This prevents the gizmo from growing very large and going outside the viewport. const int viewport_base_height = 400 * MAX(1, EDSCALE); @@ -3471,7 +3493,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { } for (int i = 0; i < 3; i++) { - Transform3D axis_angle = Transform3D(); + Transform3D axis_angle; if (xform.basis.get_column(i).normalized().dot(xform.basis.get_column((i + 1) % 3).normalized()) < 1.0) { axis_angle = axis_angle.looking_at(xform.basis.get_column(i).normalized(), xform.basis.get_column((i + 1) % 3).normalized()); } @@ -3729,24 +3751,45 @@ void Node3DEditorViewport::assign_pending_data_pointers(Node3D *p_preview_node, Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const { const float MAX_DISTANCE = 50.0; + const float FALLBACK_DISTANCE = 5.0; Vector3 world_ray = _get_ray(p_pos); Vector3 world_pos = _get_ray_pos(p_pos); - Vector3 point = world_pos + world_ray * MAX_DISTANCE; - PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state(); PhysicsDirectSpaceState3D::RayParameters ray_params; ray_params.from = world_pos; - ray_params.to = world_pos + world_ray * MAX_DISTANCE; + ray_params.to = world_pos + world_ray * camera->get_far(); PhysicsDirectSpaceState3D::RayResult result; if (ss->intersect_ray(ray_params, result)) { - point = result.position; + return result.position; } - return point; + const bool is_orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL; + + // The XZ plane. + Vector3 intersection; + Plane plane(Vector3(0, 1, 0)); + if (plane.intersects_ray(world_pos, world_ray, &intersection)) { + if (is_orthogonal || world_pos.distance_to(intersection) <= MAX_DISTANCE) { + return intersection; + } + } + + // Plane facing the camera using fallback distance. + if (is_orthogonal) { + plane = Plane(world_ray, cursor.pos - world_ray * (cursor.distance - FALLBACK_DISTANCE)); + } else { + plane = Plane(world_ray, world_pos + world_ray * FALLBACK_DISTANCE); + } + if (plane.intersects_ray(world_pos, world_ray, &intersection)) { + return intersection; + } + + // Not likely, but just in case... + return world_pos + world_ray * FALLBACK_DISTANCE; } AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_top_level_transform) { @@ -3762,7 +3805,7 @@ AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, boo if (child) { AABB child_bounds = _calculate_spatial_bounds(child, false); - if (bounds.size == Vector3() && Object::cast_to<Node3D>(p_parent)) { + if (bounds.size == Vector3() && p_parent) { bounds = child_bounds; } else { bounds.merge_with(child_bounds); @@ -3770,7 +3813,7 @@ AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, boo } } - if (bounds.size == Vector3() && !Object::cast_to<Node3D>(p_parent)) { + if (bounds.size == Vector3() && !p_parent) { bounds = AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4)); } @@ -3843,7 +3886,7 @@ void Node3DEditorViewport::_remove_preview_node() { if (preview_node->get_parent()) { for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { Node *node = preview_node->get_child(i); - node->queue_delete(); + node->queue_free(); preview_node->remove_child(node); } EditorNode::get_singleton()->get_scene_root()->remove_child(preview_node); @@ -3880,8 +3923,8 @@ bool Node3DEditorViewport::_apply_preview_material(ObjectID p_target, const Poin Vector3 xform_ray = ai.basis.xform(world_ray).normalized(); Vector3 xform_pos = ai.xform(world_pos); - for (int surface = 0; surface < surface_count; surface++) { - Ref<TriangleMesh> surface_mesh = mesh->generate_surface_triangle_mesh(surface); + for (int surface_idx = 0; surface_idx < surface_count; surface_idx++) { + Ref<TriangleMesh> surface_mesh = mesh->generate_surface_triangle_mesh(surface_idx); Vector3 rpos, rnorm; if (surface_mesh->intersect_ray(xform_pos, xform_ray, rpos, rnorm)) { @@ -3894,7 +3937,7 @@ bool Node3DEditorViewport::_apply_preview_material(ObjectID p_target, const Poin } if (dist < closest_dist) { - closest_surface = surface; + closest_surface = surface_idx; closest_dist = dist; } } @@ -3997,7 +4040,7 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po return false; } - if (!EditorNode::get_singleton()->get_edited_scene()->get_scene_file_path().is_empty()) { // cyclical instancing + if (!EditorNode::get_singleton()->get_edited_scene()->get_scene_file_path().is_empty()) { // Cyclic instantiation. if (_cyclical_dependency_exists(EditorNode::get_singleton()->get_edited_scene()->get_scene_file_path(), instantiated_scene)) { memdelete(instantiated_scene); return false; @@ -4008,47 +4051,49 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path)); } - editor_data->get_undo_redo()->add_do_method(parent, "add_child", instantiated_scene, true); - editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_owner", EditorNode::get_singleton()->get_edited_scene()); - editor_data->get_undo_redo()->add_do_reference(instantiated_scene); - editor_data->get_undo_redo()->add_undo_method(parent, "remove_child", instantiated_scene); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->add_do_method(parent, "add_child", instantiated_scene, true); + undo_redo->add_do_method(instantiated_scene, "set_owner", EditorNode::get_singleton()->get_edited_scene()); + undo_redo->add_do_reference(instantiated_scene); + undo_redo->add_undo_method(parent, "remove_child", instantiated_scene); String new_name = parent->validate_child_name(instantiated_scene); EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); - editor_data->get_undo_redo()->add_do_method(ed, "live_debug_instance_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), path, new_name); - editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); + undo_redo->add_do_method(ed, "live_debug_instantiate_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), path, new_name); + undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); Node3D *node3d = Object::cast_to<Node3D>(instantiated_scene); if (node3d) { - Transform3D global_transform; + Transform3D gl_transform; Node3D *parent_node3d = Object::cast_to<Node3D>(parent); if (parent_node3d) { - global_transform = parent_node3d->get_global_gizmo_transform(); + gl_transform = parent_node3d->get_global_gizmo_transform(); } - global_transform.origin = spatial_editor->snap_point(_get_instance_position(p_point)); - global_transform.basis *= node3d->get_transform().basis; + gl_transform.origin = preview_node_pos; + gl_transform.basis *= node3d->get_transform().basis; - editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_global_transform", global_transform); + undo_redo->add_do_method(instantiated_scene, "set_global_transform", gl_transform); } return true; } void Node3DEditorViewport::_perform_drop_data() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (spatial_editor->get_preview_material_target().is_valid()) { GeometryInstance3D *geometry_instance = Object::cast_to<GeometryInstance3D>(ObjectDB::get_instance(spatial_editor->get_preview_material_target())); MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(ObjectDB::get_instance(spatial_editor->get_preview_material_target())); if (mesh_instance && spatial_editor->get_preview_material_surface() != -1) { - editor_data->get_undo_redo()->create_action(vformat(TTR("Set Surface %d Override Material"), spatial_editor->get_preview_material_surface())); - editor_data->get_undo_redo()->add_do_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_material()); - editor_data->get_undo_redo()->add_undo_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_reset_material()); - editor_data->get_undo_redo()->commit_action(); + undo_redo->create_action(vformat(TTR("Set Surface %d Override Material"), spatial_editor->get_preview_material_surface())); + undo_redo->add_do_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_material()); + undo_redo->add_undo_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_reset_material()); + undo_redo->commit_action(); } else if (geometry_instance) { - editor_data->get_undo_redo()->create_action(TTR("Set Material Override")); - editor_data->get_undo_redo()->add_do_method(geometry_instance, "set_material_override", spatial_editor->get_preview_material()); - editor_data->get_undo_redo()->add_undo_method(geometry_instance, "set_material_override", spatial_editor->get_preview_reset_material()); - editor_data->get_undo_redo()->commit_action(); + undo_redo->create_action(TTR("Set Material Override")); + undo_redo->add_do_method(geometry_instance, "set_material_override", spatial_editor->get_preview_material()); + undo_redo->add_undo_method(geometry_instance, "set_material_override", spatial_editor->get_preview_reset_material()); + undo_redo->commit_action(); } _remove_preview_material(); @@ -4059,7 +4104,7 @@ void Node3DEditorViewport::_perform_drop_data() { Vector<String> error_files; - editor_data->get_undo_redo()->create_action(TTR("Create Node")); + undo_redo->create_action(TTR("Create Node")); for (int i = 0; i < selected_files.size(); i++) { String path = selected_files[i]; @@ -4077,7 +4122,7 @@ void Node3DEditorViewport::_perform_drop_data() { } } - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); if (error_files.size() > 0) { String files_str; @@ -4085,12 +4130,14 @@ void Node3DEditorViewport::_perform_drop_data() { files_str += error_files[i].get_file().get_basename() + ","; } files_str = files_str.substr(0, files_str.length() - 1); - accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.get_data())); + accept->set_text(vformat(TTR("Error instantiating scene from %s"), files_str.get_data())); accept->popup_centered(); } } -bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { +bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + preview_node_viewport_pos = p_point; + bool can_instantiate = false; if (!preview_node->is_inside_tree() && spatial_editor->get_preview_material().is_null()) { @@ -4108,11 +4155,13 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant ResourceLoader::get_recognized_extensions_for_type("Texture", &texture_extensions); for (int i = 0; i < files.size(); i++) { + String extension = files[i].get_extension().to_lower(); + // Check if dragged files with mesh or scene extension can be created at least once. - if (mesh_extensions.find(files[i].get_extension()) || - scene_extensions.find(files[i].get_extension()) || - material_extensions.find(files[i].get_extension()) || - texture_extensions.find(files[i].get_extension())) { + if (mesh_extensions.find(extension) || + scene_extensions.find(extension) || + material_extensions.find(extension) || + texture_extensions.find(extension)) { Ref<Resource> res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; @@ -4154,6 +4203,7 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant } if (can_instantiate) { _create_preview_node(files); + preview_node->hide(); } } } else { @@ -4163,8 +4213,7 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant } if (can_instantiate) { - Transform3D global_transform = Transform3D(Basis(), _get_instance_position(p_point)); - preview_node->set_global_transform(global_transform); + update_preview_node = true; return true; } @@ -4241,6 +4290,7 @@ void Node3DEditorViewport::commit_transform() { TTRC("Translate"), TTRC("Scale"), }; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(_transform_name[_edit.mode]); List<Node *> &selection = editor_selection->get_selected_node_list(); @@ -4646,9 +4696,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p _edit.gizmo_handle_secondary = false; index = p_index; - editor_data = SceneTreeDock::get_singleton()->get_editor_data(); editor_selection = EditorNode::get_singleton()->get_editor_selection(); - undo_redo = EditorNode::get_singleton()->get_undo_redo(); orthogonal = false; auto_orthogonal = false; @@ -4773,10 +4821,9 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p view_menu->get_popup()->connect("id_pressed", callable_mp(this, &Node3DEditorViewport::_menu_option)); display_submenu->connect("id_pressed", callable_mp(this, &Node3DEditorViewport::_menu_option)); view_menu->set_disable_shortcuts(true); -#ifndef _MSC_VER -#warning this needs to be fixed -#endif - //if (OS::get_singleton()->get_current_video_driver() == OS::VIDEO_DRIVER_GLES2) { + + // TODO: Re-evaluate with new OpenGL3 renderer, and implement. + //if (OS::get_singleton()->get_current_video_driver() == OS::RENDERING_DRIVER_OPENGL3) { if (false) { // Alternate display modes only work when using the Vulkan renderer; make this explicit. const int normal_idx = view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL); @@ -4918,7 +4965,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p accept = nullptr; freelook_active = false; - freelook_speed = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_base_speed"); + freelook_speed = EDITOR_GET("editors/3d/freelook/freelook_base_speed"); selection_menu = memnew(PopupMenu); add_child(selection_menu); @@ -5733,6 +5780,7 @@ void Node3DEditor::_xform_dialog_action() { t.basis.rotate(rotate); t.origin = translate; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("XForm Dialog")); const List<Node *> &selection = editor_selection->get_selected_node_list(); @@ -5844,6 +5892,7 @@ void Node3DEditor::_update_camera_override_viewport(Object *p_viewport) { } void Node3DEditor::_menu_item_pressed(int p_option) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (p_option) { case MENU_TOOL_SELECT: case MENU_TOOL_MOVE: @@ -6171,9 +6220,9 @@ void fragment() { grid_mat[i]->set_shader(grid_shader); } - grid_enable[0] = EditorSettings::get_singleton()->get("editors/3d/grid_xy_plane"); - grid_enable[1] = EditorSettings::get_singleton()->get("editors/3d/grid_yz_plane"); - grid_enable[2] = EditorSettings::get_singleton()->get("editors/3d/grid_xz_plane"); + grid_enable[0] = EDITOR_GET("editors/3d/grid_xy_plane"); + grid_enable[1] = EDITOR_GET("editors/3d/grid_yz_plane"); + grid_enable[2] = EDITOR_GET("editors/3d/grid_xz_plane"); grid_visible[0] = grid_enable[0]; grid_visible[1] = grid_enable[1]; grid_visible[2] = grid_enable[2]; @@ -6223,7 +6272,7 @@ void fragment() { break; } - col.a = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity"); + col.a = EDITOR_GET("editors/3d/manipulator_gizmo_opacity"); move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); move_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); @@ -6639,23 +6688,23 @@ void Node3DEditor::_init_grid() { Vector<Vector3> grid_points[3]; Vector<Vector3> grid_normals[3]; - Color primary_grid_color = EditorSettings::get_singleton()->get("editors/3d/primary_grid_color"); - Color secondary_grid_color = EditorSettings::get_singleton()->get("editors/3d/secondary_grid_color"); - int grid_size = EditorSettings::get_singleton()->get("editors/3d/grid_size"); - int primary_grid_steps = EditorSettings::get_singleton()->get("editors/3d/primary_grid_steps"); + Color primary_grid_color = EDITOR_GET("editors/3d/primary_grid_color"); + Color secondary_grid_color = EDITOR_GET("editors/3d/secondary_grid_color"); + int grid_size = EDITOR_GET("editors/3d/grid_size"); + int primary_grid_steps = EDITOR_GET("editors/3d/primary_grid_steps"); // Which grid planes are enabled? Which should we generate? - grid_enable[0] = grid_visible[0] = EditorSettings::get_singleton()->get("editors/3d/grid_xy_plane"); - grid_enable[1] = grid_visible[1] = EditorSettings::get_singleton()->get("editors/3d/grid_yz_plane"); - grid_enable[2] = grid_visible[2] = EditorSettings::get_singleton()->get("editors/3d/grid_xz_plane"); + grid_enable[0] = grid_visible[0] = EDITOR_GET("editors/3d/grid_xy_plane"); + grid_enable[1] = grid_visible[1] = EDITOR_GET("editors/3d/grid_yz_plane"); + grid_enable[2] = grid_visible[2] = EDITOR_GET("editors/3d/grid_xz_plane"); // Offsets division_level for bigger or smaller grids. // Default value is -0.2. -1.0 gives Blender-like behavior, 0.5 gives huge grids. - real_t division_level_bias = EditorSettings::get_singleton()->get("editors/3d/grid_division_level_bias"); + real_t division_level_bias = EDITOR_GET("editors/3d/grid_division_level_bias"); // Default largest grid size is 8^2 when primary_grid_steps is 8 (64m apart, so primary grid lines are 512m apart). - int division_level_max = EditorSettings::get_singleton()->get("editors/3d/grid_division_level_max"); + int division_level_max = EDITOR_GET("editors/3d/grid_division_level_max"); // Default smallest grid size is 1cm, 10^-2 (default value is -2). - int division_level_min = EditorSettings::get_singleton()->get("editors/3d/grid_division_level_min"); + int division_level_min = EDITOR_GET("editors/3d/grid_division_level_min"); ERR_FAIL_COND_MSG(division_level_max < division_level_min, "The 3D grid's maximum division level cannot be lower than its minimum division level."); if (primary_grid_steps != 10) { // Log10 of 10 is 1. @@ -6755,8 +6804,8 @@ void Node3DEditor::_init_grid() { // Don't draw lines over the origin if it's enabled. if (!(origin_enabled && Math::is_zero_approx(position_a))) { - Vector3 line_bgn = Vector3(); - Vector3 line_end = Vector3(); + Vector3 line_bgn; + Vector3 line_end; line_bgn[a] = position_a; line_end[a] = position_a; line_bgn[b] = bgn_b; @@ -6771,8 +6820,8 @@ void Node3DEditor::_init_grid() { } if (!(origin_enabled && Math::is_zero_approx(position_b))) { - Vector3 line_bgn = Vector3(); - Vector3 line_end = Vector3(); + Vector3 line_bgn; + Vector3 line_end; line_bgn[b] = position_b; line_end[b] = position_b; line_bgn[a] = bgn_a; @@ -6930,14 +6979,18 @@ HashSet<RID> _get_physics_bodies_rid(Node *node) { } void Node3DEditor::snap_selected_nodes_to_floor() { + do_snap_selected_nodes_to_floor = true; +} + +void Node3DEditor::_snap_selected_nodes_to_floor() { const List<Node *> &selection = editor_selection->get_selected_node_list(); Dictionary snap_data; for (Node *E : selection) { Node3D *sp = Object::cast_to<Node3D>(E); if (sp) { - Vector3 from = Vector3(); - Vector3 position_offset = Vector3(); + Vector3 from; + Vector3 position_offset; // Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin HashSet<VisualInstance3D *> vi = _get_child_nodes<VisualInstance3D>(sp); @@ -6967,9 +7020,10 @@ void Node3DEditor::snap_selected_nodes_to_floor() { } } if (!found_valid_shape && vi.size()) { - AABB aabb = (*vi.begin())->get_transformed_aabb(); + VisualInstance3D *begin = *vi.begin(); + AABB aabb = begin->get_global_transform().xform(begin->get_aabb()); for (const VisualInstance3D *I : vi) { - aabb.merge_with(I->get_transformed_aabb()); + aabb.merge_with(I->get_global_transform().xform(I->get_aabb())); } Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5); from = aabb.position + size; @@ -7024,6 +7078,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() { } if (snapped_to_floor) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Snap Nodes to Floor")); // Perform snapping if at least one node can be snapped @@ -7093,6 +7148,7 @@ void Node3DEditor::_add_sun_to_scene(bool p_already_added_environment) { ERR_FAIL_COND(!base); Node *new_sun = preview_sun->duplicate(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Preview Sun to Scene")); undo_redo->add_do_method(base, "add_child", new_sun, true); // Move to the beginning of the scene tree since more "global" nodes @@ -7126,6 +7182,7 @@ void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) { new_env->set_camera_attributes(preview_environment->get_camera_attributes()->duplicate(true)); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Preview Environment to Scene")); undo_redo->add_do_method(base, "add_child", new_env, true); // Move to the beginning of the scene tree since more "global" nodes @@ -7227,6 +7284,13 @@ void Node3DEditor::_notification(int p_what) { tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_pressed(false); } } break; + + case NOTIFICATION_PHYSICS_PROCESS: { + if (do_snap_selected_nodes_to_floor) { + _snap_selected_nodes_to_floor(); + do_snap_selected_nodes_to_floor = false; + } + } } } @@ -7258,14 +7322,6 @@ Vector<int> Node3DEditor::get_subgizmo_selection() { return ret; } -void Node3DEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - -Ref<EditorUndoRedoManager> Node3DEditor::get_undo_redo() { - return undo_redo; -} - void Node3DEditor::add_control_to_menu_panel(Control *p_control) { context_menu_hbox->add_child(p_control); } @@ -7583,7 +7639,7 @@ void Node3DEditor::_preview_settings_changed() { { // preview sun Transform3D t; - t.basis = Basis(Vector3(sun_rotation.x, sun_rotation.y, 0)); + t.basis = Basis::from_euler(Vector3(sun_rotation.x, sun_rotation.y, 0)); preview_sun->set_transform(t); sun_direction->queue_redraw(); preview_sun->set_param(Light3D::PARAM_ENERGY, sun_energy->get_value()); @@ -7645,6 +7701,7 @@ void Node3DEditor::_update_preview_environment() { preview_sun->get_parent()->remove_child(preview_sun); sun_state->show(); sun_vb->hide(); + preview_sun_dangling = true; } if (directional_light_count > 0) { @@ -7658,6 +7715,7 @@ void Node3DEditor::_update_preview_environment() { add_child(preview_sun, true); sun_state->hide(); sun_vb->show(); + preview_sun_dangling = false; } } @@ -7673,6 +7731,7 @@ void Node3DEditor::_update_preview_environment() { preview_environment->get_parent()->remove_child(preview_environment); environ_state->show(); environ_vb->hide(); + preview_env_dangling = true; } if (world_env_count > 0) { environ_state->set_text(TTR("Scene contains\nWorldEnvironment.\nPreview disabled.")); @@ -7685,6 +7744,7 @@ void Node3DEditor::_update_preview_environment() { add_child(preview_environment); environ_state->hide(); environ_vb->show(); + preview_env_dangling = false; } } } @@ -7712,7 +7772,6 @@ Node3DEditor::Node3DEditor() { gizmo.scale = 1.0; viewport_environment = Ref<Environment>(memnew(Environment)); - undo_redo = EditorNode::get_singleton()->get_undo_redo(); VBoxContainer *vbc = this; custom_camera = nullptr; @@ -7854,7 +7913,6 @@ Node3DEditor::Node3DEditor() { sun_button->set_toggle_mode(true); sun_button->set_flat(true); sun_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), CONNECT_DEFERRED); - sun_button->set_disabled(true); // Preview is enabled by default - ensure this applies on editor startup when there is no state yet. sun_button->set_pressed(true); @@ -7865,7 +7923,6 @@ Node3DEditor::Node3DEditor() { environ_button->set_toggle_mode(true); environ_button->set_flat(true); environ_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), CONNECT_DEFERRED); - environ_button->set_disabled(true); // Preview is enabled by default - ensure this applies on editor startup when there is no state yet. environ_button->set_pressed(true); @@ -8012,12 +8069,15 @@ Node3DEditor::Node3DEditor() { snap_dialog->add_child(snap_dialog_vbc); snap_translate = memnew(LineEdit); + snap_translate->set_select_all_on_focus(true); snap_dialog_vbc->add_margin_child(TTR("Translate Snap:"), snap_translate); snap_rotate = memnew(LineEdit); + snap_rotate->set_select_all_on_focus(true); snap_dialog_vbc->add_margin_child(TTR("Rotate Snap (deg.):"), snap_rotate); snap_scale = memnew(LineEdit); + snap_scale->set_select_all_on_focus(true); snap_dialog_vbc->add_margin_child(TTR("Scale Snap (%):"), snap_scale); _snap_update(); @@ -8036,6 +8096,7 @@ Node3DEditor::Node3DEditor() { settings_fov->set_min(MIN_FOV); settings_fov->set_step(0.1); settings_fov->set_value(EDITOR_GET("editors/3d/default_fov")); + settings_fov->set_select_all_on_focus(true); settings_vbc->add_margin_child(TTR("Perspective FOV (deg.):"), settings_fov); settings_znear = memnew(SpinBox); @@ -8043,6 +8104,7 @@ Node3DEditor::Node3DEditor() { settings_znear->set_min(MIN_Z); settings_znear->set_step(0.01); settings_znear->set_value(EDITOR_GET("editors/3d/default_z_near")); + settings_znear->set_select_all_on_focus(true); settings_vbc->add_margin_child(TTR("View Z-Near:"), settings_znear); settings_zfar = memnew(SpinBox); @@ -8050,6 +8112,7 @@ Node3DEditor::Node3DEditor() { settings_zfar->set_min(MIN_Z); settings_zfar->set_step(0.1); settings_zfar->set_value(EDITOR_GET("editors/3d/default_z_far")); + settings_zfar->set_select_all_on_focus(true); settings_vbc->add_margin_child(TTR("View Z-Far:"), settings_zfar); for (uint32_t i = 0; i < VIEWPORTS_COUNT; ++i) { @@ -8075,6 +8138,7 @@ Node3DEditor::Node3DEditor() { for (int i = 0; i < 3; i++) { xform_translate[i] = memnew(LineEdit); xform_translate[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_translate[i]->set_select_all_on_focus(true); xform_hbc->add_child(xform_translate[i]); } @@ -8088,6 +8152,7 @@ Node3DEditor::Node3DEditor() { for (int i = 0; i < 3; i++) { xform_rotate[i] = memnew(LineEdit); xform_rotate[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_rotate[i]->set_select_all_on_focus(true); xform_hbc->add_child(xform_rotate[i]); } @@ -8101,6 +8166,7 @@ Node3DEditor::Node3DEditor() { for (int i = 0; i < 3; i++) { xform_scale[i] = memnew(LineEdit); xform_scale[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_scale[i]->set_select_all_on_focus(true); xform_hbc->add_child(xform_scale[i]); } @@ -8333,16 +8399,24 @@ void fragment() { } Node3DEditor::~Node3DEditor() { memdelete(preview_node); + if (preview_sun_dangling && preview_sun) { + memdelete(preview_sun); + } + if (preview_env_dangling && preview_environment) { + memdelete(preview_environment); + } } void Node3DEditorPlugin::make_visible(bool p_visible) { if (p_visible) { spatial_editor->show(); spatial_editor->set_process(true); + spatial_editor->set_physics_process(true); } else { spatial_editor->hide(); spatial_editor->set_process(false); + spatial_editor->set_physics_process(false); } } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 580cb878ce..b7ac718182 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -33,27 +33,30 @@ #include "editor/editor_plugin.h" #include "editor/editor_scale.h" -#include "editor/editor_spin_slider.h" #include "editor/plugins/node_3d_editor_gizmos.h" -#include "scene/3d/camera_3d.h" -#include "scene/3d/light_3d.h" -#include "scene/3d/visual_instance_3d.h" -#include "scene/3d/world_environment.h" -#include "scene/gui/color_picker.h" -#include "scene/gui/panel_container.h" +#include "scene/gui/box_container.h" +#include "scene/gui/button.h" #include "scene/gui/spin_box.h" -#include "scene/gui/split_container.h" -#include "scene/resources/environment.h" -#include "scene/resources/fog_material.h" -#include "scene/resources/sky_material.h" +class AcceptDialog; +class CheckBox; +class ColorPickerButton; +class ConfirmationDialog; +class DirectionalLight3D; class EditorData; +class EditorSpinSlider; +class HSplitContainer; +class LineEdit; +class MenuButton; class Node3DEditor; class Node3DEditorViewport; +class OptionButton; +class PanelContainer; +class ProceduralSkyMaterial; +class SubViewport; class SubViewportContainer; -class DirectionalLight3D; +class VSplitContainer; class WorldEnvironment; -class EditorUndoRedoManager; class ViewportRotationControl : public Control { GDCLASS(ViewportRotationControl, Control); @@ -193,6 +196,9 @@ private: void _menu_option(int p_option); void _set_auto_orthogonal(); Node3D *preview_node = nullptr; + bool update_preview_node = false; + Point2 preview_node_viewport_pos; + Vector3 preview_node_pos; AABB *preview_bounds = nullptr; Vector<String> selected_files; AcceptDialog *accept = nullptr; @@ -200,9 +206,7 @@ private: Node *target_node = nullptr; Point2 drop_pos; - EditorData *editor_data = nullptr; EditorSelection *editor_selection = nullptr; - Ref<EditorUndoRedoManager> undo_redo; CheckBox *preview_camera = nullptr; SubViewportContainer *subviewport_container = nullptr; @@ -413,7 +417,7 @@ private: bool _create_instance(Node *parent, String &path, const Point2 &p_point); void _perform_drop_data(); - bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); void _project_settings_changed(); @@ -569,7 +573,7 @@ private: bool grid_enabled = false; bool grid_init_draw = false; Camera3D::ProjectionType grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; - Vector3 grid_camera_last_update_position = Vector3(); + Vector3 grid_camera_last_update_position; Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3]; Ref<StandardMaterial3D> gizmo_color[3]; @@ -683,7 +687,6 @@ private: HBoxContainer *context_menu_hbox = nullptr; void _generate_selection_boxes(); - Ref<EditorUndoRedoManager> undo_redo; int camera_override_viewport_id; @@ -720,6 +723,9 @@ private: void _selection_changed(); void _refresh_menu_icons(); + bool do_snap_selected_nodes_to_floor = false; + void _snap_selected_nodes_to_floor(); + // Preview Sun and Environment uint32_t world_env_count = 0; @@ -763,9 +769,11 @@ private: Button *sun_environ_settings = nullptr; DirectionalLight3D *preview_sun = nullptr; + bool preview_sun_dangling = false; WorldEnvironment *preview_environment = nullptr; + bool preview_env_dangling = false; Ref<Environment> environment; - Ref<CameraAttributesPhysical> camera_attributes; + Ref<CameraAttributesPractical> camera_attributes; Ref<ProceduralSkyMaterial> sky_material; bool sun_environ_updating = false; @@ -827,9 +835,6 @@ public: Ref<Environment> get_viewport_environment() { return viewport_environment; } - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); - Ref<EditorUndoRedoManager> get_undo_redo(); - void add_control_to_menu_panel(Control *p_control); void remove_control_from_menu_panel(Control *p_control); diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index c8bd4c1d05..3204cc8d0f 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -37,6 +37,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "scene/gui/menu_button.h" void Path2DEditor::_notification(int p_what) { switch (p_what) { @@ -119,6 +120,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } // Check for point deletion. + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if ((mb->get_button_index() == MouseButton::RIGHT && mode == MODE_EDIT) || (mb->get_button_index() == MouseButton::LEFT && mode == MODE_DELETE)) { if (dist_to_p < grab_threshold) { undo_redo->create_action(TTR("Remove Point from Curve")); @@ -153,6 +155,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && ((mb->is_command_or_control_pressed() && mode == MODE_EDIT) || mode == MODE_CREATE)) { Ref<Curve2D> curve = node->get_curve(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Point to Curve")); undo_redo->add_do_method(curve.ptr(), "add_point", cpoint); undo_redo->add_undo_method(curve.ptr(), "remove_point", curve->get_point_count()); @@ -188,6 +191,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { insertion_point = curve->get_point_count() - 2; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Split Curve")); undo_redo->add_do_method(curve.ptr(), "add_point", xform.affine_inverse().xform(gpoint2), Vector2(0, 0), Vector2(0, 0), insertion_point + 1); undo_redo->add_undo_method(curve.ptr(), "remove_point", insertion_point + 1); @@ -211,6 +215,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (!mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && action != ACTION_NONE) { Ref<Curve2D> curve = node->get_curve(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); switch (action) { case ACTION_NONE: @@ -486,6 +491,7 @@ void Path2DEditor::_mode_selected(int p_mode) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Point from Curve")); undo_redo->add_do_method(node->get_curve().ptr(), "add_point", begin); undo_redo->add_undo_method(node->get_curve().ptr(), "remove_point", node->get_curve()->get_point_count()); @@ -519,7 +525,6 @@ void Path2DEditor::_handle_option_pressed(int p_option) { Path2DEditor::Path2DEditor() { canvas_item_editor = nullptr; - undo_redo = EditorNode::get_singleton()->get_undo_redo(); mirror_handle_angle = true; mirror_handle_length = true; on_edge = false; diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index 13eca79010..c6ed257540 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -33,16 +33,15 @@ #include "editor/editor_plugin.h" #include "scene/2d/path_2d.h" +#include "scene/gui/box_container.h" #include "scene/gui/separator.h" class CanvasItemEditor; -class EditorUndoRedoManager; +class MenuButton; class Path2DEditor : public HBoxContainer { GDCLASS(Path2DEditor, HBoxContainer); - Ref<EditorUndoRedoManager> undo_redo; - CanvasItemEditor *canvas_item_editor = nullptr; Panel *panel = nullptr; Path2D *node = nullptr; diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index adfaf11264..5a7b0321b7 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -37,6 +37,7 @@ #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "node_3d_editor_plugin.h" +#include "scene/gui/menu_button.h" #include "scene/resources/curve.h" static bool _is_in_handle(int p_id, int p_num_points) { @@ -264,45 +265,45 @@ void Path3DGizmo::redraw() { if (Path3DEditorPlugin::singleton->get_edited_path() == path) { v3p.clear(); - Vector<Vector3> handles; - Vector<Vector3> sec_handles; + Vector<Vector3> handle_points; + Vector<Vector3> sec_handle_points; for (int i = 0; i < c->get_point_count(); i++) { Vector3 p = c->get_point_position(i); - handles.push_back(p); + handle_points.push_back(p); // push Out points first so they get selected if the In and Out points are on top of each other. if (i < c->get_point_count() - 1) { v3p.push_back(p); v3p.push_back(p + c->get_point_out(i)); - sec_handles.push_back(p + c->get_point_out(i)); + sec_handle_points.push_back(p + c->get_point_out(i)); } if (i > 0) { v3p.push_back(p); v3p.push_back(p + c->get_point_in(i)); - sec_handles.push_back(p + c->get_point_in(i)); + sec_handle_points.push_back(p + c->get_point_in(i)); } } if (v3p.size() > 1) { add_lines(v3p, path_thin_material); } - if (handles.size()) { - add_handles(handles, handles_material); + if (handle_points.size()) { + add_handles(handle_points, handles_material); } - if (sec_handles.size()) { - add_handles(sec_handles, sec_handles_material, Vector<int>(), false, true); + if (sec_handle_points.size()) { + add_handles(sec_handle_points, sec_handles_material, Vector<int>(), false, true); } } } Path3DGizmo::Path3DGizmo(Path3D *p_path) { path = p_path; - set_spatial_node(p_path); + set_node_3d(p_path); orig_in_length = 0; orig_out_length = 0; } -EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { +EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { if (!path) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index 53e4e2efa8..a2816c89ae 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -37,6 +37,8 @@ #include "scene/3d/path_3d.h" #include "scene/gui/separator.h" +class MenuButton; + class Path3DGizmo : public EditorNode3DGizmo { GDCLASS(Path3DGizmo, EditorNode3DGizmo); @@ -101,7 +103,7 @@ public: Path3D *get_edited_path() { return path; } static Path3DEditorPlugin *singleton; - virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override; + virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override; virtual String get_name() const override { return "Path3D"; } bool has_main_screen() const override { return false; } diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp index 9dc89133c4..2b59e4cf08 100644 --- a/editor/plugins/physical_bone_3d_editor_plugin.cpp +++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp @@ -31,6 +31,7 @@ #include "physical_bone_3d_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" +#include "scene/gui/separator.h" void PhysicalBone3DEditor::_bind_methods() { } diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 58a3a07c43..a19a42f951 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -32,14 +32,20 @@ #include "core/input/input_event.h" #include "core/math/geometry_2d.h" +#include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "scene/2d/skeleton_2d.h" +#include "scene/gui/check_box.h" #include "scene/gui/menu_button.h" #include "scene/gui/scroll_container.h" #include "scene/gui/separator.h" #include "scene/gui/slider.h" +#include "scene/gui/spin_box.h" +#include "scene/gui/split_container.h" +#include "scene/gui/texture_rect.h" #include "scene/gui/view_panner.h" Node2D *Polygon2DEditor::_get_node() const { @@ -67,7 +73,7 @@ void Polygon2DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - uv_panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + uv_panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); } break; case NOTIFICATION_READY: { @@ -150,6 +156,7 @@ void Polygon2DEditor::_sync_bones() { Array new_bones = node->call("_get_bones"); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Sync Bones")); undo_redo->add_do_method(node, "_set_bones", new_bones); undo_redo->add_undo_method(node, "_set_bones", prev_bones); @@ -279,6 +286,7 @@ void Polygon2DEditor::_uv_edit_popup_hide() { } void Polygon2DEditor::_menu_option(int p_option) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (p_option) { case MODE_EDIT_UV: { if (node->get_texture().is_null()) { @@ -299,7 +307,7 @@ void Polygon2DEditor::_menu_option(int p_option) { } if (EditorSettings::get_singleton()->has_setting("interface/dialogs/uv_editor_bounds")) { - uv_edit->popup(EditorSettings::get_singleton()->get("interface/dialogs/uv_editor_bounds")); + uv_edit->popup(EDITOR_GET("interface/dialogs/uv_editor_bounds")); } else { uv_edit->popup_centered_ratio(0.85); } @@ -391,6 +399,7 @@ void Polygon2DEditor::_update_polygon_editing_state() { void Polygon2DEditor::_commit_action() { // Makes that undo/redoing actions made outside of the UV editor still affect its polygon. + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->add_do_method(CanvasItemEditor::get_singleton(), "update_viewport"); @@ -458,8 +467,9 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { mtx.columns[2] = -uv_draw_ofs; mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom)); - Ref<InputEventMouseButton> mb = p_input; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + Ref<InputEventMouseButton> mb = p_input; if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::LEFT) { if (mb->is_pressed()) { diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index d878d3f9af..6021401e4f 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -33,11 +33,17 @@ #include "editor/plugins/abstract_polygon_2d_editor.h" +class AcceptDialog; +class ButtonGroup; +class HScrollBar; class HSlider; +class MenuButton; class Panel; class ScrollContainer; class SpinBox; +class TextureRect; class ViewPanner; +class VScrollBar; class Polygon2DEditor : public AbstractPolygon2DEditor { GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor); diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp index 2b3a5c3e23..dde44d31fa 100644 --- a/editor/plugins/polygon_3d_editor_plugin.cpp +++ b/editor/plugins/polygon_3d_editor_plugin.cpp @@ -41,6 +41,7 @@ #include "editor/editor_undo_redo_manager.h" #include "node_3d_editor_plugin.h" #include "scene/3d/camera_3d.h" +#include "scene/gui/separator.h" void Polygon3DEditor::_notification(int p_what) { switch (p_what) { @@ -95,6 +96,7 @@ void Polygon3DEditor::_menu_option(int p_option) { void Polygon3DEditor::_wip_close() { Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node; ERR_FAIL_COND_MSG(!obj, "Edited object is not valid."); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Create Polygon3D")); undo_redo->add_undo_method(obj, "set_polygon", obj->call("get_polygon")); undo_redo->add_do_method(obj, "set_polygon", wip); @@ -109,7 +111,7 @@ void Polygon3DEditor::_wip_close() { undo_redo->commit_action(); } -EditorPlugin::AfterGUIInput Polygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { +EditorPlugin::AfterGUIInput Polygon3DEditor::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { if (!node) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } @@ -184,6 +186,7 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_spatial_gui_input(Camera3D if (mb->is_pressed()) { if (mb->is_ctrl_pressed()) { if (poly.size() < 3) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Edit Poly")); undo_redo->add_undo_method(obj, "set_polygon", poly); poly.push_back(cpoint); @@ -262,6 +265,7 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_spatial_gui_input(Camera3D ERR_FAIL_INDEX_V(edited_point, poly.size(), EditorPlugin::AFTER_GUI_INPUT_PASS); poly.write[edited_point] = edited_point_pos; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Edit Poly")); undo_redo->add_do_method(obj, "set_polygon", poly); undo_redo->add_undo_method(obj, "set_polygon", pre_move_edit); @@ -290,6 +294,7 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_spatial_gui_input(Camera3D } if (closest_idx >= 0) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Edit Poly (Remove Point)")); undo_redo->add_undo_method(obj, "set_polygon", poly); poly.remove_at(closest_idx); @@ -527,7 +532,6 @@ void Polygon3DEditor::_bind_methods() { Polygon3DEditor::Polygon3DEditor() { node = nullptr; - undo_redo = EditorNode::get_undo_redo(); add_child(memnew(VSeparator)); button_create = memnew(Button); diff --git a/editor/plugins/polygon_3d_editor_plugin.h b/editor/plugins/polygon_3d_editor_plugin.h index 0eb02a39e2..2fa9820aa6 100644 --- a/editor/plugins/polygon_3d_editor_plugin.h +++ b/editor/plugins/polygon_3d_editor_plugin.h @@ -34,15 +34,15 @@ #include "editor/editor_plugin.h" #include "scene/3d/collision_polygon_3d.h" #include "scene/3d/mesh_instance_3d.h" +#include "scene/gui/box_container.h" #include "scene/resources/immediate_mesh.h" class CanvasItemEditor; -class EditorUndoRedoManager; +class MenuButton; class Polygon3DEditor : public HBoxContainer { GDCLASS(Polygon3DEditor, HBoxContainer); - Ref<EditorUndoRedoManager> undo_redo; enum Mode { MODE_CREATE, MODE_EDIT, @@ -90,7 +90,7 @@ protected: static void _bind_methods(); public: - virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event); + virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event); void edit(Node *p_node); Polygon3DEditor(); ~Polygon3DEditor(); @@ -102,7 +102,7 @@ class Polygon3DEditorPlugin : public EditorPlugin { Polygon3DEditor *polygon_editor = nullptr; public: - virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return polygon_editor->forward_spatial_gui_input(p_camera, p_event); } + virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return polygon_editor->forward_3d_gui_input(p_camera, p_event); } virtual String get_name() const override { return "Polygon3DEditor"; } bool has_main_screen() const override { return false; } diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index 21647d1b69..2794b02ba6 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" void ResourcePreloaderEditor::_notification(int p_what) { switch (p_what) { @@ -70,6 +71,7 @@ void ResourcePreloaderEditor::_files_load_request(const Vector<String> &p_paths) name = basename + " " + itos(counter); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Resource")); undo_redo->add_do_method(preloader, "add_resource", name, resource); undo_redo->add_undo_method(preloader, "remove_resource", name); @@ -114,6 +116,7 @@ void ResourcePreloaderEditor::_item_edited() { } Ref<Resource> samp = preloader->get_resource(old_name); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Rename Resource")); undo_redo->add_do_method(preloader, "remove_resource", old_name); undo_redo->add_do_method(preloader, "add_resource", new_name, samp); @@ -126,6 +129,7 @@ void ResourcePreloaderEditor::_item_edited() { } void ResourcePreloaderEditor::_remove_resource(const String &p_to_remove) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete Resource")); undo_redo->add_do_method(preloader, "remove_resource", p_to_remove); undo_redo->add_undo_method(preloader, "add_resource", p_to_remove, preloader->get_resource(p_to_remove)); @@ -159,6 +163,7 @@ void ResourcePreloaderEditor::_paste_pressed() { name = basename + " " + itos(counter); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Paste Resource")); undo_redo->add_do_method(preloader, "add_resource", name, r); undo_redo->add_undo_method(preloader, "remove_resource", name); @@ -234,10 +239,6 @@ void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column, } } -void ResourcePreloaderEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; -} - void ResourcePreloaderEditor::edit(ResourcePreloader *p_preloader) { preloader = p_preloader; @@ -321,6 +322,7 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant name = basename + "_" + itos(counter); } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Resource")); undo_redo->add_do_method(preloader, "add_resource", name, r); undo_redo->add_undo_method(preloader, "remove_resource", name); @@ -391,7 +393,6 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() { } void ResourcePreloaderEditorPlugin::edit(Object *p_object) { - preloader_editor->set_undo_redo(EditorNode::get_undo_redo()); ResourcePreloader *s = Object::cast_to<ResourcePreloader>(p_object); if (!s) { return; diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h index ef80283dae..7c1be9114d 100644 --- a/editor/plugins/resource_preloader_editor_plugin.h +++ b/editor/plugins/resource_preloader_editor_plugin.h @@ -33,11 +33,11 @@ #include "editor/editor_plugin.h" #include "scene/gui/dialogs.h" +#include "scene/gui/panel_container.h" #include "scene/gui/tree.h" #include "scene/main/resource_preloader.h" class EditorFileDialog; -class EditorUndoRedoManager; class ResourcePreloaderEditor : public PanelContainer { GDCLASS(ResourcePreloaderEditor, PanelContainer); @@ -67,8 +67,6 @@ class ResourcePreloaderEditor : public PanelContainer { void _cell_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button); void _item_edited(); - Ref<EditorUndoRedoManager> undo_redo; - Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); @@ -79,8 +77,6 @@ protected: static void _bind_methods(); public: - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); - void edit(ResourcePreloader *p_preloader); ResourcePreloaderEditor(); }; diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index de30c4100d..93a64a8f3d 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -30,6 +30,9 @@ #include "root_motion_editor_plugin.h" #include "editor/editor_node.h" +#include "scene/animation/animation_player.h" +#include "scene/animation/animation_tree.h" +#include "scene/gui/tree.h" #include "scene/main/window.h" void EditorPropertyRootMotion::_confirmed() { @@ -45,8 +48,6 @@ void EditorPropertyRootMotion::_confirmed() { } void EditorPropertyRootMotion::_node_assign() { - NodePath current = get_edited_object()->get(get_edited_property()); - AnimationTree *atree = Object::cast_to<AnimationTree>(get_edited_object()); if (!atree->has_node(atree->get_animation_player())) { EditorNode::get_singleton()->show_warning(TTR("AnimationTree has no path set to an AnimationPlayer")); @@ -73,7 +74,10 @@ void EditorPropertyRootMotion::_node_assign() { for (const StringName &E : animations) { Ref<Animation> anim = player->get_animation(E); for (int i = 0; i < anim->get_track_count(); i++) { - paths.insert(anim->track_get_path(i)); + String pathname = anim->track_get_path(i).get_concatenated_names(); + if (!paths.has(pathname)) { + paths.insert(pathname); + } } } } @@ -122,66 +126,33 @@ void EditorPropertyRootMotion::_node_assign() { continue; //no node, can't edit } - if (path.get_subname_count()) { - String concat = path.get_concatenated_subnames(); - - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node); - if (skeleton && skeleton->find_bone(concat) != -1) { - //path in skeleton - const String &bone = concat; - int idx = skeleton->find_bone(bone); - List<String> bone_path; - while (idx != -1) { - bone_path.push_front(skeleton->get_bone_name(idx)); - idx = skeleton->get_bone_parent(idx); + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node); + if (skeleton) { + HashMap<int, TreeItem *> items; + items.insert(-1, ti); + Ref<Texture> bone_icon = get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons")); + Vector<int> bones_to_process = skeleton->get_parentless_bones(); + while (bones_to_process.size() > 0) { + int current_bone_idx = bones_to_process[0]; + bones_to_process.erase(current_bone_idx); + + Vector<int> current_bone_child_bones = skeleton->get_bone_children(current_bone_idx); + int child_bone_size = current_bone_child_bones.size(); + for (int i = 0; i < child_bone_size; i++) { + bones_to_process.push_back(current_bone_child_bones[i]); } - accum += ":"; - for (List<String>::Element *F = bone_path.front(); F; F = F->next()) { - if (F != bone_path.front()) { - accum += "/"; - } - - accum += F->get(); - if (!parenthood.has(accum)) { - ti = filters->create_item(ti); - parenthood[accum] = ti; - ti->set_text(0, F->get()); - ti->set_selectable(0, true); - ti->set_editable(0, false); - ti->set_icon(0, get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons"))); - ti->set_metadata(0, accum); - } else { - ti = parenthood[accum]; - } - } + const int parent_idx = skeleton->get_bone_parent(current_bone_idx); + TreeItem *parent_item = items.find(parent_idx)->value; - ti->set_selectable(0, true); - ti->set_text(0, concat); - ti->set_icon(0, get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons"))); - ti->set_metadata(0, path); - if (path == current) { - ti->select(0); - } + TreeItem *joint_item = filters->create_item(parent_item); + items.insert(current_bone_idx, joint_item); - } else { - //just a property - ti = filters->create_item(ti); - ti->set_text(0, concat); - ti->set_selectable(0, true); - ti->set_metadata(0, path); - if (path == current) { - ti->select(0); - } - } - } else { - if (ti) { - //just a node, likely call or animation track - ti->set_selectable(0, true); - ti->set_metadata(0, path); - if (path == current) { - ti->select(0); - } + joint_item->set_text(0, skeleton->get_bone_name(current_bone_idx)); + joint_item->set_icon(0, bone_icon); + joint_item->set_selectable(0, true); + joint_item->set_metadata(0, accum + ":" + skeleton->get_bone_name(current_bone_idx)); + joint_item->set_collapsed(true); } } } @@ -197,7 +168,6 @@ void EditorPropertyRootMotion::_node_clear() { void EditorPropertyRootMotion::update_property() { NodePath p = get_edited_object()->get(get_edited_property()); - assign->set_tooltip_text(p); if (p == NodePath()) { assign->set_icon(Ref<Texture2D>()); @@ -206,26 +176,8 @@ void EditorPropertyRootMotion::update_property() { return; } - Node *base_node = nullptr; - if (base_hint != NodePath()) { - if (get_tree()->get_root()->has_node(base_hint)) { - base_node = get_tree()->get_root()->get_node(base_hint); - } - } else { - base_node = Object::cast_to<Node>(get_edited_object()); - } - - if (!base_node || !base_node->has_node(p)) { - assign->set_icon(Ref<Texture2D>()); - assign->set_text(p); - return; - } - - Node *target_node = base_node->get_node(p); - ERR_FAIL_COND(!target_node); - - assign->set_text(target_node->get_name()); - assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node")); + assign->set_icon(Ref<Texture2D>()); + assign->set_text(p); } void EditorPropertyRootMotion::setup(const NodePath &p_base_hint) { @@ -280,9 +232,6 @@ bool EditorInspectorRootMotionPlugin::can_handle(Object *p_object) { bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) { if (p_path == "root_motion_track" && p_object->is_class("AnimationTree") && p_type == Variant::NODE_PATH) { EditorPropertyRootMotion *editor = memnew(EditorPropertyRootMotion); - if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && !p_hint_text.is_empty()) { - editor->setup(p_hint_text); - } add_property_editor(p_path, editor); return true; } diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h index 5b8c1d77b3..7134b48c36 100644 --- a/editor/plugins/root_motion_editor_plugin.h +++ b/editor/plugins/root_motion_editor_plugin.h @@ -32,9 +32,8 @@ #define ROOT_MOTION_EDITOR_PLUGIN_H #include "editor/editor_inspector.h" -#include "editor/editor_spin_slider.h" -#include "editor/property_selector.h" -#include "scene/animation/animation_tree.h" + +class Tree; class EditorPropertyRootMotion : public EditorProperty { GDCLASS(EditorPropertyRootMotion, EditorProperty); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 0a111aeb49..bb5491fcb5 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -40,6 +40,7 @@ #include "editor/debugger/editor_debugger_node.h" #include "editor/debugger/script_editor_debugger.h" #include "editor/editor_file_dialog.h" +#include "editor/editor_help_search.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_run_script.h" @@ -47,8 +48,10 @@ #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" #include "editor/find_in_files.h" +#include "editor/inspector_dock.h" #include "editor/node_dock.h" #include "editor/plugins/shader_editor_plugin.h" +#include "editor/plugins/text_shader_editor.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" #include "script_text_editor.h" @@ -58,19 +61,15 @@ /*** SYNTAX HIGHLIGHTER ****/ String EditorSyntaxHighlighter::_get_name() const { - String ret; - if (GDVIRTUAL_CALL(_get_name, ret)) { - return ret; - } - return "Unnamed"; + String ret = "Unnamed"; + GDVIRTUAL_CALL(_get_name, ret); + return ret; } PackedStringArray EditorSyntaxHighlighter::_get_supported_languages() const { PackedStringArray ret; - if (GDVIRTUAL_CALL(_get_supported_languages, ret)) { - return ret; - } - return PackedStringArray(); + GDVIRTUAL_CALL(_get_supported_languages, ret); + return ret; } Ref<EditorSyntaxHighlighter> EditorSyntaxHighlighter::_create() const { @@ -127,12 +126,12 @@ void EditorStandardSyntaxHighlighter::_update_cache() { } } - const Ref<Script> script = _get_edited_resource(); - if (script.is_valid()) { + const Ref<Script> scr = _get_edited_resource(); + if (scr.is_valid()) { /* Core types. */ const Color basetype_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color"); List<String> core_types; - script->get_language()->get_core_type_words(&core_types); + scr->get_language()->get_core_type_words(&core_types); for (const String &E : core_types) { highlighter->add_keyword_color(E, basetype_color); } @@ -141,9 +140,9 @@ void EditorStandardSyntaxHighlighter::_update_cache() { const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); const Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color"); List<String> keywords; - script->get_language()->get_reserved_words(&keywords); + scr->get_language()->get_reserved_words(&keywords); for (const String &E : keywords) { - if (script->get_language()->is_control_flow_keyword(E)) { + if (scr->get_language()->is_control_flow_keyword(E)) { highlighter->add_keyword_color(E, control_flow_keyword_color); } else { highlighter->add_keyword_color(E, keyword_color); @@ -152,19 +151,19 @@ void EditorStandardSyntaxHighlighter::_update_cache() { /* Member types. */ const Color member_variable_color = EDITOR_GET("text_editor/theme/highlighting/member_variable_color"); - StringName instance_base = script->get_instance_base_type(); + StringName instance_base = scr->get_instance_base_type(); if (instance_base != StringName()) { List<PropertyInfo> plist; ClassDB::get_property_list(instance_base, &plist); for (const PropertyInfo &E : plist) { - String name = E.name; + String prop_name = E.name; if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) { continue; } - if (name.contains("/")) { + if (prop_name.contains("/")) { continue; } - highlighter->add_member_keyword_color(name, member_variable_color); + highlighter->add_member_keyword_color(prop_name, member_variable_color); } List<String> clist; @@ -177,7 +176,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() { /* Comments */ const Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color"); List<String> comments; - script->get_language()->get_comment_delimiters(&comments); + scr->get_language()->get_comment_delimiters(&comments); for (const String &comment : comments) { String beg = comment.get_slice(" ", 0); String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String(); @@ -187,7 +186,7 @@ void EditorStandardSyntaxHighlighter::_update_cache() { /* Strings */ const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color"); List<String> strings; - script->get_language()->get_string_delimiters(&strings); + scr->get_language()->get_string_delimiters(&strings); for (const String &string : strings) { String beg = string.get_slice(" ", 0); String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String(); @@ -227,6 +226,7 @@ void ScriptEditorBase::_bind_methods() { // TODO: This signal is no use for VisualScript. ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text"))); ADD_SIGNAL(MethodInfo("replace_in_files_requested", PropertyInfo(Variant::STRING, "text"))); + ADD_SIGNAL(MethodInfo("go_to_method", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::STRING, "method"))); } class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache { @@ -403,7 +403,7 @@ String ScriptEditor::_get_debug_tooltip(const String &p_text, Node *_se) { } void ScriptEditor::_breaked(bool p_breaked, bool p_can_debug) { - if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { + if (bool(EDITOR_GET("text_editor/external/use_external_editor"))) { return; } @@ -429,8 +429,8 @@ void ScriptEditor::_goto_script_line2(int p_line) { } void ScriptEditor::_goto_script_line(Ref<RefCounted> p_script, int p_line) { - Ref<Script> script = Object::cast_to<Script>(*p_script); - if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { + Ref<Script> scr = Object::cast_to<Script>(*p_script); + if (scr.is_valid() && (scr->has_source_code() || scr->get_path().is_resource_file())) { if (edit(p_script, p_line, 0)) { EditorNode::get_singleton()->push_item(p_script.ptr()); @@ -445,15 +445,15 @@ void ScriptEditor::_goto_script_line(Ref<RefCounted> p_script, int p_line) { } void ScriptEditor::_set_execution(Ref<RefCounted> p_script, int p_line) { - Ref<Script> script = Object::cast_to<Script>(*p_script); - if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { + Ref<Script> scr = Object::cast_to<Script>(*p_script); + if (scr.is_valid() && (scr->has_source_code() || scr->get_path().is_resource_file())) { for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (!se) { continue; } - if ((script != nullptr && se->get_edited_resource() == p_script) || se->get_edited_resource()->get_path() == script->get_path()) { + if ((scr != nullptr && se->get_edited_resource() == p_script) || se->get_edited_resource()->get_path() == scr->get_path()) { se->set_executing_line(p_line); } } @@ -461,15 +461,15 @@ void ScriptEditor::_set_execution(Ref<RefCounted> p_script, int p_line) { } void ScriptEditor::_clear_execution(Ref<RefCounted> p_script) { - Ref<Script> script = Object::cast_to<Script>(*p_script); - if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { + Ref<Script> scr = Object::cast_to<Script>(*p_script); + if (scr.is_valid() && (scr->has_source_code() || scr->get_path().is_resource_file())) { for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (!se) { continue; } - if ((script != nullptr && se->get_edited_resource() == p_script) || se->get_edited_resource()->get_path() == script->get_path()) { + if ((scr != nullptr && se->get_edited_resource() == p_script) || se->get_edited_resource()->get_path() == scr->get_path()) { se->clear_executing_line(); } } @@ -477,19 +477,19 @@ void ScriptEditor::_clear_execution(Ref<RefCounted> p_script) { } void ScriptEditor::_set_breakpoint(Ref<RefCounted> p_script, int p_line, bool p_enabled) { - Ref<Script> script = Object::cast_to<Script>(*p_script); - if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) { + Ref<Script> scr = Object::cast_to<Script>(*p_script); + if (scr.is_valid() && (scr->has_source_code() || scr->get_path().is_resource_file())) { // Update if open. for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); - if (se && se->get_edited_resource()->get_path() == script->get_path()) { + if (se && se->get_edited_resource()->get_path() == scr->get_path()) { se->set_breakpoint(p_line, p_enabled); return; } } // Handle closed. - Dictionary state = script_editor_cache->get_value(script->get_path(), "state"); + Dictionary state = script_editor_cache->get_value(scr->get_path(), "state"); Array breakpoints; if (state.has("breakpoints")) { breakpoints = state["breakpoints"]; @@ -503,8 +503,8 @@ void ScriptEditor::_set_breakpoint(Ref<RefCounted> p_script, int p_line, bool p_ breakpoints.push_back(p_line); } state["breakpoints"] = breakpoints; - script_editor_cache->set_value(script->get_path(), "state", state); - EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_line + 1, false); + script_editor_cache->set_value(scr->get_path(), "state", state); + EditorDebuggerNode::get_singleton()->set_breakpoint(scr->get_path(), p_line + 1, false); } } @@ -564,7 +564,7 @@ void ScriptEditor::_save_history() { Node *n = tab_container->get_current_tab_control(); if (Object::cast_to<ScriptEditorBase>(n)) { - history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state(); + history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_navigation_state(); } if (Object::cast_to<EditorHelp>(n)) { history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll(); @@ -599,7 +599,7 @@ void ScriptEditor::_go_to_tab(int p_idx) { Node *n = tab_container->get_current_tab_control(); if (Object::cast_to<ScriptEditorBase>(n)) { - history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state(); + history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_navigation_state(); } if (Object::cast_to<EditorHelp>(n)) { history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll(); @@ -625,9 +625,9 @@ void ScriptEditor::_go_to_tab(int p_idx) { Object::cast_to<ScriptEditorBase>(c)->ensure_focus(); } - Ref<Script> script = Object::cast_to<ScriptEditorBase>(c)->get_edited_resource(); - if (script != nullptr) { - notify_script_changed(script); + Ref<Script> scr = Object::cast_to<ScriptEditorBase>(c)->get_edited_resource(); + if (scr != nullptr) { + notify_script_changed(scr); } Object::cast_to<ScriptEditorBase>(c)->validate(); @@ -703,9 +703,9 @@ void ScriptEditor::_open_recent_script(int p_idx) { ResourceLoader::get_recognized_extensions_for_type("Script", &extensions); if (extensions.find(path.get_extension())) { - Ref<Script> script = ResourceLoader::load(path); - if (script.is_valid()) { - edit(script, true); + Ref<Script> scr = ResourceLoader::load(path); + if (scr.is_valid()) { + edit(scr, true); return; } } @@ -727,9 +727,9 @@ void ScriptEditor::_open_recent_script(int p_idx) { } else { EditorNode::get_singleton()->load_resource(res_path); } - Ref<Script> script = ResourceLoader::load(path); - if (script.is_valid()) { - edit(script, true); + Ref<Script> scr = ResourceLoader::load(path); + if (scr.is_valid()) { + edit(scr, true); return; } } else if (!path.is_resource_file()) { @@ -772,9 +772,9 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) { previous_scripts.push_back(file->get_path()); } - Ref<Script> script = file; - if (script.is_valid()) { - notify_script_close(script); + Ref<Script> scr = file; + if (scr.is_valid()) { + notify_script_close(scr); } } } @@ -849,8 +849,8 @@ void ScriptEditor::_close_docs_tab() { void ScriptEditor::_copy_script_path() { ScriptEditorBase *se = _get_current_editor(); if (se) { - Ref<Resource> script = se->get_edited_resource(); - DisplayServer::get_singleton()->clipboard_set(script->get_path()); + Ref<Resource> scr = se->get_edited_resource(); + DisplayServer::get_singleton()->clipboard_set(scr->get_path()); } } @@ -906,9 +906,9 @@ void ScriptEditor::_resave_scripts(const String &p_str) { continue; } - Ref<Resource> script = se->get_edited_resource(); + Ref<Resource> scr = se->get_edited_resource(); - if (script->is_built_in()) { + if (scr->is_built_in()) { continue; //internal script, who cares } @@ -926,13 +926,13 @@ void ScriptEditor::_resave_scripts(const String &p_str) { } } - Ref<TextFile> text_file = script; + Ref<TextFile> text_file = scr; if (text_file != nullptr) { se->apply_code(); _save_text_file(text_file, text_file->get_path()); break; } else { - EditorNode::get_singleton()->save_resource(script); + EditorNode::get_singleton()->save_resource(scr); } se->tag_saved_version(); } @@ -947,9 +947,9 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) { continue; } - Ref<Resource> script = se->get_edited_resource(); + Ref<Resource> scr = se->get_edited_resource(); - if (script == p_res) { + if (scr == p_res) { se->tag_saved_version(); } } @@ -1104,8 +1104,8 @@ Ref<Script> ScriptEditor::_get_current_script() { ScriptEditorBase *current = _get_current_editor(); if (current) { - Ref<Script> script = current->get_edited_resource(); - return script != nullptr ? script : nullptr; + Ref<Script> scr = current->get_edited_resource(); + return scr != nullptr ? scr : nullptr; } else { return nullptr; } @@ -1123,6 +1123,7 @@ TypedArray<Script> ScriptEditor::_get_open_scripts() const { bool ScriptEditor::toggle_scripts_panel() { list_split->set_visible(!list_split->is_visible()); + EditorSettings::get_singleton()->set_project_metadata("scripts_panel", "show_scripts_panel", list_split->is_visible()); return list_split->is_visible(); } @@ -1281,7 +1282,7 @@ void ScriptEditor::_menu_option(int p_option) { Ref<Resource> resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; - Ref<Script> script = resource; + Ref<Script> scr = resource; if (text_file != nullptr) { file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); @@ -1298,26 +1299,15 @@ void ScriptEditor::_menu_option(int p_option) { break; } - if (script != nullptr) { - Vector<DocData::ClassDoc> documentations = script->get_documentation(); - for (int j = 0; j < documentations.size(); j++) { - const DocData::ClassDoc &doc = documentations.get(j); - if (EditorHelp::get_doc_data()->has_doc(doc.name)) { - EditorHelp::get_doc_data()->remove_doc(doc.name); - } - } + if (scr.is_valid()) { + clear_docs_from_script(scr); } EditorNode::get_singleton()->push_item(resource.ptr()); EditorNode::get_singleton()->save_resource_as(resource); - if (script != nullptr) { - Vector<DocData::ClassDoc> documentations = script->get_documentation(); - for (int j = 0; j < documentations.size(); j++) { - const DocData::ClassDoc &doc = documentations.get(j); - EditorHelp::get_doc_data()->add_doc(doc); - update_doc(doc.name); - } + if (scr.is_valid()) { + update_docs_from_script(scr); } } break; @@ -1375,18 +1365,18 @@ void ScriptEditor::_menu_option(int p_option) { _copy_script_path(); } break; case SHOW_IN_FILE_SYSTEM: { - const Ref<Resource> script = current->get_edited_resource(); - String path = script->get_path(); + const Ref<Resource> scr = current->get_edited_resource(); + String path = scr->get_path(); if (!path.is_empty()) { - if (script->is_built_in()) { + if (scr->is_built_in()) { path = path.get_slice("::", 0); // Show the scene instead. } FileSystemDock *file_system_dock = FileSystemDock::get_singleton(); file_system_dock->navigate_to_path(path); // Ensure that the FileSystem dock is visible. - TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); - tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock)); + TabContainer *dock_tab_container = (TabContainer *)file_system_dock->get_parent_control(); + dock_tab_container->set_current_tab(dock_tab_container->get_tab_idx_from_control(file_system_dock)); } } break; case CLOSE_DOCS: { @@ -1496,7 +1486,7 @@ void ScriptEditor::_show_save_theme_as_dialog() { file_dialog_option = THEME_SAVE_AS; file_dialog->clear_filters(); file_dialog->add_filter("*.tet"); - file_dialog->set_current_path(EditorPaths::get_singleton()->get_text_editor_themes_dir().path_join(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))); + file_dialog->set_current_path(EditorPaths::get_singleton()->get_text_editor_themes_dir().path_join(EDITOR_GET("text_editor/theme/color_theme"))); file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("Save Theme As...")); } @@ -1610,7 +1600,7 @@ void ScriptEditor::_notification(int p_what) { EditorNode::get_singleton()->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop)); } break; - case NOTIFICATION_WM_WINDOW_FOCUS_IN: { + case NOTIFICATION_APPLICATION_FOCUS_IN: { _test_script_times_on_disk(); _update_modified_scripts_for_external_editor(); } break; @@ -1643,12 +1633,12 @@ void ScriptEditor::close_builtin_scripts_from_scene(const String &p_scene) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (se) { - Ref<Script> script = se->get_edited_resource(); - if (script == nullptr || !script.is_valid()) { + Ref<Script> scr = se->get_edited_resource(); + if (scr == nullptr || !scr.is_valid()) { continue; } - if (script->is_built_in() && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed + if (scr->is_built_in() && scr->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed _close_tab(i, false); i--; } @@ -1676,12 +1666,12 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) { continue; } - Ref<Script> script = se->get_edited_resource(); - if (script == nullptr) { + Ref<Script> scr = se->get_edited_resource(); + if (scr == nullptr) { continue; } - String base = script->get_path(); + String base = scr->get_path(); loaded_scripts.insert(base); if (base.begins_with("local://") || base.is_empty()) { continue; @@ -1742,7 +1732,7 @@ void ScriptEditor::ensure_select_current() { if (tab_container->get_tab_count() && tab_container->get_current_tab() >= 0) { ScriptEditorBase *se = _get_current_editor(); if (se) { - se->enable_editor(); + se->enable_editor(this); if (!grab_focus_block && is_visible_in_tree()) { se->ensure_focus(); @@ -1831,7 +1821,7 @@ void ScriptEditor::_update_members_overview() { } Vector<String> functions = se->get_functions(); - if (EditorSettings::get_singleton()->get("text_editor/script_list/sort_members_outline_alphabetically")) { + if (EDITOR_GET("text_editor/script_list/sort_members_outline_alphabetically")) { functions.sort(); } @@ -1898,9 +1888,9 @@ void ScriptEditor::_update_help_overview() { } void ScriptEditor::_update_script_colors() { - bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/script_list/script_temperature_enabled"); + bool script_temperature_enabled = EDITOR_GET("text_editor/script_list/script_temperature_enabled"); - int hist_size = EditorSettings::get_singleton()->get("text_editor/script_list/script_temperature_history_size"); + int hist_size = EDITOR_GET("text_editor/script_list/script_temperature_history_size"); Color hot_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); hot_color.set_s(hot_color.get_s() * 0.9); Color cold_color = get_theme_color(SNAME("font_color"), SNAME("Editor")); @@ -1944,9 +1934,9 @@ void ScriptEditor::_update_script_names() { } script_list->clear(); - bool split_script_help = EditorSettings::get_singleton()->get("text_editor/script_list/group_help_pages"); - ScriptSortBy sort_by = (ScriptSortBy)(int)EditorSettings::get_singleton()->get("text_editor/script_list/sort_scripts_by"); - ScriptListName display_as = (ScriptListName)(int)EditorSettings::get_singleton()->get("text_editor/script_list/list_script_names_as"); + bool split_script_help = EDITOR_GET("text_editor/script_list/group_help_pages"); + ScriptSortBy sort_by = (ScriptSortBy)(int)EDITOR_GET("text_editor/script_list/sort_scripts_by"); + ScriptListName display_as = (ScriptListName)(int)EDITOR_GET("text_editor/script_list/list_script_names_as"); Vector<_ScriptEditorItemData> sedata; @@ -2014,7 +2004,7 @@ void ScriptEditor::_update_script_names() { Vector<String> full_script_paths; for (int j = 0; j < sedata.size(); j++) { String name = sedata[j].name.replace("(*)", ""); - ScriptListName script_display = (ScriptListName)(int)EditorSettings::get_singleton()->get("text_editor/script_list/list_script_names_as"); + ScriptListName script_display = (ScriptListName)(int)EDITOR_GET("text_editor/script_list/list_script_names_as"); switch (script_display) { case DISPLAY_NAME: { name = name.get_file(); @@ -2116,7 +2106,7 @@ void ScriptEditor::_update_script_names() { ScriptEditorBase *se = _get_current_editor(); if (se) { - se->enable_editor(); + se->enable_editor(this); _update_selected_editor_menu(); } } @@ -2133,16 +2123,6 @@ void ScriptEditor::_update_script_names() { _update_script_colors(); } -void ScriptEditor::_update_script_connections() { - for (int i = 0; i < tab_container->get_tab_count(); i++) { - ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(tab_container->get_tab_control(i)); - if (!ste) { - continue; - } - ste->_update_connected_methods(); - } -} - Ref<TextFile> ScriptEditor::_load_text_file(const String &p_path, Error *r_error) const { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; @@ -2202,20 +2182,20 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, return false; } - Ref<Script> script = p_resource; + Ref<Script> scr = p_resource; // Don't open dominant script if using an external editor. bool use_external_editor = - EditorSettings::get_singleton()->get("text_editor/external/use_external_editor") || - (script.is_valid() && script->get_language()->overrides_external_editor()); - use_external_editor = use_external_editor && !(script.is_valid() && script->is_built_in()); // Ignore external editor for built-in scripts. - const bool open_dominant = EditorSettings::get_singleton()->get("text_editor/behavior/files/open_dominant_script_on_scene_change"); + EDITOR_GET("text_editor/external/use_external_editor") || + (scr.is_valid() && scr->get_language()->overrides_external_editor()); + use_external_editor = use_external_editor && !(scr.is_valid() && scr->is_built_in()); // Ignore external editor for built-in scripts. + const bool open_dominant = EDITOR_GET("text_editor/behavior/files/open_dominant_script_on_scene_change"); const bool should_open = (open_dominant && !use_external_editor) || !EditorNode::get_singleton()->is_changing_scene(); - if (script.is_valid() && script->get_language()->overrides_external_editor()) { + if (scr.is_valid() && scr->get_language()->overrides_external_editor()) { if (should_open) { - Error err = script->get_language()->open_in_external_editor(script, p_line >= 0 ? p_line : 0, p_col); + Error err = scr->get_language()->open_in_external_editor(scr, p_line >= 0 ? p_line : 0, p_col); if (err != OK) { ERR_PRINT("Couldn't open script in the overridden external text editor"); } @@ -2227,8 +2207,8 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, (EditorDebuggerNode::get_singleton()->get_dump_stack_script() != p_resource || EditorDebuggerNode::get_singleton()->get_debug_with_external_editor()) && p_resource->get_path().is_resource_file() && !p_resource->is_class("VisualScript")) { - String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path"); - String flags = EditorSettings::get_singleton()->get("text_editor/external/exec_flags"); + String path = EDITOR_GET("text_editor/external/exec_path"); + String flags = EDITOR_GET("text_editor/external/exec_flags"); List<String> args; bool has_file_flag = false; @@ -2289,9 +2269,9 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, continue; } - if ((script != nullptr && se->get_edited_resource() == p_resource) || se->get_edited_resource()->get_path() == p_resource->get_path()) { + if ((scr != nullptr && se->get_edited_resource() == p_resource) || se->get_edited_resource()->get_path() == p_resource->get_path()) { if (should_open) { - se->enable_editor(); + se->enable_editor(this); if (tab_container->get_current_tab() != i) { _go_to_tab(i); @@ -2334,9 +2314,9 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, } se->add_syntax_highlighter(highlighter); - if (script != nullptr && !highlighter_set) { + if (scr != nullptr && !highlighter_set) { PackedStringArray languages = highlighter->_get_supported_languages(); - if (languages.has(script->get_language()->get_name())) { + if (languages.has(scr->get_language()->get_name())) { se->set_syntax_highlighter(highlighter); highlighter_set = true; } @@ -2347,7 +2327,7 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, tab_container->add_child(se); if (p_grab_focus) { - se->enable_editor(); + se->enable_editor(this); } // If we delete a script within the filesystem, the original resource path @@ -2380,6 +2360,7 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, se->connect("request_save_history", callable_mp(this, &ScriptEditor::_save_history)); se->connect("search_in_files_requested", callable_mp(this, &ScriptEditor::_on_find_in_files_requested)); se->connect("replace_in_files_requested", callable_mp(this, &ScriptEditor::_on_replace_in_files_requested)); + se->connect("go_to_method", callable_mp(this, &ScriptEditor::script_goto_method)); //test for modification, maybe the script was not edited but was loaded @@ -2416,7 +2397,7 @@ void ScriptEditor::save_current_script() { Ref<Resource> resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; - Ref<Script> script = resource; + Ref<Script> scr = resource; if (text_file != nullptr) { current->apply_code(); @@ -2424,14 +2405,8 @@ void ScriptEditor::save_current_script() { return; } - if (script != nullptr) { - Vector<DocData::ClassDoc> documentations = script->get_documentation(); - for (int j = 0; j < documentations.size(); j++) { - const DocData::ClassDoc &doc = documentations.get(j); - if (EditorHelp::get_doc_data()->has_doc(doc.name)) { - EditorHelp::get_doc_data()->remove_doc(doc.name); - } - } + if (scr.is_valid()) { + clear_docs_from_script(scr); } if (resource->is_built_in()) { @@ -2446,13 +2421,8 @@ void ScriptEditor::save_current_script() { EditorNode::get_singleton()->save_resource(resource); } - if (script != nullptr) { - Vector<DocData::ClassDoc> documentations = script->get_documentation(); - for (int j = 0; j < documentations.size(); j++) { - const DocData::ClassDoc &doc = documentations.get(j); - EditorHelp::get_doc_data()->add_doc(doc); - update_doc(doc.name); - } + if (scr.is_valid()) { + update_docs_from_script(scr); } } @@ -2490,32 +2460,21 @@ void ScriptEditor::save_all_scripts() { if (!edited_res->is_built_in()) { Ref<TextFile> text_file = edited_res; - Ref<Script> script = edited_res; + Ref<Script> scr = edited_res; if (text_file != nullptr) { _save_text_file(text_file, text_file->get_path()); continue; } - if (script != nullptr) { - Vector<DocData::ClassDoc> documentations = script->get_documentation(); - for (int j = 0; j < documentations.size(); j++) { - const DocData::ClassDoc &doc = documentations.get(j); - if (EditorHelp::get_doc_data()->has_doc(doc.name)) { - EditorHelp::get_doc_data()->remove_doc(doc.name); - } - } + if (scr.is_valid()) { + clear_docs_from_script(scr); } EditorNode::get_singleton()->save_resource(edited_res); //external script, save it - if (script != nullptr) { - Vector<DocData::ClassDoc> documentations = script->get_documentation(); - for (int j = 0; j < documentations.size(); j++) { - const DocData::ClassDoc &doc = documentations.get(j); - EditorHelp::get_doc_data()->add_doc(doc); - update_doc(doc.name); - } + if (scr.is_valid()) { + update_docs_from_script(scr); } } else { // For built-in scripts, save their scenes instead. @@ -2544,7 +2503,7 @@ void ScriptEditor::apply_scripts() const { } } -void ScriptEditor::reload_scripts() { +void ScriptEditor::reload_scripts(bool p_refresh_only) { for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (!se) { @@ -2557,30 +2516,33 @@ void ScriptEditor::reload_scripts() { continue; //internal script, who cares } - uint64_t last_date = edited_res->get_last_modified_time(); - uint64_t date = FileAccess::get_modified_time(edited_res->get_path()); + if (!p_refresh_only) { + uint64_t last_date = edited_res->get_last_modified_time(); + uint64_t date = FileAccess::get_modified_time(edited_res->get_path()); - if (last_date == date) { - continue; - } + if (last_date == date) { + continue; + } - Ref<Script> script = edited_res; - if (script != nullptr) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); - ERR_CONTINUE(!rel_script.is_valid()); - script->set_source_code(rel_script->get_source_code()); - script->set_last_modified_time(rel_script->get_last_modified_time()); - script->reload(true); - } + Ref<Script> scr = edited_res; + if (scr != nullptr) { + Ref<Script> rel_scr = ResourceLoader::load(scr->get_path(), scr->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_CONTINUE(!rel_scr.is_valid()); + scr->set_source_code(rel_scr->get_source_code()); + scr->set_last_modified_time(rel_scr->get_last_modified_time()); + scr->reload(true); + } - Ref<TextFile> text_file = edited_res; - if (text_file != nullptr) { - Error err; - Ref<TextFile> rel_text_file = _load_text_file(text_file->get_path(), &err); - ERR_CONTINUE(!rel_text_file.is_valid()); - text_file->set_text(rel_text_file->get_text()); - text_file->set_last_modified_time(rel_text_file->get_last_modified_time()); + Ref<TextFile> text_file = edited_res; + if (text_file != nullptr) { + Error err; + Ref<TextFile> rel_text_file = _load_text_file(text_file->get_path(), &err); + ERR_CONTINUE(!rel_text_file.is_valid()); + text_file->set_text(rel_text_file->get_text()); + text_file->set_last_modified_time(rel_text_file->get_last_modified_time()); + } } + se->reload_text(); } @@ -2641,17 +2603,17 @@ void ScriptEditor::_editor_stop() { void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const PackedStringArray &p_args) { ERR_FAIL_COND(!p_obj); - Ref<Script> script = p_obj->get_script(); - ERR_FAIL_COND(!script.is_valid()); + Ref<Script> scr = p_obj->get_script(); + ERR_FAIL_COND(!scr.is_valid()); - EditorNode::get_singleton()->push_item(script.ptr()); + EditorNode::get_singleton()->push_item(scr.ptr()); for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (!se) { continue; } - if (se->get_edited_resource() != script) { + if (se->get_edited_resource() != scr) { continue; } @@ -2662,7 +2624,7 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const script_list->select(script_list->find_metadata(i)); // Save the current script so the changes can be picked up by an external editor. - if (!script.ptr()->is_built_in()) { // But only if it's not built-in script. + if (!scr.ptr()->is_built_in()) { // But only if it's not built-in script. save_current_script(); } @@ -2694,26 +2656,26 @@ void ScriptEditor::_save_layout() { void ScriptEditor::_editor_settings_changed() { textfile_extensions.clear(); - const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + const Vector<String> textfile_ext = ((String)(EDITOR_GET("docks/filesystem/textfile_extensions"))).split(",", false); for (const String &E : textfile_ext) { textfile_extensions.insert(E); } - trim_trailing_whitespace_on_save = EditorSettings::get_singleton()->get("text_editor/behavior/files/trim_trailing_whitespace_on_save"); - convert_indent_on_save = EditorSettings::get_singleton()->get("text_editor/behavior/files/convert_indent_on_save"); - use_space_indentation = EditorSettings::get_singleton()->get("text_editor/behavior/indent/type"); + trim_trailing_whitespace_on_save = EDITOR_GET("text_editor/behavior/files/trim_trailing_whitespace_on_save"); + convert_indent_on_save = EDITOR_GET("text_editor/behavior/files/convert_indent_on_save"); + use_space_indentation = EDITOR_GET("text_editor/behavior/indent/type"); - members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/script_list/show_members_overview"); - help_overview_enabled = EditorSettings::get_singleton()->get("text_editor/help/show_help_index"); + members_overview_enabled = EDITOR_GET("text_editor/script_list/show_members_overview"); + help_overview_enabled = EDITOR_GET("text_editor/help/show_help_index"); _update_members_overview_visibility(); _update_help_overview_visibility(); _update_autosave_timer(); if (current_theme.is_empty()) { - current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); - } else if (current_theme != String(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))) { - current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); + current_theme = EDITOR_GET("text_editor/theme/color_theme"); + } else if (current_theme != String(EDITOR_GET("text_editor/theme/color_theme"))) { + current_theme = EDITOR_GET("text_editor/theme/color_theme"); EditorSettings::get_singleton()->load_text_editor_theme(); } @@ -2796,7 +2758,7 @@ void ScriptEditor::_update_autosave_timer() { return; } - float autosave_time = EditorSettings::get_singleton()->get("text_editor/behavior/files/autosave_interval_secs"); + float autosave_time = EDITOR_GET("text_editor/behavior/files/autosave_interval_secs"); if (autosave_time > 0) { autosave_timer->set_wait_time(autosave_time); autosave_timer->start(); @@ -2812,7 +2774,6 @@ void ScriptEditor::_tree_changed() { waiting_update_names = true; call_deferred(SNAME("_update_script_names")); - call_deferred(SNAME("_update_script_connections")); } void ScriptEditor::_split_dragged(float) { @@ -3059,26 +3020,15 @@ void ScriptEditor::shortcut_input(const Ref<InputEvent> &p_event) { } } -void ScriptEditor::_script_list_gui_input(const Ref<InputEvent> &ev) { - Ref<InputEventMouseButton> mb = ev; - if (mb.is_valid() && mb->is_pressed()) { - switch (mb->get_button_index()) { - case MouseButton::MIDDLE: { - // Right-click selects automatically; middle-click does not. - int idx = script_list->get_item_at_position(mb->get_position(), true); - if (idx >= 0) { - script_list->select(idx); - _script_selected(idx); - _menu_option(FILE_CLOSE); - } - } break; +void ScriptEditor::_script_list_clicked(int p_item, Vector2 p_local_mouse_pos, MouseButton p_mouse_button_index) { + if (p_mouse_button_index == MouseButton::MIDDLE) { + script_list->select(p_item); + _script_selected(p_item); + _menu_option(FILE_CLOSE); + } - case MouseButton::RIGHT: { - _make_script_list_context_menu(); - } break; - default: - break; - } + if (p_mouse_button_index == MouseButton::RIGHT) { + _make_script_list_context_menu(); } } @@ -3346,6 +3296,29 @@ void ScriptEditor::update_doc(const String &p_name) { } } +void ScriptEditor::clear_docs_from_script(const Ref<Script> &p_script) { + ERR_FAIL_COND(p_script.is_null()); + + Vector<DocData::ClassDoc> documentations = p_script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } +} + +void ScriptEditor::update_docs_from_script(const Ref<Script> &p_script) { + ERR_FAIL_COND(p_script.is_null()); + + Vector<DocData::ClassDoc> documentations = p_script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } +} + void ScriptEditor::_update_selected_editor_menu() { for (int i = 0; i < tab_container->get_tab_count(); i++) { bool current = tab_container->get_current_tab() == i; @@ -3368,10 +3341,12 @@ void ScriptEditor::_update_selected_editor_menu() { script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_previous", TTR("Find Previous"), KeyModifierMask::SHIFT | Key::F3), HELP_SEARCH_FIND_PREVIOUS); script_search_menu->get_popup()->add_separator(); script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::F), SEARCH_IN_FILES); + script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/replace_in_files", TTR("Replace in Files"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::R), REPLACE_IN_FILES); script_search_menu->show(); } else { if (tab_container->get_tab_count() == 0) { script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::F), SEARCH_IN_FILES); + script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/replace_in_files", TTR("Replace in Files"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::R), REPLACE_IN_FILES); script_search_menu->show(); } else { script_search_menu->hide(); @@ -3383,7 +3358,7 @@ void ScriptEditor::_update_history_pos(int p_new_pos) { Node *n = tab_container->get_current_tab_control(); if (Object::cast_to<ScriptEditorBase>(n)) { - history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state(); + history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_navigation_state(); } if (Object::cast_to<EditorHelp>(n)) { history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll(); @@ -3394,13 +3369,14 @@ void ScriptEditor::_update_history_pos(int p_new_pos) { n = history[history_pos].control; - if (Object::cast_to<ScriptEditorBase>(n)) { - Object::cast_to<ScriptEditorBase>(n)->set_edit_state(history[history_pos].state); - Object::cast_to<ScriptEditorBase>(n)->ensure_focus(); + ScriptEditorBase *seb = Object::cast_to<ScriptEditorBase>(n); + if (seb) { + seb->set_edit_state(history[history_pos].state); + seb->ensure_focus(); - Ref<Script> script = Object::cast_to<ScriptEditorBase>(n)->get_edited_resource(); - if (script != nullptr) { - notify_script_changed(script); + Ref<Script> scr = seb->get_edited_resource(); + if (scr != nullptr) { + notify_script_changed(scr); } } @@ -3436,9 +3412,9 @@ Vector<Ref<Script>> ScriptEditor::get_open_scripts() const { continue; } - Ref<Script> script = se->get_edited_resource(); - if (script != nullptr) { - out_scripts.push_back(script); + Ref<Script> scr = se->get_edited_resource(); + if (scr != nullptr) { + out_scripts.push_back(scr); } } @@ -3460,10 +3436,10 @@ TypedArray<ScriptEditorBase> ScriptEditor::_get_open_script_editors() const { void ScriptEditor::set_scene_root_script(Ref<Script> p_script) { // Don't open dominant script if using an external editor. bool use_external_editor = - EditorSettings::get_singleton()->get("text_editor/external/use_external_editor") || + EDITOR_GET("text_editor/external/use_external_editor") || (p_script.is_valid() && p_script->get_language()->overrides_external_editor()); use_external_editor = use_external_editor && !(p_script.is_valid() && p_script->is_built_in()); // Ignore external editor for built-in scripts. - const bool open_dominant = EditorSettings::get_singleton()->get("text_editor/behavior/files/open_dominant_script_on_scene_change"); + const bool open_dominant = EDITOR_GET("text_editor/behavior/files/open_dominant_script_on_scene_change"); if (open_dominant && !use_external_editor && p_script.is_valid()) { edit(p_script); @@ -3489,9 +3465,9 @@ void ScriptEditor::_help_search(String p_text) { } void ScriptEditor::_open_script_request(const String &p_path) { - Ref<Script> script = ResourceLoader::load(p_path); - if (script.is_valid()) { - script_editor->edit(script, false); + Ref<Script> scr = ResourceLoader::load(p_path); + if (scr.is_valid()) { + script_editor->edit(scr, false); return; } @@ -3556,9 +3532,9 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb EditorNode::get_singleton()->load_scene(fpath); return; } else { - Ref<Script> script = res; - if (script.is_valid()) { - edit(script); + Ref<Script> scr = res; + if (scr.is_valid()) { + edit(scr); ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(_get_current_editor()); if (ste) { @@ -3618,7 +3594,6 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method("_goto_script_line2", &ScriptEditor::_goto_script_line2); ClassDB::bind_method("_copy_script_path", &ScriptEditor::_copy_script_path); - ClassDB::bind_method("_update_script_connections", &ScriptEditor::_update_script_connections); ClassDB::bind_method("_help_class_open", &ScriptEditor::_help_class_open); ClassDB::bind_method("_help_tab_goto", &ScriptEditor::_help_tab_goto); ClassDB::bind_method("_live_auto_reload_running_scripts", &ScriptEditor::_live_auto_reload_running_scripts); @@ -3655,8 +3630,8 @@ ScriptEditor::ScriptEditor() { waiting_update_names = false; pending_auto_reload = false; auto_reload_running_scripts = true; - members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/script_list/show_members_overview"); - help_overview_enabled = EditorSettings::get_singleton()->get("text_editor/help/show_help_index"); + members_overview_enabled = EDITOR_GET("text_editor/script_list/show_members_overview"); + help_overview_enabled = EDITOR_GET("text_editor/help/show_help_index"); VBoxContainer *main_container = memnew(VBoxContainer); add_child(main_container); @@ -3688,7 +3663,7 @@ ScriptEditor::ScriptEditor() { script_list->set_v_size_flags(SIZE_EXPAND_FILL); script_split->set_split_offset(70 * EDSCALE); _sort_list_on_update = true; - script_list->connect("gui_input", callable_mp(this, &ScriptEditor::_script_list_gui_input), CONNECT_DEFERRED); + script_list->connect("item_clicked", callable_mp(this, &ScriptEditor::_script_list_clicked), CONNECT_DEFERRED); script_list->set_allow_rmb_select(true); script_list->set_drag_forwarding(this); @@ -3701,6 +3676,7 @@ ScriptEditor::ScriptEditor() { overview_vbox->set_v_size_flags(SIZE_EXPAND_FILL); list_split->add_child(overview_vbox); + list_split->set_visible(EditorSettings::get_singleton()->get_project_metadata("scripts_panel", "show_scripts_panel", true)); buttons_hbox = memnew(HBoxContainer); overview_vbox->add_child(buttons_hbox); @@ -3714,7 +3690,7 @@ ScriptEditor::ScriptEditor() { members_overview_alphabeta_sort_button->set_flat(true); members_overview_alphabeta_sort_button->set_tooltip_text(TTR("Toggle alphabetical sorting of the method list.")); members_overview_alphabeta_sort_button->set_toggle_mode(true); - members_overview_alphabeta_sort_button->set_pressed(EditorSettings::get_singleton()->get("text_editor/script_list/sort_members_outline_alphabetically")); + members_overview_alphabeta_sort_button->set_pressed(EDITOR_GET("text_editor/script_list/sort_members_outline_alphabetically")); members_overview_alphabeta_sort_button->connect("toggled", callable_mp(this, &ScriptEditor::_toggle_members_overview_alpha_sort)); buttons_hbox->add_child(members_overview_alphabeta_sort_button); @@ -3828,12 +3804,12 @@ ScriptEditor::ScriptEditor() { script_search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptEditor::_menu_option)); menu_hb->add_child(script_search_menu); - MenuButton *debug_menu = memnew(MenuButton); - menu_hb->add_child(debug_menu); - debug_menu->hide(); // Handled by EditorDebuggerNode below. + MenuButton *debug_menu_btn = memnew(MenuButton); + menu_hb->add_child(debug_menu_btn); + debug_menu_btn->hide(); // Handled by EditorDebuggerNode below. EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton(); - debugger->set_script_debug_button(debug_menu); + debugger->set_script_debug_button(debug_menu_btn); debugger->connect("goto_script_line", callable_mp(this, &ScriptEditor::_goto_script_line)); debugger->connect("set_execution", callable_mp(this, &ScriptEditor::_set_execution)); debugger->connect("clear_execution", callable_mp(this, &ScriptEditor::_clear_execution)); @@ -3918,7 +3894,7 @@ ScriptEditor::ScriptEditor() { vbc->add_child(disk_changed_list); disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL); - disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::reload_scripts)); + disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::reload_scripts).bind(false)); disk_changed->set_ok_button_text(TTR("Reload")); disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); @@ -3956,9 +3932,9 @@ ScriptEditor::ScriptEditor() { history_pos = -1; edit_pass = 0; - trim_trailing_whitespace_on_save = EditorSettings::get_singleton()->get("text_editor/behavior/files/trim_trailing_whitespace_on_save"); - convert_indent_on_save = EditorSettings::get_singleton()->get("text_editor/behavior/files/convert_indent_on_save"); - use_space_indentation = EditorSettings::get_singleton()->get("text_editor/behavior/indent/type"); + trim_trailing_whitespace_on_save = EDITOR_GET("text_editor/behavior/files/trim_trailing_whitespace_on_save"); + convert_indent_on_save = EDITOR_GET("text_editor/behavior/files/convert_indent_on_save"); + use_space_indentation = EDITOR_GET("text_editor/behavior/indent/type"); ScriptServer::edit_request_func = _open_script_request; diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index a8e6cc6868..213fbdc22a 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -31,23 +31,22 @@ #ifndef SCRIPT_EDITOR_PLUGIN_H #define SCRIPT_EDITOR_PLUGIN_H -#include "core/object/script_language.h" -#include "editor/code_editor.h" -#include "editor/editor_help.h" -#include "editor/editor_help_search.h" #include "editor/editor_plugin.h" -#include "editor/script_create_dialog.h" -#include "scene/gui/item_list.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/split_container.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/text_edit.h" -#include "scene/gui/tree.h" -#include "scene/main/timer.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/panel_container.h" +#include "scene/resources/syntax_highlighter.h" #include "scene/resources/text_file.h" class EditorFileDialog; +class EditorHelpSearch; +class FindReplaceBar; +class HSplitContainer; +class ItemList; +class MenuButton; +class TabContainer; +class TextureRect; +class Tree; +class VSplitContainer; class EditorSyntaxHighlighter : public SyntaxHighlighter { GDCLASS(EditorSyntaxHighlighter, SyntaxHighlighter) @@ -139,13 +138,14 @@ public: virtual Ref<Resource> get_edited_resource() const = 0; virtual Vector<String> get_functions() = 0; virtual void set_edited_resource(const Ref<Resource> &p_res) = 0; - virtual void enable_editor() = 0; + virtual void enable_editor(Control *p_shortcut_context = nullptr) = 0; virtual void reload_text() = 0; virtual String get_name() = 0; virtual Ref<Texture2D> get_theme_icon() = 0; virtual bool is_unsaved() = 0; virtual Variant get_edit_state() = 0; virtual void set_edit_state(const Variant &p_state) = 0; + virtual Variant get_navigation_state() = 0; virtual void goto_line(int p_line, bool p_with_error = false) = 0; virtual void set_executing_line(int p_line) = 0; virtual void clear_executing_line() = 0; @@ -403,7 +403,6 @@ class ScriptEditor : public PanelContainer { void _filter_scripts_text_changed(const String &p_newtext); void _filter_methods_text_changed(const String &p_newtext); void _update_script_names(); - void _update_script_connections(); bool _sort_list_on_update; void _members_overview_selected(int p_idx); @@ -426,7 +425,7 @@ class ScriptEditor : public PanelContainer { virtual void input(const Ref<InputEvent> &p_event) override; virtual void shortcut_input(const Ref<InputEvent> &p_event) override; - void _script_list_gui_input(const Ref<InputEvent> &ev); + void _script_list_clicked(int p_item, Vector2 p_local_mouse_pos, MouseButton p_mouse_button_index); void _make_script_list_context_menu(); void _help_search(String p_text); @@ -477,7 +476,7 @@ public: bool toggle_scripts_panel(); bool is_scripts_panel_toggled(); void apply_scripts() const; - void reload_scripts(); + void reload_scripts(bool p_refresh_only = false); void open_script_create_dialog(const String &p_base_name, const String &p_base_path); void open_text_file_create_dialog(const String &p_base_path, const String &p_base_name = ""); Ref<Resource> open_file(const String &p_file); @@ -509,6 +508,8 @@ public: void goto_help(const String &p_desc) { _help_class_goto(p_desc); } void update_doc(const String &p_name); + void clear_docs_from_script(const Ref<Script> &p_script); + void update_docs_from_script(const Ref<Script> &p_script); bool can_take_away_focus() const; diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 42dcfb8b1f..747fdfd041 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -38,6 +38,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "scene/gui/split_container.h" void ConnectionInfoDialog::ok_pressed() { } @@ -151,7 +152,7 @@ void ScriptTextEditor::set_edited_resource(const Ref<Resource> &p_res) { code_editor->update_line_and_column(); } -void ScriptTextEditor::enable_editor() { +void ScriptTextEditor::enable_editor(Control *p_shortcut_context) { if (editor_enabled) { return; } @@ -161,6 +162,15 @@ void ScriptTextEditor::enable_editor() { _enable_code_editor(); _validate_script(); + + if (p_shortcut_context) { + for (int i = 0; i < edit_hb->get_child_count(); ++i) { + Control *c = cast_to<Control>(edit_hb->get_child(i)); + if (c) { + c->set_shortcut_context(p_shortcut_context); + } + } + } } void ScriptTextEditor::_load_theme_settings() { @@ -267,6 +277,7 @@ void ScriptTextEditor::_warning_clicked(Variant p_line) { void ScriptTextEditor::_error_clicked(Variant p_line) { if (p_line.get_type() == Variant::INT) { + code_editor->get_text_editor()->remove_secondary_carets(); code_editor->get_text_editor()->set_caret_line(p_line.operator int64_t()); } } @@ -289,11 +300,13 @@ void ScriptTextEditor::reload_text() { te->tag_saved_version(); code_editor->update_line_and_column(); + _validate_script(); } void ScriptTextEditor::add_callback(const String &p_function, PackedStringArray p_args) { String code = code_editor->get_text_editor()->get_text(); int pos = script->get_language()->find_function(p_function, code); + code_editor->get_text_editor()->remove_secondary_carets(); if (pos == -1) { //does not exist code_editor->get_text_editor()->deselect(); @@ -313,7 +326,7 @@ bool ScriptTextEditor::show_members_overview() { } void ScriptTextEditor::update_settings() { - code_editor->get_text_editor()->set_gutter_draw(connection_gutter, EditorSettings::get_singleton()->get("text_editor/appearance/gutters/show_info_gutter")); + code_editor->get_text_editor()->set_gutter_draw(connection_gutter, EDITOR_GET("text_editor/appearance/gutters/show_info_gutter")); code_editor->update_editor_settings(); } @@ -346,6 +359,10 @@ void ScriptTextEditor::set_edit_state(const Variant &p_state) { } } +Variant ScriptTextEditor::get_navigation_state() { + return code_editor->get_navigation_state(); +} + void ScriptTextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) { code_editor->convert_case(p_case); } @@ -682,7 +699,7 @@ static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_curr } void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_for_script) { - if (!bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { + if (!bool(EDITOR_GET("text_editor/external/use_external_editor"))) { return; } @@ -696,25 +713,25 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo } for (const Ref<Script> &E : scripts) { - Ref<Script> script = E; + Ref<Script> scr = E; - if (p_for_script.is_valid() && p_for_script != script) { + if (p_for_script.is_valid() && p_for_script != scr) { continue; } - if (script->is_built_in()) { + if (scr->is_built_in()) { continue; //internal script, who cares, though weird } - uint64_t last_date = script->get_last_modified_time(); - uint64_t date = FileAccess::get_modified_time(script->get_path()); + uint64_t last_date = scr->get_last_modified_time(); + uint64_t date = FileAccess::get_modified_time(scr->get_path()); if (last_date != date) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); - ERR_CONTINUE(!rel_script.is_valid()); - script->set_source_code(rel_script->get_source_code()); - script->set_last_modified_time(rel_script->get_last_modified_time()); - script->update_exports(); + Ref<Script> rel_scr = ResourceLoader::load(scr->get_path(), scr->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_CONTINUE(!rel_scr.is_valid()); + scr->set_source_code(rel_scr->get_source_code()); + scr->set_last_modified_time(rel_scr->get_last_modified_time()); + scr->update_exports(); _trigger_live_script_reload(); } @@ -956,10 +973,7 @@ void ScriptTextEditor::_update_connected_methods() { CodeEdit *text_edit = code_editor->get_text_editor(); text_edit->set_gutter_width(connection_gutter, text_edit->get_line_height()); for (int i = 0; i < text_edit->get_line_count(); i++) { - if (text_edit->get_line_gutter_metadata(i, connection_gutter) == "") { - continue; - } - text_edit->set_line_gutter_metadata(i, connection_gutter, ""); + text_edit->set_line_gutter_metadata(i, connection_gutter, Dictionary()); text_edit->set_line_gutter_icon(i, connection_gutter, nullptr); text_edit->set_line_gutter_clickable(i, connection_gutter, false); } @@ -974,13 +988,14 @@ void ScriptTextEditor::_update_connected_methods() { return; } + // Add connection icons to methods. Vector<Node *> nodes = _find_all_node_for_script(base, base, script); HashSet<StringName> methods_found; for (int i = 0; i < nodes.size(); i++) { - List<Connection> connections; - nodes[i]->get_signals_connected_to_this(&connections); + List<Connection> signal_connections; + nodes[i]->get_signals_connected_to_this(&signal_connections); - for (const Connection &connection : connections) { + for (const Connection &connection : signal_connections) { if (!(connection.flags & CONNECT_PERSIST)) { continue; } @@ -1002,8 +1017,11 @@ void ScriptTextEditor::_update_connected_methods() { for (int j = 0; j < functions.size(); j++) { String name = functions[j].get_slice(":", 0); if (name == method) { + Dictionary line_meta; + line_meta["type"] = "connection"; + line_meta["method"] = method; line = functions[j].get_slice(":", 1).to_int() - 1; - text_edit->set_line_gutter_metadata(line, connection_gutter, method); + text_edit->set_line_gutter_metadata(line, connection_gutter, line_meta); text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("Slot"), SNAME("EditorIcons"))); text_edit->set_line_gutter_clickable(line, connection_gutter, true); methods_found.insert(method); @@ -1033,6 +1051,66 @@ void ScriptTextEditor::_update_connected_methods() { } } } + + // Add override icons to methods. + methods_found.clear(); + for (int i = 0; i < functions.size(); i++) { + StringName name = StringName(functions[i].get_slice(":", 0)); + if (methods_found.has(name)) { + continue; + } + + String found_base_class; + StringName base_class = script->get_instance_base_type(); + Ref<Script> inherited_script = script->get_base_script(); + while (!inherited_script.is_null()) { + if (inherited_script->has_method(name)) { + found_base_class = "script:" + inherited_script->get_path(); + break; + } + + base_class = inherited_script->get_instance_base_type(); + inherited_script = inherited_script->get_base_script(); + } + + if (found_base_class.is_empty()) { + while (base_class) { + List<MethodInfo> methods; + ClassDB::get_method_list(base_class, &methods, true); + for (int j = 0; j < methods.size(); j++) { + if (methods[j].name == name) { + found_base_class = "builtin:" + base_class; + break; + } + } + + ClassDB::ClassInfo *base_class_ptr = ClassDB::classes.getptr(base_class)->inherits_ptr; + if (base_class_ptr == nullptr) { + break; + } + base_class = base_class_ptr->name; + } + } + + if (!found_base_class.is_empty()) { + int line = functions[i].get_slice(":", 1).to_int() - 1; + + Dictionary line_meta = text_edit->get_line_gutter_metadata(line, connection_gutter); + if (line_meta.is_empty()) { + // Add override icon to gutter. + line_meta["type"] = "inherits"; + line_meta["method"] = name; + line_meta["base_class"] = found_base_class; + text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("MethodOverride"), SNAME("EditorIcons"))); + text_edit->set_line_gutter_clickable(line, connection_gutter, true); + } else { + // If method is also connected to signal, then merge icons and keep the click behavior of the slot. + text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("MethodOverrideAndSlot"), SNAME("EditorIcons"))); + } + + methods_found.insert(name); + } + } } void ScriptTextEditor::_update_gutter_indexes() { @@ -1054,18 +1132,40 @@ void ScriptTextEditor::_gutter_clicked(int p_line, int p_gutter) { return; } - String method = code_editor->get_text_editor()->get_line_gutter_metadata(p_line, p_gutter); - if (method.is_empty()) { + Dictionary meta = code_editor->get_text_editor()->get_line_gutter_metadata(p_line, p_gutter); + String type = meta.get("type", ""); + if (type.is_empty()) { return; } - Node *base = get_tree()->get_edited_scene_root(); - if (!base) { + // All types currently need a method name. + String method = meta.get("method", ""); + if (method.is_empty()) { return; } - Vector<Node *> nodes = _find_all_node_for_script(base, base, script); - connection_info_dialog->popup_connections(method, nodes); + if (type == "connection") { + Node *base = get_tree()->get_edited_scene_root(); + if (!base) { + return; + } + + Vector<Node *> nodes = _find_all_node_for_script(base, base, script); + connection_info_dialog->popup_connections(method, nodes); + } else if (type == "inherits") { + String base_class_raw = meta["base_class"]; + PackedStringArray base_class_split = base_class_raw.split(":", true, 1); + + if (base_class_split[0] == "script") { + // Go to function declaration. + Ref<Script> base_script = ResourceLoader::load(base_class_split[1]); + ERR_FAIL_COND(!base_script.is_valid()); + emit_signal(SNAME("go_to_method"), base_script, method); + } else if (base_class_split[0] == "builtin") { + // Open method documentation. + emit_signal(SNAME("go_to_help"), "class_method:" + base_class_split[1] + ":" + method); + } + } } void ScriptTextEditor::_edit_option(int p_op) { @@ -1102,21 +1202,19 @@ void ScriptTextEditor::_edit_option(int p_op) { case EDIT_MOVE_LINE_DOWN: { code_editor->move_lines_down(); } break; - case EDIT_INDENT_LEFT: { + case EDIT_INDENT: { Ref<Script> scr = script; if (scr.is_null()) { return; } - - tx->unindent_lines(); + tx->indent_lines(); } break; - case EDIT_INDENT_RIGHT: { + case EDIT_UNINDENT: { Ref<Script> scr = script; if (scr.is_null()) { return; } - - tx->indent_lines(); + tx->unindent_lines(); } break; case EDIT_DELETE_LINE: { code_editor->delete_lines(); @@ -1281,6 +1379,7 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } + tx->remove_secondary_carets(); int line = tx->get_caret_line(); // wrap around @@ -1307,6 +1406,7 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } + tx->remove_secondary_carets(); int line = tx->get_caret_line(); // wrap around if (line <= (int)bpoints[0]) { @@ -1327,21 +1427,21 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case HELP_CONTEXTUAL: { - String text = tx->get_selected_text(); + String text = tx->get_selected_text(0); if (text.is_empty()) { - text = tx->get_word_under_caret(); + text = tx->get_word_under_caret(0); } if (!text.is_empty()) { emit_signal(SNAME("request_help"), text); } } break; case LOOKUP_SYMBOL: { - String text = tx->get_word_under_caret(); + String text = tx->get_word_under_caret(0); if (text.is_empty()) { - text = tx->get_selected_text(); + text = tx->get_selected_text(0); } if (!text.is_empty()) { - _lookup_symbol(text, tx->get_caret_line(), tx->get_caret_column()); + _lookup_symbol(text, tx->get_caret_line(0), tx->get_caret_column(0)); } } break; } @@ -1487,16 +1587,17 @@ bool ScriptTextEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_ } static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) { - if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) { - return nullptr; - } - - Ref<Script> scr = p_current_node->get_script(); - - if (scr.is_valid() && scr == script) { - return p_current_node; + // Check scripts only for the nodes belonging to the edited scene. + if (p_current_node == p_edited_scene || p_current_node->get_owner() == p_edited_scene) { + Ref<Script> scr = p_current_node->get_script(); + if (scr.is_valid() && scr == script) { + return p_current_node; + } } + // Traverse all children, even the ones not owned by the edited scene as they + // can still have child nodes added within the edited scene and thus owned by + // it (e.g. nodes added to subscene's root or to its editable children). for (int i = 0; i < p_current_node->get_child_count(); i++) { Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script); if (n) { @@ -1507,9 +1608,24 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const return nullptr; } -void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; +static String _quote_drop_data(const String &str) { + // This function prepares a string for being "dropped" into the script editor. + // The string can be a resource path, node path or property name. + + const bool using_single_quotes = EDITOR_GET("text_editor/completion/use_single_quotes"); + + String escaped = str.c_escape(); + + // If string is double quoted, there is no need to escape single quotes. + // We can revert the extra escaping added in c_escape(). + if (!using_single_quotes) { + escaped = escaped.replace("\\'", "\'"); + } + + return escaped.quote(using_single_quotes ? "'" : "\""); +} +void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { Dictionary d = p_data; CodeEdit *te = code_editor->get_text_editor(); @@ -1518,6 +1634,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data int col = pos.x; if (d.has("type") && String(d["type"]) == "resource") { + te->remove_secondary_carets(); Ref<Resource> res = d["resource"]; if (!res.is_valid()) { return; @@ -1535,6 +1652,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } if (d.has("type") && (String(d["type"]) == "files" || String(d["type"]) == "files_and_dirs")) { + te->remove_secondary_carets(); Array files = d["files"]; String text_to_drop; @@ -1545,9 +1663,9 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } if (preload) { - text_to_drop += "preload(" + String(files[i]).c_escape().quote(quote_style) + ")"; + text_to_drop += "preload(" + _quote_drop_data(String(files[i])) + ")"; } else { - text_to_drop += String(files[i]).c_escape().quote(quote_style); + text_to_drop += _quote_drop_data(String(files[i])); } } @@ -1558,8 +1676,14 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } if (d.has("type") && String(d["type"]) == "nodes") { - Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script); + te->remove_secondary_carets(); + Node *scene_root = get_tree()->get_edited_scene_root(); + if (!scene_root) { + EditorNode::get_singleton()->show_warning(TTR("Can't drop nodes without an open scene.")); + return; + } + Node *sn = _find_script_node(scene_root, scene_root, script); if (!sn) { EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop nodes because script '%s' is not used in this scene."), get_name())); return; @@ -1587,7 +1711,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } for (const String &segment : path.split("/")) { if (!segment.is_valid_identifier()) { - path = path.c_escape().quote(quote_style); + path = _quote_drop_data(path); break; } } @@ -1622,7 +1746,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data for (const String &segment : path.split("/")) { if (!segment.is_valid_identifier()) { - path = path.c_escape().quote(quote_style); + path = _quote_drop_data(path); break; } } @@ -1637,7 +1761,10 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } if (d.has("type") && String(d["type"]) == "obj_property") { - const String text_to_drop = String(d["property"]).c_escape().quote(quote_style); + te->remove_secondary_carets(); + // It is unclear whether properties may contain single or double quotes. + // Assume here that double-quotes may not exist. We are escaping single-quotes if necessary. + const String text_to_drop = _quote_drop_data(String(d["property"])); te->set_caret_line(row); te->set_caret_column(col); @@ -1657,8 +1784,8 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { local_pos = mb->get_global_position() - tx->get_global_position(); create_menu = true; } else if (k.is_valid() && k->is_action("ui_menu", true)) { - tx->adjust_viewport_to_caret(); - local_pos = tx->get_caret_draw_pos(); + tx->adjust_viewport_to_caret(0); + local_pos = tx->get_caret_draw_pos(0); create_menu = true; } @@ -1667,8 +1794,9 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { int row = pos.y; int col = pos.x; - tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click")); + tx->set_move_caret_on_right_click_enabled(EDITOR_GET("text_editor/behavior/navigation/move_caret_on_right_click")); if (tx->is_move_caret_on_right_click_enabled()) { + tx->remove_secondary_carets(); if (tx->has_selection()) { int from_line = tx->get_selection_from_line(); int to_line = tx->get_selection_to_line(); @@ -1688,10 +1816,10 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { String word_at_pos = tx->get_word_at_pos(local_pos); if (word_at_pos.is_empty()) { - word_at_pos = tx->get_word_under_caret(); + word_at_pos = tx->get_word_under_caret(0); } if (word_at_pos.is_empty()) { - word_at_pos = tx->get_selected_text(); + word_at_pos = tx->get_selected_text(0); } bool has_color = (word_at_pos == "Color"); @@ -1733,7 +1861,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { if (valid) { color_args = line.substr(begin, end - begin); String stripped = color_args.replace(" ", "").replace("(", "").replace(")", ""); - Vector<float> color = stripped.split_floats(","); + PackedFloat64Array color = stripped.split_floats(","); if (color.size() > 2) { float alpha = color.size() > 3 ? color[3] : 1.0f; color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha)); @@ -1786,8 +1914,8 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent"), EDIT_INDENT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unindent"), EDIT_UNINDENT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); @@ -1877,17 +2005,6 @@ void ScriptTextEditor::_enable_code_editor() { add_child(connection_info_dialog); - edit_hb->add_child(search_menu); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); - search_menu->get_popup()->add_separator(); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES); - search_menu->get_popup()->add_separator(); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL); - search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); - edit_hb->add_child(edit_menu); edit_menu->connect("about_to_popup", callable_mp(this, &ScriptTextEditor::_prepare_edit_menu)); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); @@ -1898,41 +2015,75 @@ void ScriptTextEditor::_enable_code_editor() { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/duplicate_selection"), EDIT_DUPLICATE_SELECTION); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES); + { + PopupMenu *sub_menu = memnew(PopupMenu); + sub_menu->set_name("line_menu"); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent"), EDIT_INDENT); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unindent"), EDIT_UNINDENT); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); + sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + edit_menu->get_popup()->add_child(sub_menu); + edit_menu->get_popup()->add_submenu_item(TTR("Line"), "line_menu"); + } + { + PopupMenu *sub_menu = memnew(PopupMenu); + sub_menu->set_name("folding_menu"); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES); + sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + edit_menu->get_popup()->add_child(sub_menu); + edit_menu->get_popup()->add_submenu_item(TTR("Folding"), "folding_menu"); + } edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/duplicate_selection"), EDIT_DUPLICATE_SELECTION); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/auto_indent"), EDIT_AUTO_INDENT); + { + PopupMenu *sub_menu = memnew(PopupMenu); + sub_menu->set_name("indent_menu"); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS); + sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/auto_indent"), EDIT_AUTO_INDENT); + sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + edit_menu->get_popup()->add_child(sub_menu); + edit_menu->get_popup()->add_submenu_item(TTR("Indentation"), "indent_menu"); + } edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); edit_menu->get_popup()->add_separator(); - - edit_menu->get_popup()->add_child(convert_case); - edit_menu->get_popup()->add_submenu_item(TTR("Convert Case"), "convert_case"); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase"), KeyModifierMask::SHIFT | Key::F4), EDIT_TO_UPPERCASE); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase"), KeyModifierMask::SHIFT | Key::F5), EDIT_TO_LOWERCASE); - convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KeyModifierMask::SHIFT | Key::F6), EDIT_CAPITALIZE); - convert_case->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); - + { + PopupMenu *sub_menu = memnew(PopupMenu); + sub_menu->set_name("convert_case"); + sub_menu->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase"), KeyModifierMask::SHIFT | Key::F4), EDIT_TO_UPPERCASE); + sub_menu->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase"), KeyModifierMask::SHIFT | Key::F5), EDIT_TO_LOWERCASE); + sub_menu->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KeyModifierMask::SHIFT | Key::F6), EDIT_CAPITALIZE); + sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + edit_menu->get_popup()->add_child(sub_menu); + edit_menu->get_popup()->add_submenu_item(TTR("Convert Case"), "convert_case"); + } edit_menu->get_popup()->add_child(highlighter_menu); edit_menu->get_popup()->add_submenu_item(TTR("Syntax Highlighter"), "highlighter_menu"); highlighter_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_change_syntax_highlighter)); + edit_hb->add_child(search_menu); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); + search_menu->get_popup()->add_separator(); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace_in_files"), REPLACE_IN_FILES); + search_menu->get_popup()->add_separator(); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL); + search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); + _load_theme_settings(); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace_in_files"), REPLACE_IN_FILES); edit_hb->add_child(goto_menu); goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_function"), SEARCH_LOCATE_FUNCTION); goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE); @@ -1989,7 +2140,7 @@ ScriptTextEditor::ScriptTextEditor() { update_settings(); - code_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line")); + code_editor->get_text_editor()->set_code_hint_draw_below(EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line")); code_editor->get_text_editor()->set_symbol_lookup_on_click_enabled(true); code_editor->get_text_editor()->set_context_menu_enabled(false); @@ -2005,9 +2156,6 @@ ScriptTextEditor::ScriptTextEditor() { edit_menu->set_switch_on_hover(true); edit_menu->set_shortcut_context(this); - convert_case = memnew(PopupMenu); - convert_case->set_name("convert_case"); - highlighter_menu = memnew(PopupMenu); highlighter_menu->set_name("highlighter_menu"); @@ -2052,7 +2200,6 @@ ScriptTextEditor::~ScriptTextEditor() { memdelete(color_panel); memdelete(edit_hb); memdelete(edit_menu); - memdelete(convert_case); memdelete(highlighter_menu); memdelete(search_menu); memdelete(goto_menu); @@ -2077,8 +2224,8 @@ void ScriptTextEditor::register_editor() { // Leave these at zero, same can be accomplished with tab/shift-tab, including selection. // The next/previous in history shortcut in this case makes a lot more sense. - ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), Key::NONE); - ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), Key::NONE); + ED_SHORTCUT("script_text_editor/indent", TTR("Indent"), Key::NONE); + ED_SHORTCUT("script_text_editor/unindent", TTR("Unindent"), KeyModifierMask::SHIFT | Key::TAB); ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KeyModifierMask::CMD_OR_CTRL | Key::K); ED_SHORTCUT("script_text_editor/toggle_fold_line", TTR("Fold/Unfold Line"), KeyModifierMask::ALT | Key::F); ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), Key::NONE); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 8d2fb98721..cbc4153e12 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -31,10 +31,14 @@ #ifndef SCRIPT_TEXT_EDITOR_H #define SCRIPT_TEXT_EDITOR_H +#include "script_editor_plugin.h" + +#include "editor/code_editor.h" #include "scene/gui/color_picker.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" -#include "script_editor_plugin.h" + +class RichTextLabel; class ConnectionInfoDialog : public AcceptDialog { GDCLASS(ConnectionInfoDialog, AcceptDialog); @@ -79,7 +83,6 @@ class ScriptTextEditor : public ScriptEditorBase { PopupMenu *breakpoints_menu = nullptr; PopupMenu *highlighter_menu = nullptr; PopupMenu *context_menu = nullptr; - PopupMenu *convert_case = nullptr; GotoLineDialog *goto_line_dialog = nullptr; ScriptEditorQuickOpen *quick_open = nullptr; @@ -117,8 +120,8 @@ class ScriptTextEditor : public ScriptEditorBase { EDIT_TOGGLE_COMMENT, EDIT_MOVE_LINE_UP, EDIT_MOVE_LINE_DOWN, - EDIT_INDENT_RIGHT, - EDIT_INDENT_LEFT, + EDIT_INDENT, + EDIT_UNINDENT, EDIT_DELETE_LINE, EDIT_DUPLICATE_SELECTION, EDIT_PICK_COLOR, @@ -207,7 +210,7 @@ public: virtual void apply_code() override; virtual Ref<Resource> get_edited_resource() const override; virtual void set_edited_resource(const Ref<Resource> &p_res) override; - virtual void enable_editor() override; + virtual void enable_editor(Control *p_shortcut_context = nullptr) override; virtual Vector<String> get_functions() override; virtual void reload_text() override; virtual String get_name() override; @@ -215,6 +218,7 @@ public: virtual bool is_unsaved() override; virtual Variant get_edit_state() override; virtual void set_edit_state(const Variant &p_state) override; + virtual Variant get_navigation_state() override; virtual void ensure_focus() override; virtual void trim_trailing_whitespace() override; virtual void insert_final_newline() override; diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 246bc4b183..fbc94c70f8 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -30,1168 +30,16 @@ #include "shader_editor_plugin.h" -#include "core/io/resource_loader.h" -#include "core/io/resource_saver.h" -#include "core/os/keyboard.h" -#include "core/os/os.h" -#include "core/version_generated.gen.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" -#include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" #include "editor/filesystem_dock.h" +#include "editor/inspector_dock.h" +#include "editor/plugins/text_shader_editor.h" #include "editor/plugins/visual_shader_editor_plugin.h" -#include "editor/project_settings_editor.h" #include "editor/shader_create_dialog.h" -#include "scene/gui/split_container.h" -#include "servers/display_server.h" -#include "servers/rendering/shader_preprocessor.h" -#include "servers/rendering/shader_types.h" - -/*** SHADER SYNTAX HIGHLIGHTER ****/ - -Dictionary GDShaderSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_line) { - Dictionary color_map; - - for (const Point2i ®ion : disabled_branch_regions) { - if (p_line >= region.x && p_line <= region.y) { - Dictionary highlighter_info; - highlighter_info["color"] = disabled_branch_color; - - color_map[0] = highlighter_info; - return color_map; - } - } - - return CodeHighlighter::_get_line_syntax_highlighting_impl(p_line); -} - -void GDShaderSyntaxHighlighter::add_disabled_branch_region(const Point2i &p_region) { - ERR_FAIL_COND(p_region.x < 0); - ERR_FAIL_COND(p_region.y < 0); - - for (int i = 0; i < disabled_branch_regions.size(); i++) { - ERR_FAIL_COND_MSG(disabled_branch_regions[i].x == p_region.x, "Branch region with a start line '" + itos(p_region.x) + "' already exists."); - } - - Point2i disabled_branch_region; - disabled_branch_region.x = p_region.x; - disabled_branch_region.y = p_region.y; - disabled_branch_regions.push_back(disabled_branch_region); - - clear_highlighting_cache(); -} - -void GDShaderSyntaxHighlighter::clear_disabled_branch_regions() { - disabled_branch_regions.clear(); - clear_highlighting_cache(); -} - -void GDShaderSyntaxHighlighter::set_disabled_branch_color(const Color &p_color) { - disabled_branch_color = p_color; - clear_highlighting_cache(); -} - -/*** SHADER SCRIPT EDITOR ****/ - -static bool saved_warnings_enabled = false; -static bool saved_treat_warning_as_errors = false; -static HashMap<ShaderWarning::Code, bool> saved_warnings; -static uint32_t saved_warning_flags = 0U; - -void ShaderTextEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_THEME_CHANGED: { - if (is_visible_in_tree()) { - _load_theme_settings(); - if (warnings.size() > 0 && last_compile_result == OK) { - warnings_panel->clear(); - _update_warning_panel(); - } - } - } break; - } -} - -Ref<Shader> ShaderTextEditor::get_edited_shader() const { - return shader; -} - -Ref<ShaderInclude> ShaderTextEditor::get_edited_shader_include() const { - return shader_inc; -} - -void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader) { - set_edited_shader(p_shader, p_shader->get_code()); -} - -void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader, const String &p_code) { - if (shader == p_shader) { - return; - } - if (shader.is_valid()) { - shader->disconnect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); - } - shader = p_shader; - shader_inc = Ref<ShaderInclude>(); - - set_edited_code(p_code); - - if (shader.is_valid()) { - shader->connect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); - } -} - -void ShaderTextEditor::set_edited_shader_include(const Ref<ShaderInclude> &p_shader_inc) { - set_edited_shader_include(p_shader_inc, p_shader_inc->get_code()); -} - -void ShaderTextEditor::_shader_changed() { - // This function is used for dependencies (include changing changes main shader and forces it to revalidate) - if (block_shader_changed) { - return; - } - dependencies_version++; - _validate_script(); -} - -void ShaderTextEditor::set_edited_shader_include(const Ref<ShaderInclude> &p_shader_inc, const String &p_code) { - if (shader_inc == p_shader_inc) { - return; - } - if (shader_inc.is_valid()) { - shader_inc->disconnect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); - } - shader_inc = p_shader_inc; - shader = Ref<Shader>(); - - set_edited_code(p_code); - - if (shader_inc.is_valid()) { - shader_inc->connect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); - } -} - -void ShaderTextEditor::set_edited_code(const String &p_code) { - _load_theme_settings(); - - get_text_editor()->set_text(p_code); - get_text_editor()->clear_undo_history(); - get_text_editor()->call_deferred(SNAME("set_h_scroll"), 0); - get_text_editor()->call_deferred(SNAME("set_v_scroll"), 0); - get_text_editor()->tag_saved_version(); - - _validate_script(); - _line_col_changed(); -} - -void ShaderTextEditor::reload_text() { - ERR_FAIL_COND(shader.is_null()); - - CodeEdit *te = get_text_editor(); - int column = te->get_caret_column(); - int row = te->get_caret_line(); - int h = te->get_h_scroll(); - int v = te->get_v_scroll(); - - te->set_text(shader->get_code()); - te->set_caret_line(row); - te->set_caret_column(column); - te->set_h_scroll(h); - te->set_v_scroll(v); - - te->tag_saved_version(); - - update_line_and_column(); -} - -void ShaderTextEditor::set_warnings_panel(RichTextLabel *p_warnings_panel) { - warnings_panel = p_warnings_panel; -} - -void ShaderTextEditor::_load_theme_settings() { - CodeEdit *text_editor = get_text_editor(); - Color updated_marked_line_color = EDITOR_GET("text_editor/theme/highlighting/mark_color"); - if (updated_marked_line_color != marked_line_color) { - for (int i = 0; i < text_editor->get_line_count(); i++) { - if (text_editor->get_line_background_color(i) == marked_line_color) { - text_editor->set_line_background_color(i, updated_marked_line_color); - } - } - marked_line_color = updated_marked_line_color; - } - - syntax_highlighter->set_number_color(EDITOR_GET("text_editor/theme/highlighting/number_color")); - syntax_highlighter->set_symbol_color(EDITOR_GET("text_editor/theme/highlighting/symbol_color")); - syntax_highlighter->set_function_color(EDITOR_GET("text_editor/theme/highlighting/function_color")); - syntax_highlighter->set_member_variable_color(EDITOR_GET("text_editor/theme/highlighting/member_variable_color")); - - syntax_highlighter->clear_keyword_colors(); - - const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); - const Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color"); - - List<String> keywords; - ShaderLanguage::get_keyword_list(&keywords); - - for (const String &E : keywords) { - if (ShaderLanguage::is_control_flow_keyword(E)) { - syntax_highlighter->add_keyword_color(E, control_flow_keyword_color); - } else { - syntax_highlighter->add_keyword_color(E, keyword_color); - } - } - - List<String> pp_keywords; - ShaderPreprocessor::get_keyword_list(&pp_keywords, false); - - for (const String &E : pp_keywords) { - syntax_highlighter->add_keyword_color(E, keyword_color); - } - - // Colorize built-ins like `COLOR` differently to make them easier - // to distinguish from keywords at a quick glance. - - List<String> built_ins; - - if (shader_inc.is_valid()) { - for (int i = 0; i < RenderingServer::SHADER_MAX; i++) { - for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) { - for (const KeyValue<StringName, ShaderLanguage::BuiltInInfo> &F : E.value.built_ins) { - built_ins.push_back(F.key); - } - } - - const Vector<ShaderLanguage::ModeInfo> &modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i)); - - for (int j = 0; j < modes.size(); j++) { - const ShaderLanguage::ModeInfo &info = modes[j]; - - if (!info.options.is_empty()) { - for (int k = 0; k < info.options.size(); k++) { - built_ins.push_back(String(info.name) + "_" + String(info.options[k])); - } - } else { - built_ins.push_back(String(info.name)); - } - } - } - } else if (shader.is_valid()) { - for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode()))) { - for (const KeyValue<StringName, ShaderLanguage::BuiltInInfo> &F : E.value.built_ins) { - built_ins.push_back(F.key); - } - } - - const Vector<ShaderLanguage::ModeInfo> &modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())); - - for (int i = 0; i < modes.size(); i++) { - const ShaderLanguage::ModeInfo &info = modes[i]; - - if (!info.options.is_empty()) { - for (int j = 0; j < info.options.size(); j++) { - built_ins.push_back(String(info.name) + "_" + String(info.options[j])); - } - } else { - built_ins.push_back(String(info.name)); - } - } - } - - const Color user_type_color = EDITOR_GET("text_editor/theme/highlighting/user_type_color"); - - for (const String &E : built_ins) { - syntax_highlighter->add_keyword_color(E, user_type_color); - } - - // Colorize comments. - const Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color"); - syntax_highlighter->clear_color_regions(); - syntax_highlighter->add_color_region("/*", "*/", comment_color, false); - syntax_highlighter->add_color_region("//", "", comment_color, true); - syntax_highlighter->set_disabled_branch_color(comment_color); - - text_editor->clear_comment_delimiters(); - text_editor->add_comment_delimiter("/*", "*/", false); - text_editor->add_comment_delimiter("//", "", true); - - if (!text_editor->has_auto_brace_completion_open_key("/*")) { - text_editor->add_auto_brace_completion_pair("/*", "*/"); - } - - // Colorize preprocessor include strings. - const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color"); - syntax_highlighter->add_color_region("\"", "\"", string_color, false); - - if (warnings_panel) { - // Warnings panel. - warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts"))); - warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"))); - } -} - -void ShaderTextEditor::_check_shader_mode() { - String type = ShaderLanguage::get_shader_type(get_text_editor()->get_text()); - - Shader::Mode mode; - - if (type == "canvas_item") { - mode = Shader::MODE_CANVAS_ITEM; - } else if (type == "particles") { - mode = Shader::MODE_PARTICLES; - } else if (type == "sky") { - mode = Shader::MODE_SKY; - } else if (type == "fog") { - mode = Shader::MODE_FOG; - } else { - mode = Shader::MODE_SPATIAL; - } - - if (shader->get_mode() != mode) { - set_block_shader_changed(true); - shader->set_code(get_text_editor()->get_text()); - set_block_shader_changed(false); - _load_theme_settings(); - } -} - -static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) { - RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_variable); - return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); -} - -static String complete_from_path; - -static void _complete_include_paths_search(EditorFileSystemDirectory *p_efsd, List<ScriptLanguage::CodeCompletionOption> *r_options) { - if (!p_efsd) { - return; - } - for (int i = 0; i < p_efsd->get_file_count(); i++) { - if (p_efsd->get_file_type(i) == SNAME("ShaderInclude")) { - String path = p_efsd->get_file_path(i); - if (path.begins_with(complete_from_path)) { - path = path.replace_first(complete_from_path, ""); - } - r_options->push_back(ScriptLanguage::CodeCompletionOption(path, ScriptLanguage::CODE_COMPLETION_KIND_FILE_PATH)); - } - } - for (int j = 0; j < p_efsd->get_subdir_count(); j++) { - _complete_include_paths_search(p_efsd->get_subdir(j), r_options); - } -} - -static void _complete_include_paths(List<ScriptLanguage::CodeCompletionOption> *r_options) { - _complete_include_paths_search(EditorFileSystem::get_singleton()->get_filesystem(), r_options); -} - -void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptLanguage::CodeCompletionOption> *r_options) { - List<ScriptLanguage::CodeCompletionOption> pp_options; - ShaderPreprocessor preprocessor; - String code; - complete_from_path = (shader.is_valid() ? shader->get_path() : shader_inc->get_path()).get_base_dir(); - if (!complete_from_path.ends_with("/")) { - complete_from_path += "/"; - } - preprocessor.preprocess(p_code, "", code, nullptr, nullptr, nullptr, nullptr, &pp_options, _complete_include_paths); - complete_from_path = String(); - if (pp_options.size()) { - for (const ScriptLanguage::CodeCompletionOption &E : pp_options) { - r_options->push_back(E); - } - return; - } - - ShaderLanguage sl; - String calltip; - ShaderLanguage::ShaderCompileInfo info; - info.global_shader_uniform_type_func = _get_global_shader_uniform_type; - - if (shader.is_null()) { - info.is_include = true; - - sl.complete(code, info, r_options, calltip); - get_text_editor()->set_code_hint(calltip); - return; - } - _check_shader_mode(); - info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())); - info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())); - info.shader_types = ShaderTypes::get_singleton()->get_types(); - - sl.complete(code, info, r_options, calltip); - get_text_editor()->set_code_hint(calltip); -} - -void ShaderTextEditor::_validate_script() { - emit_signal(SNAME("script_changed")); // Ensure to notify that it changed, so it is applied - - String code; - - if (shader.is_valid()) { - _check_shader_mode(); - code = shader->get_code(); - } else { - code = shader_inc->get_code(); - } - - ShaderPreprocessor preprocessor; - String code_pp; - String error_pp; - List<ShaderPreprocessor::FilePosition> err_positions; - List<ShaderPreprocessor::Region> regions; - String filename; - if (shader.is_valid()) { - filename = shader->get_path(); - } else if (shader_inc.is_valid()) { - filename = shader_inc->get_path(); - } - last_compile_result = preprocessor.preprocess(code, filename, code_pp, &error_pp, &err_positions, ®ions); - - for (int i = 0; i < get_text_editor()->get_line_count(); i++) { - get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); - } - - syntax_highlighter->clear_disabled_branch_regions(); - for (const ShaderPreprocessor::Region ®ion : regions) { - if (!region.enabled) { - if (filename != region.file) { - continue; - } - syntax_highlighter->add_disabled_branch_region(Point2i(region.from_line, region.to_line)); - } - } - - set_error(""); - set_error_count(0); - - if (last_compile_result != OK) { - //preprocessor error - ERR_FAIL_COND(err_positions.size() == 0); - - String error_text = error_pp; - int error_line = err_positions.front()->get().line; - if (err_positions.size() == 1) { - // Error in main file - error_text = "error(" + itos(error_line) + "): " + error_text; - } else { - error_text = "error(" + itos(error_line) + ") in include " + err_positions.back()->get().file.get_file() + ":" + itos(err_positions.back()->get().line) + ": " + error_text; - set_error_count(err_positions.size() - 1); - } - - set_error(error_text); - set_error_pos(error_line - 1, 0); - for (int i = 0; i < get_text_editor()->get_line_count(); i++) { - get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); - } - get_text_editor()->set_line_background_color(error_line - 1, marked_line_color); - - set_warning_count(0); - - } else { - ShaderLanguage sl; - - sl.enable_warning_checking(saved_warnings_enabled); - uint32_t flags = saved_warning_flags; - if (shader.is_null()) { - if (flags & ShaderWarning::UNUSED_CONSTANT) { - flags &= ~(ShaderWarning::UNUSED_CONSTANT); - } - if (flags & ShaderWarning::UNUSED_FUNCTION) { - flags &= ~(ShaderWarning::UNUSED_FUNCTION); - } - if (flags & ShaderWarning::UNUSED_STRUCT) { - flags &= ~(ShaderWarning::UNUSED_STRUCT); - } - if (flags & ShaderWarning::UNUSED_UNIFORM) { - flags &= ~(ShaderWarning::UNUSED_UNIFORM); - } - if (flags & ShaderWarning::UNUSED_VARYING) { - flags &= ~(ShaderWarning::UNUSED_VARYING); - } - } - sl.set_warning_flags(flags); - - ShaderLanguage::ShaderCompileInfo info; - info.global_shader_uniform_type_func = _get_global_shader_uniform_type; - - if (shader.is_null()) { - info.is_include = true; - } else { - Shader::Mode mode = shader->get_mode(); - info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(mode)); - info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(mode)); - info.shader_types = ShaderTypes::get_singleton()->get_types(); - } - - code = code_pp; - //compiler error - last_compile_result = sl.compile(code, info); - - if (last_compile_result != OK) { - String error_text; - int error_line; - Vector<ShaderLanguage::FilePosition> include_positions = sl.get_include_positions(); - if (include_positions.size() > 1) { - //error is in an include - error_line = include_positions[0].line; - error_text = "error(" + itos(error_line) + ") in include " + include_positions[include_positions.size() - 1].file + ":" + itos(include_positions[include_positions.size() - 1].line) + ": " + sl.get_error_text(); - set_error_count(include_positions.size() - 1); - } else { - error_line = sl.get_error_line(); - error_text = "error(" + itos(error_line) + "): " + sl.get_error_text(); - set_error_count(0); - } - set_error(error_text); - set_error_pos(error_line - 1, 0); - get_text_editor()->set_line_background_color(error_line - 1, marked_line_color); - } else { - set_error(""); - } - - if (warnings.size() > 0 || last_compile_result != OK) { - warnings_panel->clear(); - } - warnings.clear(); - for (List<ShaderWarning>::Element *E = sl.get_warnings_ptr(); E; E = E->next()) { - warnings.push_back(E->get()); - } - if (warnings.size() > 0 && last_compile_result == OK) { - warnings.sort_custom<WarningsComparator>(); - _update_warning_panel(); - } else { - set_warning_count(0); - } - } - - emit_signal(SNAME("script_validated"), last_compile_result == OK); // Notify that validation finished, to update the list of scripts -} - -void ShaderTextEditor::_update_warning_panel() { - int warning_count = 0; - - warnings_panel->push_table(2); - for (int i = 0; i < warnings.size(); i++) { - ShaderWarning &w = warnings[i]; - - if (warning_count == 0) { - if (saved_treat_warning_as_errors) { - String error_text = "error(" + itos(w.get_line()) + "): " + w.get_message() + " " + TTR("Warnings should be fixed to prevent errors."); - set_error_pos(w.get_line() - 1, 0); - set_error(error_text); - get_text_editor()->set_line_background_color(w.get_line() - 1, marked_line_color); - } - } - - warning_count++; - int line = w.get_line(); - - // First cell. - warnings_panel->push_cell(); - warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); - if (line != -1) { - warnings_panel->push_meta(line - 1); - warnings_panel->add_text(TTR("Line") + " " + itos(line)); - warnings_panel->add_text(" (" + w.get_name() + "):"); - warnings_panel->pop(); // Meta goto. - } else { - warnings_panel->add_text(w.get_name() + ":"); - } - warnings_panel->pop(); // Color. - warnings_panel->pop(); // Cell. - - // Second cell. - warnings_panel->push_cell(); - warnings_panel->add_text(w.get_message()); - warnings_panel->pop(); // Cell. - } - warnings_panel->pop(); // Table. - - set_warning_count(warning_count); -} - -void ShaderTextEditor::_bind_methods() { - ADD_SIGNAL(MethodInfo("script_validated", PropertyInfo(Variant::BOOL, "valid"))); -} - -ShaderTextEditor::ShaderTextEditor() { - syntax_highlighter.instantiate(); - get_text_editor()->set_syntax_highlighter(syntax_highlighter); -} - -/*** SCRIPT EDITOR ******/ - -void ShaderEditor::_menu_option(int p_option) { - switch (p_option) { - case EDIT_UNDO: { - shader_editor->get_text_editor()->undo(); - } break; - case EDIT_REDO: { - shader_editor->get_text_editor()->redo(); - } break; - case EDIT_CUT: { - shader_editor->get_text_editor()->cut(); - } break; - case EDIT_COPY: { - shader_editor->get_text_editor()->copy(); - } break; - case EDIT_PASTE: { - shader_editor->get_text_editor()->paste(); - } break; - case EDIT_SELECT_ALL: { - shader_editor->get_text_editor()->select_all(); - } break; - case EDIT_MOVE_LINE_UP: { - shader_editor->move_lines_up(); - } break; - case EDIT_MOVE_LINE_DOWN: { - shader_editor->move_lines_down(); - } break; - case EDIT_INDENT_LEFT: { - if (shader.is_null()) { - return; - } - shader_editor->get_text_editor()->unindent_lines(); - } break; - case EDIT_INDENT_RIGHT: { - if (shader.is_null()) { - return; - } - shader_editor->get_text_editor()->indent_lines(); - } break; - case EDIT_DELETE_LINE: { - shader_editor->delete_lines(); - } break; - case EDIT_DUPLICATE_SELECTION: { - shader_editor->duplicate_selection(); - } break; - case EDIT_TOGGLE_COMMENT: { - if (shader.is_null()) { - return; - } - - shader_editor->toggle_inline_comment("//"); - - } break; - case EDIT_COMPLETE: { - shader_editor->get_text_editor()->request_code_completion(); - } break; - case SEARCH_FIND: { - shader_editor->get_find_replace_bar()->popup_search(); - } break; - case SEARCH_FIND_NEXT: { - shader_editor->get_find_replace_bar()->search_next(); - } break; - case SEARCH_FIND_PREV: { - shader_editor->get_find_replace_bar()->search_prev(); - } break; - case SEARCH_REPLACE: { - shader_editor->get_find_replace_bar()->popup_replace(); - } break; - case SEARCH_GOTO_LINE: { - goto_line_dialog->popup_find_line(shader_editor->get_text_editor()); - } break; - case BOOKMARK_TOGGLE: { - shader_editor->toggle_bookmark(); - } break; - case BOOKMARK_GOTO_NEXT: { - shader_editor->goto_next_bookmark(); - } break; - case BOOKMARK_GOTO_PREV: { - shader_editor->goto_prev_bookmark(); - } break; - case BOOKMARK_REMOVE_ALL: { - shader_editor->remove_all_bookmarks(); - } break; - case HELP_DOCS: { - OS::get_singleton()->shell_open(vformat("%s/tutorials/shaders/shader_reference/index.html", VERSION_DOCS_URL)); - } break; - } - if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) { - shader_editor->get_text_editor()->call_deferred(SNAME("grab_focus")); - } -} - -void ShaderEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: - case NOTIFICATION_THEME_CHANGED: { - PopupMenu *popup = help_menu->get_popup(); - popup->set_item_icon(popup->get_item_index(HELP_DOCS), get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons"))); - } break; - - case NOTIFICATION_WM_WINDOW_FOCUS_IN: { - _check_for_external_edit(); - } break; - } -} - -void ShaderEditor::_editor_settings_changed() { - shader_editor->update_editor_settings(); - - shader_editor->get_text_editor()->add_theme_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/appearance/whitespace/line_spacing")); - shader_editor->get_text_editor()->set_draw_breakpoints_gutter(false); - shader_editor->get_text_editor()->set_draw_executing_lines_gutter(false); -} - -void ShaderEditor::_show_warnings_panel(bool p_show) { - warnings_panel->set_visible(p_show); -} - -void ShaderEditor::_warning_clicked(Variant p_line) { - if (p_line.get_type() == Variant::INT) { - shader_editor->get_text_editor()->set_caret_line(p_line.operator int64_t()); - } -} - -void ShaderEditor::_bind_methods() { - ClassDB::bind_method("_show_warnings_panel", &ShaderEditor::_show_warnings_panel); - ClassDB::bind_method("_warning_clicked", &ShaderEditor::_warning_clicked); - - ADD_SIGNAL(MethodInfo("validation_changed")); -} - -void ShaderEditor::ensure_select_current() { -} - -void ShaderEditor::goto_line_selection(int p_line, int p_begin, int p_end) { - shader_editor->goto_line_selection(p_line, p_begin, p_end); -} - -void ShaderEditor::_project_settings_changed() { - _update_warnings(true); -} - -void ShaderEditor::_update_warnings(bool p_validate) { - bool changed = false; - - bool warnings_enabled = GLOBAL_GET("debug/shader_language/warnings/enable").booleanize(); - if (warnings_enabled != saved_warnings_enabled) { - saved_warnings_enabled = warnings_enabled; - changed = true; - } - - bool treat_warning_as_errors = GLOBAL_GET("debug/shader_language/warnings/treat_warnings_as_errors").booleanize(); - if (treat_warning_as_errors != saved_treat_warning_as_errors) { - saved_treat_warning_as_errors = treat_warning_as_errors; - changed = true; - } - - bool update_flags = false; - - for (int i = 0; i < ShaderWarning::WARNING_MAX; i++) { - ShaderWarning::Code code = (ShaderWarning::Code)i; - bool value = GLOBAL_GET("debug/shader_language/warnings/" + ShaderWarning::get_name_from_code(code).to_lower()); - - if (saved_warnings[code] != value) { - saved_warnings[code] = value; - update_flags = true; - changed = true; - } - } - - if (update_flags) { - saved_warning_flags = (uint32_t)ShaderWarning::get_flags_from_codemap(saved_warnings); - } - - if (p_validate && changed && shader_editor && shader_editor->get_edited_shader().is_valid()) { - shader_editor->validate_script(); - } -} - -void ShaderEditor::_check_for_external_edit() { - bool use_autoreload = bool(EDITOR_GET("text_editor/behavior/files/auto_reload_scripts_on_external_change")); - - if (shader_inc.is_valid()) { - if (shader_inc->get_last_modified_time() != FileAccess::get_modified_time(shader_inc->get_path())) { - if (use_autoreload) { - _reload_shader_include_from_disk(); - } else { - disk_changed->call_deferred(SNAME("popup_centered")); - } - } - return; - } - - if (shader.is_null() || shader->is_built_in()) { - return; - } - - if (shader->get_last_modified_time() != FileAccess::get_modified_time(shader->get_path())) { - if (use_autoreload) { - _reload_shader_from_disk(); - } else { - disk_changed->call_deferred(SNAME("popup_centered")); - } - } -} - -void ShaderEditor::_reload_shader_from_disk() { - Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); - ERR_FAIL_COND(!rel_shader.is_valid()); - - shader_editor->set_block_shader_changed(true); - shader->set_code(rel_shader->get_code()); - shader_editor->set_block_shader_changed(false); - shader->set_last_modified_time(rel_shader->get_last_modified_time()); - shader_editor->reload_text(); -} - -void ShaderEditor::_reload_shader_include_from_disk() { - Ref<ShaderInclude> rel_shader_include = ResourceLoader::load(shader_inc->get_path(), shader_inc->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); - ERR_FAIL_COND(!rel_shader_include.is_valid()); - - shader_editor->set_block_shader_changed(true); - shader_inc->set_code(rel_shader_include->get_code()); - shader_editor->set_block_shader_changed(false); - shader_inc->set_last_modified_time(rel_shader_include->get_last_modified_time()); - shader_editor->reload_text(); -} - -void ShaderEditor::_reload() { - if (shader.is_valid()) { - _reload_shader_from_disk(); - } else if (shader_inc.is_valid()) { - _reload_shader_include_from_disk(); - } -} - -void ShaderEditor::edit(const Ref<Shader> &p_shader) { - if (p_shader.is_null() || !p_shader->is_text_shader()) { - return; - } - - if (shader == p_shader) { - return; - } - - shader = p_shader; - shader_inc = Ref<ShaderInclude>(); - - shader_editor->set_edited_shader(shader); -} - -void ShaderEditor::edit(const Ref<ShaderInclude> &p_shader_inc) { - if (p_shader_inc.is_null()) { - return; - } - - if (shader_inc == p_shader_inc) { - return; - } - - shader_inc = p_shader_inc; - shader = Ref<Shader>(); - - shader_editor->set_edited_shader_include(p_shader_inc); -} - -void ShaderEditor::save_external_data(const String &p_str) { - if (shader.is_null() && shader_inc.is_null()) { - disk_changed->hide(); - return; - } - - apply_shaders(); - - Ref<Shader> edited_shader = shader_editor->get_edited_shader(); - if (edited_shader.is_valid()) { - ResourceSaver::save(edited_shader); - } - if (shader.is_valid() && shader != edited_shader) { - ResourceSaver::save(shader); - } - - Ref<ShaderInclude> edited_shader_inc = shader_editor->get_edited_shader_include(); - if (edited_shader_inc.is_valid()) { - ResourceSaver::save(edited_shader_inc); - } - if (shader_inc.is_valid() && shader_inc != edited_shader_inc) { - ResourceSaver::save(shader_inc); - } - shader_editor->get_text_editor()->tag_saved_version(); - - disk_changed->hide(); -} - -void ShaderEditor::validate_script() { - shader_editor->_validate_script(); -} - -bool ShaderEditor::is_unsaved() const { - return shader_editor->get_text_editor()->get_saved_version() != shader_editor->get_text_editor()->get_version(); -} - -void ShaderEditor::apply_shaders() { - String editor_code = shader_editor->get_text_editor()->get_text(); - if (shader.is_valid()) { - String shader_code = shader->get_code(); - if (shader_code != editor_code || dependencies_version != shader_editor->get_dependencies_version()) { - shader_editor->set_block_shader_changed(true); - shader->set_code(editor_code); - shader_editor->set_block_shader_changed(false); - shader->set_edited(true); - } - } - if (shader_inc.is_valid()) { - String shader_inc_code = shader_inc->get_code(); - if (shader_inc_code != editor_code || dependencies_version != shader_editor->get_dependencies_version()) { - shader_editor->set_block_shader_changed(true); - shader_inc->set_code(editor_code); - shader_editor->set_block_shader_changed(false); - shader_inc->set_edited(true); - } - } - - dependencies_version = shader_editor->get_dependencies_version(); -} - -void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { - Ref<InputEventMouseButton> mb = ev; - - if (mb.is_valid()) { - if (mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { - CodeEdit *tx = shader_editor->get_text_editor(); - - Point2i pos = tx->get_line_column_at_pos(mb->get_global_position() - tx->get_global_position()); - int row = pos.y; - int col = pos.x; - tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click")); - - if (tx->is_move_caret_on_right_click_enabled()) { - if (tx->has_selection()) { - int from_line = tx->get_selection_from_line(); - int to_line = tx->get_selection_to_line(); - int from_column = tx->get_selection_from_column(); - int to_column = tx->get_selection_to_column(); - - if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) { - // Right click is outside the selected text - tx->deselect(); - } - } - if (!tx->has_selection()) { - tx->set_caret_line(row, true, false); - tx->set_caret_column(col); - } - } - _make_context_menu(tx->has_selection(), get_local_mouse_position()); - } - } - - Ref<InputEventKey> k = ev; - if (k.is_valid() && k->is_pressed() && k->is_action("ui_menu", true)) { - CodeEdit *tx = shader_editor->get_text_editor(); - tx->adjust_viewport_to_caret(); - _make_context_menu(tx->has_selection(), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->get_caret_draw_pos())); - context_menu->grab_focus(); - } -} - -void ShaderEditor::_update_bookmark_list() { - bookmarks_menu->clear(); - - bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); - bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL); - bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); - bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); - - PackedInt32Array bookmark_list = shader_editor->get_text_editor()->get_bookmarked_lines(); - if (bookmark_list.size() == 0) { - return; - } - - bookmarks_menu->add_separator(); - - for (int i = 0; i < bookmark_list.size(); i++) { - String line = shader_editor->get_text_editor()->get_line(bookmark_list[i]).strip_edges(); - // Limit the size of the line if too big. - if (line.length() > 50) { - line = line.substr(0, 50); - } - - bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\""); - bookmarks_menu->set_item_metadata(-1, bookmark_list[i]); - } -} - -void ShaderEditor::_bookmark_item_pressed(int p_idx) { - if (p_idx < 4) { // Any item before the separator. - _menu_option(bookmarks_menu->get_item_id(p_idx)); - } else { - shader_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx)); - } -} - -void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) { - context_menu->clear(); - if (p_selection) { - context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); - } - - context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); - context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); - context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); - - context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); - - context_menu->set_position(get_screen_position() + p_position); - context_menu->reset_size(); - context_menu->popup(); -} - -ShaderEditor::ShaderEditor() { - GLOBAL_DEF("debug/shader_language/warnings/enable", true); - GLOBAL_DEF("debug/shader_language/warnings/treat_warnings_as_errors", false); - for (int i = 0; i < (int)ShaderWarning::WARNING_MAX; i++) { - GLOBAL_DEF("debug/shader_language/warnings/" + ShaderWarning::get_name_from_code((ShaderWarning::Code)i).to_lower(), true); - } - _update_warnings(false); - - shader_editor = memnew(ShaderTextEditor); - - shader_editor->connect("script_validated", callable_mp(this, &ShaderEditor::_script_validated)); - - shader_editor->set_v_size_flags(SIZE_EXPAND_FILL); - shader_editor->add_theme_constant_override("separation", 0); - shader_editor->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - - shader_editor->connect("show_warnings_panel", callable_mp(this, &ShaderEditor::_show_warnings_panel)); - shader_editor->connect("script_changed", callable_mp(this, &ShaderEditor::apply_shaders)); - EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &ShaderEditor::_editor_settings_changed)); - ProjectSettingsEditor::get_singleton()->connect("confirmed", callable_mp(this, &ShaderEditor::_project_settings_changed)); - - shader_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line")); - - shader_editor->get_text_editor()->set_symbol_lookup_on_click_enabled(true); - shader_editor->get_text_editor()->set_context_menu_enabled(false); - shader_editor->get_text_editor()->connect("gui_input", callable_mp(this, &ShaderEditor::_text_edit_gui_input)); - - shader_editor->update_editor_settings(); - - context_menu = memnew(PopupMenu); - add_child(context_menu); - context_menu->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option)); - - VBoxContainer *main_container = memnew(VBoxContainer); - HBoxContainer *hbc = memnew(HBoxContainer); - - edit_menu = memnew(MenuButton); - edit_menu->set_shortcut_context(this); - edit_menu->set_text(TTR("Edit")); - edit_menu->set_switch_on_hover(true); - - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/duplicate_selection"), EDIT_DUPLICATE_SELECTION); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); - edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option)); - - search_menu = memnew(MenuButton); - search_menu->set_shortcut_context(this); - search_menu->set_text(TTR("Search")); - search_menu->set_switch_on_hover(true); - - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); - search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option)); - - MenuButton *goto_menu = memnew(MenuButton); - goto_menu->set_shortcut_context(this); - goto_menu->set_text(TTR("Go To")); - goto_menu->set_switch_on_hover(true); - goto_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option)); - - goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE); - goto_menu->get_popup()->add_separator(); - - bookmarks_menu = memnew(PopupMenu); - bookmarks_menu->set_name("Bookmarks"); - goto_menu->get_popup()->add_child(bookmarks_menu); - goto_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "Bookmarks"); - _update_bookmark_list(); - bookmarks_menu->connect("about_to_popup", callable_mp(this, &ShaderEditor::_update_bookmark_list)); - bookmarks_menu->connect("index_pressed", callable_mp(this, &ShaderEditor::_bookmark_item_pressed)); - - help_menu = memnew(MenuButton); - help_menu->set_text(TTR("Help")); - help_menu->set_switch_on_hover(true); - help_menu->get_popup()->add_item(TTR("Online Docs"), HELP_DOCS); - help_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option)); - - add_child(main_container); - main_container->add_child(hbc); - hbc->add_child(search_menu); - hbc->add_child(edit_menu); - hbc->add_child(goto_menu); - hbc->add_child(help_menu); - hbc->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles"))); - - VSplitContainer *editor_box = memnew(VSplitContainer); - main_container->add_child(editor_box); - editor_box->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - editor_box->set_v_size_flags(SIZE_EXPAND_FILL); - editor_box->add_child(shader_editor); - - FindReplaceBar *bar = memnew(FindReplaceBar); - main_container->add_child(bar); - bar->hide(); - shader_editor->set_find_replace_bar(bar); - - warnings_panel = memnew(RichTextLabel); - warnings_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); - warnings_panel->set_h_size_flags(SIZE_EXPAND_FILL); - warnings_panel->set_meta_underline(true); - warnings_panel->set_selection_enabled(true); - warnings_panel->set_focus_mode(FOCUS_CLICK); - warnings_panel->hide(); - warnings_panel->connect("meta_clicked", callable_mp(this, &ShaderEditor::_warning_clicked)); - editor_box->add_child(warnings_panel); - shader_editor->set_warnings_panel(warnings_panel); - - goto_line_dialog = memnew(GotoLineDialog); - add_child(goto_line_dialog); - - disk_changed = memnew(ConfirmationDialog); - - VBoxContainer *vbc = memnew(VBoxContainer); - disk_changed->add_child(vbc); - - Label *dl = memnew(Label); - dl->set_text(TTR("This shader has been modified on disk.\nWhat action should be taken?")); - vbc->add_child(dl); - - disk_changed->connect("confirmed", callable_mp(this, &ShaderEditor::_reload)); - disk_changed->set_ok_button_text(TTR("Reload")); - - disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); - disk_changed->connect("custom_action", callable_mp(this, &ShaderEditor::save_external_data)); - - add_child(disk_changed); - - _editor_settings_changed(); -} +#include "scene/gui/item_list.h" +#include "scene/gui/texture_rect.h" void ShaderEditorPlugin::_update_shader_list() { shader_list->clear(); @@ -1237,7 +85,7 @@ void ShaderEditorPlugin::_update_shader_list() { shader_list->select(shader_tabs->get_current_tab()); } - for (int i = 1; i < FILE_MAX; i++) { + for (int i = FILE_SAVE; i < FILE_MAX; i++) { file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), edited_shaders.size() == 0); } @@ -1246,7 +94,7 @@ void ShaderEditorPlugin::_update_shader_list() { void ShaderEditorPlugin::_update_shader_list_status() { for (int i = 0; i < shader_list->get_item_count(); i++) { - ShaderEditor *se = Object::cast_to<ShaderEditor>(shader_tabs->get_tab_control(i)); + TextShaderEditor *se = Object::cast_to<TextShaderEditor>(shader_tabs->get_tab_control(i)); if (se) { if (se->was_compilation_successful()) { shader_list->set_item_tag_icon(i, Ref<Texture2D>()); @@ -1281,7 +129,7 @@ void ShaderEditorPlugin::edit(Object *p_object) { } } es.shader_inc = Ref<ShaderInclude>(si); - es.shader_editor = memnew(ShaderEditor); + es.shader_editor = memnew(TextShaderEditor); es.shader_editor->edit(si); shader_tabs->add_child(es.shader_editor); es.shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list)); @@ -1301,7 +149,7 @@ void ShaderEditorPlugin::edit(Object *p_object) { shader_tabs->add_child(es.visual_shader_editor); es.visual_shader_editor->edit(vs.ptr()); } else { - es.shader_editor = memnew(ShaderEditor); + es.shader_editor = memnew(TextShaderEditor); shader_tabs->add_child(es.shader_editor); es.shader_editor->edit(s); es.shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list)); @@ -1326,7 +174,7 @@ void ShaderEditorPlugin::make_visible(bool p_visible) { void ShaderEditorPlugin::selected_notify() { } -ShaderEditor *ShaderEditorPlugin::get_shader_editor(const Ref<Shader> &p_for_shader) { +TextShaderEditor *ShaderEditorPlugin::get_shader_editor(const Ref<Shader> &p_for_shader) { for (uint32_t i = 0; i < edited_shaders.size(); i++) { if (edited_shaders[i].shader == p_for_shader) { return edited_shaders[i].shader_editor; @@ -1366,6 +214,7 @@ void ShaderEditorPlugin::_shader_selected(int p_index) { edited_shaders[p_index].shader_editor->validate_script(); } shader_tabs->set_current_tab(p_index); + shader_list->select(p_index); } void ShaderEditorPlugin::_shader_list_clicked(int p_item, Vector2 p_local_mouse_pos, MouseButton p_mouse_button_index) { @@ -1375,13 +224,12 @@ void ShaderEditorPlugin::_shader_list_clicked(int p_item, Vector2 p_local_mouse_ } void ShaderEditorPlugin::_close_shader(int p_index) { - int index = shader_tabs->get_current_tab(); - ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); - Control *c = shader_tabs->get_tab_control(index); + ERR_FAIL_INDEX(p_index, shader_tabs->get_tab_count()); + Control *c = shader_tabs->get_tab_control(p_index); memdelete(c); - edited_shaders.remove_at(index); + edited_shaders.remove_at(p_index); _update_shader_list(); - EditorNode::get_singleton()->get_undo_redo()->clear_history(); // To prevent undo on deleted graphs. + EditorNode::get_undo_redo()->clear_history(); // To prevent undo on deleted graphs. } void ShaderEditorPlugin::_resource_saved(Object *obj) { @@ -1420,6 +268,9 @@ void ShaderEditorPlugin::_menu_item_pressed(int p_index) { } else { EditorNode::get_singleton()->save_resource(edited_shaders[index].shader_inc); } + if (edited_shaders[index].shader_editor) { + edited_shaders[index].shader_editor->tag_saved_version(); + } } break; case FILE_SAVE_AS: { int index = shader_tabs->get_current_tab(); @@ -1438,6 +289,9 @@ void ShaderEditorPlugin::_menu_item_pressed(int p_index) { } EditorNode::get_singleton()->save_resource_as(edited_shaders[index].shader_inc, path); } + if (edited_shaders[index].shader_editor) { + edited_shaders[index].shader_editor->tag_saved_version(); + } } break; case FILE_INSPECT: { int index = shader_tabs->get_current_tab(); @@ -1588,7 +442,7 @@ ShaderEditorPlugin::ShaderEditorPlugin() { file_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed)); file_hb->add_child(file_menu); - for (int i = 2; i < FILE_MAX; i++) { + for (int i = FILE_SAVE; i < FILE_MAX; i++) { file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), true); } diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index f48b2fc70e..1ae419053e 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -31,181 +31,15 @@ #ifndef SHADER_EDITOR_PLUGIN_H #define SHADER_EDITOR_PLUGIN_H -#include "editor/code_editor.h" #include "editor/editor_plugin.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/panel_container.h" -#include "scene/gui/rich_text_label.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/text_edit.h" -#include "scene/main/timer.h" -#include "scene/resources/shader.h" -#include "scene/resources/shader_include.h" -#include "servers/rendering/shader_warnings.h" -class ItemList; -class VisualShaderEditor; class HSplitContainer; +class ItemList; +class MenuButton; class ShaderCreateDialog; - -class GDShaderSyntaxHighlighter : public CodeHighlighter { - GDCLASS(GDShaderSyntaxHighlighter, CodeHighlighter) - -private: - Vector<Point2i> disabled_branch_regions; - Color disabled_branch_color; - -public: - virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override; - - void add_disabled_branch_region(const Point2i &p_region); - void clear_disabled_branch_regions(); - void set_disabled_branch_color(const Color &p_color); -}; - -class ShaderTextEditor : public CodeTextEditor { - GDCLASS(ShaderTextEditor, CodeTextEditor); - - Color marked_line_color = Color(1, 1, 1); - - struct WarningsComparator { - _ALWAYS_INLINE_ bool operator()(const ShaderWarning &p_a, const ShaderWarning &p_b) const { return (p_a.get_line() < p_b.get_line()); } - }; - - Ref<GDShaderSyntaxHighlighter> syntax_highlighter; - RichTextLabel *warnings_panel = nullptr; - Ref<Shader> shader; - Ref<ShaderInclude> shader_inc; - List<ShaderWarning> warnings; - Error last_compile_result = Error::OK; - - void _check_shader_mode(); - void _update_warning_panel(); - - bool block_shader_changed = false; - void _shader_changed(); - - uint32_t dependencies_version = 0; // Incremented if deps changed - -protected: - void _notification(int p_what); - static void _bind_methods(); - virtual void _load_theme_settings() override; - - virtual void _code_complete_script(const String &p_code, List<ScriptLanguage::CodeCompletionOption> *r_options) override; - -public: - void set_block_shader_changed(bool p_block) { block_shader_changed = p_block; } - uint32_t get_dependencies_version() const { return dependencies_version; } - - virtual void _validate_script() override; - - void reload_text(); - void set_warnings_panel(RichTextLabel *p_warnings_panel); - - Ref<Shader> get_edited_shader() const; - Ref<ShaderInclude> get_edited_shader_include() const; - - void set_edited_shader(const Ref<Shader> &p_shader); - void set_edited_shader(const Ref<Shader> &p_shader, const String &p_code); - void set_edited_shader_include(const Ref<ShaderInclude> &p_include); - void set_edited_shader_include(const Ref<ShaderInclude> &p_include, const String &p_code); - void set_edited_code(const String &p_code); - - ShaderTextEditor(); -}; - -class ShaderEditor : public MarginContainer { - GDCLASS(ShaderEditor, MarginContainer); - - enum { - EDIT_UNDO, - EDIT_REDO, - EDIT_CUT, - EDIT_COPY, - EDIT_PASTE, - EDIT_SELECT_ALL, - EDIT_MOVE_LINE_UP, - EDIT_MOVE_LINE_DOWN, - EDIT_INDENT_LEFT, - EDIT_INDENT_RIGHT, - EDIT_DELETE_LINE, - EDIT_DUPLICATE_SELECTION, - EDIT_TOGGLE_COMMENT, - EDIT_COMPLETE, - SEARCH_FIND, - SEARCH_FIND_NEXT, - SEARCH_FIND_PREV, - SEARCH_REPLACE, - SEARCH_GOTO_LINE, - BOOKMARK_TOGGLE, - BOOKMARK_GOTO_NEXT, - BOOKMARK_GOTO_PREV, - BOOKMARK_REMOVE_ALL, - HELP_DOCS, - }; - - MenuButton *edit_menu = nullptr; - MenuButton *search_menu = nullptr; - PopupMenu *bookmarks_menu = nullptr; - MenuButton *help_menu = nullptr; - PopupMenu *context_menu = nullptr; - RichTextLabel *warnings_panel = nullptr; - uint64_t idle = 0; - - GotoLineDialog *goto_line_dialog = nullptr; - ConfirmationDialog *erase_tab_confirm = nullptr; - ConfirmationDialog *disk_changed = nullptr; - - ShaderTextEditor *shader_editor = nullptr; - bool compilation_success = true; - - void _menu_option(int p_option); - mutable Ref<Shader> shader; - mutable Ref<ShaderInclude> shader_inc; - - void _editor_settings_changed(); - void _project_settings_changed(); - - void _check_for_external_edit(); - void _reload_shader_from_disk(); - void _reload_shader_include_from_disk(); - void _reload(); - void _show_warnings_panel(bool p_show); - void _warning_clicked(Variant p_line); - void _update_warnings(bool p_validate); - - void _script_validated(bool p_valid) { - compilation_success = p_valid; - emit_signal(SNAME("validation_changed")); - } - - uint32_t dependencies_version = 0xFFFFFFFF; - -protected: - void _notification(int p_what); - static void _bind_methods(); - void _make_context_menu(bool p_selection, Vector2 p_position); - void _text_edit_gui_input(const Ref<InputEvent> &p_ev); - - void _update_bookmark_list(); - void _bookmark_item_pressed(int p_idx); - -public: - bool was_compilation_successful() const { return compilation_success; } - void apply_shaders(); - void ensure_select_current(); - void edit(const Ref<Shader> &p_shader); - void edit(const Ref<ShaderInclude> &p_shader_inc); - void goto_line_selection(int p_line, int p_begin, int p_end); - void save_external_data(const String &p_str = ""); - void validate_script(); - bool is_unsaved() const; - - virtual Size2 get_minimum_size() const override { return Size2(0, 200); } - - ShaderEditor(); -}; +class TabContainer; +class TextShaderEditor; +class VisualShaderEditor; class ShaderEditorPlugin : public EditorPlugin { GDCLASS(ShaderEditorPlugin, EditorPlugin); @@ -213,12 +47,14 @@ class ShaderEditorPlugin : public EditorPlugin { struct EditedShader { Ref<Shader> shader; Ref<ShaderInclude> shader_inc; - ShaderEditor *shader_editor = nullptr; + TextShaderEditor *shader_editor = nullptr; VisualShaderEditor *visual_shader_editor = nullptr; }; LocalVector<EditedShader> edited_shaders; + // Always valid operations come first in the enum, file-specific ones + // should go after FILE_SAVE which is used to build the menu accordingly. enum { FILE_NEW, FILE_NEW_INCLUDE, @@ -265,7 +101,7 @@ public: virtual void make_visible(bool p_visible) override; virtual void selected_notify() override; - ShaderEditor *get_shader_editor(const Ref<Shader> &p_for_shader); + TextShaderEditor *get_shader_editor(const Ref<Shader> &p_for_shader); VisualShaderEditor *get_visual_shader_editor(const Ref<Shader> &p_for_shader); virtual void save_external_data() override; diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp index 4874944d33..4e33c421ae 100644 --- a/editor/plugins/shader_file_editor_plugin.cpp +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -37,6 +37,8 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "scene/gui/item_list.h" +#include "scene/gui/split_container.h" #include "servers/display_server.h" #include "servers/rendering/shader_types.h" @@ -286,6 +288,7 @@ ShaderFileEditor::ShaderFileEditor() { error_text = memnew(RichTextLabel); error_text->set_v_size_flags(SIZE_EXPAND_FILL); + error_text->set_selection_enabled(true); main_vb->add_child(error_text); } diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp index dbad81d743..5ae21a430d 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.cpp +++ b/editor/plugins/skeleton_2d_editor_plugin.cpp @@ -35,6 +35,7 @@ #include "editor/editor_undo_redo_manager.h" #include "scene/2d/mesh_instance_2d.h" #include "scene/gui/box_container.h" +#include "scene/gui/menu_button.h" #include "thirdparty/misc/clipper.hpp" void Skeleton2DEditor::_node_removed(Node *p_node) { diff --git a/editor/plugins/skeleton_2d_editor_plugin.h b/editor/plugins/skeleton_2d_editor_plugin.h index 295725b751..6794f72955 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.h +++ b/editor/plugins/skeleton_2d_editor_plugin.h @@ -35,6 +35,9 @@ #include "scene/2d/skeleton_2d.h" #include "scene/gui/spin_box.h" +class AcceptDialog; +class MenuButton; + class Skeleton2DEditor : public Control { GDCLASS(Skeleton2DEditor, Control); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 2478ac9514..e8bbfd1b91 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -34,6 +34,7 @@ #include "editor/editor_node.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "node_3d_editor_plugin.h" @@ -41,6 +42,7 @@ #include "scene/3d/joint_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/physics_body_3d.h" +#include "scene/gui/separator.h" #include "scene/resources/capsule_shape_3d.h" #include "scene/resources/skeleton_profile.h" #include "scene/resources/sphere_shape_3d.h" @@ -113,6 +115,7 @@ void BoneTransformEditor::_value_changed(const String &p_property, Variant p_val return; } if (skeleton) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS); undo_redo->add_undo_property(skeleton, p_property, skeleton->get(p_property)); undo_redo->add_do_property(skeleton, p_property, p_value); @@ -122,7 +125,6 @@ void BoneTransformEditor::_value_changed(const String &p_property, Variant p_val BoneTransformEditor::BoneTransformEditor(Skeleton3D *p_skeleton) : skeleton(p_skeleton) { - undo_redo = EditorNode::get_undo_redo(); } void BoneTransformEditor::set_keyable(const bool p_keyable) { @@ -587,25 +589,25 @@ void Skeleton3DEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data void Skeleton3DEditor::move_skeleton_bone(NodePath p_skeleton_path, int32_t p_selected_boneidx, int32_t p_target_boneidx) { Node *node = get_node_or_null(p_skeleton_path); - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node); - ERR_FAIL_NULL(skeleton); + Skeleton3D *skeleton_node = Object::cast_to<Skeleton3D>(node); + ERR_FAIL_NULL(skeleton_node); Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo(); ur->create_action(TTR("Set Bone Parentage")); // If the target is a child of ourselves, we move only *us* and not our children. - if (skeleton->is_bone_parent_of(p_target_boneidx, p_selected_boneidx)) { - const BoneId parent_idx = skeleton->get_bone_parent(p_selected_boneidx); - const int bone_count = skeleton->get_bone_count(); + if (skeleton_node->is_bone_parent_of(p_target_boneidx, p_selected_boneidx)) { + const BoneId parent_idx = skeleton_node->get_bone_parent(p_selected_boneidx); + const int bone_count = skeleton_node->get_bone_count(); for (BoneId i = 0; i < bone_count; ++i) { - if (skeleton->get_bone_parent(i) == p_selected_boneidx) { - ur->add_undo_method(skeleton, "set_bone_parent", i, skeleton->get_bone_parent(i)); - ur->add_do_method(skeleton, "set_bone_parent", i, parent_idx); - skeleton->set_bone_parent(i, parent_idx); + if (skeleton_node->get_bone_parent(i) == p_selected_boneidx) { + ur->add_undo_method(skeleton_node, "set_bone_parent", i, skeleton_node->get_bone_parent(i)); + ur->add_do_method(skeleton_node, "set_bone_parent", i, parent_idx); + skeleton_node->set_bone_parent(i, parent_idx); } } } - ur->add_undo_method(skeleton, "set_bone_parent", p_selected_boneidx, skeleton->get_bone_parent(p_selected_boneidx)); - ur->add_do_method(skeleton, "set_bone_parent", p_selected_boneidx, p_target_boneidx); - skeleton->set_bone_parent(p_selected_boneidx, p_target_boneidx); + ur->add_undo_method(skeleton_node, "set_bone_parent", p_selected_boneidx, skeleton_node->get_bone_parent(p_selected_boneidx)); + ur->add_do_method(skeleton_node, "set_bone_parent", p_selected_boneidx, p_target_boneidx); + skeleton_node->set_bone_parent(p_selected_boneidx, p_target_boneidx); update_joint_tree(); ur->commit_action(); @@ -714,12 +716,12 @@ void Skeleton3DEditor::create_editors() { // Skeleton options. PopupMenu *p = skeleton_options->get_popup(); - p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/reset_all_poses", TTR("Reset all bone Poses")), SKELETON_OPTION_RESET_ALL_POSES); - p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/reset_selected_poses", TTR("Reset selected Poses")), SKELETON_OPTION_RESET_SELECTED_POSES); - p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/all_poses_to_rests", TTR("Apply all poses to rests")), SKELETON_OPTION_ALL_POSES_TO_RESTS); - p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/selected_poses_to_rests", TTR("Apply selected poses to rests")), SKELETON_OPTION_SELECTED_POSES_TO_RESTS); - p->add_item(TTR("Create physical skeleton"), SKELETON_OPTION_CREATE_PHYSICAL_SKELETON); - p->add_item(TTR("Export skeleton profile"), SKELETON_OPTION_EXPORT_SKELETON_PROFILE); + p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/reset_all_poses", TTR("Reset All Bone Poses")), SKELETON_OPTION_RESET_ALL_POSES); + p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/reset_selected_poses", TTR("Reset Selected Poses")), SKELETON_OPTION_RESET_SELECTED_POSES); + p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/all_poses_to_rests", TTR("Apply All Poses to Rests")), SKELETON_OPTION_ALL_POSES_TO_RESTS); + p->add_shortcut(ED_SHORTCUT("skeleton_3d_editor/selected_poses_to_rests", TTR("Apply Selected Poses to Rests")), SKELETON_OPTION_SELECTED_POSES_TO_RESTS); + p->add_item(TTR("Create Physical Skeleton"), SKELETON_OPTION_CREATE_PHYSICAL_SKELETON); + p->add_item(TTR("Export Skeleton Profile"), SKELETON_OPTION_EXPORT_SKELETON_PROFILE); p->connect("id_pressed", callable_mp(this, &Skeleton3DEditor::_on_click_skeleton_option)); set_bone_options_enabled(false); @@ -1082,7 +1084,7 @@ void Skeleton3DEditor::select_bone(int p_idx) { Skeleton3DEditor::~Skeleton3DEditor() { singleton = nullptr; - handles_mesh_instance->queue_delete(); + handles_mesh_instance->queue_free(); Node3DEditor *ne = Node3DEditor::get_singleton(); @@ -1128,7 +1130,7 @@ Skeleton3DEditorPlugin::Skeleton3DEditorPlugin() { Node3DEditor::get_singleton()->add_gizmo_plugin(gizmo_plugin); } -EditorPlugin::AfterGUIInput Skeleton3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { +EditorPlugin::AfterGUIInput Skeleton3DEditorPlugin::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { Skeleton3DEditor *se = Skeleton3DEditor::get_singleton(); Node3DEditor *ne = Node3DEditor::get_singleton(); if (se && se->is_edit_mode()) { @@ -1234,12 +1236,12 @@ int Skeleton3DGizmoPlugin::get_priority() const { } int Skeleton3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const { - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_spatial_node()); + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_node_3d()); ERR_FAIL_COND_V(!skeleton, -1); Skeleton3DEditor *se = Skeleton3DEditor::get_singleton(); - if (!se->is_edit_mode()) { + if (!se || !se->is_edit_mode()) { return -1; } @@ -1277,18 +1279,18 @@ int Skeleton3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gi } Transform3D Skeleton3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const { - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_spatial_node()); + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_node_3d()); ERR_FAIL_COND_V(!skeleton, Transform3D()); return skeleton->get_bone_global_pose(p_id); } void Skeleton3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) { - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_spatial_node()); + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_node_3d()); ERR_FAIL_COND(!skeleton); // Prepare for global to local. - Transform3D original_to_local = Transform3D(); + Transform3D original_to_local; int parent_idx = skeleton->get_bone_parent(p_id); if (parent_idx >= 0) { original_to_local = original_to_local * skeleton->get_bone_global_pose(parent_idx); @@ -1296,7 +1298,7 @@ void Skeleton3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gi Basis to_local = original_to_local.get_basis().inverse(); // Prepare transform. - Transform3D t = Transform3D(); + Transform3D t; // Basis. t.basis = to_local * p_transform.get_basis(); @@ -1313,7 +1315,7 @@ void Skeleton3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gi } void Skeleton3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) { - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_spatial_node()); + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_node_3d()); ERR_FAIL_COND(!skeleton); Skeleton3DEditor *se = Skeleton3DEditor::get_singleton(); @@ -1346,7 +1348,7 @@ void Skeleton3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, c } void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_spatial_node()); + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_gizmo->get_node_3d()); p_gizmo->clear(); int selected = -1; @@ -1355,10 +1357,10 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { selected = se->get_selected_bone(); } - Color bone_color = EditorSettings::get_singleton()->get("editors/3d_gizmos/gizmo_colors/skeleton"); - Color selected_bone_color = EditorSettings::get_singleton()->get("editors/3d_gizmos/gizmo_colors/selected_bone"); - real_t bone_axis_length = EditorSettings::get_singleton()->get("editors/3d_gizmos/gizmo_settings/bone_axis_length"); - int bone_shape = EditorSettings::get_singleton()->get("editors/3d_gizmos/gizmo_settings/bone_shape"); + Color bone_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/skeleton"); + Color selected_bone_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/selected_bone"); + real_t bone_axis_length = EDITOR_GET("editors/3d_gizmos/gizmo_settings/bone_axis_length"); + int bone_shape = EDITOR_GET("editors/3d_gizmos/gizmo_settings/bone_shape"); LocalVector<Color> axis_colors; axis_colors.push_back(Node3DEditor::get_singleton()->get_theme_color(SNAME("axis_x_color"), SNAME("Editor"))); diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index 9747ed8374..8ef61861d0 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -41,11 +41,13 @@ #include "scene/resources/immediate_mesh.h" class EditorInspectorPluginSkeleton; -class EditorUndoRedoManager; class Joint; class PhysicalBone3D; class Skeleton3DEditorPlugin; class Button; +class Tree; +class TreeItem; +class VSeparator; class BoneTransformEditor : public VBoxContainer { GDCLASS(BoneTransformEditor, VBoxContainer); @@ -65,8 +67,6 @@ class BoneTransformEditor : public VBoxContainer { Skeleton3D *skeleton = nullptr; // String property; - Ref<EditorUndoRedoManager> undo_redo; - bool toggle_enabled = false; bool updating = false; @@ -238,7 +238,7 @@ class Skeleton3DEditorPlugin : public EditorPlugin { EditorInspectorPluginSkeleton *skeleton_plugin = nullptr; public: - virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override; + virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override; bool has_main_screen() const override { return false; } virtual bool handles(Object *p_object) const override; diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp index b78b70cd5c..110ad7cac0 100644 --- a/editor/plugins/sprite_2d_editor_plugin.cpp +++ b/editor/plugins/sprite_2d_editor_plugin.cpp @@ -41,6 +41,7 @@ #include "scene/2d/mesh_instance_2d.h" #include "scene/2d/polygon_2d.h" #include "scene/gui/box_container.h" +#include "scene/gui/menu_button.h" #include "thirdparty/misc/clipper.hpp" void Sprite2DEditor::_node_removed(Node *p_node) { diff --git a/editor/plugins/sprite_2d_editor_plugin.h b/editor/plugins/sprite_2d_editor_plugin.h index b87f108bd2..ae1083ed41 100644 --- a/editor/plugins/sprite_2d_editor_plugin.h +++ b/editor/plugins/sprite_2d_editor_plugin.h @@ -35,6 +35,10 @@ #include "scene/2d/sprite_2d.h" #include "scene/gui/spin_box.h" +class AcceptDialog; +class ConfirmationDialog; +class MenuButton; + class Sprite2DEditor : public Control { GDCLASS(Sprite2DEditor, Control); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index d0a1ddafa1..64e899b121 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -34,6 +34,7 @@ #include "core/io/resource_loader.h" #include "core/os/keyboard.h" #include "editor/editor_file_dialog.h" +#include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -43,6 +44,7 @@ #include "scene/gui/center_container.h" #include "scene/gui/margin_container.h" #include "scene/gui/panel_container.h" +#include "scene/gui/separator.h" static void _draw_shadowed_line(Control *p_control, const Point2 &p_from, const Size2 &p_size, const Size2 &p_shadow_offset, Color p_color, Color p_shadow_color) { p_control->draw_line(p_from, p_from + p_size, p_color); @@ -67,14 +69,18 @@ int SpriteFramesEditor::_sheet_preview_position_to_frame_index(const Point2 &p_p const Size2i block_size = frame_size + separation; const Point2i position = p_position / sheet_zoom - offset; - if (position.x % block_size.x > frame_size.x || position.y % block_size.y > frame_size.y) { + if (position.x < 0 || position.y < 0) { + return -1; // Out of bounds. + } + + if (position.x % block_size.x >= frame_size.x || position.y % block_size.y >= frame_size.y) { return -1; // Gap between frames. } const Point2i frame = position / block_size; const Size2i frame_count = _get_frame_count(); - if (frame.x < 0 || frame.y < 0 || frame.x >= frame_count.x || frame.y >= frame_count.y) { - return -1; // Out of bound. + if (frame.x >= frame_count.x || frame.y >= frame_count.y) { + return -1; // Out of bounds. } return frame_count.x * frame.y + frame.x; @@ -245,6 +251,7 @@ void SpriteFramesEditor::_sheet_add_frames() { const Size2i offset = _get_offset(); const Size2i separation = _get_separation(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Frame")); int fc = frames->get_frame_count(edited_anim); @@ -414,16 +421,16 @@ void SpriteFramesEditor::_notification(int p_what) { load_sheet->set_icon(get_theme_icon(SNAME("SpriteSheet"), SNAME("EditorIcons"))); copy->set_icon(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons"))); paste->set_icon(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons"))); - empty->set_icon(get_theme_icon(SNAME("InsertBefore"), SNAME("EditorIcons"))); - empty2->set_icon(get_theme_icon(SNAME("InsertAfter"), SNAME("EditorIcons"))); + empty_before->set_icon(get_theme_icon(SNAME("InsertBefore"), SNAME("EditorIcons"))); + empty_after->set_icon(get_theme_icon(SNAME("InsertAfter"), SNAME("EditorIcons"))); move_up->set_icon(get_theme_icon(SNAME("MoveLeft"), SNAME("EditorIcons"))); move_down->set_icon(get_theme_icon(SNAME("MoveRight"), SNAME("EditorIcons"))); - _delete->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); + delete_frame->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons"))); zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons"))); zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons"))); - new_anim->set_icon(get_theme_icon(SNAME("New"), SNAME("EditorIcons"))); - remove_anim->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); + add_anim->set_icon(get_theme_icon(SNAME("New"), SNAME("EditorIcons"))); + delete_anim->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); anim_search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); split_sheet_zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons"))); split_sheet_zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons"))); @@ -463,6 +470,7 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_ return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Frame")); int fc = frames->get_frame_count(edited_anim); @@ -523,6 +531,7 @@ void SpriteFramesEditor::_paste_pressed() { return; ///beh should show an error i guess } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Paste Frame")); undo_redo->add_do_method(frames, "add_frame", edited_anim, r); undo_redo->add_undo_method(frames, "remove_frame", edited_anim, frames->get_frame_count(edited_anim)); @@ -560,6 +569,7 @@ void SpriteFramesEditor::_empty_pressed() { Ref<Texture2D> r; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Empty")); undo_redo->add_do_method(frames, "add_frame", edited_anim, r, from); undo_redo->add_undo_method(frames, "remove_frame", edited_anim, from); @@ -583,6 +593,7 @@ void SpriteFramesEditor::_empty2_pressed() { Ref<Texture2D> r; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Empty")); undo_redo->add_do_method(frames, "add_frame", edited_anim, r, from + 1); undo_redo->add_undo_method(frames, "remove_frame", edited_anim, from + 1); @@ -606,6 +617,7 @@ void SpriteFramesEditor::_up_pressed() { sel = to_move; sel -= 1; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete Resource")); undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move - 1)); undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame(edited_anim, to_move)); @@ -631,6 +643,7 @@ void SpriteFramesEditor::_down_pressed() { sel = to_move; sel += 1; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete Resource")); undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move + 1)); undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame(edited_anim, to_move)); @@ -653,6 +666,7 @@ void SpriteFramesEditor::_delete_pressed() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete Resource")); undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete); undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete); @@ -739,6 +753,7 @@ void SpriteFramesEditor::_animation_name_edited() { List<Node *> nodes; _find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(), &nodes, Ref<SpriteFrames>(frames)); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Rename Animation")); undo_redo->add_do_method(frames, "rename_animation", edited_anim, name); undo_redo->add_undo_method(frames, "rename_animation", name, edited_anim); @@ -768,6 +783,7 @@ void SpriteFramesEditor::_animation_add() { List<Node *> nodes; _find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(), &nodes, Ref<SpriteFrames>(frames)); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Animation")); undo_redo->add_do_method(frames, "add_animation", name); undo_redo->add_undo_method(frames, "remove_animation", name); @@ -800,6 +816,7 @@ void SpriteFramesEditor::_animation_remove() { } void SpriteFramesEditor::_animation_remove_confirmed() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Animation")); undo_redo->add_do_method(frames, "remove_animation", edited_anim); undo_redo->add_undo_method(frames, "add_animation", edited_anim); @@ -827,6 +844,7 @@ void SpriteFramesEditor::_animation_loop_changed() { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Animation Loop")); undo_redo->add_do_method(frames, "set_animation_loop", edited_anim, anim_loop->is_pressed()); undo_redo->add_undo_method(frames, "set_animation_loop", edited_anim, frames->get_animation_loop(edited_anim)); @@ -840,6 +858,7 @@ void SpriteFramesEditor::_animation_fps_changed(double p_value) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Animation FPS"), UndoRedo::MERGE_ENDS); undo_redo->add_do_method(frames, "set_animation_speed", edited_anim, p_value); undo_redo->add_undo_method(frames, "set_animation_speed", edited_anim, frames->get_animation_speed(edited_anim)); @@ -1016,23 +1035,19 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) { hide(); } - new_anim->set_disabled(read_only); - remove_anim->set_disabled(read_only); + add_anim->set_disabled(read_only); + delete_anim->set_disabled(read_only); anim_speed->set_editable(!read_only); anim_loop->set_disabled(read_only); load->set_disabled(read_only); load_sheet->set_disabled(read_only); copy->set_disabled(read_only); paste->set_disabled(read_only); - empty->set_disabled(read_only); - empty2->set_disabled(read_only); + empty_before->set_disabled(read_only); + empty_after->set_disabled(read_only); move_up->set_disabled(read_only); move_down->set_disabled(read_only); - _delete->set_disabled(read_only); -} - -void SpriteFramesEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; + delete_frame->set_disabled(read_only); } Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { @@ -1095,8 +1110,8 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant & } for (int i = 0; i < files.size(); i++) { - String file = files[i]; - String ftype = EditorFileSystem::get_singleton()->get_file_type(file); + String f = files[i]; + String ftype = EditorFileSystem::get_singleton()->get_file_type(f); if (!ClassDB::is_parent_class(ftype, "Texture2D")) { return false; @@ -1132,6 +1147,7 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da reorder = true; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (reorder) { //drop is from reordering frames int from_frame = -1; if (d.has("frame")) { @@ -1187,18 +1203,16 @@ SpriteFramesEditor::SpriteFramesEditor() { HBoxContainer *hbc_animlist = memnew(HBoxContainer); sub_vb->add_child(hbc_animlist); - new_anim = memnew(Button); - new_anim->set_flat(true); - new_anim->set_tooltip_text(TTR("New Animation")); - hbc_animlist->add_child(new_anim); - new_anim->connect("pressed", callable_mp(this, &SpriteFramesEditor::_animation_add)); + add_anim = memnew(Button); + add_anim->set_flat(true); + hbc_animlist->add_child(add_anim); + add_anim->connect("pressed", callable_mp(this, &SpriteFramesEditor::_animation_add)); - remove_anim = memnew(Button); - remove_anim->set_flat(true); - remove_anim->set_tooltip_text(TTR("Remove Animation")); - hbc_animlist->add_child(remove_anim); - remove_anim->set_disabled(true); - remove_anim->connect("pressed", callable_mp(this, &SpriteFramesEditor::_animation_remove)); + delete_anim = memnew(Button); + delete_anim->set_flat(true); + hbc_animlist->add_child(delete_anim); + delete_anim->set_disabled(true); + delete_anim->connect("pressed", callable_mp(this, &SpriteFramesEditor::_animation_remove)); anim_search_box = memnew(LineEdit); hbc_animlist->add_child(anim_search_box); @@ -1215,6 +1229,11 @@ SpriteFramesEditor::SpriteFramesEditor() { animations->connect("item_edited", callable_mp(this, &SpriteFramesEditor::_animation_name_edited)); animations->set_allow_reselect(true); + add_anim->set_shortcut_context(animations); + add_anim->set_shortcut(ED_SHORTCUT("sprite_frames/new_animation", TTR("Add Animation"), KeyModifierMask::CMD_OR_CTRL | Key::N)); + delete_anim->set_shortcut_context(animations); + delete_anim->set_shortcut(ED_SHORTCUT("sprite_frames/delete_animation", TTR("Delete Animation"), Key::KEY_DELETE)); + HBoxContainer *hbc_anim_speed = memnew(HBoxContainer); hbc_anim_speed->add_child(memnew(Label(TTR("Speed:")))); vbc_animlist->add_child(hbc_anim_speed); @@ -1244,54 +1263,45 @@ SpriteFramesEditor::SpriteFramesEditor() { load = memnew(Button); load->set_flat(true); - load->set_tooltip_text(TTR("Add a Texture from File")); hbc->add_child(load); load_sheet = memnew(Button); load_sheet->set_flat(true); - load_sheet->set_tooltip_text(TTR("Add Frames from a Sprite Sheet")); hbc->add_child(load_sheet); hbc->add_child(memnew(VSeparator)); copy = memnew(Button); copy->set_flat(true); - copy->set_tooltip_text(TTR("Copy")); hbc->add_child(copy); paste = memnew(Button); paste->set_flat(true); - paste->set_tooltip_text(TTR("Paste")); hbc->add_child(paste); hbc->add_child(memnew(VSeparator)); - empty = memnew(Button); - empty->set_flat(true); - empty->set_tooltip_text(TTR("Insert Empty (Before)")); - hbc->add_child(empty); + empty_before = memnew(Button); + empty_before->set_flat(true); + hbc->add_child(empty_before); - empty2 = memnew(Button); - empty2->set_flat(true); - empty2->set_tooltip_text(TTR("Insert Empty (After)")); - hbc->add_child(empty2); + empty_after = memnew(Button); + empty_after->set_flat(true); + hbc->add_child(empty_after); hbc->add_child(memnew(VSeparator)); move_up = memnew(Button); move_up->set_flat(true); - move_up->set_tooltip_text(TTR("Move (Before)")); hbc->add_child(move_up); move_down = memnew(Button); move_down->set_flat(true); - move_down->set_tooltip_text(TTR("Move (After)")); hbc->add_child(move_down); - _delete = memnew(Button); - _delete->set_flat(true); - _delete->set_tooltip_text(TTR("Delete")); - hbc->add_child(_delete); + delete_frame = memnew(Button); + delete_frame->set_flat(true); + hbc->add_child(delete_frame); hbc->add_spacer(); @@ -1333,13 +1343,40 @@ SpriteFramesEditor::SpriteFramesEditor() { load->connect("pressed", callable_mp(this, &SpriteFramesEditor::_load_pressed)); load_sheet->connect("pressed", callable_mp(this, &SpriteFramesEditor::_open_sprite_sheet)); - _delete->connect("pressed", callable_mp(this, &SpriteFramesEditor::_delete_pressed)); + delete_frame->connect("pressed", callable_mp(this, &SpriteFramesEditor::_delete_pressed)); copy->connect("pressed", callable_mp(this, &SpriteFramesEditor::_copy_pressed)); paste->connect("pressed", callable_mp(this, &SpriteFramesEditor::_paste_pressed)); - empty->connect("pressed", callable_mp(this, &SpriteFramesEditor::_empty_pressed)); - empty2->connect("pressed", callable_mp(this, &SpriteFramesEditor::_empty2_pressed)); + empty_before->connect("pressed", callable_mp(this, &SpriteFramesEditor::_empty_pressed)); + empty_after->connect("pressed", callable_mp(this, &SpriteFramesEditor::_empty2_pressed)); move_up->connect("pressed", callable_mp(this, &SpriteFramesEditor::_up_pressed)); move_down->connect("pressed", callable_mp(this, &SpriteFramesEditor::_down_pressed)); + + load->set_shortcut_context(tree); + load->set_shortcut(ED_SHORTCUT("sprite_frames/load_from_file", TTR("Add frame from file"), KeyModifierMask::CMD_OR_CTRL | Key::O)); + load_sheet->set_shortcut_context(tree); + load_sheet->set_shortcut(ED_SHORTCUT("sprite_frames/load_from_sheet", TTR("Add frames from sprite sheet"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::O)); + delete_frame->set_shortcut_context(tree); + delete_frame->set_shortcut(ED_SHORTCUT("sprite_frames/delete", TTR("Delete Frame"), Key::KEY_DELETE)); + copy->set_shortcut_context(tree); + copy->set_shortcut(ED_SHORTCUT("sprite_frames/copy", TTR("Copy Frame"), KeyModifierMask::CMD_OR_CTRL | Key::C)); + paste->set_shortcut_context(tree); + paste->set_shortcut(ED_SHORTCUT("sprite_frames/paste", TTR("Paste Frame"), KeyModifierMask::CMD_OR_CTRL | Key::V)); + empty_before->set_shortcut_context(tree); + empty_before->set_shortcut(ED_SHORTCUT("sprite_frames/empty_before", TTR("Insert Empty (Before Selected)"), KeyModifierMask::ALT | Key::LEFT)); + empty_after->set_shortcut_context(tree); + empty_after->set_shortcut(ED_SHORTCUT("sprite_frames/empty_after", TTR("Insert Empty (After Selected)"), KeyModifierMask::ALT | Key::RIGHT)); + move_up->set_shortcut_context(tree); + move_up->set_shortcut(ED_SHORTCUT("sprite_frames/move_left", TTR("Move Frame Left"), KeyModifierMask::CMD_OR_CTRL | Key::LEFT)); + move_down->set_shortcut_context(tree); + move_down->set_shortcut(ED_SHORTCUT("sprite_frames/move_right", TTR("Move Frame Right"), KeyModifierMask::CMD_OR_CTRL | Key::RIGHT)); + + zoom_out->set_shortcut_context(tree); + zoom_out->set_shortcut(ED_SHORTCUT_ARRAY("sprite_frames/zoom_out", TTR("Zoom Out"), + { int32_t(KeyModifierMask::CMD_OR_CTRL | Key::MINUS), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_SUBTRACT) })); + zoom_in->set_shortcut_context(tree); + zoom_in->set_shortcut(ED_SHORTCUT_ARRAY("sprite_frames/zoom_in", TTR("Zoom In"), + { int32_t(KeyModifierMask::CMD_OR_CTRL | Key::EQUAL), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_ADD) })); + file->connect("files_selected", callable_mp(this, &SpriteFramesEditor::_file_load_request).bind(-1)); loading_scene = false; sel = -1; @@ -1500,13 +1537,11 @@ SpriteFramesEditor::SpriteFramesEditor() { _zoom_reset(); // Ensure the anim search box is wide enough by default. - // Not by setting its minimum size so it can still be shrinked if desired. + // Not by setting its minimum size so it can still be shrunk if desired. set_split_offset(56 * EDSCALE); } void SpriteFramesEditorPlugin::edit(Object *p_object) { - frames_editor->set_undo_redo(get_undo_redo()); - SpriteFrames *s; AnimatedSprite2D *animated_sprite = Object::cast_to<AnimatedSprite2D>(p_object); if (animated_sprite) { diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index 092f556c63..64245ee1e0 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -45,7 +45,6 @@ #include "scene/gui/tree.h" class EditorFileDialog; -class EditorUndoRedoManager; class SpriteFramesEditor : public HSplitContainer { GDCLASS(SpriteFramesEditor, HSplitContainer); @@ -61,11 +60,11 @@ class SpriteFramesEditor : public HSplitContainer { Button *load = nullptr; Button *load_sheet = nullptr; - Button *_delete = nullptr; + Button *delete_frame = nullptr; Button *copy = nullptr; Button *paste = nullptr; - Button *empty = nullptr; - Button *empty2 = nullptr; + Button *empty_before = nullptr; + Button *empty_after = nullptr; Button *move_up = nullptr; Button *move_down = nullptr; Button *zoom_out = nullptr; @@ -75,8 +74,8 @@ class SpriteFramesEditor : public HSplitContainer { bool loading_scene; int sel; - Button *new_anim = nullptr; - Button *remove_anim = nullptr; + Button *add_anim = nullptr; + Button *delete_anim = nullptr; LineEdit *anim_search_box = nullptr; Tree *animations = nullptr; @@ -154,8 +153,6 @@ class SpriteFramesEditor : public HSplitContainer { bool updating; bool updating_split_settings = false; // Skip SpinBox/Range callback when setting value by code. - Ref<EditorUndoRedoManager> undo_redo; - Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); @@ -179,8 +176,6 @@ protected: static void _bind_methods(); public: - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); - void edit(SpriteFrames *p_frames); SpriteFramesEditor(); }; diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index fffcce6d9a..afc54a2b83 100644 --- a/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp @@ -31,6 +31,7 @@ #include "style_box_editor_plugin.h" #include "editor/editor_scale.h" +#include "scene/gui/texture_button.h" bool StyleBoxPreview::grid_preview_enabled = true; @@ -80,9 +81,9 @@ void StyleBoxPreview::_notification(int p_what) { // See https://github.com/godotengine/godot/issues/50743. break; } - grid_preview->set_normal_texture(get_theme_icon(SNAME("StyleBoxGridInvisible"), SNAME("EditorIcons"))); - grid_preview->set_pressed_texture(get_theme_icon(SNAME("StyleBoxGridVisible"), SNAME("EditorIcons"))); - grid_preview->set_hover_texture(get_theme_icon(SNAME("StyleBoxGridVisible"), SNAME("EditorIcons"))); + grid_preview->set_texture_normal(get_theme_icon(SNAME("StyleBoxGridInvisible"), SNAME("EditorIcons"))); + grid_preview->set_texture_pressed(get_theme_icon(SNAME("StyleBoxGridVisible"), SNAME("EditorIcons"))); + grid_preview->set_texture_hover(get_theme_icon(SNAME("StyleBoxGridVisible"), SNAME("EditorIcons"))); checkerboard->set_texture(get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"))); } break; } diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h index a072745d8f..d5351d3f34 100644 --- a/editor/plugins/style_box_editor_plugin.h +++ b/editor/plugins/style_box_editor_plugin.h @@ -37,6 +37,8 @@ #include "scene/gui/texture_rect.h" #include "scene/resources/style_box.h" +class TextureButton; + class StyleBoxPreview : public VBoxContainer { GDCLASS(StyleBoxPreview, VBoxContainer); diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 76332b2d10..baf5e363f8 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -33,6 +33,7 @@ #include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" +#include "scene/gui/menu_button.h" void TextEditor::add_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) { ERR_FAIL_COND(p_highlighter.is_null()); @@ -108,7 +109,7 @@ void TextEditor::set_edited_resource(const Ref<Resource> &p_res) { code_editor->update_line_and_column(); } -void TextEditor::enable_editor() { +void TextEditor::enable_editor(Control *p_shortcut_context) { if (editor_enabled) { return; } @@ -116,6 +117,15 @@ void TextEditor::enable_editor() { editor_enabled = true; _load_theme_settings(); + + if (p_shortcut_context) { + for (int i = 0; i < edit_hb->get_child_count(); ++i) { + Control *c = cast_to<Control>(edit_hb->get_child(i)); + if (c) { + c->set_shortcut_context(p_shortcut_context); + } + } + } } void TextEditor::add_callback(const String &p_function, PackedStringArray p_args) { @@ -150,6 +160,7 @@ void TextEditor::reload_text() { te->tag_saved_version(); code_editor->update_line_and_column(); + _validate_script(); } void TextEditor::_validate_script() { @@ -221,6 +232,10 @@ void TextEditor::set_edit_state(const Variant &p_state) { ensure_focus(); } +Variant TextEditor::get_navigation_state() { + return code_editor->get_navigation_state(); +} + void TextEditor::trim_trailing_whitespace() { code_editor->trim_trailing_whitespace(); } @@ -325,12 +340,12 @@ void TextEditor::_edit_option(int p_op) { case EDIT_MOVE_LINE_DOWN: { code_editor->move_lines_down(); } break; - case EDIT_INDENT_LEFT: { - tx->unindent_lines(); - } break; - case EDIT_INDENT_RIGHT: { + case EDIT_INDENT: { tx->indent_lines(); } break; + case EDIT_UNINDENT: { + tx->unindent_lines(); + } break; case EDIT_DELETE_LINE: { code_editor->delete_lines(); } break; @@ -435,11 +450,12 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { int row = pos.y; int col = pos.x; - tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click")); + tx->set_move_caret_on_right_click_enabled(EDITOR_GET("text_editor/behavior/navigation/move_caret_on_right_click")); bool can_fold = tx->can_fold_line(row); bool is_folded = tx->is_line_folded(row); if (tx->is_move_caret_on_right_click_enabled()) { + tx->remove_secondary_carets(); if (tx->has_selection()) { int from_line = tx->get_selection_from_line(); int to_line = tx->get_selection_to_line(); @@ -466,9 +482,9 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { Ref<InputEventKey> k = ev; if (k.is_valid() && k->is_pressed() && k->is_action("ui_menu", true)) { CodeEdit *tx = code_editor->get_text_editor(); - int line = tx->get_caret_line(); - tx->adjust_viewport_to_caret(); - _make_context_menu(tx->has_selection(), tx->can_fold_line(line), tx->is_line_folded(line), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->get_caret_draw_pos())); + int line = tx->get_caret_line(0); + tx->adjust_viewport_to_caret(0); + _make_context_menu(tx->has_selection(0), tx->can_fold_line(line), tx->is_line_folded(line), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->get_caret_draw_pos(0))); context_menu->grab_focus(); } } @@ -493,8 +509,8 @@ void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent"), EDIT_INDENT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unindent"), EDIT_UNINDENT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); if (p_selection) { @@ -574,8 +590,8 @@ TextEditor::TextEditor() { edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent"), EDIT_INDENT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unindent"), EDIT_UNINDENT); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES); diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index 15f7c45653..9f2132bc0b 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -33,6 +33,8 @@ #include "script_editor_plugin.h" +#include "editor/code_editor.h" + class TextEditor : public ScriptEditorBase { GDCLASS(TextEditor, ScriptEditorBase); @@ -63,8 +65,8 @@ private: EDIT_CONVERT_INDENT_TO_TABS, EDIT_MOVE_LINE_UP, EDIT_MOVE_LINE_DOWN, - EDIT_INDENT_RIGHT, - EDIT_INDENT_LEFT, + EDIT_INDENT, + EDIT_UNINDENT, EDIT_DELETE_LINE, EDIT_DUPLICATE_SELECTION, EDIT_TO_UPPERCASE, @@ -111,12 +113,13 @@ public: virtual Ref<Texture2D> get_theme_icon() override; virtual Ref<Resource> get_edited_resource() const override; virtual void set_edited_resource(const Ref<Resource> &p_res) override; - virtual void enable_editor() override; + virtual void enable_editor(Control *p_shortcut_context = nullptr) override; virtual void reload_text() override; virtual void apply_code() override; virtual bool is_unsaved() override; virtual Variant get_edit_state() override; virtual void set_edit_state(const Variant &p_state) override; + virtual Variant get_navigation_state() override; virtual Vector<String> get_functions() override; virtual PackedInt32Array get_breakpoints() override; virtual void set_breakpoint(int p_line, bool p_enabled) override{}; diff --git a/editor/plugins/text_shader_editor.cpp b/editor/plugins/text_shader_editor.cpp new file mode 100644 index 0000000000..767eeaefc5 --- /dev/null +++ b/editor/plugins/text_shader_editor.cpp @@ -0,0 +1,1196 @@ +/*************************************************************************/ +/* text_shader_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "text_shader_editor.h" + +#include "core/version_generated.gen.h" +#include "editor/editor_node.h" +#include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "editor/filesystem_dock.h" +#include "editor/project_settings_editor.h" +#include "scene/gui/split_container.h" +#include "servers/rendering/shader_preprocessor.h" +#include "servers/rendering/shader_types.h" + +/*** SHADER SYNTAX HIGHLIGHTER ****/ + +Dictionary GDShaderSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_line) { + Dictionary color_map; + + for (const Point2i ®ion : disabled_branch_regions) { + if (p_line >= region.x && p_line <= region.y) { + Dictionary highlighter_info; + highlighter_info["color"] = disabled_branch_color; + + color_map[0] = highlighter_info; + return color_map; + } + } + + return CodeHighlighter::_get_line_syntax_highlighting_impl(p_line); +} + +void GDShaderSyntaxHighlighter::add_disabled_branch_region(const Point2i &p_region) { + ERR_FAIL_COND(p_region.x < 0); + ERR_FAIL_COND(p_region.y < 0); + + for (int i = 0; i < disabled_branch_regions.size(); i++) { + ERR_FAIL_COND_MSG(disabled_branch_regions[i].x == p_region.x, "Branch region with a start line '" + itos(p_region.x) + "' already exists."); + } + + Point2i disabled_branch_region; + disabled_branch_region.x = p_region.x; + disabled_branch_region.y = p_region.y; + disabled_branch_regions.push_back(disabled_branch_region); + + clear_highlighting_cache(); +} + +void GDShaderSyntaxHighlighter::clear_disabled_branch_regions() { + disabled_branch_regions.clear(); + clear_highlighting_cache(); +} + +void GDShaderSyntaxHighlighter::set_disabled_branch_color(const Color &p_color) { + disabled_branch_color = p_color; + clear_highlighting_cache(); +} + +/*** SHADER SCRIPT EDITOR ****/ + +static bool saved_warnings_enabled = false; +static bool saved_treat_warning_as_errors = false; +static HashMap<ShaderWarning::Code, bool> saved_warnings; +static uint32_t saved_warning_flags = 0U; + +void ShaderTextEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_THEME_CHANGED: { + if (is_visible_in_tree()) { + _load_theme_settings(); + if (warnings.size() > 0 && last_compile_result == OK) { + warnings_panel->clear(); + _update_warning_panel(); + } + } + } break; + } +} + +Ref<Shader> ShaderTextEditor::get_edited_shader() const { + return shader; +} + +Ref<ShaderInclude> ShaderTextEditor::get_edited_shader_include() const { + return shader_inc; +} + +void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader) { + set_edited_shader(p_shader, p_shader->get_code()); +} + +void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader, const String &p_code) { + if (shader == p_shader) { + return; + } + if (shader.is_valid()) { + shader->disconnect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); + } + shader = p_shader; + shader_inc = Ref<ShaderInclude>(); + + set_edited_code(p_code); + + if (shader.is_valid()) { + shader->connect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); + } +} + +void ShaderTextEditor::set_edited_shader_include(const Ref<ShaderInclude> &p_shader_inc) { + set_edited_shader_include(p_shader_inc, p_shader_inc->get_code()); +} + +void ShaderTextEditor::_shader_changed() { + // This function is used for dependencies (include changing changes main shader and forces it to revalidate) + if (block_shader_changed) { + return; + } + dependencies_version++; + _validate_script(); +} + +void ShaderTextEditor::set_edited_shader_include(const Ref<ShaderInclude> &p_shader_inc, const String &p_code) { + if (shader_inc == p_shader_inc) { + return; + } + if (shader_inc.is_valid()) { + shader_inc->disconnect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); + } + shader_inc = p_shader_inc; + shader = Ref<Shader>(); + + set_edited_code(p_code); + + if (shader_inc.is_valid()) { + shader_inc->connect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); + } +} + +void ShaderTextEditor::set_edited_code(const String &p_code) { + _load_theme_settings(); + + get_text_editor()->set_text(p_code); + get_text_editor()->clear_undo_history(); + get_text_editor()->call_deferred(SNAME("set_h_scroll"), 0); + get_text_editor()->call_deferred(SNAME("set_v_scroll"), 0); + get_text_editor()->tag_saved_version(); + + _validate_script(); + _line_col_changed(); +} + +void ShaderTextEditor::reload_text() { + ERR_FAIL_COND(shader.is_null()); + + CodeEdit *te = get_text_editor(); + int column = te->get_caret_column(); + int row = te->get_caret_line(); + int h = te->get_h_scroll(); + int v = te->get_v_scroll(); + + te->set_text(shader->get_code()); + te->set_caret_line(row); + te->set_caret_column(column); + te->set_h_scroll(h); + te->set_v_scroll(v); + + te->tag_saved_version(); + + update_line_and_column(); +} + +void ShaderTextEditor::set_warnings_panel(RichTextLabel *p_warnings_panel) { + warnings_panel = p_warnings_panel; +} + +void ShaderTextEditor::_load_theme_settings() { + CodeEdit *te = get_text_editor(); + Color updated_marked_line_color = EDITOR_GET("text_editor/theme/highlighting/mark_color"); + if (updated_marked_line_color != marked_line_color) { + for (int i = 0; i < te->get_line_count(); i++) { + if (te->get_line_background_color(i) == marked_line_color) { + te->set_line_background_color(i, updated_marked_line_color); + } + } + marked_line_color = updated_marked_line_color; + } + + syntax_highlighter->set_number_color(EDITOR_GET("text_editor/theme/highlighting/number_color")); + syntax_highlighter->set_symbol_color(EDITOR_GET("text_editor/theme/highlighting/symbol_color")); + syntax_highlighter->set_function_color(EDITOR_GET("text_editor/theme/highlighting/function_color")); + syntax_highlighter->set_member_variable_color(EDITOR_GET("text_editor/theme/highlighting/member_variable_color")); + + syntax_highlighter->clear_keyword_colors(); + + const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); + const Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color"); + + List<String> keywords; + ShaderLanguage::get_keyword_list(&keywords); + + for (const String &E : keywords) { + if (ShaderLanguage::is_control_flow_keyword(E)) { + syntax_highlighter->add_keyword_color(E, control_flow_keyword_color); + } else { + syntax_highlighter->add_keyword_color(E, keyword_color); + } + } + + List<String> pp_keywords; + ShaderPreprocessor::get_keyword_list(&pp_keywords, false); + + for (const String &E : pp_keywords) { + syntax_highlighter->add_keyword_color(E, keyword_color); + } + + // Colorize built-ins like `COLOR` differently to make them easier + // to distinguish from keywords at a quick glance. + + List<String> built_ins; + + if (shader_inc.is_valid()) { + for (int i = 0; i < RenderingServer::SHADER_MAX; i++) { + for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) { + for (const KeyValue<StringName, ShaderLanguage::BuiltInInfo> &F : E.value.built_ins) { + built_ins.push_back(F.key); + } + } + + const Vector<ShaderLanguage::ModeInfo> &modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i)); + + for (int j = 0; j < modes.size(); j++) { + const ShaderLanguage::ModeInfo &mode_info = modes[j]; + + if (!mode_info.options.is_empty()) { + for (int k = 0; k < mode_info.options.size(); k++) { + built_ins.push_back(String(mode_info.name) + "_" + String(mode_info.options[k])); + } + } else { + built_ins.push_back(String(mode_info.name)); + } + } + } + } else if (shader.is_valid()) { + for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode()))) { + for (const KeyValue<StringName, ShaderLanguage::BuiltInInfo> &F : E.value.built_ins) { + built_ins.push_back(F.key); + } + } + + const Vector<ShaderLanguage::ModeInfo> &modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())); + + for (int i = 0; i < modes.size(); i++) { + const ShaderLanguage::ModeInfo &mode_info = modes[i]; + + if (!mode_info.options.is_empty()) { + for (int j = 0; j < mode_info.options.size(); j++) { + built_ins.push_back(String(mode_info.name) + "_" + String(mode_info.options[j])); + } + } else { + built_ins.push_back(String(mode_info.name)); + } + } + } + + const Color user_type_color = EDITOR_GET("text_editor/theme/highlighting/user_type_color"); + + for (const String &E : built_ins) { + syntax_highlighter->add_keyword_color(E, user_type_color); + } + + // Colorize comments. + const Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color"); + syntax_highlighter->clear_color_regions(); + syntax_highlighter->add_color_region("/*", "*/", comment_color, false); + syntax_highlighter->add_color_region("//", "", comment_color, true); + syntax_highlighter->set_disabled_branch_color(comment_color); + + te->clear_comment_delimiters(); + te->add_comment_delimiter("/*", "*/", false); + te->add_comment_delimiter("//", "", true); + + if (!te->has_auto_brace_completion_open_key("/*")) { + te->add_auto_brace_completion_pair("/*", "*/"); + } + + // Colorize preprocessor include strings. + const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color"); + syntax_highlighter->add_color_region("\"", "\"", string_color, false); + + if (warnings_panel) { + // Warnings panel. + warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts"))); + warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"))); + } +} + +void ShaderTextEditor::_check_shader_mode() { + String type = ShaderLanguage::get_shader_type(get_text_editor()->get_text()); + + Shader::Mode mode; + + if (type == "canvas_item") { + mode = Shader::MODE_CANVAS_ITEM; + } else if (type == "particles") { + mode = Shader::MODE_PARTICLES; + } else if (type == "sky") { + mode = Shader::MODE_SKY; + } else if (type == "fog") { + mode = Shader::MODE_FOG; + } else { + mode = Shader::MODE_SPATIAL; + } + + if (shader->get_mode() != mode) { + set_block_shader_changed(true); + shader->set_code(get_text_editor()->get_text()); + set_block_shader_changed(false); + _load_theme_settings(); + } +} + +static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) { + RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_variable); + return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); +} + +static String complete_from_path; + +static void _complete_include_paths_search(EditorFileSystemDirectory *p_efsd, List<ScriptLanguage::CodeCompletionOption> *r_options) { + if (!p_efsd) { + return; + } + for (int i = 0; i < p_efsd->get_file_count(); i++) { + if (p_efsd->get_file_type(i) == SNAME("ShaderInclude")) { + String path = p_efsd->get_file_path(i); + if (path.begins_with(complete_from_path)) { + path = path.replace_first(complete_from_path, ""); + } + r_options->push_back(ScriptLanguage::CodeCompletionOption(path, ScriptLanguage::CODE_COMPLETION_KIND_FILE_PATH)); + } + } + for (int j = 0; j < p_efsd->get_subdir_count(); j++) { + _complete_include_paths_search(p_efsd->get_subdir(j), r_options); + } +} + +static void _complete_include_paths(List<ScriptLanguage::CodeCompletionOption> *r_options) { + _complete_include_paths_search(EditorFileSystem::get_singleton()->get_filesystem(), r_options); +} + +void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptLanguage::CodeCompletionOption> *r_options) { + List<ScriptLanguage::CodeCompletionOption> pp_options; + List<ScriptLanguage::CodeCompletionOption> pp_defines; + ShaderPreprocessor preprocessor; + String code; + complete_from_path = (shader.is_valid() ? shader->get_path() : shader_inc->get_path()).get_base_dir(); + if (!complete_from_path.ends_with("/")) { + complete_from_path += "/"; + } + preprocessor.preprocess(p_code, "", code, nullptr, nullptr, nullptr, nullptr, &pp_options, &pp_defines, _complete_include_paths); + complete_from_path = String(); + if (pp_options.size()) { + for (const ScriptLanguage::CodeCompletionOption &E : pp_options) { + r_options->push_back(E); + } + return; + } + for (const ScriptLanguage::CodeCompletionOption &E : pp_defines) { + r_options->push_back(E); + } + + ShaderLanguage sl; + String calltip; + ShaderLanguage::ShaderCompileInfo comp_info; + comp_info.global_shader_uniform_type_func = _get_global_shader_uniform_type; + + if (shader.is_null()) { + comp_info.is_include = true; + + sl.complete(code, comp_info, r_options, calltip); + get_text_editor()->set_code_hint(calltip); + return; + } + _check_shader_mode(); + comp_info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())); + comp_info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())); + comp_info.shader_types = ShaderTypes::get_singleton()->get_types(); + + sl.complete(code, comp_info, r_options, calltip); + get_text_editor()->set_code_hint(calltip); +} + +void ShaderTextEditor::_validate_script() { + emit_signal(SNAME("script_changed")); // Ensure to notify that it changed, so it is applied + + String code; + + if (shader.is_valid()) { + _check_shader_mode(); + code = shader->get_code(); + } else { + code = shader_inc->get_code(); + } + + ShaderPreprocessor preprocessor; + String code_pp; + String error_pp; + List<ShaderPreprocessor::FilePosition> err_positions; + List<ShaderPreprocessor::Region> regions; + String filename; + if (shader.is_valid()) { + filename = shader->get_path(); + } else if (shader_inc.is_valid()) { + filename = shader_inc->get_path(); + } + last_compile_result = preprocessor.preprocess(code, filename, code_pp, &error_pp, &err_positions, ®ions); + + for (int i = 0; i < get_text_editor()->get_line_count(); i++) { + get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); + } + + syntax_highlighter->clear_disabled_branch_regions(); + for (const ShaderPreprocessor::Region ®ion : regions) { + if (!region.enabled) { + if (filename != region.file) { + continue; + } + syntax_highlighter->add_disabled_branch_region(Point2i(region.from_line, region.to_line)); + } + } + + set_error(""); + set_error_count(0); + + if (last_compile_result != OK) { + //preprocessor error + ERR_FAIL_COND(err_positions.size() == 0); + + String err_text = error_pp; + int err_line = err_positions.front()->get().line; + if (err_positions.size() == 1) { + // Error in main file + err_text = "error(" + itos(err_line) + "): " + err_text; + } else { + err_text = "error(" + itos(err_line) + ") in include " + err_positions.back()->get().file.get_file() + ":" + itos(err_positions.back()->get().line) + ": " + err_text; + set_error_count(err_positions.size() - 1); + } + + set_error(err_text); + set_error_pos(err_line - 1, 0); + for (int i = 0; i < get_text_editor()->get_line_count(); i++) { + get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); + } + get_text_editor()->set_line_background_color(err_line - 1, marked_line_color); + + set_warning_count(0); + + } else { + ShaderLanguage sl; + + sl.enable_warning_checking(saved_warnings_enabled); + uint32_t flags = saved_warning_flags; + if (shader.is_null()) { + if (flags & ShaderWarning::UNUSED_CONSTANT) { + flags &= ~(ShaderWarning::UNUSED_CONSTANT); + } + if (flags & ShaderWarning::UNUSED_FUNCTION) { + flags &= ~(ShaderWarning::UNUSED_FUNCTION); + } + if (flags & ShaderWarning::UNUSED_STRUCT) { + flags &= ~(ShaderWarning::UNUSED_STRUCT); + } + if (flags & ShaderWarning::UNUSED_UNIFORM) { + flags &= ~(ShaderWarning::UNUSED_UNIFORM); + } + if (flags & ShaderWarning::UNUSED_VARYING) { + flags &= ~(ShaderWarning::UNUSED_VARYING); + } + } + sl.set_warning_flags(flags); + + ShaderLanguage::ShaderCompileInfo comp_info; + comp_info.global_shader_uniform_type_func = _get_global_shader_uniform_type; + + if (shader.is_null()) { + comp_info.is_include = true; + } else { + Shader::Mode mode = shader->get_mode(); + comp_info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(mode)); + comp_info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(mode)); + comp_info.shader_types = ShaderTypes::get_singleton()->get_types(); + } + + code = code_pp; + //compiler error + last_compile_result = sl.compile(code, comp_info); + + if (last_compile_result != OK) { + String err_text; + int err_line; + Vector<ShaderLanguage::FilePosition> include_positions = sl.get_include_positions(); + if (include_positions.size() > 1) { + //error is in an include + err_line = include_positions[0].line; + err_text = "error(" + itos(err_line) + ") in include " + include_positions[include_positions.size() - 1].file + ":" + itos(include_positions[include_positions.size() - 1].line) + ": " + sl.get_error_text(); + set_error_count(include_positions.size() - 1); + } else { + err_line = sl.get_error_line(); + err_text = "error(" + itos(err_line) + "): " + sl.get_error_text(); + set_error_count(0); + } + set_error(err_text); + set_error_pos(err_line - 1, 0); + get_text_editor()->set_line_background_color(err_line - 1, marked_line_color); + } else { + set_error(""); + } + + if (warnings.size() > 0 || last_compile_result != OK) { + warnings_panel->clear(); + } + warnings.clear(); + for (List<ShaderWarning>::Element *E = sl.get_warnings_ptr(); E; E = E->next()) { + warnings.push_back(E->get()); + } + if (warnings.size() > 0 && last_compile_result == OK) { + warnings.sort_custom<WarningsComparator>(); + _update_warning_panel(); + } else { + set_warning_count(0); + } + } + + emit_signal(SNAME("script_validated"), last_compile_result == OK); // Notify that validation finished, to update the list of scripts +} + +void ShaderTextEditor::_update_warning_panel() { + int warning_count = 0; + + warnings_panel->push_table(2); + for (int i = 0; i < warnings.size(); i++) { + ShaderWarning &w = warnings[i]; + + if (warning_count == 0) { + if (saved_treat_warning_as_errors) { + String error_text = "error(" + itos(w.get_line()) + "): " + w.get_message() + " " + TTR("Warnings should be fixed to prevent errors."); + set_error_pos(w.get_line() - 1, 0); + set_error(error_text); + get_text_editor()->set_line_background_color(w.get_line() - 1, marked_line_color); + } + } + + warning_count++; + int line = w.get_line(); + + // First cell. + warnings_panel->push_cell(); + warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + if (line != -1) { + warnings_panel->push_meta(line - 1); + warnings_panel->add_text(TTR("Line") + " " + itos(line)); + warnings_panel->add_text(" (" + w.get_name() + "):"); + warnings_panel->pop(); // Meta goto. + } else { + warnings_panel->add_text(w.get_name() + ":"); + } + warnings_panel->pop(); // Color. + warnings_panel->pop(); // Cell. + + // Second cell. + warnings_panel->push_cell(); + warnings_panel->add_text(w.get_message()); + warnings_panel->pop(); // Cell. + } + warnings_panel->pop(); // Table. + + set_warning_count(warning_count); +} + +void ShaderTextEditor::_bind_methods() { + ADD_SIGNAL(MethodInfo("script_validated", PropertyInfo(Variant::BOOL, "valid"))); +} + +ShaderTextEditor::ShaderTextEditor() { + syntax_highlighter.instantiate(); + get_text_editor()->set_syntax_highlighter(syntax_highlighter); +} + +/*** SCRIPT EDITOR ******/ + +void TextShaderEditor::_menu_option(int p_option) { + switch (p_option) { + case EDIT_UNDO: { + shader_editor->get_text_editor()->undo(); + } break; + case EDIT_REDO: { + shader_editor->get_text_editor()->redo(); + } break; + case EDIT_CUT: { + shader_editor->get_text_editor()->cut(); + } break; + case EDIT_COPY: { + shader_editor->get_text_editor()->copy(); + } break; + case EDIT_PASTE: { + shader_editor->get_text_editor()->paste(); + } break; + case EDIT_SELECT_ALL: { + shader_editor->get_text_editor()->select_all(); + } break; + case EDIT_MOVE_LINE_UP: { + shader_editor->move_lines_up(); + } break; + case EDIT_MOVE_LINE_DOWN: { + shader_editor->move_lines_down(); + } break; + case EDIT_INDENT: { + if (shader.is_null()) { + return; + } + shader_editor->get_text_editor()->indent_lines(); + } break; + case EDIT_UNINDENT: { + if (shader.is_null()) { + return; + } + shader_editor->get_text_editor()->unindent_lines(); + } break; + case EDIT_DELETE_LINE: { + shader_editor->delete_lines(); + } break; + case EDIT_DUPLICATE_SELECTION: { + shader_editor->duplicate_selection(); + } break; + case EDIT_TOGGLE_COMMENT: { + if (shader.is_null()) { + return; + } + + shader_editor->toggle_inline_comment("//"); + + } break; + case EDIT_COMPLETE: { + shader_editor->get_text_editor()->request_code_completion(); + } break; + case SEARCH_FIND: { + shader_editor->get_find_replace_bar()->popup_search(); + } break; + case SEARCH_FIND_NEXT: { + shader_editor->get_find_replace_bar()->search_next(); + } break; + case SEARCH_FIND_PREV: { + shader_editor->get_find_replace_bar()->search_prev(); + } break; + case SEARCH_REPLACE: { + shader_editor->get_find_replace_bar()->popup_replace(); + } break; + case SEARCH_GOTO_LINE: { + goto_line_dialog->popup_find_line(shader_editor->get_text_editor()); + } break; + case BOOKMARK_TOGGLE: { + shader_editor->toggle_bookmark(); + } break; + case BOOKMARK_GOTO_NEXT: { + shader_editor->goto_next_bookmark(); + } break; + case BOOKMARK_GOTO_PREV: { + shader_editor->goto_prev_bookmark(); + } break; + case BOOKMARK_REMOVE_ALL: { + shader_editor->remove_all_bookmarks(); + } break; + case HELP_DOCS: { + OS::get_singleton()->shell_open(vformat("%s/tutorials/shaders/shader_reference/index.html", VERSION_DOCS_URL)); + } break; + } + if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) { + shader_editor->get_text_editor()->call_deferred(SNAME("grab_focus")); + } +} + +void TextShaderEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + PopupMenu *popup = help_menu->get_popup(); + popup->set_item_icon(popup->get_item_index(HELP_DOCS), get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons"))); + } break; + + case NOTIFICATION_APPLICATION_FOCUS_IN: { + _check_for_external_edit(); + } break; + } +} + +void TextShaderEditor::_editor_settings_changed() { + shader_editor->update_editor_settings(); + + shader_editor->get_text_editor()->add_theme_constant_override("line_spacing", EDITOR_GET("text_editor/appearance/whitespace/line_spacing")); + shader_editor->get_text_editor()->set_draw_breakpoints_gutter(false); + shader_editor->get_text_editor()->set_draw_executing_lines_gutter(false); +} + +void TextShaderEditor::_show_warnings_panel(bool p_show) { + warnings_panel->set_visible(p_show); +} + +void TextShaderEditor::_warning_clicked(Variant p_line) { + if (p_line.get_type() == Variant::INT) { + shader_editor->get_text_editor()->set_caret_line(p_line.operator int64_t()); + } +} + +void TextShaderEditor::_bind_methods() { + ClassDB::bind_method("_show_warnings_panel", &TextShaderEditor::_show_warnings_panel); + ClassDB::bind_method("_warning_clicked", &TextShaderEditor::_warning_clicked); + + ADD_SIGNAL(MethodInfo("validation_changed")); +} + +void TextShaderEditor::ensure_select_current() { +} + +void TextShaderEditor::goto_line_selection(int p_line, int p_begin, int p_end) { + shader_editor->goto_line_selection(p_line, p_begin, p_end); +} + +void TextShaderEditor::_project_settings_changed() { + _update_warnings(true); +} + +void TextShaderEditor::_update_warnings(bool p_validate) { + bool changed = false; + + bool warnings_enabled = GLOBAL_GET("debug/shader_language/warnings/enable").booleanize(); + if (warnings_enabled != saved_warnings_enabled) { + saved_warnings_enabled = warnings_enabled; + changed = true; + } + + bool treat_warning_as_errors = GLOBAL_GET("debug/shader_language/warnings/treat_warnings_as_errors").booleanize(); + if (treat_warning_as_errors != saved_treat_warning_as_errors) { + saved_treat_warning_as_errors = treat_warning_as_errors; + changed = true; + } + + bool update_flags = false; + + for (int i = 0; i < ShaderWarning::WARNING_MAX; i++) { + ShaderWarning::Code code = (ShaderWarning::Code)i; + bool value = GLOBAL_GET("debug/shader_language/warnings/" + ShaderWarning::get_name_from_code(code).to_lower()); + + if (saved_warnings[code] != value) { + saved_warnings[code] = value; + update_flags = true; + changed = true; + } + } + + if (update_flags) { + saved_warning_flags = (uint32_t)ShaderWarning::get_flags_from_codemap(saved_warnings); + } + + if (p_validate && changed && shader_editor && shader_editor->get_edited_shader().is_valid()) { + shader_editor->validate_script(); + } +} + +void TextShaderEditor::_check_for_external_edit() { + bool use_autoreload = bool(EDITOR_GET("text_editor/behavior/files/auto_reload_scripts_on_external_change")); + + if (shader_inc.is_valid()) { + if (shader_inc->get_last_modified_time() != FileAccess::get_modified_time(shader_inc->get_path())) { + if (use_autoreload) { + _reload_shader_include_from_disk(); + } else { + disk_changed->call_deferred(SNAME("popup_centered")); + } + } + return; + } + + if (shader.is_null() || shader->is_built_in()) { + return; + } + + if (shader->get_last_modified_time() != FileAccess::get_modified_time(shader->get_path())) { + if (use_autoreload) { + _reload_shader_from_disk(); + } else { + disk_changed->call_deferred(SNAME("popup_centered")); + } + } +} + +void TextShaderEditor::_reload_shader_from_disk() { + Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_FAIL_COND(!rel_shader.is_valid()); + + shader_editor->set_block_shader_changed(true); + shader->set_code(rel_shader->get_code()); + shader_editor->set_block_shader_changed(false); + shader->set_last_modified_time(rel_shader->get_last_modified_time()); + shader_editor->reload_text(); +} + +void TextShaderEditor::_reload_shader_include_from_disk() { + Ref<ShaderInclude> rel_shader_include = ResourceLoader::load(shader_inc->get_path(), shader_inc->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_FAIL_COND(!rel_shader_include.is_valid()); + + shader_editor->set_block_shader_changed(true); + shader_inc->set_code(rel_shader_include->get_code()); + shader_editor->set_block_shader_changed(false); + shader_inc->set_last_modified_time(rel_shader_include->get_last_modified_time()); + shader_editor->reload_text(); +} + +void TextShaderEditor::_reload() { + if (shader.is_valid()) { + _reload_shader_from_disk(); + } else if (shader_inc.is_valid()) { + _reload_shader_include_from_disk(); + } +} + +void TextShaderEditor::edit(const Ref<Shader> &p_shader) { + if (p_shader.is_null() || !p_shader->is_text_shader()) { + return; + } + + if (shader == p_shader) { + return; + } + + shader = p_shader; + shader_inc = Ref<ShaderInclude>(); + + shader_editor->set_edited_shader(shader); +} + +void TextShaderEditor::edit(const Ref<ShaderInclude> &p_shader_inc) { + if (p_shader_inc.is_null()) { + return; + } + + if (shader_inc == p_shader_inc) { + return; + } + + shader_inc = p_shader_inc; + shader = Ref<Shader>(); + + shader_editor->set_edited_shader_include(p_shader_inc); +} + +void TextShaderEditor::save_external_data(const String &p_str) { + if (shader.is_null() && shader_inc.is_null()) { + disk_changed->hide(); + return; + } + + apply_shaders(); + + Ref<Shader> edited_shader = shader_editor->get_edited_shader(); + if (edited_shader.is_valid()) { + ResourceSaver::save(edited_shader); + } + if (shader.is_valid() && shader != edited_shader) { + ResourceSaver::save(shader); + } + + Ref<ShaderInclude> edited_shader_inc = shader_editor->get_edited_shader_include(); + if (edited_shader_inc.is_valid()) { + ResourceSaver::save(edited_shader_inc); + } + if (shader_inc.is_valid() && shader_inc != edited_shader_inc) { + ResourceSaver::save(shader_inc); + } + shader_editor->get_text_editor()->tag_saved_version(); + + disk_changed->hide(); +} + +void TextShaderEditor::validate_script() { + shader_editor->_validate_script(); +} + +bool TextShaderEditor::is_unsaved() const { + return shader_editor->get_text_editor()->get_saved_version() != shader_editor->get_text_editor()->get_version(); +} + +void TextShaderEditor::tag_saved_version() { + shader_editor->get_text_editor()->tag_saved_version(); +} + +void TextShaderEditor::apply_shaders() { + String editor_code = shader_editor->get_text_editor()->get_text(); + if (shader.is_valid()) { + String shader_code = shader->get_code(); + if (shader_code != editor_code || dependencies_version != shader_editor->get_dependencies_version()) { + shader_editor->set_block_shader_changed(true); + shader->set_code(editor_code); + shader_editor->set_block_shader_changed(false); + shader->set_edited(true); + } + } + if (shader_inc.is_valid()) { + String shader_inc_code = shader_inc->get_code(); + if (shader_inc_code != editor_code || dependencies_version != shader_editor->get_dependencies_version()) { + shader_editor->set_block_shader_changed(true); + shader_inc->set_code(editor_code); + shader_editor->set_block_shader_changed(false); + shader_inc->set_edited(true); + } + } + + dependencies_version = shader_editor->get_dependencies_version(); +} + +void TextShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { + Ref<InputEventMouseButton> mb = ev; + + if (mb.is_valid()) { + if (mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { + CodeEdit *tx = shader_editor->get_text_editor(); + + Point2i pos = tx->get_line_column_at_pos(mb->get_global_position() - tx->get_global_position()); + int row = pos.y; + int col = pos.x; + tx->set_move_caret_on_right_click_enabled(EDITOR_GET("text_editor/behavior/navigation/move_caret_on_right_click")); + + if (tx->is_move_caret_on_right_click_enabled()) { + tx->remove_secondary_carets(); + if (tx->has_selection()) { + int from_line = tx->get_selection_from_line(); + int to_line = tx->get_selection_to_line(); + int from_column = tx->get_selection_from_column(); + int to_column = tx->get_selection_to_column(); + + if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) { + // Right click is outside the selected text + tx->deselect(); + } + } + if (!tx->has_selection()) { + tx->set_caret_line(row, true, false); + tx->set_caret_column(col); + } + } + _make_context_menu(tx->has_selection(), get_local_mouse_position()); + } + } + + Ref<InputEventKey> k = ev; + if (k.is_valid() && k->is_pressed() && k->is_action("ui_menu", true)) { + CodeEdit *tx = shader_editor->get_text_editor(); + tx->adjust_viewport_to_caret(); + _make_context_menu(tx->has_selection(), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->get_caret_draw_pos())); + context_menu->grab_focus(); + } +} + +void TextShaderEditor::_update_bookmark_list() { + bookmarks_menu->clear(); + + bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); + bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL); + bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); + bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); + + PackedInt32Array bookmark_list = shader_editor->get_text_editor()->get_bookmarked_lines(); + if (bookmark_list.size() == 0) { + return; + } + + bookmarks_menu->add_separator(); + + for (int i = 0; i < bookmark_list.size(); i++) { + String line = shader_editor->get_text_editor()->get_line(bookmark_list[i]).strip_edges(); + // Limit the size of the line if too big. + if (line.length() > 50) { + line = line.substr(0, 50); + } + + bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\""); + bookmarks_menu->set_item_metadata(-1, bookmark_list[i]); + } +} + +void TextShaderEditor::_bookmark_item_pressed(int p_idx) { + if (p_idx < 4) { // Any item before the separator. + _menu_option(bookmarks_menu->get_item_id(p_idx)); + } else { + shader_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx)); + } +} + +void TextShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) { + context_menu->clear(); + if (p_selection) { + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + } + + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); + context_menu->add_separator(); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); + + context_menu->add_separator(); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent"), EDIT_INDENT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unindent"), EDIT_UNINDENT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); + + context_menu->set_position(get_screen_position() + p_position); + context_menu->reset_size(); + context_menu->popup(); +} + +TextShaderEditor::TextShaderEditor() { + GLOBAL_DEF("debug/shader_language/warnings/enable", true); + GLOBAL_DEF("debug/shader_language/warnings/treat_warnings_as_errors", false); + for (int i = 0; i < (int)ShaderWarning::WARNING_MAX; i++) { + GLOBAL_DEF("debug/shader_language/warnings/" + ShaderWarning::get_name_from_code((ShaderWarning::Code)i).to_lower(), true); + } + _update_warnings(false); + + shader_editor = memnew(ShaderTextEditor); + + shader_editor->connect("script_validated", callable_mp(this, &TextShaderEditor::_script_validated)); + + shader_editor->set_v_size_flags(SIZE_EXPAND_FILL); + shader_editor->add_theme_constant_override("separation", 0); + shader_editor->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); + + shader_editor->connect("show_warnings_panel", callable_mp(this, &TextShaderEditor::_show_warnings_panel)); + shader_editor->connect("script_changed", callable_mp(this, &TextShaderEditor::apply_shaders)); + EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &TextShaderEditor::_editor_settings_changed)); + ProjectSettingsEditor::get_singleton()->connect("confirmed", callable_mp(this, &TextShaderEditor::_project_settings_changed)); + + shader_editor->get_text_editor()->set_code_hint_draw_below(EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line")); + + shader_editor->get_text_editor()->set_symbol_lookup_on_click_enabled(true); + shader_editor->get_text_editor()->set_context_menu_enabled(false); + shader_editor->get_text_editor()->connect("gui_input", callable_mp(this, &TextShaderEditor::_text_edit_gui_input)); + + shader_editor->update_editor_settings(); + + context_menu = memnew(PopupMenu); + add_child(context_menu); + context_menu->connect("id_pressed", callable_mp(this, &TextShaderEditor::_menu_option)); + + VBoxContainer *main_container = memnew(VBoxContainer); + HBoxContainer *hbc = memnew(HBoxContainer); + + edit_menu = memnew(MenuButton); + edit_menu->set_shortcut_context(this); + edit_menu->set_text(TTR("Edit")); + edit_menu->set_switch_on_hover(true); + + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent"), EDIT_INDENT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unindent"), EDIT_UNINDENT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/duplicate_selection"), EDIT_DUPLICATE_SELECTION); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); + edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &TextShaderEditor::_menu_option)); + + search_menu = memnew(MenuButton); + search_menu->set_shortcut_context(this); + search_menu->set_text(TTR("Search")); + search_menu->set_switch_on_hover(true); + + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); + search_menu->get_popup()->connect("id_pressed", callable_mp(this, &TextShaderEditor::_menu_option)); + + MenuButton *goto_menu = memnew(MenuButton); + goto_menu->set_shortcut_context(this); + goto_menu->set_text(TTR("Go To")); + goto_menu->set_switch_on_hover(true); + goto_menu->get_popup()->connect("id_pressed", callable_mp(this, &TextShaderEditor::_menu_option)); + + goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE); + goto_menu->get_popup()->add_separator(); + + bookmarks_menu = memnew(PopupMenu); + bookmarks_menu->set_name("Bookmarks"); + goto_menu->get_popup()->add_child(bookmarks_menu); + goto_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "Bookmarks"); + _update_bookmark_list(); + bookmarks_menu->connect("about_to_popup", callable_mp(this, &TextShaderEditor::_update_bookmark_list)); + bookmarks_menu->connect("index_pressed", callable_mp(this, &TextShaderEditor::_bookmark_item_pressed)); + + help_menu = memnew(MenuButton); + help_menu->set_text(TTR("Help")); + help_menu->set_switch_on_hover(true); + help_menu->get_popup()->add_item(TTR("Online Docs"), HELP_DOCS); + help_menu->get_popup()->connect("id_pressed", callable_mp(this, &TextShaderEditor::_menu_option)); + + add_child(main_container); + main_container->add_child(hbc); + hbc->add_child(search_menu); + hbc->add_child(edit_menu); + hbc->add_child(goto_menu); + hbc->add_child(help_menu); + hbc->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles"))); + + VSplitContainer *editor_box = memnew(VSplitContainer); + main_container->add_child(editor_box); + editor_box->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); + editor_box->set_v_size_flags(SIZE_EXPAND_FILL); + editor_box->add_child(shader_editor); + + FindReplaceBar *bar = memnew(FindReplaceBar); + main_container->add_child(bar); + bar->hide(); + shader_editor->set_find_replace_bar(bar); + + warnings_panel = memnew(RichTextLabel); + warnings_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); + warnings_panel->set_h_size_flags(SIZE_EXPAND_FILL); + warnings_panel->set_meta_underline(true); + warnings_panel->set_selection_enabled(true); + warnings_panel->set_focus_mode(FOCUS_CLICK); + warnings_panel->hide(); + warnings_panel->connect("meta_clicked", callable_mp(this, &TextShaderEditor::_warning_clicked)); + editor_box->add_child(warnings_panel); + shader_editor->set_warnings_panel(warnings_panel); + + goto_line_dialog = memnew(GotoLineDialog); + add_child(goto_line_dialog); + + disk_changed = memnew(ConfirmationDialog); + + VBoxContainer *vbc = memnew(VBoxContainer); + disk_changed->add_child(vbc); + + Label *dl = memnew(Label); + dl->set_text(TTR("This shader has been modified on disk.\nWhat action should be taken?")); + vbc->add_child(dl); + + disk_changed->connect("confirmed", callable_mp(this, &TextShaderEditor::_reload)); + disk_changed->set_ok_button_text(TTR("Reload")); + + disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); + disk_changed->connect("custom_action", callable_mp(this, &TextShaderEditor::save_external_data)); + + add_child(disk_changed); + + _editor_settings_changed(); +} diff --git a/editor/plugins/text_shader_editor.h b/editor/plugins/text_shader_editor.h new file mode 100644 index 0000000000..c2094342ed --- /dev/null +++ b/editor/plugins/text_shader_editor.h @@ -0,0 +1,200 @@ +/*************************************************************************/ +/* text_shader_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEXT_SHADER_EDITOR_H +#define TEXT_SHADER_EDITOR_H + +#include "editor/code_editor.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/rich_text_label.h" +#include "servers/rendering/shader_warnings.h" + +class GDShaderSyntaxHighlighter : public CodeHighlighter { + GDCLASS(GDShaderSyntaxHighlighter, CodeHighlighter) + +private: + Vector<Point2i> disabled_branch_regions; + Color disabled_branch_color; + +public: + virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override; + + void add_disabled_branch_region(const Point2i &p_region); + void clear_disabled_branch_regions(); + void set_disabled_branch_color(const Color &p_color); +}; + +class ShaderTextEditor : public CodeTextEditor { + GDCLASS(ShaderTextEditor, CodeTextEditor); + + Color marked_line_color = Color(1, 1, 1); + + struct WarningsComparator { + _ALWAYS_INLINE_ bool operator()(const ShaderWarning &p_a, const ShaderWarning &p_b) const { return (p_a.get_line() < p_b.get_line()); } + }; + + Ref<GDShaderSyntaxHighlighter> syntax_highlighter; + RichTextLabel *warnings_panel = nullptr; + Ref<Shader> shader; + Ref<ShaderInclude> shader_inc; + List<ShaderWarning> warnings; + Error last_compile_result = Error::OK; + + void _check_shader_mode(); + void _update_warning_panel(); + + bool block_shader_changed = false; + void _shader_changed(); + + uint32_t dependencies_version = 0; // Incremented if deps changed + +protected: + void _notification(int p_what); + static void _bind_methods(); + virtual void _load_theme_settings() override; + + virtual void _code_complete_script(const String &p_code, List<ScriptLanguage::CodeCompletionOption> *r_options) override; + +public: + void set_block_shader_changed(bool p_block) { block_shader_changed = p_block; } + uint32_t get_dependencies_version() const { return dependencies_version; } + + virtual void _validate_script() override; + + void reload_text(); + void set_warnings_panel(RichTextLabel *p_warnings_panel); + + Ref<Shader> get_edited_shader() const; + Ref<ShaderInclude> get_edited_shader_include() const; + + void set_edited_shader(const Ref<Shader> &p_shader); + void set_edited_shader(const Ref<Shader> &p_shader, const String &p_code); + void set_edited_shader_include(const Ref<ShaderInclude> &p_include); + void set_edited_shader_include(const Ref<ShaderInclude> &p_include, const String &p_code); + void set_edited_code(const String &p_code); + + ShaderTextEditor(); +}; + +class TextShaderEditor : public MarginContainer { + GDCLASS(TextShaderEditor, MarginContainer); + + enum { + EDIT_UNDO, + EDIT_REDO, + EDIT_CUT, + EDIT_COPY, + EDIT_PASTE, + EDIT_SELECT_ALL, + EDIT_MOVE_LINE_UP, + EDIT_MOVE_LINE_DOWN, + EDIT_INDENT, + EDIT_UNINDENT, + EDIT_DELETE_LINE, + EDIT_DUPLICATE_SELECTION, + EDIT_TOGGLE_COMMENT, + EDIT_COMPLETE, + SEARCH_FIND, + SEARCH_FIND_NEXT, + SEARCH_FIND_PREV, + SEARCH_REPLACE, + SEARCH_GOTO_LINE, + BOOKMARK_TOGGLE, + BOOKMARK_GOTO_NEXT, + BOOKMARK_GOTO_PREV, + BOOKMARK_REMOVE_ALL, + HELP_DOCS, + }; + + MenuButton *edit_menu = nullptr; + MenuButton *search_menu = nullptr; + PopupMenu *bookmarks_menu = nullptr; + MenuButton *help_menu = nullptr; + PopupMenu *context_menu = nullptr; + RichTextLabel *warnings_panel = nullptr; + uint64_t idle = 0; + + GotoLineDialog *goto_line_dialog = nullptr; + ConfirmationDialog *erase_tab_confirm = nullptr; + ConfirmationDialog *disk_changed = nullptr; + + ShaderTextEditor *shader_editor = nullptr; + bool compilation_success = true; + + void _menu_option(int p_option); + mutable Ref<Shader> shader; + mutable Ref<ShaderInclude> shader_inc; + + void _editor_settings_changed(); + void _project_settings_changed(); + + void _check_for_external_edit(); + void _reload_shader_from_disk(); + void _reload_shader_include_from_disk(); + void _reload(); + void _show_warnings_panel(bool p_show); + void _warning_clicked(Variant p_line); + void _update_warnings(bool p_validate); + + void _script_validated(bool p_valid) { + compilation_success = p_valid; + emit_signal(SNAME("validation_changed")); + } + + uint32_t dependencies_version = 0xFFFFFFFF; + +protected: + void _notification(int p_what); + static void _bind_methods(); + void _make_context_menu(bool p_selection, Vector2 p_position); + void _text_edit_gui_input(const Ref<InputEvent> &p_ev); + + void _update_bookmark_list(); + void _bookmark_item_pressed(int p_idx); + +public: + bool was_compilation_successful() const { return compilation_success; } + void apply_shaders(); + void ensure_select_current(); + void edit(const Ref<Shader> &p_shader); + void edit(const Ref<ShaderInclude> &p_shader_inc); + void goto_line_selection(int p_line, int p_begin, int p_end); + void save_external_data(const String &p_str = ""); + void validate_script(); + bool is_unsaved() const; + void tag_saved_version(); + + virtual Size2 get_minimum_size() const override { return Size2(0, 200); } + + TextShaderEditor(); +}; + +#endif // TEXT_SHADER_EDITOR_H diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index 3ea62184c6..bdea12c2cb 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -30,6 +30,8 @@ #include "texture_3d_editor_plugin.h" +#include "scene/gui/label.h" + void Texture3DEditor::_texture_rect_draw() { texture_rect->draw_rect(Rect2(Point2(), texture_rect->get_size()), Color(1, 1, 1, 1)); } @@ -138,10 +140,6 @@ void Texture3DEditor::edit(Ref<Texture3D> p_texture) { } } -void Texture3DEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_layer_changed"), &Texture3DEditor::_layer_changed); -} - Texture3DEditor::Texture3DEditor() { set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED); set_custom_minimum_size(Size2(1, 150)); @@ -173,7 +171,7 @@ Texture3DEditor::Texture3DEditor() { info->add_theme_constant_override("shadow_offset_y", 2); setting = false; - layer->connect("value_changed", Callable(this, "_layer_changed")); + layer->connect("value_changed", callable_mp(this, &Texture3DEditor::_layer_changed)); } Texture3DEditor::~Texture3DEditor() { diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h index 357bdb0845..6790f6f2d5 100644 --- a/editor/plugins/texture_3d_editor_plugin.h +++ b/editor/plugins/texture_3d_editor_plugin.h @@ -31,6 +31,7 @@ #ifndef TEXTURE_3D_EDITOR_PLUGIN_H #define TEXTURE_3D_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "scene/gui/spin_box.h" #include "scene/resources/shader.h" @@ -66,8 +67,6 @@ class Texture3DEditor : public Control { protected: void _notification(int p_what); - static void _bind_methods(); - public: void edit(Ref<Texture3D> p_texture); Texture3DEditor(); diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index be382759f5..5783912c96 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -29,8 +29,9 @@ /*************************************************************************/ #include "texture_editor_plugin.h" - #include "editor/editor_scale.h" +#include "scene/gui/label.h" +#include "scene/gui/texture_rect.h" TextureRect *TexturePreview::get_texture_display() { return texture_display; @@ -123,6 +124,7 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) { add_child(checkerboard); texture_display = memnew(TextureRect); + texture_display->set_texture_filter(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); texture_display->set_texture(p_texture); texture_display->set_anchors_preset(TextureRect::PRESET_FULL_RECT); texture_display->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h index 9beada556c..d7312bfcb4 100644 --- a/editor/plugins/texture_editor_plugin.h +++ b/editor/plugins/texture_editor_plugin.h @@ -31,9 +31,13 @@ #ifndef TEXTURE_EDITOR_PLUGIN_H #define TEXTURE_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" +#include "scene/gui/margin_container.h" #include "scene/resources/texture.h" +class TextureRect; + class TexturePreview : public MarginContainer { GDCLASS(TexturePreview, MarginContainer); diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index dd8633360e..479e84682b 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -30,6 +30,8 @@ #include "texture_layered_editor_plugin.h" +#include "scene/gui/label.h" + void TextureLayeredEditor::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); @@ -214,10 +216,6 @@ void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { } } -void TextureLayeredEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_layer_changed"), &TextureLayeredEditor::_layer_changed); -} - TextureLayeredEditor::TextureLayeredEditor() { set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED); set_custom_minimum_size(Size2(1, 150)); @@ -249,7 +247,7 @@ TextureLayeredEditor::TextureLayeredEditor() { info->add_theme_constant_override("shadow_offset_y", 2); setting = false; - layer->connect("value_changed", Callable(this, "_layer_changed")); + layer->connect("value_changed", callable_mp(this, &TextureLayeredEditor::_layer_changed)); } TextureLayeredEditor::~TextureLayeredEditor() { diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h index f49aa83eb2..16a2f65386 100644 --- a/editor/plugins/texture_layered_editor_plugin.h +++ b/editor/plugins/texture_layered_editor_plugin.h @@ -31,6 +31,7 @@ #ifndef TEXTURE_LAYERED_EDITOR_PLUGIN_H #define TEXTURE_LAYERED_EDITOR_PLUGIN_H +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "scene/gui/spin_box.h" #include "scene/resources/shader.h" @@ -68,7 +69,6 @@ class TextureLayeredEditor : public Control { protected: void _notification(int p_what); virtual void gui_input(const Ref<InputEvent> &p_event) override; - static void _bind_methods(); public: void edit(Ref<TextureLayered> p_texture); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 8e04391a94..fdfa3f8d0a 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -38,7 +38,9 @@ #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "scene/gui/check_box.h" +#include "scene/gui/option_button.h" #include "scene/gui/separator.h" +#include "scene/gui/spin_box.h" #include "scene/gui/view_panner.h" #include "scene/resources/texture.h" @@ -86,8 +88,8 @@ void TextureRegionEditor::_region_draw() { mtx.scale_basis(Vector2(draw_zoom, draw_zoom)); RS::get_singleton()->canvas_item_add_set_transform(edit_draw->get_canvas_item(), mtx); - edit_draw->draw_rect(Rect2(Point2(), base_tex->get_size()), Color(0.5, 0.5, 0.5, 0.5), false); - edit_draw->draw_texture(base_tex, Point2()); + edit_draw->draw_rect(Rect2(Point2(), preview_tex->get_size()), Color(0.5, 0.5, 0.5, 0.5), false); + edit_draw->draw_texture(preview_tex, Point2()); RS::get_singleton()->canvas_item_add_set_transform(edit_draw->get_canvas_item(), Transform2D()); const Color color = get_theme_color(SNAME("mono_color"), SNAME("Editor")); @@ -242,7 +244,7 @@ void TextureRegionEditor::_region_draw() { hscroll->set_value((hscroll->get_min() + hscroll->get_max() - hscroll->get_page()) / 2); vscroll->set_value((vscroll->get_min() + vscroll->get_max() - vscroll->get_page()) / 2); // This ensures that the view is updated correctly. - callable_mp(this, &TextureRegionEditor::_pan_callback).bind(Vector2(1, 0)).call_deferredp(nullptr, 0); + callable_mp(this, &TextureRegionEditor::_pan_callback).bind(Vector2(1, 0)).call_deferred(); request_center = false; } @@ -298,6 +300,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { mtx.xform(rect.position + Vector2(0, rect.size.y / 2)) + Vector2(-handle_offset, 0) }; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); Ref<InputEventMouseButton> mb = p_input; if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::LEFT) { @@ -835,7 +838,7 @@ void TextureRegionEditor::_notification(int p_what) { [[fallthrough]]; } case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); } break; case NOTIFICATION_VISIBILITY_CHANGED: { if (snap_mode == SNAP_AUTOSLICE && is_visible() && autoslice_is_dirty) { @@ -905,6 +908,13 @@ void TextureRegionEditor::edit(Object *p_obj) { if (atlas_tex.is_valid()) { atlas_tex->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } + + node_sprite_2d = nullptr; + node_sprite_3d = nullptr; + node_ninepatch = nullptr; + obj_styleBox = Ref<StyleBoxTexture>(nullptr); + atlas_tex = Ref<AtlasTexture>(nullptr); + if (p_obj) { node_sprite_2d = Object::cast_to<Sprite2D>(p_obj); node_sprite_3d = Object::cast_to<Sprite3D>(p_obj); @@ -926,13 +936,8 @@ void TextureRegionEditor::edit(Object *p_obj) { p_obj->connect("texture_changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } _edit_region(); - } else { - node_sprite_2d = nullptr; - node_sprite_3d = nullptr; - node_ninepatch = nullptr; - obj_styleBox = Ref<StyleBoxTexture>(nullptr); - atlas_tex = Ref<AtlasTexture>(nullptr); } + edit_draw->queue_redraw(); popup_centered_ratio(0.5); request_center = true; @@ -946,20 +951,80 @@ void TextureRegionEditor::_texture_changed() { } void TextureRegionEditor::_edit_region() { + CanvasItem::TextureFilter filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS; + Ref<Texture2D> texture = nullptr; if (atlas_tex.is_valid()) { texture = atlas_tex->get_atlas(); } else if (node_sprite_2d) { texture = node_sprite_2d->get_texture(); + filter = node_sprite_2d->get_texture_filter_in_tree(); } else if (node_sprite_3d) { texture = node_sprite_3d->get_texture(); + + StandardMaterial3D::TextureFilter filter_3d = node_sprite_3d->get_texture_filter(); + + switch (filter_3d) { + case StandardMaterial3D::TEXTURE_FILTER_NEAREST: + filter = CanvasItem::TEXTURE_FILTER_NEAREST; + break; + case StandardMaterial3D::TEXTURE_FILTER_LINEAR: + filter = CanvasItem::TEXTURE_FILTER_LINEAR; + break; + case StandardMaterial3D::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: + filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS; + break; + case StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: + filter = CanvasItem::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; + break; + case StandardMaterial3D::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: + filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC; + break; + case StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: + filter = CanvasItem::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC; + break; + default: + // fallback to project default + filter = CanvasItem::TEXTURE_FILTER_PARENT_NODE; + break; + } } else if (node_ninepatch) { texture = node_ninepatch->get_texture(); + filter = node_ninepatch->get_texture_filter_in_tree(); } else if (obj_styleBox.is_valid()) { texture = obj_styleBox->get_texture(); } + // occurs when get_texture_filter_in_tree reaches the scene root + if (filter == CanvasItem::TEXTURE_FILTER_PARENT_NODE) { + SubViewport *root = EditorNode::get_singleton()->get_scene_root(); + + if (root != nullptr) { + Viewport::DefaultCanvasItemTextureFilter filter_default = root->get_default_canvas_item_texture_filter(); + + // depending on default filter, set filter to match, otherwise fall back on nearest w/ mipmaps + switch (filter_default) { + case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST: + filter = CanvasItem::TEXTURE_FILTER_NEAREST; + break; + case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR: + filter = CanvasItem::TEXTURE_FILTER_LINEAR; + break; + case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: + filter = CanvasItem::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; + break; + case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: + default: + filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS; + break; + } + } else { + filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS; + } + } + if (texture.is_null()) { + preview_tex->set_diffuse_texture(nullptr); _zoom_reset(); hscroll->hide(); vscroll->hide(); @@ -967,6 +1032,9 @@ void TextureRegionEditor::_edit_region() { return; } + preview_tex->set_texture_filter(filter); + preview_tex->set_diffuse_texture(texture); + if (cache_map.has(texture->get_rid())) { autoslice_cache = cache_map[texture->get_rid()]; autoslice_is_dirty = false; @@ -1000,7 +1068,8 @@ TextureRegionEditor::TextureRegionEditor() { node_ninepatch = nullptr; obj_styleBox = Ref<StyleBoxTexture>(nullptr); atlas_tex = Ref<AtlasTexture>(nullptr); - undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + preview_tex = Ref<CanvasTexture>(memnew(CanvasTexture)); snap_step = Vector2(10, 10); snap_separation = Vector2(0, 0); diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index e3bbaf49fc..90a5b20e14 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -32,15 +32,17 @@ #define TEXTURE_REGION_EDITOR_PLUGIN_H #include "canvas_item_editor_plugin.h" +#include "editor/editor_inspector.h" #include "editor/editor_plugin.h" #include "scene/2d/sprite_2d.h" #include "scene/3d/sprite_3d.h" +#include "scene/gui/dialogs.h" #include "scene/gui/nine_patch_rect.h" #include "scene/resources/style_box.h" #include "scene/resources/texture.h" class ViewPanner; -class EditorUndoRedoManager; +class OptionButton; class TextureRegionEditor : public AcceptDialog { GDCLASS(TextureRegionEditor, AcceptDialog); @@ -69,8 +71,6 @@ class TextureRegionEditor : public AcceptDialog { VScrollBar *vscroll = nullptr; HScrollBar *hscroll = nullptr; - Ref<EditorUndoRedoManager> undo_redo; - Vector2 draw_ofs; float draw_zoom = 0.0; bool updating_scroll = false; @@ -86,6 +86,8 @@ class TextureRegionEditor : public AcceptDialog { Ref<StyleBoxTexture> obj_styleBox; Ref<AtlasTexture> atlas_tex; + Ref<CanvasTexture> preview_tex; + Rect2 rect; Rect2 rect_prev; float prev_margin = 0.0f; diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 1fb9b42449..135b218768 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -38,6 +38,8 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/progress_dialog.h" #include "scene/gui/color_picker.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/split_container.h" #include "scene/theme/theme_db.h" void ThemeItemImportTree::_update_items_tree() { @@ -134,7 +136,7 @@ void ThemeItemImportTree::_update_items_tree() { data_type_node->set_checked(IMPORT_ITEM_DATA, false); data_type_node->set_editable(IMPORT_ITEM_DATA, true); - List<TreeItem *> *item_list; + List<TreeItem *> *item_list = nullptr; switch (dt) { case Theme::DATA_TYPE_COLOR: @@ -398,7 +400,7 @@ void ThemeItemImportTree::_restore_selected_item(TreeItem *p_tree_item) { void ThemeItemImportTree::_update_total_selected(Theme::DataType p_data_type) { ERR_FAIL_INDEX_MSG(p_data_type, Theme::DATA_TYPE_MAX, "Theme item data type is out of bounds."); - Label *total_selected_items_label; + Label *total_selected_items_label = nullptr; switch (p_data_type) { case Theme::DATA_TYPE_COLOR: total_selected_items_label = total_selected_colors_label; @@ -562,7 +564,7 @@ void ThemeItemImportTree::_select_all_data_type_pressed(int p_data_type) { } Theme::DataType data_type = (Theme::DataType)p_data_type; - List<TreeItem *> *item_list; + List<TreeItem *> *item_list = nullptr; switch (data_type) { case Theme::DATA_TYPE_COLOR: @@ -617,7 +619,7 @@ void ThemeItemImportTree::_select_full_data_type_pressed(int p_data_type) { } Theme::DataType data_type = (Theme::DataType)p_data_type; - List<TreeItem *> *item_list; + List<TreeItem *> *item_list = nullptr; switch (data_type) { case Theme::DATA_TYPE_COLOR: @@ -674,7 +676,7 @@ void ThemeItemImportTree::_deselect_all_data_type_pressed(int p_data_type) { } Theme::DataType data_type = (Theme::DataType)p_data_type; - List<TreeItem *> *item_list; + List<TreeItem *> *item_list = nullptr; switch (data_type) { case Theme::DATA_TYPE_COLOR: @@ -982,17 +984,17 @@ ThemeItemImportTree::ThemeItemImportTree() { for (int i = 0; i < Theme::DATA_TYPE_MAX; i++) { Theme::DataType dt = (Theme::DataType)i; - TextureRect *select_items_icon; - Label *select_items_label; - Button *deselect_all_items_button; - Button *select_all_items_button; - Button *select_full_items_button; - Label *total_selected_items_label; + TextureRect *select_items_icon = nullptr; + Label *select_items_label = nullptr; + Button *deselect_all_items_button = nullptr; + Button *select_all_items_button = nullptr; + Button *select_full_items_button = nullptr; + Label *total_selected_items_label = nullptr; - String items_title = ""; - String select_all_items_tooltip = ""; - String select_full_items_tooltip = ""; - String deselect_all_items_tooltip = ""; + String items_title; + String select_all_items_tooltip; + String select_full_items_tooltip; + String deselect_all_items_tooltip; switch (dt) { case Theme::DATA_TYPE_COLOR: @@ -2481,7 +2483,7 @@ void ThemeTypeEditor::_update_type_items() { { for (int i = color_items_list->get_child_count() - 1; i >= 0; i--) { Node *node = color_items_list->get_child(i); - node->queue_delete(); + node->queue_free(); color_items_list->remove_child(node); } @@ -2510,7 +2512,7 @@ void ThemeTypeEditor::_update_type_items() { { for (int i = constant_items_list->get_child_count() - 1; i >= 0; i--) { Node *node = constant_items_list->get_child(i); - node->queue_delete(); + node->queue_free(); constant_items_list->remove_child(node); } @@ -2543,7 +2545,7 @@ void ThemeTypeEditor::_update_type_items() { { for (int i = font_items_list->get_child_count() - 1; i >= 0; i--) { Node *node = font_items_list->get_child(i); - node->queue_delete(); + node->queue_free(); font_items_list->remove_child(node); } @@ -2581,7 +2583,7 @@ void ThemeTypeEditor::_update_type_items() { { for (int i = font_size_items_list->get_child_count() - 1; i >= 0; i--) { Node *node = font_size_items_list->get_child(i); - node->queue_delete(); + node->queue_free(); font_size_items_list->remove_child(node); } @@ -2614,7 +2616,7 @@ void ThemeTypeEditor::_update_type_items() { { for (int i = icon_items_list->get_child_count() - 1; i >= 0; i--) { Node *node = icon_items_list->get_child(i); - node->queue_delete(); + node->queue_free(); icon_items_list->remove_child(node); } @@ -2652,7 +2654,7 @@ void ThemeTypeEditor::_update_type_items() { { for (int i = stylebox_items_list->get_child_count() - 1; i >= 0; i--) { Node *node = stylebox_items_list->get_child(i); - node->queue_delete(); + node->queue_free(); stylebox_items_list->remove_child(node); } diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index 9f89a047cb..b54aa5de6c 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -45,6 +45,8 @@ #include "scene/resources/theme.h" class EditorFileDialog; +class PanelContainer; +class TabContainer; class ThemeItemImportTree : public VBoxContainer { GDCLASS(ThemeItemImportTree, VBoxContainer); diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp index 8cc96201e7..082b21bbe5 100644 --- a/editor/plugins/theme_editor_preview.cpp +++ b/editor/plugins/theme_editor_preview.cpp @@ -36,9 +36,12 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "scene/gui/button.h" +#include "scene/gui/check_box.h" #include "scene/gui/check_button.h" #include "scene/gui/color_picker.h" #include "scene/gui/progress_bar.h" +#include "scene/gui/text_edit.h" +#include "scene/gui/tree.h" #include "scene/resources/packed_scene.h" #include "scene/theme/theme_db.h" @@ -459,7 +462,7 @@ void SceneThemeEditorPreview::_reload_scene() { for (int i = preview_content->get_child_count() - 1; i >= 0; i--) { Node *node = preview_content->get_child(i); - node->queue_delete(); + node->queue_free(); preview_content->remove_child(node); } diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp index d7e08db954..e266d26b73 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.cpp +++ b/editor/plugins/tiles/atlas_merging_dialog.cpp @@ -47,9 +47,7 @@ void AtlasMergingDialog::_generate_merged(Vector<Ref<TileSetAtlasSource>> p_atla merged_mapping.clear(); if (p_atlas_sources.size() >= 2) { - Ref<Image> output_image; - output_image.instantiate(); - output_image->create(1, 1, false, Image::FORMAT_RGBA8); + Ref<Image> output_image = Image::create_empty(1, 1, false, Image::FORMAT_RGBA8); // Compute the new texture region size. Vector2i new_texture_region_size; @@ -156,6 +154,7 @@ void AtlasMergingDialog::_merge_confirmed(String p_path) { Ref<Texture2D> new_texture_resource = ResourceLoader::load(p_path, "Texture2D"); merged->set_texture(new_texture_resource); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Merge TileSetAtlasSource")); int next_id = tile_set->get_next_source_id(); undo_redo->add_do_method(*tile_set, "add_source", merged, next_id); @@ -195,6 +194,7 @@ void AtlasMergingDialog::ok_pressed() { } void AtlasMergingDialog::cancel_pressed() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); for (int i = 0; i < commited_actions_count; i++) { undo_redo->undo(); } @@ -250,8 +250,6 @@ void AtlasMergingDialog::update_tile_set(Ref<TileSet> p_tile_set) { } AtlasMergingDialog::AtlasMergingDialog() { - undo_redo = EditorNode::get_singleton()->get_undo_redo(); - // Atlas merging window. set_title(TTR("Atlas Merging")); set_hide_on_ok(false); diff --git a/editor/plugins/tiles/atlas_merging_dialog.h b/editor/plugins/tiles/atlas_merging_dialog.h index c7e4635d16..228c188817 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.h +++ b/editor/plugins/tiles/atlas_merging_dialog.h @@ -38,7 +38,6 @@ #include "scene/resources/tile_set.h" class EditorFileDialog; -class EditorUndoRedoManager; class AtlasMergingDialog : public ConfirmationDialog { GDCLASS(AtlasMergingDialog, ConfirmationDialog); @@ -50,8 +49,6 @@ private: LocalVector<HashMap<Vector2i, Vector2i>> merged_mapping; Ref<TileSet> tile_set; - Ref<EditorUndoRedoManager> undo_redo; - // Settings. int next_line_after_column = 30; diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index d9291503cb..4fe7178e7e 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -192,6 +192,19 @@ void TileAtlasView::_draw_base_tiles() { rect = rect.intersection(Rect2i(Vector2(), texture->get_size())); if (rect.size.x > 0 && rect.size.y > 0) { base_tiles_draw->draw_texture_rect_region(texture, rect, rect); + } + } + } + } + + // Draw dark overlay after for performance reasons. + for (int x = 0; x < grid_size.x; x++) { + for (int y = 0; y < grid_size.y; y++) { + Vector2i coords = Vector2i(x, y); + if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { + Rect2i rect = Rect2i((texture_region_size + separation) * coords + margins, texture_region_size + separation); + rect = rect.intersection(Rect2i(Vector2(), texture->get_size())); + if (rect.size.x > 0 && rect.size.y > 0) { base_tiles_draw->draw_rect(rect, Color(0.0, 0.0, 0.0, 0.5)); } } @@ -242,23 +255,34 @@ void TileAtlasView::_draw_base_tiles() { // Draw the tile. TileMap::draw_tile(base_tiles_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, 0, frame); + } + } - // Draw, the texture in the separation areas - if (separation.x > 0) { - Rect2i right_sep_rect = Rect2i(base_frame_rect.get_position() + Vector2i(base_frame_rect.size.x, 0), Vector2i(separation.x, base_frame_rect.size.y)); - right_sep_rect = right_sep_rect.intersection(Rect2i(Vector2(), texture->get_size())); - if (right_sep_rect.size.x > 0 && right_sep_rect.size.y > 0) { - base_tiles_draw->draw_texture_rect_region(texture, right_sep_rect, right_sep_rect); - base_tiles_draw->draw_rect(right_sep_rect, Color(0.0, 0.0, 0.0, 0.5)); + // Draw Dark overlay on separation in its own pass. + if (separation.x > 0 || separation.y > 0) { + for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) { + Vector2i atlas_coords = tile_set_atlas_source->get_tile_id(i); + + for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(atlas_coords); frame++) { + // Update the y to max value. + Rect2i base_frame_rect = tile_set_atlas_source->get_tile_texture_region(atlas_coords, frame); + + if (separation.x > 0) { + Rect2i right_sep_rect = Rect2i(base_frame_rect.get_position() + Vector2i(base_frame_rect.size.x, 0), Vector2i(separation.x, base_frame_rect.size.y)); + right_sep_rect = right_sep_rect.intersection(Rect2i(Vector2(), texture->get_size())); + if (right_sep_rect.size.x > 0 && right_sep_rect.size.y > 0) { + //base_tiles_draw->draw_texture_rect_region(texture, right_sep_rect, right_sep_rect); + base_tiles_draw->draw_rect(right_sep_rect, Color(0.0, 0.0, 0.0, 0.5)); + } } - } - if (separation.y > 0) { - Rect2i bottom_sep_rect = Rect2i(base_frame_rect.get_position() + Vector2i(0, base_frame_rect.size.y), Vector2i(base_frame_rect.size.x + separation.x, separation.y)); - bottom_sep_rect = bottom_sep_rect.intersection(Rect2i(Vector2(), texture->get_size())); - if (bottom_sep_rect.size.x > 0 && bottom_sep_rect.size.y > 0) { - base_tiles_draw->draw_texture_rect_region(texture, bottom_sep_rect, bottom_sep_rect); - base_tiles_draw->draw_rect(bottom_sep_rect, Color(0.0, 0.0, 0.0, 0.5)); + if (separation.y > 0) { + Rect2i bottom_sep_rect = Rect2i(base_frame_rect.get_position() + Vector2i(0, base_frame_rect.size.y), Vector2i(base_frame_rect.size.x + separation.x, separation.y)); + bottom_sep_rect = bottom_sep_rect.intersection(Rect2i(Vector2(), texture->get_size())); + if (bottom_sep_rect.size.x > 0 && bottom_sep_rect.size.y > 0) { + //base_tiles_draw->draw_texture_rect_region(texture, bottom_sep_rect, bottom_sep_rect); + base_tiles_draw->draw_rect(bottom_sep_rect, Color(0.0, 0.0, 0.0, 0.5)); + } } } } @@ -298,7 +322,7 @@ void TileAtlasView::_draw_base_tiles_texture_grid() { void TileAtlasView::_draw_base_tiles_shape_grid() { // Draw the shapes. - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Vector2i tile_shape_size = tile_set->get_tile_size(); for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) { Vector2i tile_id = tile_set_atlas_source->get_tile_id(i); @@ -403,6 +427,9 @@ void TileAtlasView::set_atlas_source(TileSet *p_tile_set, TileSetAtlasSource *p_ // Update everything. _update_zoom_and_panning(); + base_tiles_drawing_root->set_size(_compute_base_tiles_control_size()); + alternative_tiles_drawing_root->set_size(_compute_alternative_tiles_control_size()); + // Update. base_tiles_draw->queue_redraw(); base_tiles_texture_grid->queue_redraw(); @@ -506,7 +533,7 @@ void TileAtlasView::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); } break; case NOTIFICATION_READY: { @@ -530,11 +557,11 @@ TileAtlasView::TileAtlasView() { panel->set_v_size_flags(SIZE_EXPAND_FILL); add_child(panel); - // Scrollingsc zoom_widget = memnew(EditorZoomWidget); add_child(zoom_widget); zoom_widget->set_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE); zoom_widget->connect("zoom_changed", callable_mp(this, &TileAtlasView::_zoom_widget_changed).unbind(1)); + zoom_widget->set_shortcut_context(this); button_center_view = memnew(Button); button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons"))); @@ -601,7 +628,6 @@ TileAtlasView::TileAtlasView() { base_tiles_drawing_root = memnew(Control); base_tiles_drawing_root->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); - base_tiles_drawing_root->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); base_tiles_drawing_root->set_texture_filter(TEXTURE_FILTER_NEAREST); base_tiles_root_control->add_child(base_tiles_drawing_root); @@ -645,7 +671,6 @@ TileAtlasView::TileAtlasView() { alternative_tiles_drawing_root = memnew(Control); alternative_tiles_drawing_root->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); - alternative_tiles_drawing_root->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); alternative_tiles_drawing_root->set_texture_filter(TEXTURE_FILTER_NEAREST); alternative_tiles_root_control->add_child(alternative_tiles_drawing_root); diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 4d54001b94..993f606f2f 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -38,8 +38,13 @@ #include "editor/editor_node.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/option_button.h" +#include "scene/gui/separator.h" + #ifdef DEBUG_ENABLED #include "servers/navigation_server_3d.h" #endif // DEBUG_ENABLED @@ -128,7 +133,7 @@ void GenericTilePolygonEditor::_base_control_draw() { real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons")); const Ref<Texture2D> add_handle = get_theme_icon(SNAME("EditorHandleAdd"), SNAME("EditorIcons")); const Ref<StyleBox> focus_stylebox = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles")); @@ -153,7 +158,14 @@ void GenericTilePolygonEditor::_base_control_draw() { // Draw the background. if (background_texture.is_valid()) { - base_control->draw_texture_rect_region(background_texture, Rect2(-background_region.size / 2 - background_offset, background_region.size), background_region, background_modulate, background_transpose); + Size2 region_size = background_region.size; + if (background_h_flip) { + region_size.x = -region_size.x; + } + if (background_v_flip) { + region_size.y = -region_size.y; + } + base_control->draw_texture_rect_region(background_texture, Rect2(-background_region.size / 2 - background_offset, region_size), background_region, background_modulate, background_transpose); } // Draw the polygons. @@ -212,8 +224,8 @@ void GenericTilePolygonEditor::_base_control_draw() { for (int i = 0; i < (int)polygons.size(); i++) { const Vector<Vector2> &polygon = polygons[i]; for (int j = 0; j < polygon.size(); j++) { - const Color modulate = (tinted_polygon_index == i && tinted_point_index == j) ? Color(0.5, 1, 2) : Color(1, 1, 1); - base_control->draw_texture(handle, xform.xform(polygon[j]) - handle->get_size() / 2, modulate); + const Color poly_modulate = (tinted_polygon_index == i && tinted_point_index == j) ? Color(0.5, 1, 2) : Color(1, 1, 1); + base_control->draw_texture(handle, xform.xform(polygon[j]) - handle->get_size() / 2, poly_modulate); } } } @@ -255,7 +267,7 @@ void GenericTilePolygonEditor::_zoom_changed() { void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) { Ref<EditorUndoRedoManager> undo_redo; if (use_undo_redo) { - undo_redo = editor_undo_redo; + undo_redo = EditorNode::get_undo_redo(); } else { // This nice hack allows for discarding undo actions without making code too complex. undo_redo.instantiate(); @@ -420,7 +432,7 @@ void GenericTilePolygonEditor::_snap_to_half_pixel(Point2 &r_point) { void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) { Ref<EditorUndoRedoManager> undo_redo; if (use_undo_redo) { - undo_redo = editor_undo_redo; + undo_redo = EditorNode::get_undo_redo(); } else { // This nice hack allows for discarding undo actions without making code too complex. undo_redo.instantiate(); @@ -756,8 +768,6 @@ void GenericTilePolygonEditor::_bind_methods() { } GenericTilePolygonEditor::GenericTilePolygonEditor() { - editor_undo_redo = EditorNode::get_undo_redo(); - toolbar = memnew(HBoxContainer); add_child(toolbar); @@ -831,6 +841,7 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() { editor_zoom_widget = memnew(EditorZoomWidget); editor_zoom_widget->set_position(Vector2(5, 5)); editor_zoom_widget->connect("zoom_changed", callable_mp(this, &GenericTilePolygonEditor::_zoom_changed).unbind(1)); + editor_zoom_widget->set_shortcut_context(this); root->add_child(editor_zoom_widget); button_center_view = memnew(Button); @@ -845,6 +856,7 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() { void TileDataDefaultEditor::_property_value_changed(StringName p_property, Variant p_value, StringName p_field) { ERR_FAIL_COND(!dummy_object); dummy_object->set(p_property, p_value); + emit_signal(SNAME("needs_redraw")); } Variant TileDataDefaultEditor::_get_painted_value() { @@ -875,6 +887,7 @@ Variant TileDataDefaultEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_s } void TileDataDefaultEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) { Vector2i coords = E.key.get_atlas_coords(); undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/%s", coords.x, coords.y, E.key.alternative_tile, property), E.value); @@ -884,7 +897,7 @@ void TileDataDefaultEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_s void TileDataDefaultEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_set_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) { if (drag_type == DRAG_TYPE_PAINT_RECT) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); p_canvas_item->draw_set_transform_matrix(p_transform); @@ -943,6 +956,7 @@ void TileDataDefaultEditor::forward_painting_atlas_gui_input(TileAtlasView *p_ti } } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::LEFT) { @@ -1066,6 +1080,7 @@ void TileDataDefaultEditor::forward_painting_alternatives_gui_input(TileAtlasVie drag_last_pos = mb->get_position(); } } else { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Painting Tiles Property")); _setup_undo_redo_action(p_tile_set_atlas_source, drag_modified, drag_painted_value); undo_redo->commit_action(false); @@ -1116,7 +1131,7 @@ void TileDataDefaultEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2 Color color = Color(1, 1, 1); if (p_selected) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); selection_color.set_v(0.9); color = selection_color; @@ -1137,10 +1152,11 @@ void TileDataDefaultEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2 void TileDataDefaultEditor::setup_property_editor(Variant::Type p_type, String p_property, String p_label, Variant p_default_value) { ERR_FAIL_COND_MSG(!property.is_empty(), "Cannot setup TileDataDefaultEditor twice"); property = p_property; + property_type = p_type; // Update everything. if (property_editor) { - property_editor->queue_delete(); + property_editor->queue_free(); } // Update the dummy object. @@ -1181,9 +1197,11 @@ void TileDataDefaultEditor::_notification(int p_what) { } } -TileDataDefaultEditor::TileDataDefaultEditor() { - undo_redo = EditorNode::get_undo_redo(); +Variant::Type TileDataDefaultEditor::get_property_type() { + return property_type; +} +TileDataDefaultEditor::TileDataDefaultEditor() { label = memnew(Label); label->set_text(TTR("Painting:")); label->set_theme_type_variation("HeaderSmall"); @@ -1199,7 +1217,7 @@ TileDataDefaultEditor::TileDataDefaultEditor() { } TileDataDefaultEditor::~TileDataDefaultEditor() { - toolbar->queue_delete(); + toolbar->queue_free(); memdelete(dummy_object); } @@ -1210,7 +1228,7 @@ void TileDataTextureOffsetEditor::draw_over_tile(CanvasItem *p_canvas_item, Tran Vector2i tile_set_tile_size = tile_set->get_tile_size(); Color color = Color(1.0, 0.0, 0.0); if (p_selected) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); color = selection_color; } @@ -1232,7 +1250,7 @@ void TileDataPositionEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform Color color = Color(1.0, 1.0, 1.0); if (p_selected) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); color = selection_color; } @@ -1246,7 +1264,7 @@ void TileDataYSortEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2D Color color = Color(1.0, 1.0, 1.0); if (p_selected) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); color = selection_color; } @@ -1258,7 +1276,7 @@ void TileDataOcclusionShapeEditor::draw_over_tile(CanvasItem *p_canvas_item, Tra TileData *tile_data = _get_tile_data(p_cell); ERR_FAIL_COND(!tile_data); - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); Color color = grid_color.darkened(0.2); if (p_selected) { @@ -1314,6 +1332,7 @@ Variant TileDataOcclusionShapeEditor::_get_value(TileSetAtlasSource *p_tile_set_ } void TileDataOcclusionShapeEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) { Vector2i coords = E.key.get_atlas_coords(); undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/occlusion_layer_%d/polygon", coords.x, coords.y, E.key.alternative_tile, occlusion_layer), E.value); @@ -1334,8 +1353,6 @@ void TileDataOcclusionShapeEditor::_notification(int p_what) { } TileDataOcclusionShapeEditor::TileDataOcclusionShapeEditor() { - undo_redo = EditorNode::get_undo_redo(); - polygon_editor = memnew(GenericTilePolygonEditor); add_child(polygon_editor); } @@ -1402,11 +1419,11 @@ void TileDataCollisionEditor::_polygons_changed() { dummy_object->remove_dummy_property(vformat("polygon_%d_one_way_margin", i)); } for (int i = polygon_editor->get_polygon_count(); property_editors.has(vformat("polygon_%d_one_way", i)); i++) { - property_editors[vformat("polygon_%d_one_way", i)]->queue_delete(); + property_editors[vformat("polygon_%d_one_way", i)]->queue_free(); property_editors.erase(vformat("polygon_%d_one_way", i)); } for (int i = polygon_editor->get_polygon_count(); property_editors.has(vformat("polygon_%d_one_way_margin", i)); i++) { - property_editors[vformat("polygon_%d_one_way_margin", i)]->queue_delete(); + property_editors[vformat("polygon_%d_one_way_margin", i)]->queue_free(); property_editors.erase(vformat("polygon_%d_one_way_margin", i)); } } @@ -1495,6 +1512,7 @@ Variant TileDataCollisionEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas void TileDataCollisionEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) { Array new_array = p_new_value; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); for (KeyValue<TileMapCell, Variant> &E : p_previous_values) { Array old_array = E.value; @@ -1531,8 +1549,6 @@ void TileDataCollisionEditor::_notification(int p_what) { } TileDataCollisionEditor::TileDataCollisionEditor() { - undo_redo = EditorNode::get_undo_redo(); - polygon_editor = memnew(GenericTilePolygonEditor); polygon_editor->set_multiple_polygon_mode(true); polygon_editor->connect("polygons_changed", callable_mp(this, &TileDataCollisionEditor::_polygons_changed)); @@ -1577,7 +1593,7 @@ void TileDataCollisionEditor::draw_over_tile(CanvasItem *p_canvas_item, Transfor // Draw all shapes. Vector<Color> color; if (p_selected) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); selection_color.a = 0.7; color.push_back(selection_color); @@ -1750,7 +1766,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET_RECT) { // Draw selection rectangle. - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); p_canvas_item->draw_set_transform_matrix(p_transform); @@ -1977,6 +1993,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t } } drag_last_pos = mm->get_position(); + accept_event(); } else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) { int terrain_set = Dictionary(drag_painted_value)["terrain_set"]; int terrain = Dictionary(drag_painted_value)["terrain"]; @@ -2026,14 +2043,15 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t } } drag_last_pos = mm->get_position(); + accept_event(); } } Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == MouseButton::LEFT) { + if (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT) { if (mb->is_pressed()) { - if (picker_button->is_pressed()) { + if (mb->get_button_index() == MouseButton::LEFT && picker_button->is_pressed()) { Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position()); coords = p_tile_set_atlas_source->get_tile_at_coords(coords); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { @@ -2060,6 +2078,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t terrain_set_property_editor->update_property(); _update_terrain_selector(); picker_button->set_pressed(false); + accept_event(); } } else { Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position()); @@ -2071,6 +2090,10 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t int terrain_set = int(dummy_object->get("terrain_set")); int terrain = int(dummy_object->get("terrain")); if (terrain_set == -1 || !tile_data || tile_data->get_terrain_set() != terrain_set) { + // Paint terrain sets. + if (mb->get_button_index() == MouseButton::RIGHT) { + terrain_set = -1; + } if (mb->is_ctrl_pressed()) { // Paint terrain set with rect. drag_type = DRAG_TYPE_PAINT_TERRAIN_SET_RECT; @@ -2106,9 +2129,14 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t } drag_last_pos = mb->get_position(); } + accept_event(); } else if (tile_data->get_terrain_set() == terrain_set) { + // Paint terrain bits. + if (mb->get_button_index() == MouseButton::RIGHT) { + terrain = -1; + } if (mb->is_ctrl_pressed()) { - // Paint terrain set with rect. + // Paint terrain bits with rect. drag_type = DRAG_TYPE_PAINT_TERRAIN_BITS_RECT; drag_modified.clear(); Dictionary painted_dict; @@ -2163,9 +2191,11 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t } drag_last_pos = mb->get_position(); } + accept_event(); } } } else { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET_RECT) { Rect2i rect; rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos)); @@ -2190,18 +2220,21 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t for (const TileMapCell &E : edited) { Vector2i coords = E.get_atlas_coords(); TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.alternative_tile), tile_data->get_terrain_set()); undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.alternative_tile), drag_painted_value); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.alternative_tile), tile_data->get_terrain()); - for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { - TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); - if (tile_data->is_valid_terrain_peering_bit(bit)) { - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.alternative_tile), tile_data->get_terrain_peering_bit(bit)); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.alternative_tile), tile_data->get_terrain_set()); + if (tile_data->get_terrain_set() >= 0) { + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.alternative_tile), tile_data->get_terrain()); + for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { + TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); + if (tile_data->is_valid_terrain_peering_bit(bit)) { + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.alternative_tile), tile_data->get_terrain_peering_bit(bit)); + } } } } undo_redo->commit_action(true); drag_type = DRAG_TYPE_NONE; + accept_event(); } else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET) { undo_redo->create_action(TTR("Painting Terrain Set")); for (KeyValue<TileMapCell, Variant> &E : drag_modified) { @@ -2209,17 +2242,20 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t Vector2i coords = E.key.get_atlas_coords(); undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), drag_painted_value); undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), dict["terrain_set"]); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.key.alternative_tile), dict["terrain"]); - Array array = dict["terrain_peering_bits"]; - for (int i = 0; i < array.size(); i++) { - TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); - if (tile_set->is_valid_terrain_peering_bit(dict["terrain_set"], bit)) { - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]); + if (int(dict["terrain_set"]) >= 0) { + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.key.alternative_tile), dict["terrain"]); + Array array = dict["terrain_peering_bits"]; + for (int i = 0; i < array.size(); i++) { + TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); + if (tile_set->is_valid_terrain_peering_bit(dict["terrain_set"], bit)) { + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]); + } } } } undo_redo->commit_action(false); drag_type = DRAG_TYPE_NONE; + accept_event(); } else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) { Dictionary painted = Dictionary(drag_painted_value); int terrain_set = int(painted["terrain_set"]); @@ -2243,6 +2279,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t } undo_redo->commit_action(false); drag_type = DRAG_TYPE_NONE; + accept_event(); } else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS_RECT) { Dictionary painted = Dictionary(drag_painted_value); int terrain_set = int(painted["terrain_set"]); @@ -2312,6 +2349,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t } undo_redo->commit_action(true); drag_type = DRAG_TYPE_NONE; + accept_event(); } } } @@ -2348,6 +2386,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi } drag_last_pos = mm->get_position(); + accept_event(); } else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) { Dictionary painted = Dictionary(drag_painted_value); int terrain_set = int(painted["terrain_set"]); @@ -2400,14 +2439,15 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi } } drag_last_pos = mm->get_position(); + accept_event(); } } Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == MouseButton::LEFT) { + if (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT) { if (mb->is_pressed()) { - if (picker_button->is_pressed()) { + if (mb->get_button_index() == MouseButton::LEFT && picker_button->is_pressed()) { Vector3i tile = p_tile_atlas_view->get_alternative_tile_at_pos(mb->get_position()); Vector2i coords = Vector2i(tile.x, tile.y); int alternative_tile = tile.z; @@ -2437,6 +2477,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi terrain_set_property_editor->update_property(); _update_terrain_selector(); picker_button->set_pressed(false); + accept_event(); } } else { int terrain_set = int(dummy_object->get("terrain_set")); @@ -2446,93 +2487,106 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi Vector2i coords = Vector2i(tile.x, tile.y); int alternative_tile = tile.z; - TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile); + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile); - if (terrain_set == -1 || !tile_data || tile_data->get_terrain_set() != terrain_set) { - drag_type = DRAG_TYPE_PAINT_TERRAIN_SET; - drag_modified.clear(); - drag_painted_value = int(dummy_object->get("terrain_set")); - if (coords != TileSetSource::INVALID_ATLAS_COORDS) { - TileMapCell cell; - cell.source_id = 0; - cell.set_atlas_coords(coords); - cell.alternative_tile = alternative_tile; - Dictionary dict; - dict["terrain_set"] = tile_data->get_terrain_set(); - Array array; - for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { - TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); - array.push_back(tile_data->is_valid_terrain_peering_bit(bit) ? tile_data->get_terrain_peering_bit(bit) : -1); + if (terrain_set == -1 || !tile_data || tile_data->get_terrain_set() != terrain_set) { + // Paint terrain sets. + drag_type = DRAG_TYPE_PAINT_TERRAIN_SET; + drag_modified.clear(); + drag_painted_value = int(dummy_object->get("terrain_set")); + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { + TileMapCell cell; + cell.source_id = 0; + cell.set_atlas_coords(coords); + cell.alternative_tile = alternative_tile; + Dictionary dict; + dict["terrain_set"] = tile_data->get_terrain_set(); + Array array; + for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { + TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); + array.push_back(tile_data->is_valid_terrain_peering_bit(bit) ? tile_data->get_terrain_peering_bit(bit) : -1); + } + dict["terrain_peering_bits"] = array; + drag_modified[cell] = dict; + tile_data->set_terrain_set(drag_painted_value); } - dict["terrain_peering_bits"] = array; - drag_modified[cell] = dict; - tile_data->set_terrain_set(drag_painted_value); - } - drag_last_pos = mb->get_position(); - } else if (tile_data->get_terrain_set() == terrain_set) { - // Paint terrain bits. - drag_type = DRAG_TYPE_PAINT_TERRAIN_BITS; - drag_modified.clear(); - Dictionary painted_dict; - painted_dict["terrain_set"] = terrain_set; - painted_dict["terrain"] = terrain; - drag_painted_value = painted_dict; - - if (coords != TileSetSource::INVALID_ATLAS_COORDS) { - TileMapCell cell; - cell.source_id = 0; - cell.set_atlas_coords(coords); - cell.alternative_tile = alternative_tile; - - // Save the old terrain_set and terrains bits. - Dictionary dict; - dict["terrain_set"] = tile_data->get_terrain_set(); - dict["terrain"] = tile_data->get_terrain(); - Array array; - for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { - TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); - array.push_back(tile_data->is_valid_terrain_peering_bit(bit) ? tile_data->get_terrain_peering_bit(bit) : -1); + drag_last_pos = mb->get_position(); + accept_event(); + } else if (tile_data->get_terrain_set() == terrain_set) { + // Paint terrain bits. + if (mb->get_button_index() == MouseButton::RIGHT) { + terrain = -1; } - dict["terrain_peering_bits"] = array; - drag_modified[cell] = dict; + // Paint terrain bits. + drag_type = DRAG_TYPE_PAINT_TERRAIN_BITS; + drag_modified.clear(); + Dictionary painted_dict; + painted_dict["terrain_set"] = terrain_set; + painted_dict["terrain"] = terrain; + drag_painted_value = painted_dict; - // Set the terrain bit. - Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); - Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { + TileMapCell cell; + cell.source_id = 0; + cell.set_atlas_coords(coords); + cell.alternative_tile = alternative_tile; - Vector<Vector2> polygon = tile_set->get_terrain_polygon(terrain_set); - if (Geometry2D::is_point_in_polygon(mb->get_position() - position, polygon)) { - tile_data->set_terrain(terrain); - } - for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { - TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); - if (tile_set->is_valid_terrain_peering_bit(terrain_set, bit)) { - polygon = tile_set->get_terrain_peering_bit_polygon(terrain_set, bit); - if (Geometry2D::is_point_in_polygon(mb->get_position() - position, polygon)) { - tile_data->set_terrain_peering_bit(bit, terrain); + // Save the old terrain_set and terrains bits. + Dictionary dict; + dict["terrain_set"] = tile_data->get_terrain_set(); + dict["terrain"] = tile_data->get_terrain(); + Array array; + for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { + TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); + array.push_back(tile_data->is_valid_terrain_peering_bit(bit) ? tile_data->get_terrain_peering_bit(bit) : -1); + } + dict["terrain_peering_bits"] = array; + drag_modified[cell] = dict; + + // Set the terrain bit. + Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); + + Vector<Vector2> polygon = tile_set->get_terrain_polygon(terrain_set); + if (Geometry2D::is_point_in_polygon(mb->get_position() - position, polygon)) { + tile_data->set_terrain(terrain); + } + for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { + TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); + if (tile_set->is_valid_terrain_peering_bit(terrain_set, bit)) { + polygon = tile_set->get_terrain_peering_bit_polygon(terrain_set, bit); + if (Geometry2D::is_point_in_polygon(mb->get_position() - position, polygon)) { + tile_data->set_terrain_peering_bit(bit, terrain); + } } } } + drag_last_pos = mb->get_position(); + accept_event(); } - drag_last_pos = mb->get_position(); } } } else { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET) { undo_redo->create_action(TTR("Painting Tiles Property")); for (KeyValue<TileMapCell, Variant> &E : drag_modified) { Dictionary dict = E.value; Vector2i coords = E.key.get_atlas_coords(); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), dict["terrain_set"]); undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), drag_painted_value); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.key.alternative_tile), dict["terrain"]); - Array array = dict["terrain_peering_bits"]; - for (int i = 0; i < array.size(); i++) { - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), dict["terrain_set"]); + if (int(dict["terrain_set"]) >= 0) { + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.key.alternative_tile), dict["terrain"]); + Array array = dict["terrain_peering_bits"]; + for (int i = 0; i < array.size(); i++) { + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]); + } } } undo_redo->commit_action(false); drag_type = DRAG_TYPE_NONE; + accept_event(); } else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) { Dictionary painted = Dictionary(drag_painted_value); int terrain_set = int(painted["terrain_set"]); @@ -2556,6 +2610,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi } undo_redo->commit_action(false); drag_type = DRAG_TYPE_NONE; + accept_event(); } } } @@ -2579,8 +2634,6 @@ void TileDataTerrainsEditor::_notification(int p_what) { } TileDataTerrainsEditor::TileDataTerrainsEditor() { - undo_redo = EditorNode::get_undo_redo(); - label = memnew(Label); label->set_text(TTR("Painting:")); label->set_theme_type_variation("HeaderSmall"); @@ -2617,32 +2670,32 @@ TileDataTerrainsEditor::TileDataTerrainsEditor() { } TileDataTerrainsEditor::~TileDataTerrainsEditor() { - toolbar->queue_delete(); + toolbar->queue_free(); memdelete(dummy_object); } Variant TileDataNavigationEditor::_get_painted_value() { - Ref<NavigationPolygon> navigation_polygon; - navigation_polygon.instantiate(); + Ref<NavigationPolygon> nav_polygon; + nav_polygon.instantiate(); for (int i = 0; i < polygon_editor->get_polygon_count(); i++) { Vector<Vector2> polygon = polygon_editor->get_polygon(i); - navigation_polygon->add_outline(polygon); + nav_polygon->add_outline(polygon); } - navigation_polygon->make_polygons_from_outlines(); - return navigation_polygon; + nav_polygon->make_polygons_from_outlines(); + return nav_polygon; } void TileDataNavigationEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); - Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(navigation_layer); + Ref<NavigationPolygon> nav_polygon = tile_data->get_navigation_polygon(navigation_layer); polygon_editor->clear_polygons(); - if (navigation_polygon.is_valid()) { - for (int i = 0; i < navigation_polygon->get_outline_count(); i++) { - polygon_editor->add_polygon(navigation_polygon->get_outline(i)); + if (nav_polygon.is_valid()) { + for (int i = 0; i < nav_polygon->get_outline_count(); i++) { + polygon_editor->add_polygon(nav_polygon->get_outline(i)); } } polygon_editor->set_background(p_tile_set_atlas_source->get_texture(), p_tile_set_atlas_source->get_tile_texture_region(p_coords), p_tile_set_atlas_source->get_tile_effective_texture_offset(p_coords, p_alternative_tile), tile_data->get_flip_h(), tile_data->get_flip_v(), tile_data->get_transpose(), tile_data->get_modulate()); @@ -2651,8 +2704,8 @@ void TileDataNavigationEditor::_set_painted_value(TileSetAtlasSource *p_tile_set void TileDataNavigationEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) { TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); - Ref<NavigationPolygon> navigation_polygon = p_value; - tile_data->set_navigation_polygon(navigation_layer, navigation_polygon); + Ref<NavigationPolygon> nav_polygon = p_value; + tile_data->set_navigation_polygon(navigation_layer, nav_polygon); polygon_editor->set_background(p_tile_set_atlas_source->get_texture(), p_tile_set_atlas_source->get_tile_texture_region(p_coords), p_tile_set_atlas_source->get_tile_effective_texture_offset(p_coords, p_alternative_tile), tile_data->get_flip_h(), tile_data->get_flip_v(), tile_data->get_transpose(), tile_data->get_modulate()); } @@ -2664,6 +2717,7 @@ Variant TileDataNavigationEditor::_get_value(TileSetAtlasSource *p_tile_set_atla } void TileDataNavigationEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) { Vector2i coords = E.key.get_atlas_coords(); undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/navigation_layer_%d/polygon", coords.x, coords.y, E.key.alternative_tile, navigation_layer), E.value); @@ -2686,8 +2740,6 @@ void TileDataNavigationEditor::_notification(int p_what) { } TileDataNavigationEditor::TileDataNavigationEditor() { - undo_redo = EditorNode::get_undo_redo(); - polygon_editor = memnew(GenericTilePolygonEditor); polygon_editor->set_multiple_polygon_mode(true); add_child(polygon_editor); @@ -2700,9 +2752,9 @@ void TileDataNavigationEditor::draw_over_tile(CanvasItem *p_canvas_item, Transfo // Draw all shapes. RenderingServer::get_singleton()->canvas_item_add_set_transform(p_canvas_item->get_canvas_item(), p_transform); - Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(navigation_layer); - if (navigation_polygon.is_valid()) { - Vector<Vector2> verts = navigation_polygon->get_vertices(); + Ref<NavigationPolygon> nav_polygon = tile_data->get_navigation_polygon(navigation_layer); + if (nav_polygon.is_valid()) { + Vector<Vector2> verts = nav_polygon->get_vertices(); if (verts.size() < 3) { return; } @@ -2712,16 +2764,16 @@ void TileDataNavigationEditor::draw_over_tile(CanvasItem *p_canvas_item, Transfo color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color(); #endif // DEBUG_ENABLED if (p_selected) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); selection_color.a = 0.7; color = selection_color; } RandomPCG rand; - for (int i = 0; i < navigation_polygon->get_polygon_count(); i++) { + for (int i = 0; i < nav_polygon->get_polygon_count(); i++) { // An array of vertices for this polygon. - Vector<int> polygon = navigation_polygon->get_polygon(i); + Vector<int> polygon = nav_polygon->get_polygon(i); Vector<Vector2> vertices; vertices.resize(polygon.size()); for (int j = 0; j < polygon.size(); j++) { diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h index c1560138b2..e98e1d6701 100644 --- a/editor/plugins/tiles/tile_data_editors.h +++ b/editor/plugins/tiles/tile_data_editors.h @@ -39,6 +39,7 @@ #include "scene/gui/control.h" #include "scene/gui/label.h" +class MenuButton; class EditorUndoRedoManager; class TileDataEditor : public VBoxContainer { @@ -95,7 +96,6 @@ private: bool multiple_polygon_mode = false; bool use_undo_redo = true; - Ref<EditorUndoRedoManager> editor_undo_redo; // UI int hovered_polygon_index = -1; @@ -216,10 +216,9 @@ private: protected: DummyObject *dummy_object = memnew(DummyObject); - Ref<EditorUndoRedoManager> undo_redo; - StringName type; String property; + Variant::Type property_type; void _notification(int p_what); virtual Variant _get_painted_value(); @@ -237,6 +236,7 @@ public: virtual void draw_over_tile(CanvasItem *p_canvas_item, Transform2D p_transform, TileMapCell p_cell, bool p_selected = false) override; void setup_property_editor(Variant::Type p_type, String p_property, String p_label = "", Variant p_default_value = Variant()); + Variant::Type get_property_type(); TileDataDefaultEditor(); ~TileDataDefaultEditor(); @@ -281,8 +281,6 @@ private: virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override; protected: - Ref<EditorUndoRedoManager> undo_redo; - virtual void _tile_set_changed() override; void _notification(int p_what); @@ -316,8 +314,6 @@ class TileDataCollisionEditor : public TileDataDefaultEditor { virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override; protected: - Ref<EditorUndoRedoManager> undo_redo; - virtual void _tile_set_changed() override; void _notification(int p_what); @@ -368,8 +364,6 @@ protected: void _notification(int p_what); - Ref<EditorUndoRedoManager> undo_redo; - public: virtual Control *get_toolbar() override { return toolbar; }; virtual void forward_draw_over_atlas(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) override; @@ -401,8 +395,6 @@ private: virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override; protected: - Ref<EditorUndoRedoManager> undo_redo; - virtual void _tile_set_changed() override; void _notification(int p_what); diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 79230891f1..e622a0817a 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -35,6 +35,7 @@ #include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/plugins/canvas_item_editor_plugin.h" @@ -272,6 +273,7 @@ void TileMapEditorTilesPlugin::_patterns_item_list_gui_input(const Ref<InputEven if (ED_IS_SHORTCUT("tiles_editor/paste", p_event) && p_event->is_pressed() && !p_event->is_echo()) { select_last_pattern = true; int new_pattern_index = tile_set->get_patterns_count(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add TileSet pattern")); undo_redo->add_do_method(*tile_set, "add_pattern", tile_map_clipboard, new_pattern_index); undo_redo->add_undo_method(*tile_set, "remove_pattern", new_pattern_index); @@ -281,6 +283,7 @@ void TileMapEditorTilesPlugin::_patterns_item_list_gui_input(const Ref<InputEven if (ED_IS_SHORTCUT("tiles_editor/delete", p_event) && p_event->is_pressed() && !p_event->is_echo()) { Vector<int> selected = patterns_item_list->get_selected_items(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove TileSet patterns")); for (int i = 0; i < selected.size(); i++) { int pattern_index = selected[i]; @@ -396,7 +399,7 @@ void TileMapEditorTilesPlugin::_update_scenes_collection_view() { } // Icon size update. - int int_size = int(EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size")) * EDSCALE; + int int_size = int(EDITOR_GET("filesystem/file_dialog/thumbnail_size")) * EDSCALE; scene_tiles_list->set_fixed_icon_size(Vector2(int_size, int_size)); } @@ -460,7 +463,7 @@ void TileMapEditorTilesPlugin::_update_theme() { source_sort_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Sort"), SNAME("EditorIcons"))); select_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons"))); paint_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); - line_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons"))); + line_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Line"), SNAME("EditorIcons"))); rect_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Rectangle"), SNAME("EditorIcons"))); bucket_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Bucket"), SNAME("EditorIcons"))); @@ -511,6 +514,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p if (ED_IS_SHORTCUT("tiles_editor/cut", p_event)) { // Delete selected tiles. if (!tile_map_selection.is_empty()) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete tiles")); for (const Vector2i &E : tile_map_selection) { undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E, TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); @@ -542,6 +546,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p if (ED_IS_SHORTCUT("tiles_editor/delete", p_event)) { // Delete selected tiles. if (!tile_map_selection.is_empty()) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete tiles")); for (const Vector2i &E : tile_map_selection) { undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E, TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); @@ -739,7 +744,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over if (drag_type == DRAG_TYPE_MOVE || (drag_type == DRAG_TYPE_SELECT && !Input::get_singleton()->is_key_pressed(Key::CTRL) && !Input::get_singleton()->is_key_pressed(Key::SHIFT))) { // Do nothing } else { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); tile_map->draw_cells_outline(p_overlay, tile_map_selection, selection_color, xform); } @@ -844,9 +849,9 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over const int fading = 5; // Draw the lines of the grid behind the preview. - bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"); + bool display_grid = EDITOR_GET("editors/tiles_editor/display_grid"); if (display_grid) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); if (drawn_grid_rect.size.x > 0 && drawn_grid_rect.size.y > 0) { drawn_grid_rect = drawn_grid_rect.grow(fading); for (int x = drawn_grid_rect.position.x; x < (drawn_grid_rect.position.x + drawn_grid_rect.size.x); x++) { @@ -1233,6 +1238,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() { Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform(); Vector2 mpos = xform.affine_inverse().xform(CanvasItemEditor::get_singleton()->get_viewport_control()->get_local_mouse_position()); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (drag_type) { case DRAG_TYPE_SELECT: { undo_redo->create_action(TTR("Change selection")); @@ -1682,7 +1688,7 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() { } // Draw the selection. - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); for (const TileMapCell &E : tile_set_selection) { if (E.source_id == source_id && E.alternative_tile == 0) { @@ -1735,7 +1741,6 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_mouse_exited() { hovered_tile.source_id = TileSet::INVALID_SOURCE; hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; - tile_set_dragging_selection = false; tile_atlas_control->queue_redraw(); } @@ -1894,7 +1899,6 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_mouse_exited() { hovered_tile.source_id = TileSet::INVALID_SOURCE; hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; - tile_set_dragging_selection = false; alternative_tiles_control->queue_redraw(); } @@ -2004,6 +2008,7 @@ void TileMapEditorTilesPlugin::_set_source_sort(int p_sort) { } TilesEditorPlugin::get_singleton()->set_sorting_option(p_sort); _update_tile_set_sources_list(); + EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "tile_source_sort", p_sort); } void TileMapEditorTilesPlugin::_bind_methods() { @@ -2013,8 +2018,6 @@ void TileMapEditorTilesPlugin::_bind_methods() { } TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { - undo_redo = EditorNode::get_undo_redo(); - CanvasItemEditor::get_singleton() ->get_viewport_control() ->connect("mouse_exited", callable_mp(this, &TileMapEditorTilesPlugin::_mouse_exited_viewport)); @@ -2268,6 +2271,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { patterns_help_label = memnew(Label); patterns_help_label->set_text(TTR("Drag and drop or paste a TileMap selection here to store a pattern.")); + patterns_help_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); patterns_help_label->set_anchors_and_offsets_preset(Control::PRESET_CENTER); patterns_item_list->add_child(patterns_help_label); @@ -2349,27 +2353,27 @@ HashMap<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrain_path_o } HashMap<Vector2i, TileMapCell> output; - for (const KeyValue<Vector2i, TileSet::TerrainsPattern> &E : terrain_fill_output) { - if (painted_set.has(E.key)) { + for (const KeyValue<Vector2i, TileSet::TerrainsPattern> &kv : terrain_fill_output) { + if (painted_set.has(kv.key)) { // Paint a random tile with the correct terrain for the painted path. - output[E.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, E.value); + output[kv.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value); } else { // Avoids updating the painted path from the output if the new pattern is the same as before. - bool keep_old = false; - TileMapCell cell = tile_map->get_cell(tile_map_layer, E.key); + TileSet::TerrainsPattern in_map_terrain_pattern = TileSet::TerrainsPattern(*tile_set, p_terrain_set); + TileMapCell cell = tile_map->get_cell(tile_map_layer, kv.key); if (cell.source_id != TileSet::INVALID_SOURCE) { TileSetSource *source = *tile_set->get_source(cell.source_id); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { // Get tile data. TileData *tile_data = atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile); - if (tile_data && tile_data->get_terrains_pattern() == E.value) { - keep_old = true; + if (tile_data && tile_data->get_terrain_set() == p_terrain_set) { + in_map_terrain_pattern = tile_data->get_terrains_pattern(); } } } - if (!keep_old) { - output[E.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, E.value); + if (in_map_terrain_pattern != kv.value) { + output[kv.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value); } } } @@ -2396,24 +2400,28 @@ HashMap<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrain_patter } HashMap<Vector2i, TileMapCell> output; - for (const KeyValue<Vector2i, TileSet::TerrainsPattern> &E : terrain_fill_output) { - if (painted_set.has(E.key)) { + for (const KeyValue<Vector2i, TileSet::TerrainsPattern> &kv : terrain_fill_output) { + if (painted_set.has(kv.key)) { // Paint a random tile with the correct terrain for the painted path. - output[E.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, E.value); + output[kv.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value); } else { // Avoids updating the painted path from the output if the new pattern is the same as before. - TileMapCell cell = tile_map->get_cell(tile_map_layer, E.key); + TileSet::TerrainsPattern in_map_terrain_pattern = TileSet::TerrainsPattern(*tile_set, p_terrain_set); + TileMapCell cell = tile_map->get_cell(tile_map_layer, kv.key); if (cell.source_id != TileSet::INVALID_SOURCE) { TileSetSource *source = *tile_set->get_source(cell.source_id); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { // Get tile data. TileData *tile_data = atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile); - if (tile_data && !(tile_data->get_terrains_pattern() == E.value)) { - output[E.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, E.value); + if (tile_data && tile_data->get_terrain_set() == p_terrain_set) { + in_map_terrain_pattern = tile_data->get_terrains_pattern(); } } } + if (in_map_terrain_pattern != kv.value) { + output[kv.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value); + } } } return output; @@ -2430,20 +2438,16 @@ HashMap<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_line(Vector2i return HashMap<Vector2i, TileMapCell>(); } - if (selected_type == SELECTED_TYPE_CONNECT) { - return _draw_terrain_path_or_connect(TileMapEditor::get_line(tile_map, p_start_cell, p_end_cell), selected_terrain_set, selected_terrain, true); - } else if (selected_type == SELECTED_TYPE_PATH) { - return _draw_terrain_path_or_connect(TileMapEditor::get_line(tile_map, p_start_cell, p_end_cell), selected_terrain_set, selected_terrain, false); - } else { // SELECTED_TYPE_PATTERN - TileSet::TerrainsPattern terrains_pattern; - if (p_erase) { - terrains_pattern = TileSet::TerrainsPattern(*tile_set, selected_terrain_set); - } else { - terrains_pattern = selected_terrains_pattern; + if (p_erase) { + return _draw_terrain_pattern(TileMapEditor::get_line(tile_map, p_start_cell, p_end_cell), selected_terrain_set, TileSet::TerrainsPattern(*tile_set, selected_terrain_set)); + } else { + if (selected_type == SELECTED_TYPE_CONNECT) { + return _draw_terrain_path_or_connect(TileMapEditor::get_line(tile_map, p_start_cell, p_end_cell), selected_terrain_set, selected_terrain, true); + } else if (selected_type == SELECTED_TYPE_PATH) { + return _draw_terrain_path_or_connect(TileMapEditor::get_line(tile_map, p_start_cell, p_end_cell), selected_terrain_set, selected_terrain, false); + } else { // SELECTED_TYPE_PATTERN + return _draw_terrain_pattern(TileMapEditor::get_line(tile_map, p_start_cell, p_end_cell), selected_terrain_set, selected_terrains_pattern); } - - Vector<Vector2i> line = TileMapEditor::get_line(tile_map, p_start_cell, p_end_cell); - return _draw_terrain_pattern(line, selected_terrain_set, terrains_pattern); } } @@ -2470,16 +2474,14 @@ HashMap<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_rect(Vector2i } } - if (selected_type == SELECTED_TYPE_CONNECT || selected_type == SELECTED_TYPE_PATH) { - return _draw_terrain_path_or_connect(to_draw, selected_terrain_set, selected_terrain, true); - } else { // SELECTED_TYPE_PATTERN - TileSet::TerrainsPattern terrains_pattern; - if (p_erase) { - terrains_pattern = TileSet::TerrainsPattern(*tile_set, selected_terrain_set); - } else { - terrains_pattern = selected_terrains_pattern; + if (p_erase) { + return _draw_terrain_pattern(to_draw, selected_terrain_set, TileSet::TerrainsPattern(*tile_set, selected_terrain_set)); + } else { + if (selected_type == SELECTED_TYPE_CONNECT || selected_type == SELECTED_TYPE_PATH) { + return _draw_terrain_path_or_connect(to_draw, selected_terrain_set, selected_terrain, true); + } else { // SELECTED_TYPE_PATTERN + return _draw_terrain_pattern(to_draw, selected_terrain_set, selected_terrains_pattern); } - return _draw_terrain_pattern(to_draw, selected_terrain_set, terrains_pattern); } } @@ -2611,16 +2613,14 @@ HashMap<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_bucket_fill(Ve cells_to_draw_as_vector.append(cell); } - if (selected_type == SELECTED_TYPE_CONNECT || selected_type == SELECTED_TYPE_PATH) { - return _draw_terrain_path_or_connect(cells_to_draw_as_vector, selected_terrain_set, selected_terrain, true); - } else { // SELECTED_TYPE_PATTERN - TileSet::TerrainsPattern terrains_pattern; - if (p_erase) { - terrains_pattern = TileSet::TerrainsPattern(*tile_set, selected_terrain_set); - } else { - terrains_pattern = selected_terrains_pattern; + if (p_erase) { + return _draw_terrain_pattern(cells_to_draw_as_vector, selected_terrain_set, TileSet::TerrainsPattern(*tile_set, selected_terrain_set)); + } else { + if (selected_type == SELECTED_TYPE_CONNECT || selected_type == SELECTED_TYPE_PATH) { + return _draw_terrain_path_or_connect(cells_to_draw_as_vector, selected_terrain_set, selected_terrain, true); + } else { // SELECTED_TYPE_PATTERN + return _draw_terrain_pattern(cells_to_draw_as_vector, selected_terrain_set, selected_terrains_pattern); } - return _draw_terrain_pattern(cells_to_draw_as_vector, selected_terrain_set, terrains_pattern); } } @@ -2638,6 +2638,7 @@ void TileMapEditorTerrainsPlugin::_stop_dragging() { Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform(); Vector2 mpos = xform.affine_inverse().xform(CanvasItemEditor::get_singleton()->get_viewport_control()->get_local_mouse_position()); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (drag_type) { case DRAG_TYPE_PICK: { Vector2i coords = tile_map->local_to_map(mpos); @@ -3028,9 +3029,9 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o const int fading = 5; // Draw the lines of the grid behind the preview. - bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"); + bool display_grid = EDITOR_GET("editors/tiles_editor/display_grid"); if (display_grid) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); if (drawn_grid_rect.size.x > 0 && drawn_grid_rect.size.y > 0) { drawn_grid_rect = drawn_grid_rect.grow(fading); for (int x = drawn_grid_rect.position.x; x < (drawn_grid_rect.position.x + drawn_grid_rect.size.x); x++) { @@ -3200,10 +3201,10 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() { TreeItem *selected_tree_item = terrains_tree->get_selected(); if (selected_tree_item && selected_tree_item->get_metadata(0)) { Dictionary metadata_dict = selected_tree_item->get_metadata(0); - int selected_terrain_set = metadata_dict["terrain_set"]; - int selected_terrain_id = metadata_dict["terrain_id"]; - ERR_FAIL_INDEX(selected_terrain_set, tile_set->get_terrain_sets_count()); - ERR_FAIL_INDEX(selected_terrain_id, tile_set->get_terrains_count(selected_terrain_set)); + int sel_terrain_set = metadata_dict["terrain_set"]; + int sel_terrain_id = metadata_dict["terrain_id"]; + ERR_FAIL_INDEX(sel_terrain_set, tile_set->get_terrain_sets_count()); + ERR_FAIL_INDEX(sel_terrain_id, tile_set->get_terrains_count(sel_terrain_set)); // Add the two first generic modes int item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_theme_icon(SNAME("TerrainConnect"), SNAME("EditorIcons"))); @@ -3221,13 +3222,13 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() { // Sort the items in a map by the number of corresponding terrains. RBMap<int, RBSet<TileSet::TerrainsPattern>> sorted; - for (const TileSet::TerrainsPattern &E : per_terrain_terrains_patterns[selected_terrain_set][selected_terrain_id]) { + for (const TileSet::TerrainsPattern &E : per_terrain_terrains_patterns[sel_terrain_set][sel_terrain_id]) { // Count the number of matching sides/terrains. int count = 0; for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); - if (tile_set->is_valid_terrain_peering_bit(selected_terrain_set, bit) && E.get_terrain_peering_bit(bit) == selected_terrain_id) { + if (tile_set->is_valid_terrain_peering_bit(sel_terrain_set, bit) && E.get_terrain_peering_bit(bit) == sel_terrain_id) { count++; } } @@ -3244,7 +3245,7 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() { bool transpose = false; double max_probability = -1.0; - for (const TileMapCell &cell : tile_set->get_tiles_for_terrains_pattern(selected_terrain_set, terrains_pattern)) { + for (const TileMapCell &cell : tile_set->get_tiles_for_terrains_pattern(sel_terrain_set, terrains_pattern)) { Ref<TileSetSource> source = tile_set->get_source(cell.source_id); Ref<TileSetAtlasSource> atlas_source = source; @@ -3286,7 +3287,7 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() { void TileMapEditorTerrainsPlugin::_update_theme() { paint_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); - line_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons"))); + line_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Line"), SNAME("EditorIcons"))); rect_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Rectangle"), SNAME("EditorIcons"))); bucket_tool_button->set_icon(main_vbox_container->get_theme_icon(SNAME("Bucket"), SNAME("EditorIcons"))); @@ -3308,8 +3309,6 @@ void TileMapEditorTerrainsPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_la } TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() { - undo_redo = EditorNode::get_undo_redo(); - main_vbox_container = memnew(VBoxContainer); main_vbox_container->connect("tree_entered", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_theme)); main_vbox_container->connect("theme_changed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_theme)); @@ -3425,7 +3424,7 @@ void TileMapEditor::_notification(int p_what) { warning_pattern_texture = get_theme_icon(SNAME("WarningPattern"), SNAME("EditorIcons")); advanced_menu_button->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons"))); toggle_grid_button->set_icon(get_theme_icon(SNAME("Grid"), SNAME("EditorIcons"))); - toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid")); + toggle_grid_button->set_pressed(EDITOR_GET("editors/tiles_editor/display_grid")); toggle_highlight_selected_layer_button->set_icon(get_theme_icon(SNAME("TileMapHighlightSelected"), SNAME("EditorIcons"))); } break; @@ -3440,7 +3439,7 @@ void TileMapEditor::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid")); + toggle_grid_button->set_pressed(EDITOR_GET("editors/tiles_editor/display_grid")); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -3483,6 +3482,7 @@ void TileMapEditor::_advanced_menu_button_id_pressed(int p_id) { } if (p_id == 0) { // Replace Tile Proxies + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Replace Tiles with Proxies")); for (int layer_index = 0; layer_index < tile_map->get_layers_count(); layer_index++) { TypedArray<Vector2i> used_cells = tile_map->get_used_cells(layer_index); @@ -3699,8 +3699,8 @@ void TileMapEditor::_update_layers_selection() { } void TileMapEditor::_move_tile_map_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) { - Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); - ERR_FAIL_COND(undo_redo.is_null()); + Ref<EditorUndoRedoManager> undo_redo_man = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); + ERR_FAIL_COND(undo_redo_man.is_null()); TileMap *tile_map = Object::cast_to<TileMap>(p_edited); if (!tile_map) { @@ -3731,12 +3731,12 @@ void TileMapEditor::_move_tile_map_array_element(Object *p_undo_redo, Object *p_ end = MIN(MAX(p_from_index, p_to_pos) + 1, end); } -#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property)); +#define ADD_UNDO(obj, property) undo_redo_man->add_undo_property(obj, property, obj->get(property)); // Save layers' properties. if (p_from_index < 0) { - undo_redo->add_undo_method(tile_map, "remove_layer", p_to_pos < 0 ? tile_map->get_layers_count() : p_to_pos); + undo_redo_man->add_undo_method(tile_map, "remove_layer", p_to_pos < 0 ? tile_map->get_layers_count() : p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_undo_method(tile_map, "add_layer", p_from_index); + undo_redo_man->add_undo_method(tile_map, "add_layer", p_from_index); } List<PropertyInfo> properties; @@ -3762,11 +3762,11 @@ void TileMapEditor::_move_tile_map_array_element(Object *p_undo_redo, Object *p_ #undef ADD_UNDO if (p_from_index < 0) { - undo_redo->add_do_method(tile_map, "add_layer", p_to_pos); + undo_redo_man->add_do_method(tile_map, "add_layer", p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_do_method(tile_map, "remove_layer", p_from_index); + undo_redo_man->add_do_method(tile_map, "remove_layer", p_from_index); } else { - undo_redo->add_do_method(tile_map, "move_layer", p_from_index, p_to_pos); + undo_redo_man->add_do_method(tile_map, "move_layer", p_from_index, p_to_pos); } } @@ -3883,9 +3883,9 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { } // Draw the grid. - bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"); + bool display_grid = EDITOR_GET("editors/tiles_editor/display_grid"); if (display_grid) { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) { for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) { Vector2i pos_in_rect = Vector2i(x, y) - displayed_rect.position; @@ -3956,8 +3956,6 @@ void TileMapEditor::edit(TileMap *p_tile_map) { } TileMapEditor::TileMapEditor() { - undo_redo = EditorNode::get_undo_redo(); - set_process_internal(true); // Shortcuts. diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index 9a47d8bbc4..ad27795437 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -47,8 +47,6 @@ #include "scene/gui/tab_bar.h" #include "scene/gui/tree.h" -class EditorUndoRedoManager; - class TileMapEditorPlugin : public Object { public: struct TabData { @@ -70,7 +68,6 @@ class TileMapEditorTilesPlugin : public TileMapEditorPlugin { GDCLASS(TileMapEditorTilesPlugin, TileMapEditorPlugin); private: - Ref<EditorUndoRedoManager> undo_redo; ObjectID tile_map_id; int tile_map_layer = -1; virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer) override; @@ -223,7 +220,6 @@ class TileMapEditorTerrainsPlugin : public TileMapEditorPlugin { GDCLASS(TileMapEditorTerrainsPlugin, TileMapEditorPlugin); private: - Ref<EditorUndoRedoManager> undo_redo; ObjectID tile_map_id; int tile_map_layer = -1; virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer) override; @@ -317,7 +313,6 @@ class TileMapEditor : public VBoxContainer { GDCLASS(TileMapEditor, VBoxContainer); private: - Ref<EditorUndoRedoManager> undo_redo; bool tileset_changed_needs_update = false; ObjectID tile_map_id; int tile_map_layer = -1; diff --git a/editor/plugins/tiles/tile_proxies_manager_dialog.cpp b/editor/plugins/tiles/tile_proxies_manager_dialog.cpp index 9e4c29fa79..7058b28e68 100644 --- a/editor/plugins/tiles/tile_proxies_manager_dialog.cpp +++ b/editor/plugins/tiles/tile_proxies_manager_dialog.cpp @@ -32,7 +32,9 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "scene/gui/separator.h" void TileProxiesManagerDialog::_right_clicked(int p_item, Vector2 p_local_mouse_pos, Object *p_item_list, MouseButton p_mouse_button_index) { if (p_mouse_button_index != MouseButton::RIGHT) { @@ -53,6 +55,7 @@ void TileProxiesManagerDialog::_menu_id_pressed(int p_id) { } void TileProxiesManagerDialog::_delete_selected_bindings() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Tile Proxies")); Vector<int> source_level_selected = source_level_list->get_selected_items(); @@ -152,6 +155,7 @@ void TileProxiesManagerDialog::_property_changed(const String &p_path, const Var } void TileProxiesManagerDialog::_add_button_pressed() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (from.source_id != TileSet::INVALID_SOURCE && to.source_id != TileSet::INVALID_SOURCE) { Vector2i from_coords = from.get_atlas_coords(); Vector2i to_coords = to.get_atlas_coords(); @@ -192,6 +196,7 @@ void TileProxiesManagerDialog::_add_button_pressed() { } void TileProxiesManagerDialog::_clear_invalid_button_pressed() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete All Invalid Tile Proxies")); undo_redo->add_do_method(*tile_set, "cleanup_invalid_tile_proxies"); @@ -219,6 +224,7 @@ void TileProxiesManagerDialog::_clear_invalid_button_pressed() { } void TileProxiesManagerDialog::_clear_all_button_pressed() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete All Tile Proxies")); undo_redo->add_do_method(*tile_set, "clear_tile_proxies"); @@ -299,6 +305,7 @@ void TileProxiesManagerDialog::_unhandled_key_input(Ref<InputEvent> p_event) { } void TileProxiesManagerDialog::cancel_pressed() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); for (int i = 0; i < commited_actions_count; i++) { undo_redo->undo(); } @@ -318,8 +325,6 @@ void TileProxiesManagerDialog::update_tile_set(Ref<TileSet> p_tile_set) { } TileProxiesManagerDialog::TileProxiesManagerDialog() { - undo_redo = EditorNode::get_singleton()->get_undo_redo(); - // Tile proxy management window. set_title(TTR("Tile Proxies Management")); set_process_unhandled_key_input(true); diff --git a/editor/plugins/tiles/tile_proxies_manager_dialog.h b/editor/plugins/tiles/tile_proxies_manager_dialog.h index 511e442a10..e2363eb809 100644 --- a/editor/plugins/tiles/tile_proxies_manager_dialog.h +++ b/editor/plugins/tiles/tile_proxies_manager_dialog.h @@ -36,6 +36,8 @@ #include "scene/gui/dialogs.h" #include "scene/gui/item_list.h" +class EditorUndoRedoManager; + class TileProxiesManagerDialog : public ConfirmationDialog { GDCLASS(TileProxiesManagerDialog, ConfirmationDialog); @@ -43,8 +45,6 @@ private: int commited_actions_count = 0; Ref<TileSet> tile_set; - Ref<EditorUndoRedoManager> undo_redo; - TileMapCell from; TileMapCell to; diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 228e475083..fc13393582 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -33,10 +33,12 @@ #include "tiles_editor_plugin.h" #include "editor/editor_inspector.h" +#include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" #include "editor/progress_dialog.h" -#include "editor/editor_node.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/control.h" @@ -401,7 +403,7 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<Pro if (all_alternatve_id_zero) { p_list->push_back(PropertyInfo(Variant::NIL, "Animation", PROPERTY_HINT_NONE, "animation_", PROPERTY_USAGE_GROUP)); p_list->push_back(PropertyInfo(Variant::INT, "animation_columns", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::VECTOR2I, "animation_separation", PROPERTY_HINT_NONE, "suffix:px")); + p_list->push_back(PropertyInfo(Variant::VECTOR2I, "animation_separation", PROPERTY_HINT_NONE, "")); p_list->push_back(PropertyInfo(Variant::FLOAT, "animation_speed", PROPERTY_HINT_NONE, "")); p_list->push_back(PropertyInfo(Variant::INT, "animation_frames_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Frames,animation_frame_")); // Not optimal, but returns value for the first tile. This is similar to what MultiNodeEdit does. @@ -541,11 +543,13 @@ void TileSetAtlasSourceEditor::_update_source_inspector() { void TileSetAtlasSourceEditor::_update_fix_selected_and_hovered_tiles() { // Fix selected. - for (RBSet<TileSelection>::Element *E = selection.front(); E; E = E->next()) { + for (RBSet<TileSelection>::Element *E = selection.front(); E;) { + RBSet<TileSelection>::Element *N = E->next(); TileSelection selected = E->get(); if (!tile_set_atlas_source->has_tile(selected.tile) || !tile_set_atlas_source->has_alternative_tile(selected.tile, selected.alternative)) { selection.erase(E); } + E = N; } // Fix hovered. @@ -561,9 +565,9 @@ void TileSetAtlasSourceEditor::_update_fix_selected_and_hovered_tiles() { void TileSetAtlasSourceEditor::_update_atlas_source_inspector() { // Update visibility. - bool visible = tools_button_group->get_pressed_button() == tool_setup_atlas_source_button; - atlas_source_inspector_label->set_visible(visible); - atlas_source_inspector->set_visible(visible); + bool inspector_visible = tools_button_group->get_pressed_button() == tool_setup_atlas_source_button; + atlas_source_inspector_label->set_visible(inspector_visible); + atlas_source_inspector->set_visible(inspector_visible); } void TileSetAtlasSourceEditor::_update_tile_inspector() { @@ -671,7 +675,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } } for (int i = tile_set->get_occlusion_layers_count(); tile_data_editors.has(vformat("occlusion_layer_%d", i)); i++) { - tile_data_editors[vformat("occlusion_layer_%d", i)]->queue_delete(); + tile_data_editors[vformat("occlusion_layer_%d", i)]->queue_free(); tile_data_editors.erase(vformat("occlusion_layer_%d", i)); } @@ -710,7 +714,7 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } } for (int i = tile_set->get_physics_layers_count(); tile_data_editors.has(vformat("physics_layer_%d", i)); i++) { - tile_data_editors[vformat("physics_layer_%d", i)]->queue_delete(); + tile_data_editors[vformat("physics_layer_%d", i)]->queue_free(); tile_data_editors.erase(vformat("physics_layer_%d", i)); } @@ -728,29 +732,40 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } } for (int i = tile_set->get_navigation_layers_count(); tile_data_editors.has(vformat("navigation_layer_%d", i)); i++) { - tile_data_editors[vformat("navigation_layer_%d", i)]->queue_delete(); + tile_data_editors[vformat("navigation_layer_%d", i)]->queue_free(); tile_data_editors.erase(vformat("navigation_layer_%d", i)); } // --- Custom Data --- ADD_TILE_DATA_EDITOR_GROUP("Custom Data"); for (int i = 0; i < tile_set->get_custom_data_layers_count(); i++) { - if (tile_set->get_custom_data_layer_name(i).is_empty()) { - ADD_TILE_DATA_EDITOR(group, vformat("Custom Data %d", i), vformat("custom_data_%d", i)); + String editor_name = vformat("custom_data_%d", i); + String prop_name = tile_set->get_custom_data_layer_name(i); + Variant::Type prop_type = tile_set->get_custom_data_layer_type(i); + + if (prop_name.is_empty()) { + ADD_TILE_DATA_EDITOR(group, vformat("Custom Data %d", i), editor_name); } else { - ADD_TILE_DATA_EDITOR(group, tile_set->get_custom_data_layer_name(i), vformat("custom_data_%d", i)); + ADD_TILE_DATA_EDITOR(group, prop_name, editor_name); } - if (!tile_data_editors.has(vformat("custom_data_%d", i))) { + + // If the type of the edited property has been changed, delete the + // editor and create a new one. + if (tile_data_editors.has(editor_name) && ((TileDataDefaultEditor *)tile_data_editors[editor_name])->get_property_type() != prop_type) { + tile_data_editors[vformat("custom_data_%d", i)]->queue_free(); + tile_data_editors.erase(vformat("custom_data_%d", i)); + } + if (!tile_data_editors.has(editor_name)) { TileDataDefaultEditor *tile_data_custom_data_editor = memnew(TileDataDefaultEditor()); tile_data_custom_data_editor->hide(); - tile_data_custom_data_editor->setup_property_editor(tile_set->get_custom_data_layer_type(i), vformat("custom_data_%d", i), tile_set->get_custom_data_layer_name(i)); + tile_data_custom_data_editor->setup_property_editor(prop_type, editor_name, prop_name); tile_data_custom_data_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); tile_data_custom_data_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); - tile_data_editors[vformat("custom_data_%d", i)] = tile_data_custom_data_editor; + tile_data_editors[editor_name] = tile_data_custom_data_editor; } } for (int i = tile_set->get_custom_data_layers_count(); tile_data_editors.has(vformat("custom_data_%d", i)); i++) { - tile_data_editors[vformat("custom_data_%d", i)]->queue_delete(); + tile_data_editors[vformat("custom_data_%d", i)]->queue_free(); tile_data_editors.erase(vformat("custom_data_%d", i)); } @@ -884,7 +899,7 @@ void TileSetAtlasSourceEditor::_update_atlas_view() { // Create a bunch of buttons to add alternative tiles. for (int i = 0; i < alternative_tiles_control->get_child_count(); i++) { - alternative_tiles_control->get_child(i)->queue_delete(); + alternative_tiles_control->get_child(i)->queue_free(); } Vector2i pos; @@ -1310,6 +1325,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven } void TileSetAtlasSourceEditor::_end_dragging() { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (drag_type) { case DRAG_TYPE_CREATE_TILES: undo_redo->create_action(TTR("Create tiles")); @@ -1540,6 +1556,8 @@ HashMap<Vector2i, List<const PropertyInfo *>> TileSetAtlasSourceEditor::_group_p } void TileSetAtlasSourceEditor::_menu_option(int p_option) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + switch (p_option) { case TILE_DELETE: { List<PropertyInfo> list; @@ -1667,7 +1685,7 @@ Array TileSetAtlasSourceEditor::_get_selection_as_array() { void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { // Colors. - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); // Draw the selected tile. @@ -1958,7 +1976,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_mouse_exited() { } void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() { - Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); // Update the hovered alternative tile. @@ -1997,7 +2015,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { continue; } Rect2i rect = tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); - Vector2 position = rect.get_center(); + Vector2 position = rect.get_center() + tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); Transform2D xform = alternative_tiles_control->get_parent_control()->get_transform(); xform.translate_local(position); @@ -2021,7 +2039,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { continue; } Rect2i rect = tile_atlas_view->get_alternative_tile_rect(E.tile, E.alternative); - Vector2 position = rect.get_center(); + Vector2 position = rect.get_center() + tile_set_atlas_source->get_tile_effective_texture_offset(E.tile, E.alternative); Transform2D xform = alternative_tiles_control->get_parent_control()->get_transform(); xform.translate_local(position); @@ -2043,6 +2061,13 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { } void TileSetAtlasSourceEditor::_tile_set_changed() { + if (tile_set->get_source_count() == 0) { + // No sources, so nothing to do here anymore. + tile_set->disconnect("changed", callable_mp(this, &TileSetAtlasSourceEditor::_tile_set_changed)); + tile_set = Ref<TileSet>(); + return; + } + tile_set_changed_needs_update = true; } @@ -2060,14 +2085,14 @@ void TileSetAtlasSourceEditor::_atlas_source_proxy_object_changed(String p_what) } void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) { - Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); - ERR_FAIL_COND(!undo_redo.is_valid()); + Ref<EditorUndoRedoManager> undo_redo_man = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); + ERR_FAIL_COND(!undo_redo_man.is_valid()); -#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property)); +#define ADD_UNDO(obj, property) undo_redo_man->add_undo_property(obj, property, obj->get(property)); AtlasTileProxyObject *tile_data_proxy = Object::cast_to<AtlasTileProxyObject>(p_edited); if (tile_data_proxy) { - UndoRedo *internal_undo_redo = undo_redo->get_history_for_object(tile_data_proxy).undo_redo; + UndoRedo *internal_undo_redo = undo_redo_man->get_history_for_object(tile_data_proxy).undo_redo; internal_undo_redo->start_force_keep_in_merge_ends(); Vector<String> components = String(p_property).split("/", true, 2); @@ -2100,7 +2125,7 @@ void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo TileSetAtlasSource *atlas_source = atlas_source_proxy->get_edited(); ERR_FAIL_COND(!atlas_source); - UndoRedo *internal_undo_redo = undo_redo->get_history_for_object(atlas_source).undo_redo; + UndoRedo *internal_undo_redo = undo_redo_man->get_history_for_object(atlas_source).undo_redo; internal_undo_redo->start_force_keep_in_merge_ends(); PackedVector2Array arr; @@ -2191,6 +2216,7 @@ void TileSetAtlasSourceEditor::_auto_create_tiles() { Vector2i separation = tile_set_atlas_source->get_separation(); Vector2i texture_region_size = tile_set_atlas_source->get_texture_region_size(); Size2i grid_size = tile_set_atlas_source->get_atlas_grid_size(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Create tiles in non-transparent texture regions")); for (int y = 0; y < grid_size.y; y++) { for (int x = 0; x < grid_size.x; x++) { @@ -2236,6 +2262,7 @@ void TileSetAtlasSourceEditor::_auto_remove_tiles() { Vector2i texture_region_size = tile_set_atlas_source->get_texture_region_size(); Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove tiles in fully transparent texture regions")); List<PropertyInfo> list; @@ -2329,8 +2356,6 @@ void TileSetAtlasSourceEditor::_bind_methods() { } TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { - undo_redo = EditorNode::get_undo_redo(); - set_process_unhandled_key_input(true); set_process_internal(true); @@ -2359,7 +2384,6 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tile_proxy_object->connect("changed", callable_mp(this, &TileSetAtlasSourceEditor::_tile_proxy_object_changed)); tile_inspector = memnew(EditorInspector); - tile_inspector->set_undo_redo(undo_redo); tile_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); tile_inspector->edit(tile_proxy_object); tile_inspector->set_use_folding(true); @@ -2407,7 +2431,6 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { atlas_source_proxy_object->connect("changed", callable_mp(this, &TileSetAtlasSourceEditor::_atlas_source_proxy_object_changed)); atlas_source_inspector = memnew(EditorInspector); - atlas_source_inspector->set_undo_redo(undo_redo); atlas_source_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); atlas_source_inspector->edit(atlas_source_proxy_object); middle_vbox_container->add_child(atlas_source_inspector); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h index badb702e29..14e120e2a3 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.h +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h @@ -37,7 +37,10 @@ #include "scene/gui/split_container.h" #include "scene/resources/tile_set.h" +class Popup; class TileSet; +class Tree; +class VSeparator; class TileSetAtlasSourceEditor : public HBoxContainer { GDCLASS(TileSetAtlasSourceEditor, HBoxContainer); @@ -114,8 +117,6 @@ private: TileSetAtlasSource *tile_set_atlas_source = nullptr; int tile_set_atlas_source_id = TileSet::INVALID_SOURCE; - Ref<EditorUndoRedoManager> undo_redo; - bool tile_set_changed_needs_update = false; // -- Properties painting -- diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index 80a8318bbb..b24c5059b0 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -36,6 +36,7 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "scene/gui/box_container.h" @@ -66,6 +67,7 @@ void TileSetEditor::_drop_data_fw(const Point2 &p_point, const Variant &p_data, // Actually create the new source. Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource); atlas_source->set_texture(resource); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add a new atlas source")); undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id); undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size()); @@ -256,6 +258,7 @@ void TileSetEditor::_source_delete_pressed() { Ref<TileSetSource> source = tile_set->get_source(to_delete); // Remove the source. + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove source")); undo_redo->add_do_method(*tile_set, "remove_source", to_delete); undo_redo->add_undo_method(*tile_set, "add_source", source, to_delete); @@ -274,6 +277,7 @@ void TileSetEditor::_source_add_id_pressed(int p_id_pressed) { Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource); // Add a new source. + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add atlas source")); undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id); undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size()); @@ -288,6 +292,7 @@ void TileSetEditor::_source_add_id_pressed(int p_id_pressed) { Ref<TileSetScenesCollectionSource> scene_collection_source = memnew(TileSetScenesCollectionSource); // Add a new source. + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add atlas source")); undo_redo->add_do_method(*tile_set, "add_source", scene_collection_source, source_id); undo_redo->add_undo_method(*tile_set, "remove_source", source_id); @@ -329,6 +334,7 @@ void TileSetEditor::_set_source_sort(int p_sort) { } } _update_sources_list(old_selected); + EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "tile_source_sort", p_sort); } void TileSetEditor::_notification(int p_what) { @@ -360,6 +366,7 @@ void TileSetEditor::_patterns_item_list_gui_input(const Ref<InputEvent> &p_event if (ED_IS_SHORTCUT("tiles_editor/delete", p_event) && p_event->is_pressed() && !p_event->is_echo()) { Vector<int> selected = patterns_item_list->get_selected_items(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove TileSet patterns")); for (int i = 0; i < selected.size(); i++) { int pattern_index = selected[i]; @@ -406,11 +413,11 @@ void TileSetEditor::_tab_changed(int p_tab_changed) { } void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) { - Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); - ERR_FAIL_COND(undo_redo.is_null()); + Ref<EditorUndoRedoManager> undo_redo_man = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); + ERR_FAIL_COND(undo_redo_man.is_null()); - TileSet *tile_set = Object::cast_to<TileSet>(p_edited); - if (!tile_set) { + TileSet *ed_tile_set = Object::cast_to<TileSet>(p_edited); + if (!ed_tile_set) { return; } @@ -420,18 +427,18 @@ void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_ int begin = 0; int end; if (p_array_prefix == "occlusion_layer_") { - end = tile_set->get_occlusion_layers_count(); + end = ed_tile_set->get_occlusion_layers_count(); } else if (p_array_prefix == "physics_layer_") { - end = tile_set->get_physics_layers_count(); + end = ed_tile_set->get_physics_layers_count(); } else if (p_array_prefix == "terrain_set_") { - end = tile_set->get_terrain_sets_count(); + end = ed_tile_set->get_terrain_sets_count(); } else if (components.size() >= 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "terrain_") { int terrain_set = components[0].trim_prefix("terrain_set_").to_int(); - end = tile_set->get_terrains_count(terrain_set); + end = ed_tile_set->get_terrains_count(terrain_set); } else if (p_array_prefix == "navigation_layer_") { - end = tile_set->get_navigation_layers_count(); + end = ed_tile_set->get_navigation_layers_count(); } else if (p_array_prefix == "custom_data_layer_") { - end = tile_set->get_custom_data_layers_count(); + end = ed_tile_set->get_custom_data_layers_count(); } else { ERR_FAIL_MSG("Invalid array prefix for TileSet."); } @@ -451,10 +458,10 @@ void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_ end = MIN(MAX(p_from_index, p_to_pos) + 1, end); } -#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property)); +#define ADD_UNDO(obj, property) undo_redo_man->add_undo_property(obj, property, obj->get(property)); // Save layers' properties. List<PropertyInfo> properties; - tile_set->get_property_list(&properties); + ed_tile_set->get_property_list(&properties); for (PropertyInfo pi : properties) { if (pi.name.begins_with(p_array_prefix)) { String str = pi.name.trim_prefix(p_array_prefix); @@ -468,17 +475,17 @@ void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_ if (to_char_index > 0) { int array_index = str.left(to_char_index).to_int(); if (array_index >= begin && array_index < end) { - ADD_UNDO(tile_set, pi.name); + ADD_UNDO(ed_tile_set, pi.name); } } } } // Save properties for TileSetAtlasSources tile data - for (int i = 0; i < tile_set->get_source_count(); i++) { - int source_id = tile_set->get_source_id(i); + for (int i = 0; i < ed_tile_set->get_source_count(); i++) { + int source_id = ed_tile_set->get_source_id(i); - Ref<TileSetAtlasSource> tas = tile_set->get_source(source_id); + Ref<TileSetAtlasSource> tas = ed_tile_set->get_source(source_id); if (tas.is_valid()) { for (int j = 0; j < tas->get_tiles_count(); j++) { Vector2i tile_id = tas->get_tile_id(j); @@ -536,68 +543,68 @@ void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_ // Add do method. if (p_array_prefix == "occlusion_layer_") { if (p_from_index < 0) { - undo_redo->add_do_method(tile_set, "add_occlusion_layer", p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "add_occlusion_layer", p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_do_method(tile_set, "remove_occlusion_layer", p_from_index); + undo_redo_man->add_do_method(ed_tile_set, "remove_occlusion_layer", p_from_index); } else { - undo_redo->add_do_method(tile_set, "move_occlusion_layer", p_from_index, p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "move_occlusion_layer", p_from_index, p_to_pos); } } else if (p_array_prefix == "physics_layer_") { if (p_from_index < 0) { - undo_redo->add_do_method(tile_set, "add_physics_layer", p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "add_physics_layer", p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_do_method(tile_set, "remove_physics_layer", p_from_index); + undo_redo_man->add_do_method(ed_tile_set, "remove_physics_layer", p_from_index); } else { - undo_redo->add_do_method(tile_set, "move_physics_layer", p_from_index, p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "move_physics_layer", p_from_index, p_to_pos); } } else if (p_array_prefix == "terrain_set_") { if (p_from_index < 0) { - undo_redo->add_do_method(tile_set, "add_terrain_set", p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "add_terrain_set", p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_do_method(tile_set, "remove_terrain_set", p_from_index); + undo_redo_man->add_do_method(ed_tile_set, "remove_terrain_set", p_from_index); } else { - undo_redo->add_do_method(tile_set, "move_terrain_set", p_from_index, p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "move_terrain_set", p_from_index, p_to_pos); } } else if (components.size() >= 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "terrain_") { int terrain_set = components[0].trim_prefix("terrain_set_").to_int(); if (p_from_index < 0) { - undo_redo->add_do_method(tile_set, "add_terrain", terrain_set, p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "add_terrain", terrain_set, p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_do_method(tile_set, "remove_terrain", terrain_set, p_from_index); + undo_redo_man->add_do_method(ed_tile_set, "remove_terrain", terrain_set, p_from_index); } else { - undo_redo->add_do_method(tile_set, "move_terrain", terrain_set, p_from_index, p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "move_terrain", terrain_set, p_from_index, p_to_pos); } } else if (p_array_prefix == "navigation_layer_") { if (p_from_index < 0) { - undo_redo->add_do_method(tile_set, "add_navigation_layer", p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "add_navigation_layer", p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_do_method(tile_set, "remove_navigation_layer", p_from_index); + undo_redo_man->add_do_method(ed_tile_set, "remove_navigation_layer", p_from_index); } else { - undo_redo->add_do_method(tile_set, "move_navigation_layer", p_from_index, p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "move_navigation_layer", p_from_index, p_to_pos); } } else if (p_array_prefix == "custom_data_layer_") { if (p_from_index < 0) { - undo_redo->add_do_method(tile_set, "add_custom_data_layer", p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "add_custom_data_layer", p_to_pos); } else if (p_to_pos < 0) { - undo_redo->add_do_method(tile_set, "remove_custom_data_layer", p_from_index); + undo_redo_man->add_do_method(ed_tile_set, "remove_custom_data_layer", p_from_index); } else { - undo_redo->add_do_method(tile_set, "move_custom_data_layer", p_from_index, p_to_pos); + undo_redo_man->add_do_method(ed_tile_set, "move_custom_data_layer", p_from_index, p_to_pos); } } } void TileSetEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) { - Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); - ERR_FAIL_COND(undo_redo.is_null()); + Ref<EditorUndoRedoManager> undo_redo_man = Object::cast_to<EditorUndoRedoManager>(p_undo_redo); + ERR_FAIL_COND(undo_redo_man.is_null()); -#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property)); - TileSet *tile_set = Object::cast_to<TileSet>(p_edited); - if (tile_set) { +#define ADD_UNDO(obj, property) undo_redo_man->add_undo_property(obj, property, obj->get(property)); + TileSet *ed_tile_set = Object::cast_to<TileSet>(p_edited); + if (ed_tile_set) { Vector<String> components = p_property.split("/", true, 3); - for (int i = 0; i < tile_set->get_source_count(); i++) { - int source_id = tile_set->get_source_id(i); + for (int i = 0; i < ed_tile_set->get_source_count(); i++) { + int source_id = ed_tile_set->get_source_id(i); - Ref<TileSetAtlasSource> tas = tile_set->get_source(source_id); + Ref<TileSetAtlasSource> tas = ed_tile_set->get_source(source_id); if (tas.is_valid()) { for (int j = 0; j < tas->get_tiles_count(); j++) { Vector2i tile_id = tas->get_tile_id(j); @@ -648,7 +655,12 @@ void TileSetEditor::edit(Ref<TileSet> p_tile_set) { // Add the listener again. if (tile_set.is_valid()) { tile_set->connect("changed", callable_mp(this, &TileSetEditor::_tile_set_changed)); - _update_sources_list(); + if (first_edit) { + first_edit = false; + _set_source_sort(EditorSettings::get_singleton()->get_project_metadata("editor_metadata", "tile_source_sort", 0)); + } else { + _update_sources_list(); + } _update_patterns_list(); } @@ -660,8 +672,6 @@ void TileSetEditor::edit(Ref<TileSet> p_tile_set) { TileSetEditor::TileSetEditor() { singleton = this; - undo_redo = EditorNode::get_undo_redo(); - set_process_internal(true); // TabBar. @@ -695,7 +705,7 @@ TileSetEditor::TileSetEditor() { source_sort_button = memnew(MenuButton); source_sort_button->set_flat(true); - source_sort_button->set_tooltip_text(TTR("Sort sources")); + source_sort_button->set_tooltip_text(TTR("Sort Sources")); PopupMenu *p = source_sort_button->get_popup(); p->connect("id_pressed", callable_mp(this, &TileSetEditor::_set_source_sort)); @@ -795,6 +805,7 @@ TileSetEditor::TileSetEditor() { patterns_help_label = memnew(Label); patterns_help_label->set_text(TTR("Add new patterns in the TileMap editing mode.")); + patterns_help_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); patterns_help_label->set_anchors_and_offsets_preset(Control::PRESET_CENTER); patterns_item_list->add_child(patterns_help_label); @@ -802,9 +813,3 @@ TileSetEditor::TileSetEditor() { EditorNode::get_singleton()->get_editor_data().add_move_array_element_function(SNAME("TileSet"), callable_mp(this, &TileSetEditor::_move_tile_set_array_element)); EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(callable_mp(this, &TileSetEditor::_undo_redo_inspector_callback)); } - -TileSetEditor::~TileSetEditor() { - if (tile_set.is_valid()) { - tile_set->disconnect("changed", callable_mp(this, &TileSetEditor::_tile_set_changed)); - } -} diff --git a/editor/plugins/tiles/tile_set_editor.h b/editor/plugins/tiles/tile_set_editor.h index 3b9b80dac4..95697f7ecc 100644 --- a/editor/plugins/tiles/tile_set_editor.h +++ b/editor/plugins/tiles/tile_set_editor.h @@ -39,8 +39,6 @@ #include "tile_set_atlas_source_editor.h" #include "tile_set_scenes_collection_source_editor.h" -class EditorUndoRedoManager; - class TileSetEditor : public VBoxContainer { GDCLASS(TileSetEditor, VBoxContainer); @@ -60,8 +58,6 @@ private: TileSetAtlasSourceEditor *tile_set_atlas_source_editor = nullptr; TileSetScenesCollectionSourceEditor *tile_set_scenes_collection_source_editor = nullptr; - Ref<EditorUndoRedoManager> undo_redo; - void _drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); bool _can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; @@ -83,6 +79,8 @@ private: AtlasMergingDialog *atlas_merging_dialog = nullptr; TileProxiesManagerDialog *tile_proxies_manager_dialog = nullptr; + bool first_edit = true; + // Patterns. ItemList *patterns_item_list = nullptr; Label *patterns_help_label = nullptr; @@ -107,7 +105,6 @@ public: void edit(Ref<TileSet> p_tile_set); TileSetEditor(); - ~TileSetEditor(); }; #endif // TILE_SET_EDITOR_H diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp index f7622e68ab..a14aad6652 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -35,8 +35,10 @@ #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" #include "scene/gui/item_list.h" +#include "scene/gui/split_container.h" #include "core/core_string_names.h" @@ -235,6 +237,7 @@ void TileSetScenesCollectionSourceEditor::_scenes_list_item_activated(int p_inde void TileSetScenesCollectionSourceEditor::_source_add_pressed() { int scene_id = tile_set_scenes_collection_source->get_next_scene_tile_id(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add a Scene Tile")); undo_redo->add_do_method(tile_set_scenes_collection_source, "create_scene_tile", Ref<PackedScene>(), scene_id); undo_redo->add_undo_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id); @@ -249,6 +252,7 @@ void TileSetScenesCollectionSourceEditor::_source_delete_pressed() { ERR_FAIL_COND(selected_indices.size() <= 0); int scene_id = scene_tiles_list->get_item_metadata(selected_indices[0]); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove a Scene Tile")); undo_redo->add_do_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id); undo_redo->add_undo_method(tile_set_scenes_collection_source, "create_scene_tile", tile_set_scenes_collection_source->get_scene_tile_scene(scene_id), scene_id); @@ -323,7 +327,7 @@ void TileSetScenesCollectionSourceEditor::_update_scenes_list() { } // Icon size update. - int int_size = int(EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size")) * EDSCALE; + int int_size = int(EDITOR_GET("filesystem/file_dialog/thumbnail_size")) * EDSCALE; scene_tiles_list->set_fixed_icon_size(Vector2(int_size, int_size)); } @@ -400,6 +404,7 @@ void TileSetScenesCollectionSourceEditor::_drop_data_fw(const Point2 &p_point, c Ref<PackedScene> resource = ResourceLoader::load(files[i]); if (resource.is_valid()) { int scene_id = tile_set_scenes_collection_source->get_next_scene_tile_id(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add a Scene Tile")); undo_redo->add_do_method(tile_set_scenes_collection_source, "create_scene_tile", resource, scene_id); undo_redo->add_undo_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id); @@ -453,8 +458,6 @@ void TileSetScenesCollectionSourceEditor::_bind_methods() { } TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() { - undo_redo = EditorNode::get_undo_redo(); - // -- Right side -- HSplitContainer *split_container_right_side = memnew(HSplitContainer); split_container_right_side->set_h_size_flags(SIZE_EXPAND_FILL); @@ -479,7 +482,6 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() { scenes_collection_source_proxy_object->connect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_scenes_collection_source_proxy_object_changed)); scenes_collection_source_inspector = memnew(EditorInspector); - scenes_collection_source_inspector->set_undo_redo(undo_redo); scenes_collection_source_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); scenes_collection_source_inspector->edit(scenes_collection_source_proxy_object); middle_vbox_container->add_child(scenes_collection_source_inspector); @@ -495,7 +497,6 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() { tile_proxy_object->connect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_update_action_buttons).unbind(1)); tile_inspector = memnew(EditorInspector); - tile_inspector->set_undo_redo(undo_redo); tile_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); tile_inspector->edit(tile_proxy_object); tile_inspector->set_use_folding(true); diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h index 0284b45c0f..7270cccbd8 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h @@ -37,8 +37,6 @@ #include "scene/gui/item_list.h" #include "scene/resources/tile_set.h" -class UndoRedo; - class TileSetScenesCollectionSourceEditor : public HBoxContainer { GDCLASS(TileSetScenesCollectionSourceEditor, HBoxContainer); @@ -97,8 +95,6 @@ private: TileSetScenesCollectionSource *tile_set_scenes_collection_source = nullptr; int tile_set_source_id = -1; - Ref<EditorUndoRedoManager> undo_redo; - bool tile_set_scenes_collection_source_changed_needs_update = false; // Source inspector. diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index 17115519e2..5d93f58f34 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -30,10 +30,13 @@ #include "tiles_editor_plugin.h" +#include "tile_set_editor.h" + #include "core/os/mutex.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "scene/2d/tile_map.h" @@ -43,8 +46,6 @@ #include "scene/gui/separator.h" #include "scene/resources/tile_set.h" -#include "tile_set_editor.h" - TilesEditorPlugin *TilesEditorPlugin::singleton = nullptr; void TilesEditorPlugin::_preview_frame_started() { @@ -66,12 +67,14 @@ void TilesEditorPlugin::_thread() { pattern_preview_sem.wait(); pattern_preview_mutex.lock(); - if (pattern_preview_queue.size()) { + if (pattern_preview_queue.size() == 0) { + pattern_preview_mutex.unlock(); + } else { QueueItem item = pattern_preview_queue.front()->get(); pattern_preview_queue.pop_front(); pattern_preview_mutex.unlock(); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + int thumbnail_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); thumbnail_size *= EDSCALE; Vector2 thumbnail_size2 = Vector2(thumbnail_size, thumbnail_size); @@ -90,7 +93,7 @@ void TilesEditorPlugin::_thread() { TypedArray<Vector2i> used_cells = tile_map->get_used_cells(0); - Rect2 encompassing_rect = Rect2(); + Rect2 encompassing_rect; encompassing_rect.set_position(tile_map->map_to_local(used_cells[0])); for (int i = 0; i < used_cells.size(); i++) { Vector2i cell = used_cells[i]; @@ -129,9 +132,7 @@ void TilesEditorPlugin::_thread() { Callable::CallError error; item.callback.callp(args_ptr, 2, r, error); - viewport->queue_delete(); - } else { - pattern_preview_mutex.unlock(); + viewport->queue_free(); } } } @@ -264,12 +265,12 @@ void TilesEditorPlugin::set_sorting_option(int p_option) { source_sort = p_option; } -List<int> TilesEditorPlugin::get_sorted_sources(const Ref<TileSet> tile_set) const { - SourceNameComparator::tile_set = tile_set; +List<int> TilesEditorPlugin::get_sorted_sources(const Ref<TileSet> p_tile_set) const { + SourceNameComparator::tile_set = p_tile_set; List<int> source_ids; - for (int i = 0; i < tile_set->get_source_count(); i++) { - source_ids.push_back(tile_set->get_source_id(i)); + for (int i = 0; i < p_tile_set->get_source_count(); i++) { + source_ids.push_back(p_tile_set->get_source_id(i)); } switch (source_sort) { diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h index b1fe6f8df6..fe0d8179bc 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.h +++ b/editor/plugins/tiles/tiles_editor_plugin.h @@ -71,7 +71,7 @@ private: // For synchronization. int atlas_sources_lists_current = 0; float atlas_view_zoom = 1.0; - Vector2 atlas_view_scroll = Vector2(); + Vector2 atlas_view_scroll; void _tile_map_changed(); @@ -122,7 +122,7 @@ public: // Sorting. void set_sorting_option(int p_option); - List<int> get_sorted_sources(const Ref<TileSet> tile_set) const; + List<int> get_sorted_sources(const Ref<TileSet> p_tile_set) const; virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index 336ce9e4c8..86aa897c78 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -38,6 +38,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" +#include "editor/plugins/script_editor_plugin.h" #include "scene/gui/separator.h" #define CHECK_PLUGIN_INITIALIZED() \ @@ -430,7 +431,7 @@ void VersionControlEditorPlugin::_discard_file(String p_file_path, EditorVCSInte CHECK_PLUGIN_INITIALIZED(); EditorVCSInterface::get_singleton()->discard_file(p_file_path); } - // FIXIT: The project.godot file shows weird behaviour + // FIXIT: The project.godot file shows weird behavior EditorFileSystem::get_singleton()->update_file(p_file_path); } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index ee8148f00a..f32e0bdfa2 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -32,31 +32,31 @@ #include "core/config/project_settings.h" #include "core/core_string_names.h" -#include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/math_defs.h" #include "core/os/keyboard.h" -#include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/inspector_dock.h" #include "editor/plugins/curve_editor_plugin.h" #include "editor/plugins/shader_editor_plugin.h" -#include "scene/animation/animation_player.h" #include "scene/gui/button.h" +#include "scene/gui/check_box.h" #include "scene/gui/code_edit.h" #include "scene/gui/graph_edit.h" #include "scene/gui/menu_button.h" -#include "scene/gui/panel.h" +#include "scene/gui/option_button.h" #include "scene/gui/popup.h" #include "scene/gui/rich_text_label.h" +#include "scene/gui/separator.h" #include "scene/gui/tree.h" #include "scene/gui/view_panner.h" #include "scene/main/window.h" #include "scene/resources/visual_shader_nodes.h" #include "scene/resources/visual_shader_particle_nodes.h" -#include "scene/resources/visual_shader_sdf_nodes.h" #include "servers/display_server.h" #include "servers/rendering/shader_types.h" @@ -86,11 +86,9 @@ void VisualShaderNodePlugin::set_editor(VisualShaderEditor *p_editor) { } Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) { - Object *ret; - if (GDVIRTUAL_CALL(_create_editor, p_parent_resource, p_node, ret)) { - return Object::cast_to<Control>(ret); - } - return nullptr; + Object *ret = nullptr; + GDVIRTUAL_CALL(_create_editor, p_parent_resource, p_node, ret); + return Object::cast_to<Control>(ret); } void VisualShaderNodePlugin::_bind_methods() { @@ -818,8 +816,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (vsnode->is_output_port_expandable(i)) { TextureButton *expand = memnew(TextureButton); expand->set_toggle_mode(true); - expand->set_normal_texture(editor->get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); - expand->set_pressed_texture(editor->get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); + expand->set_texture_normal(editor->get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); + expand->set_texture_pressed(editor->get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); expand->set_v_size_flags(Control::SIZE_SHRINK_CENTER); expand->set_pressed(vsnode->_is_output_port_expanded(i)); expand->connect("pressed", callable_mp(editor, &VisualShaderEditor::_expand_output_port).bind(p_id, i, !vsnode->_is_output_port_expanded(i)), CONNECT_DEFERRED); @@ -828,8 +826,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (vsnode->has_output_port_preview(i) && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) { TextureButton *preview = memnew(TextureButton); preview->set_toggle_mode(true); - preview->set_normal_texture(editor->get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons"))); - preview->set_pressed_texture(editor->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); + preview->set_texture_normal(editor->get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons"))); + preview->set_texture_pressed(editor->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER); register_output_port(p_id, j, preview); @@ -1115,6 +1113,8 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) { } visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE); _set_mode(visual_shader->get_mode()); + + _update_nodes(); } else { if (visual_shader.is_valid()) { Callable ce = callable_mp(this, &VisualShaderEditor::_update_preview); @@ -1235,11 +1235,11 @@ void VisualShaderEditor::_update_nodes() { Ref<Resource> res = ResourceLoader::load(script_path); ERR_FAIL_COND(res.is_null()); ERR_FAIL_COND(!res->is_class("Script")); - Ref<Script> script = Ref<Script>(res); + Ref<Script> scr = Ref<Script>(res); Ref<VisualShaderNodeCustom> ref; ref.instantiate(); - ref->set_script(script); + ref->set_script(scr); if (!ref->is_available(visual_shader->get_mode(), visual_shader->get_shader_type())) { continue; } @@ -1278,7 +1278,7 @@ void VisualShaderEditor::_update_nodes() { Dictionary dict; dict["name"] = name; - dict["script"] = script; + dict["script"] = scr; dict["description"] = description; dict["return_icon_type"] = return_icon_type; @@ -1358,7 +1358,7 @@ void VisualShaderEditor::_update_options_menu() { Color unsupported_color = get_theme_color(SNAME("error_color"), SNAME("Editor")); Color supported_color = get_theme_color(SNAME("warning_color"), SNAME("Editor")); - static bool low_driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "opengl3"; + static bool low_driver = GLOBAL_GET("rendering/renderer/rendering_method") == "gl_compatibility"; HashMap<String, TreeItem *> folders; @@ -1661,6 +1661,7 @@ void VisualShaderEditor::_update_parameters(bool p_update_refs) { } void VisualShaderEditor::_update_parameter_refs(HashSet<String> &p_deleted_names) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); for (int i = 0; i < VisualShader::TYPE_MAX; i++) { VisualShader::Type type = VisualShader::Type(i); @@ -1705,9 +1706,9 @@ void VisualShaderEditor::_update_graph() { } } - List<VisualShader::Connection> connections; - visual_shader->get_node_connections(type, &connections); - graph_plugin->set_connections(connections); + List<VisualShader::Connection> node_connections; + visual_shader->get_node_connections(type, &node_connections); + graph_plugin->set_connections(node_connections); Vector<int> nodes = visual_shader->get_node_list(type); @@ -1724,7 +1725,7 @@ void VisualShaderEditor::_update_graph() { graph_plugin->make_dirty(false); - for (const VisualShader::Connection &E : connections) { + for (const VisualShader::Connection &E : node_connections) { int from = E.from_node; int from_idx = E.from_port; int to = E.to_node; @@ -1733,9 +1734,9 @@ void VisualShaderEditor::_update_graph() { graph->connect_node(itos(from), from_idx, itos(to), to_idx); } - float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + float graph_minimap_opacity = EDITOR_GET("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); - float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + float graph_lines_curvature = EDITOR_GET("editors/visual_editors/lines_curvature"); graph->set_connection_lines_curvature(graph_lines_curvature); } @@ -1760,6 +1761,7 @@ void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Input Port")); undo_redo->add_do_method(node.ptr(), "add_input_port", p_port, p_port_type, p_name); undo_redo->add_undo_method(node.ptr(), "remove_input_port", p_port); @@ -1775,6 +1777,7 @@ void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_typ return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Output Port")); undo_redo->add_do_method(node.ptr(), "add_output_port", p_port, p_port_type, p_name); undo_redo->add_undo_method(node.ptr(), "remove_output_port", p_port); @@ -1790,6 +1793,7 @@ void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_p return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Input Port Type")); undo_redo->add_do_method(node.ptr(), "set_input_port_type", p_port, p_type); undo_redo->add_undo_method(node.ptr(), "set_input_port_type", p_port, node->get_input_port_type(p_port)); @@ -1805,6 +1809,7 @@ void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_ return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Output Port Type")); undo_redo->add_do_method(node.ptr(), "set_output_port_type", p_port, p_type); undo_redo->add_undo_method(node.ptr(), "set_output_port_type", p_port, node->get_output_port_type(p_port)); @@ -1833,6 +1838,7 @@ void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *p return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Input Port Name")); undo_redo->add_do_method(node.ptr(), "set_input_port_name", p_port_id, validated_name); undo_redo->add_undo_method(node.ptr(), "set_input_port_name", p_port_id, node->get_input_port_name(p_port_id)); @@ -1859,6 +1865,7 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object * return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Change Output Port Name")); undo_redo->add_do_method(node.ptr(), "set_output_port_name", p_port_id, validated_name); undo_redo->add_undo_method(node.ptr(), "set_output_port_name", p_port_id, prev_name); @@ -1871,6 +1878,7 @@ void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expa Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node); ERR_FAIL_COND(!node.is_valid()); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (p_expand) { undo_redo->create_action(TTR("Expand Output Port")); } else { @@ -1899,45 +1907,45 @@ void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expa visual_shader->get_node_connections(type, &conns); for (const VisualShader::Connection &E : conns) { - int from_node = E.from_node; - int from_port = E.from_port; - int to_node = E.to_node; - int to_port = E.to_port; + int cn_from_node = E.from_node; + int cn_from_port = E.from_port; + int cn_to_node = E.to_node; + int cn_to_port = E.to_port; - if (from_node == p_node) { + if (cn_from_node == p_node) { if (p_expand) { - if (from_port > p_port) { // reconnect ports after expanded ports - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); + if (cn_from_port > p_port) { // reconnect ports after expanded ports + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); - undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port + type_size, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port + type_size, to_node, to_port); + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port + type_size, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port + type_size, cn_to_node, cn_to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port + type_size, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port + type_size, to_node, to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port + type_size, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port + type_size, cn_to_node, cn_to_port); } } else { - if (from_port > p_port + type_size) { // reconnect ports after expanded ports - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); + if (cn_from_port > p_port + type_size) { // reconnect ports after expanded ports + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); - undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_port - type_size, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port - type_size, to_node, to_port); + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, cn_from_node, cn_from_port - type_size, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port - type_size, cn_to_node, cn_to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port - type_size, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port - type_size, to_node, to_port); - } else if (from_port > p_port) { // disconnect component ports - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port - type_size, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port - type_size, cn_to_node, cn_to_port); + } else if (cn_from_port > p_port) { // disconnect component ports + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); } } } @@ -1968,35 +1976,36 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Input Port")); List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); for (const VisualShader::Connection &E : conns) { - int from_node = E.from_node; - int from_port = E.from_port; - int to_node = E.to_node; - int to_port = E.to_port; - - if (to_node == p_node) { - if (to_port == p_port) { - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); - - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); - } else if (to_port > p_port) { - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); - - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); - - undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port - 1); - undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port - 1); - - undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port - 1); - undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port - 1); + int cn_from_node = E.from_node; + int cn_from_port = E.from_port; + int cn_to_node = E.to_node; + int cn_to_port = E.to_port; + + if (cn_to_node == p_node) { + if (cn_to_port == p_port) { + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + } else if (cn_to_port > p_port) { + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port - 1); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port - 1); + + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port - 1); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port - 1); } } } @@ -2017,35 +2026,36 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Remove Output Port")); List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); for (const VisualShader::Connection &E : conns) { - int from_node = E.from_node; - int from_port = E.from_port; - int to_node = E.to_node; - int to_port = E.to_port; - - if (from_node == p_node) { - if (from_port == p_port) { - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); - - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); - } else if (from_port > p_port) { - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); - - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); - - undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port - 1, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port - 1, to_node, to_port); - - undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port - 1, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port - 1, to_node, to_port); + int cn_from_node = E.from_node; + int cn_from_port = E.from_port; + int cn_to_node = E.to_node; + int cn_to_port = E.to_port; + + if (cn_from_node == p_node) { + if (cn_from_port == p_port) { + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + } else if (cn_from_port > p_port) { + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, cn_from_node, cn_from_port - 1, cn_to_node, cn_to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port - 1, cn_to_node, cn_to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port - 1, cn_to_node, cn_to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port - 1, cn_to_node, cn_to_port); } } } @@ -2083,6 +2093,7 @@ void VisualShaderEditor::_expression_focus_out(Object *code_edit, int p_node) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set VisualShader Expression")); undo_redo->add_do_method(node.ptr(), "set_expression", expression_box->get_text()); undo_redo->add_undo_method(node.ptr(), "set_expression", node->get_expression()); @@ -2146,6 +2157,7 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Resize VisualShader Node"), UndoRedo::MERGE_ENDS); undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size); undo_redo->add_undo_method(this, "_set_node_size", p_type, p_node, node->get_size()); @@ -2162,6 +2174,7 @@ void VisualShaderEditor::_preview_select_port(int p_node, int p_port) { if (node->get_output_port_for_preview() == p_port) { p_port = -1; //toggle it } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(p_port == -1 ? TTR("Hide Port Preview") : TTR("Show Port Preview")); undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", p_port); undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", prev_port); @@ -2207,6 +2220,7 @@ void VisualShaderEditor::_comment_title_popup_hide() { if (node->get_title() == comment_title_change_edit->get_text()) { return; // nothing changed - ignored } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Comment Node Title")); undo_redo->add_do_method(node.ptr(), "set_title", comment_title_change_edit->get_text()); undo_redo->add_undo_method(node.ptr(), "set_title", node->get_title()); @@ -2249,6 +2263,7 @@ void VisualShaderEditor::_comment_desc_popup_hide() { if (node->get_description() == comment_desc_change_edit->get_text()) { return; // nothing changed - ignored } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Comment Node Description")); undo_redo->add_do_method(node.ptr(), "set_description", comment_desc_change_edit->get_text()); undo_redo->add_undo_method(node.ptr(), "set_description", node->get_title()); @@ -2269,6 +2284,7 @@ void VisualShaderEditor::_parameter_line_edit_changed(const String &p_text, int return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Parameter Name")); undo_redo->add_do_method(node.ptr(), "set_parameter_name", validated_name); undo_redo->add_undo_method(node.ptr(), "set_parameter_name", node->get_parameter_name()); @@ -2304,6 +2320,7 @@ void VisualShaderEditor::_port_edited(const StringName &p_property, const Varian Ref<VisualShaderNode> vsn = visual_shader->get_node(type, editing_node); ERR_FAIL_COND(!vsn.is_valid()); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Input Default Port")); Ref<VisualShaderNodeCustom> custom = Object::cast_to<VisualShaderNodeCustom>(vsn.ptr()); @@ -2727,6 +2744,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri int id_to_use = visual_shader->get_valid_node_id(type); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (p_resource_path.is_empty()) { undo_redo->create_action(TTR("Add Node to Visual Shader")); } else { @@ -2896,6 +2914,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri } void VisualShaderEditor::_add_varying(const String &p_name, VisualShader::VaryingMode p_mode, VisualShader::VaryingType p_type) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Add Varying to Visual Shader: %s"), p_name)); undo_redo->add_do_method(visual_shader.ptr(), "add_varying", p_name, p_mode, p_type); @@ -2930,18 +2949,19 @@ void VisualShaderEditor::_add_varying(const String &p_name, VisualShader::Varyin } void VisualShaderEditor::_remove_varying(const String &p_name) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Remove Varying from Visual Shader: %s"), p_name)); - VisualShader::VaryingMode mode = visual_shader->get_varying_mode(p_name); + VisualShader::VaryingMode var_mode = visual_shader->get_varying_mode(p_name); undo_redo->add_do_method(visual_shader.ptr(), "remove_varying", p_name); - undo_redo->add_undo_method(visual_shader.ptr(), "add_varying", p_name, mode, visual_shader->get_varying_type(p_name)); + undo_redo->add_undo_method(visual_shader.ptr(), "add_varying", p_name, var_mode, visual_shader->get_varying_type(p_name)); undo_redo->add_do_method(this, "_update_varyings"); undo_redo->add_undo_method(this, "_update_varyings"); for (int i = 0; i <= VisualShader::TYPE_LIGHT; i++) { - if (mode == VisualShader::VARYING_MODE_FRAG_TO_LIGHT && i == 0) { + if (var_mode == VisualShader::VARYING_MODE_FRAG_TO_LIGHT && i == 0) { continue; } @@ -2967,10 +2987,10 @@ void VisualShaderEditor::_remove_varying(const String &p_name) { } } - List<VisualShader::Connection> connections; - visual_shader->get_node_connections(type, &connections); + List<VisualShader::Connection> node_connections; + visual_shader->get_node_connections(type, &node_connections); - for (VisualShader::Connection &E : connections) { + for (VisualShader::Connection &E : node_connections) { Ref<VisualShaderNodeVaryingGetter> var_getter = Object::cast_to<VisualShaderNodeVaryingGetter>(visual_shader->get_node(type, E.from_node).ptr()); if (var_getter.is_valid() && E.from_port > 0) { undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); @@ -3017,6 +3037,7 @@ void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_t void VisualShaderEditor::_nodes_dragged() { drag_dirty = false; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Node(s) Moved")); for (const DragOp &E : drag_buffer) { @@ -3040,6 +3061,7 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Nodes Connected")); List<VisualShader::Connection> conns; @@ -3071,6 +3093,7 @@ void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from int from = p_from.to_int(); int to = p_to.to_int(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Nodes Disconnected")); undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index); undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index); @@ -3110,6 +3133,7 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); for (const int &F : p_nodes) { for (const VisualShader::Connection &E : conns) { if (E.from_node == F || E.to_node == F) { @@ -3182,6 +3206,7 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { } void VisualShaderEditor::_replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_to); undo_redo->add_undo_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_from); } @@ -3216,6 +3241,7 @@ void VisualShaderEditor::_update_parameter(VisualShader::Type p_type_id, int p_n void VisualShaderEditor::_convert_constants_to_parameters(bool p_vice_versa) { VisualShader::Type type_id = get_current_shader_type(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (!p_vice_versa) { undo_redo->create_action(TTR("Convert Constant Node(s) To Parameter(s)")); } else { @@ -3414,6 +3440,7 @@ void VisualShaderEditor::_delete_node_request(int p_type, int p_node) { List<int> to_erase; to_erase.push_back(p_node); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete VisualShader Node")); _delete_nodes(p_type, to_erase); undo_redo->commit_action(); @@ -3442,6 +3469,7 @@ void VisualShaderEditor::_delete_nodes_request(const TypedArray<StringName> &p_n return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete VisualShader Node(s)")); _delete_nodes(get_current_shader_type(), to_erase); undo_redo->commit_action(); @@ -3625,12 +3653,6 @@ void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos, VisualShaderNod node_filter->select_all(); } -void VisualShaderEditor::_show_varying_menu() { - varying_options->set_item_disabled(int(VaryingMenuOptions::REMOVE), visual_shader->get_varyings_count() == 0); - varying_options->set_position(graph->get_screen_position() + varying_button->get_position() + Size2(0, varying_button->get_size().height)); - varying_options->popup(); -} - void VisualShaderEditor::_varying_menu_id_pressed(int p_idx) { switch (VaryingMenuOptions(p_idx)) { case VaryingMenuOptions::ADD: { @@ -3679,10 +3701,10 @@ void VisualShaderEditor::_sbox_input(const Ref<InputEvent> &p_ie) { void VisualShaderEditor::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); - graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning"))); - graph->set_minimap_opacity(EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity")); - graph->set_connection_lines_curvature(EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature")); + graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); + graph->set_warped_panning(bool(EDITOR_GET("editors/panning/warped_mouse_panning"))); + graph->set_minimap_opacity(EDITOR_GET("editors/visual_editors/minimap_opacity")); + graph->set_connection_lines_curvature(EDITOR_GET("editors/visual_editors/lines_curvature")); _update_graph(); } break; @@ -3702,12 +3724,12 @@ void VisualShaderEditor::_notification(int p_what) { category = category->get_next(); } - graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); - graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning"))); + graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning"))); + graph->set_warped_panning(bool(EDITOR_GET("editors/panning/warped_mouse_panning"))); [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { - highend_label->set_modulate(get_theme_color(SNAME("vulkan_color"), SNAME("Editor"))); + highend_label->set_modulate(get_theme_color(SNAME("highend_color"), SNAME("Editor"))); node_filter->set_right_icon(Control::get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); @@ -3847,10 +3869,10 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<CopyItem> &r_items, Li } } - List<VisualShader::Connection> connections; - visual_shader->get_node_connections(type, &connections); + List<VisualShader::Connection> node_connections; + visual_shader->get_node_connections(type, &node_connections); - for (const VisualShader::Connection &E : connections) { + for (const VisualShader::Connection &E : node_connections) { if (nodes.has(E.from_node) && nodes.has(E.to_node)) { r_connections.push_back(E); } @@ -3860,6 +3882,7 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<CopyItem> &r_items, Li } void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, const List<VisualShader::Connection> &p_connections, const Vector2 &p_offset, bool p_duplicate) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (p_duplicate) { undo_redo->create_action(TTR("Duplicate VisualShader Node(s)")); } else { @@ -3961,15 +3984,15 @@ void VisualShaderEditor::_duplicate_nodes() { int type = get_current_shader_type(); List<CopyItem> items; - List<VisualShader::Connection> connections; + List<VisualShader::Connection> node_connections; - _dup_copy_nodes(type, items, connections); + _dup_copy_nodes(type, items, node_connections); if (items.is_empty()) { return; } - _dup_paste_nodes(type, items, connections, Vector2(10, 10) * EDSCALE, true); + _dup_paste_nodes(type, items, node_connections, Vector2(10, 10) * EDSCALE, true); } void VisualShaderEditor::_copy_nodes(bool p_cut) { @@ -3978,6 +4001,7 @@ void VisualShaderEditor::_copy_nodes(bool p_cut) { _dup_copy_nodes(get_current_shader_type(), copy_items_buffer, copy_connections_buffer); if (p_cut) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Cut VisualShader Node(s)")); List<int> ids; @@ -4064,11 +4088,11 @@ void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input, bool type_changed = next_input_type != prev_input_type; - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); - undo_redo->create_action(TTR("Visual Shader Input Type Changed")); + Ref<EditorUndoRedoManager> &undo_redo_man = EditorNode::get_undo_redo(); + undo_redo_man->create_action(TTR("Visual Shader Input Type Changed")); - undo_redo->add_do_method(p_input.ptr(), "set_input_name", p_name); - undo_redo->add_undo_method(p_input.ptr(), "set_input_name", prev_name); + undo_redo_man->add_do_method(p_input.ptr(), "set_input_name", p_name); + undo_redo_man->add_undo_method(p_input.ptr(), "set_input_name", prev_name); if (type_changed) { for (int type_id = 0; type_id < VisualShader::TYPE_MAX; type_id++) { @@ -4098,30 +4122,30 @@ void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input, List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); for (const VisualShader::Connection &E : conns) { - int from_node = E.from_node; - int from_port = E.from_port; - int to_node = E.to_node; - int to_port = E.to_port; - - if (from_node == id) { - bool is_incompatible_types = !visual_shader->is_port_types_compatible(p_input->get_input_type_by_name(p_name), visual_shader->get_node(type, to_node)->get_input_port_type(to_port)); - - if (is_incompatible_types || from_port > type_size) { - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); + int cn_from_node = E.from_node; + int cn_from_port = E.from_port; + int cn_to_node = E.to_node; + int cn_to_port = E.to_port; + + if (cn_from_node == id) { + bool is_incompatible_types = !visual_shader->is_port_types_compatible(p_input->get_input_type_by_name(p_name), visual_shader->get_node(type, cn_to_node)->get_input_port_type(cn_to_port)); + + if (is_incompatible_types || cn_from_port > type_size) { + undo_redo_man->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo_man->add_undo_method(visual_shader.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo_man->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); + undo_redo_man->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, cn_from_node, cn_from_port, cn_to_node, cn_to_port); } } } - undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, id); - undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id); + undo_redo_man->add_do_method(graph_plugin.ptr(), "update_node", type_id, id); + undo_redo_man->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id); } } } - undo_redo->commit_action(); + undo_redo_man->commit_action(); } void VisualShaderEditor::_parameter_ref_select_item(Ref<VisualShaderNodeParameterRef> p_parameter_ref, String p_name) { @@ -4133,11 +4157,11 @@ void VisualShaderEditor::_parameter_ref_select_item(Ref<VisualShaderNodeParamete bool type_changed = p_parameter_ref->get_parameter_type_by_name(p_name) != p_parameter_ref->get_parameter_type_by_name(prev_name); - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); - undo_redo->create_action(TTR("ParameterRef Name Changed")); + Ref<EditorUndoRedoManager> &undo_redo_man = EditorNode::get_undo_redo(); + undo_redo_man->create_action(TTR("ParameterRef Name Changed")); - undo_redo->add_do_method(p_parameter_ref.ptr(), "set_parameter_name", p_name); - undo_redo->add_undo_method(p_parameter_ref.ptr(), "set_parameter_name", prev_name); + undo_redo_man->add_do_method(p_parameter_ref.ptr(), "set_parameter_name", p_name); + undo_redo_man->add_undo_method(p_parameter_ref.ptr(), "set_parameter_name", prev_name); // update output port for (int type_id = 0; type_id < VisualShader::TYPE_MAX; type_id++) { @@ -4152,20 +4176,20 @@ void VisualShaderEditor::_parameter_ref_select_item(Ref<VisualShaderNodeParamete if (visual_shader->is_port_types_compatible(p_parameter_ref->get_parameter_type_by_name(p_name), visual_shader->get_node(type, E.to_node)->get_input_port_type(E.to_port))) { continue; } - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); } } } - undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, id); - undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id); + undo_redo_man->add_do_method(graph_plugin.ptr(), "update_node", type_id, id); + undo_redo_man->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id); break; } } - undo_redo->commit_action(); + undo_redo_man->commit_action(); } void VisualShaderEditor::_varying_select_item(Ref<VisualShaderNodeVarying> p_varying, String p_name) { @@ -4177,11 +4201,11 @@ void VisualShaderEditor::_varying_select_item(Ref<VisualShaderNodeVarying> p_var bool is_getter = Ref<VisualShaderNodeVaryingGetter>(p_varying.ptr()).is_valid(); - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); - undo_redo->create_action(TTR("Varying Name Changed")); + Ref<EditorUndoRedoManager> &undo_redo_man = EditorNode::get_undo_redo(); + undo_redo_man->create_action(TTR("Varying Name Changed")); - undo_redo->add_do_method(p_varying.ptr(), "set_varying_name", p_name); - undo_redo->add_undo_method(p_varying.ptr(), "set_varying_name", prev_name); + undo_redo_man->add_do_method(p_varying.ptr(), "set_varying_name", p_name); + undo_redo_man->add_undo_method(p_varying.ptr(), "set_varying_name", prev_name); VisualShader::VaryingType vtype = p_varying->get_varying_type_by_name(p_name); VisualShader::VaryingType prev_vtype = p_varying->get_varying_type_by_name(prev_name); @@ -4189,8 +4213,8 @@ void VisualShaderEditor::_varying_select_item(Ref<VisualShaderNodeVarying> p_var bool type_changed = vtype != prev_vtype; if (type_changed) { - undo_redo->add_do_method(p_varying.ptr(), "set_varying_type", vtype); - undo_redo->add_undo_method(p_varying.ptr(), "set_varying_type", prev_vtype); + undo_redo_man->add_do_method(p_varying.ptr(), "set_varying_type", vtype); + undo_redo_man->add_undo_method(p_varying.ptr(), "set_varying_type", prev_vtype); } // update ports @@ -4209,32 +4233,32 @@ void VisualShaderEditor::_varying_select_item(Ref<VisualShaderNodeVarying> p_var if (visual_shader->is_port_types_compatible(p_varying->get_varying_type_by_name(p_name), visual_shader->get_node(type, E.to_node)->get_input_port_type(E.to_port))) { continue; } - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); } } else { if (E.to_node == id) { if (visual_shader->is_port_types_compatible(p_varying->get_varying_type_by_name(p_name), visual_shader->get_node(type, E.from_node)->get_output_port_type(E.from_port))) { continue; } - undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); + undo_redo_man->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port); } } } } - undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, id); - undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id); + undo_redo_man->add_do_method(graph_plugin.ptr(), "update_node", type_id, id); + undo_redo_man->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id); break; } } - undo_redo->commit_action(); + undo_redo_man->commit_action(); } void VisualShaderEditor::_float_constant_selected(int p_which) { @@ -4248,6 +4272,7 @@ void VisualShaderEditor::_float_constant_selected(int p_which) { return; // same } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(vformat(TTR("Set Constant: %s"), float_constant_defs[p_which].name)); undo_redo->add_do_method(node.ptr(), "set_constant", float_constant_defs[p_which].value); undo_redo->add_undo_method(node.ptr(), "set_constant", node->get_constant()); @@ -4336,7 +4361,7 @@ void VisualShaderEditor::_update_varying_tree() { } } - varying_options->set_item_disabled(int(VaryingMenuOptions::REMOVE), count == 0); + varying_button->get_popup()->set_item_disabled(int(VaryingMenuOptions::REMOVE), count == 0); } void VisualShaderEditor::_varying_create() { @@ -4508,6 +4533,7 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da saved_node_pos_dirty = true; _add_node(idx, add_options[idx].ops); } else if (d.has("files")) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Node(s) to Visual Shader")); if (d["files"].get_type() == Variant::PACKED_STRING_ARRAY) { @@ -4515,8 +4541,8 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da for (int i = 0; i < arr.size(); i++) { String type = ResourceLoader::get_resource_type(arr[i]); if (type == "GDScript") { - Ref<Script> script = ResourceLoader::load(arr[i]); - if (script->get_instance_base_type() == "VisualShaderNodeCustom") { + Ref<Script> scr = ResourceLoader::load(arr[i]); + if (scr->get_instance_base_type() == "VisualShaderNodeCustom") { saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE); saved_node_pos_dirty = true; @@ -4686,9 +4712,9 @@ VisualShaderEditor::VisualShaderEditor() { graph->set_show_zoom_label(true); add_child(graph); graph->set_drag_forwarding(this); - float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); + float graph_minimap_opacity = EDITOR_GET("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); - float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); + float graph_lines_curvature = EDITOR_GET("editors/visual_editors/lines_curvature"); graph->set_connection_lines_curvature(graph_lines_curvature); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT); @@ -4811,17 +4837,15 @@ VisualShaderEditor::VisualShaderEditor() { graph->get_zoom_hbox()->move_child(add_node, 0); add_node->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_members_dialog).bind(false, VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PORT_TYPE_MAX)); - varying_button = memnew(Button); - varying_button->set_flat(true); + varying_button = memnew(MenuButton); varying_button->set_text(TTR("Manage Varyings")); + varying_button->set_switch_on_hover(true); graph->get_zoom_hbox()->add_child(varying_button); - varying_button->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_varying_menu)); - varying_options = memnew(PopupMenu); - add_child(varying_options); - varying_options->add_item(TTR("Add Varying"), int(VaryingMenuOptions::ADD)); - varying_options->add_item(TTR("Remove Varying"), int(VaryingMenuOptions::REMOVE)); - varying_options->connect("id_pressed", callable_mp(this, &VisualShaderEditor::_varying_menu_id_pressed)); + PopupMenu *varying_menu = varying_button->get_popup(); + varying_menu->add_item(TTR("Add Varying"), int(VaryingMenuOptions::ADD)); + varying_menu->add_item(TTR("Remove Varying"), int(VaryingMenuOptions::REMOVE)); + varying_menu->connect("id_pressed", callable_mp(this, &VisualShaderEditor::_varying_menu_id_pressed)); preview_shader = memnew(Button); preview_shader->set_flat(true); @@ -5087,23 +5111,23 @@ VisualShaderEditor::VisualShaderEditor() { const String &compare_func_desc = TTR("Returns the boolean result of the %s comparison between two parameters."); - add_options.push_back(AddOption("Equal", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Equal (==)")), { VisualShaderNodeCompare::FUNC_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("GreaterThan", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than (>)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("GreaterThanEqual", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than or Equal (>=)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("Equal (==)", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Equal (==)")), { VisualShaderNodeCompare::FUNC_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("GreaterThan (>)", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than (>)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("GreaterThanEqual (>=)", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than or Equal (>=)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("If", "Conditional/Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("IsInf", "Conditional/Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF and a scalar parameter."), { VisualShaderNodeIs::FUNC_IS_INF }, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("IsNaN", "Conditional/Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between NaN and a scalar parameter."), { VisualShaderNodeIs::FUNC_IS_NAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("LessThan", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), { VisualShaderNodeCompare::FUNC_LESS_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("LessThanEqual", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), { VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("NotEqual", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), { VisualShaderNodeCompare::FUNC_NOT_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("Switch", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 3D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Switch2D", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 2D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("SwitchBool", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_BOOLEAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("SwitchFloat", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_FLOAT }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("SwitchInt", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated integer scalar if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_INT }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("SwitchTransform", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated transform if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_TRANSFORM }, VisualShaderNode::PORT_TYPE_TRANSFORM)); - - add_options.push_back(AddOption("Compare", "Conditional/Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("LessThan (<)", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), { VisualShaderNodeCompare::FUNC_LESS_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("LessThanEqual (<=)", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), { VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("NotEqual (!=)", "Conditional/Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), { VisualShaderNodeCompare::FUNC_NOT_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("Switch (==)", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 3D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Switch2D (==)", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 2D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("SwitchBool (==)", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_BOOLEAN }, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("SwitchFloat (==)", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_FLOAT }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SwitchInt (==)", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated integer scalar if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_INT }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("SwitchTransform (==)", "Conditional/Functions", "VisualShaderNodeSwitch", TTR("Returns an associated transform if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_TRANSFORM }, VisualShaderNode::PORT_TYPE_TRANSFORM)); + + add_options.push_back(AddOption("Compare (==)", "Conditional/Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("Is", "Conditional/Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("BooleanConstant", "Conditional/Variables", "VisualShaderNodeBooleanConstant", TTR("Boolean constant."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN)); @@ -5246,6 +5270,9 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Light", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light", "LIGHT"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("LightColor", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color", "LIGHT_COLOR"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("LightPosition", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_position", "LIGHT_POSITION"), { "light_position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightDirection", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_direction", "LIGHT_DIRECTION"), { "light_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightIsDirectional", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_is_directional", "LIGHT_IS_DIRECTIONAL"), { "light_is_directional" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightEnergy", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_energy", "LIGHT_ENERGY"), { "light_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("LightVertex", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "light_vertex", "LIGHT_VERTEX"), { "light_vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("Normal", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal", "NORMAL"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("PointCoord", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord", "POINT_COORD"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); @@ -5305,7 +5332,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("EmitParticle", "Particles", "VisualShaderNodeParticleEmit", "", {}, -1, TYPE_FLAGS_PROCESS | TYPE_FLAGS_PROCESS_CUSTOM | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("ParticleAccelerator", "Particles", "VisualShaderNodeParticleAccelerator", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("ParticleRandomness", "Particles", "VisualShaderNodeParticleRandomness", "", {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles/Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", TTR("A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("MultiplyByAxisAngle (*)", "Particles/Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", TTR("A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("BoxEmitter", "Particles/Emitters", "VisualShaderNodeParticleBoxEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("MeshEmitter", "Particles/Emitters", "VisualShaderNodeParticleMeshEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); @@ -5356,10 +5383,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Max", "Scalar/Functions", "VisualShaderNodeFloatOp", TTR("Returns the greater of two values."), { VisualShaderNodeFloatOp::OP_MAX }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Min", "Scalar/Functions", "VisualShaderNodeFloatOp", TTR("Returns the lesser of two values."), { VisualShaderNodeFloatOp::OP_MIN }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Mix", "Scalar/Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two scalars."), { VisualShaderNodeMix::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("MultiplyAdd", "Scalar/Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on scalars."), { VisualShaderNodeMultiplyAdd::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Negate", "Scalar/Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeFloatFunc::FUNC_NEGATE }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Negate", "Scalar/Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeIntFunc::FUNC_NEGATE }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("OneMinus", "Scalar/Functions", "VisualShaderNodeFloatFunc", TTR("1.0 - scalar"), { VisualShaderNodeFloatFunc::FUNC_ONEMINUS }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("MultiplyAdd (a * b + c)", "Scalar/Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on scalars."), { VisualShaderNodeMultiplyAdd::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Negate (*-1)", "Scalar/Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeFloatFunc::FUNC_NEGATE }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Negate (*-1)", "Scalar/Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeIntFunc::FUNC_NEGATE }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("OneMinus (1-)", "Scalar/Functions", "VisualShaderNodeFloatFunc", TTR("1.0 - scalar"), { VisualShaderNodeFloatFunc::FUNC_ONEMINUS }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Pow", "Scalar/Functions", "VisualShaderNodeFloatOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeFloatOp::OP_POW }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Radians", "Scalar/Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeFloatFunc::FUNC_RADIANS }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Reciprocal", "Scalar/Functions", "VisualShaderNodeFloatFunc", TTR("1.0 / scalar"), { VisualShaderNodeFloatFunc::FUNC_RECIPROCAL }, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -5378,21 +5405,21 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("TanH", "Scalar/Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeFloatFunc::FUNC_TANH }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Trunc", "Scalar/Functions", "VisualShaderNodeFloatFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeFloatFunc::FUNC_TRUNC }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Add", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Sums two floating-point scalars."), { VisualShaderNodeFloatOp::OP_ADD }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Add", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Sums two integer scalars."), { VisualShaderNodeIntOp::OP_ADD }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("BitwiseAND", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise AND (a & b) operation for two integers."), { VisualShaderNodeIntOp::OP_BITWISE_AND }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("BitwiseLeftShift", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise left shift (a << b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_LEFT_SHIFT }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("BitwiseOR", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise OR (a | b) operation for two integers."), { VisualShaderNodeIntOp::OP_BITWISE_OR }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("BitwiseRightShift", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise right shift (a >> b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_RIGHT_SHIFT }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("BitwiseXOR", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise XOR (a ^ b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_XOR }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("Divide", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Divides two floating-point scalars."), { VisualShaderNodeFloatOp::OP_DIV }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Divide", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Divides two integer scalars."), { VisualShaderNodeIntOp::OP_DIV }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("Multiply", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Multiplies two floating-point scalars."), { VisualShaderNodeFloatOp::OP_MUL }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Multiply", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Multiplies two integer scalars."), { VisualShaderNodeIntOp::OP_MUL }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Add (+)", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Sums two floating-point scalars."), { VisualShaderNodeFloatOp::OP_ADD }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Add (+)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Sums two integer scalars."), { VisualShaderNodeIntOp::OP_ADD }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseAND (&)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise AND (a & b) operation for two integers."), { VisualShaderNodeIntOp::OP_BITWISE_AND }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseLeftShift (<<)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise left shift (a << b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_LEFT_SHIFT }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseOR (|)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise OR (a | b) operation for two integers."), { VisualShaderNodeIntOp::OP_BITWISE_OR }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseRightShift (>>)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise right shift (a >> b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_RIGHT_SHIFT }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseXOR (^)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise XOR (a ^ b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_XOR }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Divide (/)", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Divides two floating-point scalars."), { VisualShaderNodeFloatOp::OP_DIV }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Divide (/)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Divides two integer scalars."), { VisualShaderNodeIntOp::OP_DIV }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Multiply (*)", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Multiplies two floating-point scalars."), { VisualShaderNodeFloatOp::OP_MUL }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Multiply (*)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Multiplies two integer scalars."), { VisualShaderNodeIntOp::OP_MUL }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); add_options.push_back(AddOption("Remainder", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Returns the remainder of the two floating-point scalars."), { VisualShaderNodeFloatOp::OP_MOD }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Remainder", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Returns the remainder of the two integer scalars."), { VisualShaderNodeIntOp::OP_MOD }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); - add_options.push_back(AddOption("Subtract", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Subtracts two floating-point scalars."), { VisualShaderNodeFloatOp::OP_SUB }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Subtract", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Subtracts two integer scalars."), { VisualShaderNodeIntOp::OP_SUB }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Subtract (-)", "Scalar/Operators", "VisualShaderNodeFloatOp", TTR("Subtracts two floating-point scalars."), { VisualShaderNodeFloatOp::OP_SUB }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Subtract (-)", "Scalar/Operators", "VisualShaderNodeIntOp", TTR("Subtracts two integer scalars."), { VisualShaderNodeIntOp::OP_SUB }, VisualShaderNode::PORT_TYPE_SCALAR_INT)); add_options.push_back(AddOption("FloatConstant", "Scalar/Variables", "VisualShaderNodeFloatConstant", TTR("Scalar floating-point constant."), {}, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("IntConstant", "Scalar/Variables", "VisualShaderNodeIntConstant", TTR("Scalar integer constant."), {}, VisualShaderNode::PORT_TYPE_SCALAR_INT)); @@ -5449,12 +5476,12 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Inverse", "Transform/Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), { VisualShaderNodeTransformFunc::FUNC_INVERSE }, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("Transpose", "Transform/Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), { VisualShaderNodeTransformFunc::FUNC_TRANSPOSE }, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("Add", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Sums two transforms."), { VisualShaderNodeTransformOp::OP_ADD }, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("Divide", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Divides two transforms."), { VisualShaderNodeTransformOp::OP_A_DIV_B }, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("Multiply", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Multiplies two transforms."), { VisualShaderNodeTransformOp::OP_AxB }, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("MultiplyComp", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Performs per-component multiplication of two transforms."), { VisualShaderNodeTransformOp::OP_AxB_COMP }, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("Subtract", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Subtracts two transforms."), { VisualShaderNodeTransformOp::OP_A_MINUS_B }, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("TransformVectorMult", "Transform/Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Add (+)", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Sums two transforms."), { VisualShaderNodeTransformOp::OP_ADD }, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("Divide (/)", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Divides two transforms."), { VisualShaderNodeTransformOp::OP_A_DIV_B }, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("Multiply (*)", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Multiplies two transforms."), { VisualShaderNodeTransformOp::OP_AxB }, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("MultiplyComp (*)", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Performs per-component multiplication of two transforms."), { VisualShaderNodeTransformOp::OP_AxB_COMP }, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("Subtract (-)", "Transform/Operators", "VisualShaderNodeTransformOp", TTR("Subtracts two transforms."), { VisualShaderNodeTransformOp::OP_A_MINUS_B }, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("TransformVectorMult (*)", "Transform/Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("TransformConstant", "Transform/Variables", "VisualShaderNodeTransformConstant", TTR("Transform constant."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("TransformParameter", "Transform/Variables", "VisualShaderNodeTransformParameter", TTR("Transform parameter."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM)); @@ -5570,21 +5597,21 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("MixS", "Vector/Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("MixS", "Vector/Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("MixS", "Vector/Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_4D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("MultiplyAdd", "Vector/Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("MultiplyAdd", "Vector/Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("MultiplyAdd", "Vector/Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Negate", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Negate", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Negate", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("MultiplyAdd (a * b + c)", "Vector/Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("MultiplyAdd (a * b + c)", "Vector/Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("MultiplyAdd (a * b + c)", "Vector/Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Negate (*-1)", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Negate (*-1)", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Negate (*-1)", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); add_options.push_back(AddOption("Normalize", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Normalize", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Normalize", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("OneMinus", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("OneMinus", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("OneMinus", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Pow", "Vector/Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Pow", "Vector/Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Pow", "Vector/Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("OneMinus (1-)", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("OneMinus (1-)", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("OneMinus (1-)", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Pow (^)", "Vector/Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Pow (^)", "Vector/Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Pow (^)", "Vector/Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); add_options.push_back(AddOption("Radians", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Radians", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Radians", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); @@ -5629,9 +5656,9 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("StepS", "Vector/Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("StepS", "Vector/Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("StepS", "Vector/Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_4D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Sum", "Vector/Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); - add_options.push_back(AddOption("Sum", "Vector/Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); - add_options.push_back(AddOption("Sum", "Vector/Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); + add_options.push_back(AddOption("Sum (+)", "Vector/Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); + add_options.push_back(AddOption("Sum (+)", "Vector/Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); + add_options.push_back(AddOption("Sum (+)", "Vector/Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true)); add_options.push_back(AddOption("Tan", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Tan", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Tan", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); @@ -5642,21 +5669,21 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Trunc", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Trunc", "Vector/Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Add", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Adds 2D vector to 2D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Add", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Adds 3D vector to 3D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Add", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Adds 4D vector to 4D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Divide", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Divides 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Divide", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Divides 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Divide", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Divides 4D vector by 4D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Multiply", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Multiply", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Multiply", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 4D vector by 4D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Add (+)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Adds 2D vector to 2D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Add (+)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Adds 3D vector to 3D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Add (+)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Adds 4D vector to 4D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Divide (/)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Divides 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Divide (/)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Divides 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Divide (/)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Divides 4D vector by 4D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Multiply (*)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Multiply (*)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Multiply (*)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 4D vector by 4D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); add_options.push_back(AddOption("Remainder", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 2D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Remainder", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 3D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Remainder", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 4D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Subtract", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 2D vector from 2D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Subtract", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); - add_options.push_back(AddOption("Subtract", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 4D vector from 4D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); + add_options.push_back(AddOption("Subtract (-)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 2D vector from 2D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Subtract (-)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); + add_options.push_back(AddOption("Subtract (-)", "Vector/Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 4D vector from 4D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); add_options.push_back(AddOption("Vector2Constant", "Vector/Variables", "VisualShaderNodeVec2Constant", TTR("2D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Vector2Parameter", "Vector/Variables", "VisualShaderNodeVec2Parameter", TTR("2D vector parameter."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); @@ -5682,8 +5709,6 @@ VisualShaderEditor::VisualShaderEditor() { _update_options_menu(); - undo_redo = EditorNode::get_undo_redo(); - Ref<VisualShaderNodePluginDefault> default_plugin; default_plugin.instantiate(); default_plugin->set_editor(this); @@ -5891,7 +5916,7 @@ public: return; } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); updating = true; undo_redo->create_action(TTR("Edit Visual Property:") + " " + p_property, UndoRedo::MERGE_ENDS); @@ -6093,7 +6118,7 @@ void EditorPropertyVisualShaderMode::_option_selected(int p_which) { return; } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Visual Shader Mode Changed")); //do is easy undo_redo->add_do_method(visual_shader.ptr(), "set_mode", p_which); @@ -6226,9 +6251,9 @@ void VisualShaderNodePortPreview::_shader_changed() { } } - Ref<ShaderMaterial> material; - material.instantiate(); - material->set_shader(preview_shader); + Ref<ShaderMaterial> mat; + mat.instantiate(); + mat->set_shader(preview_shader); //find if a material is also being edited and copy parameters to this one @@ -6249,12 +6274,12 @@ void VisualShaderNodePortPreview::_shader_changed() { List<PropertyInfo> params; src_mat->get_shader()->get_shader_uniform_list(¶ms); for (const PropertyInfo &E : params) { - material->set(E.name, src_mat->get(E.name)); + mat->set(E.name, src_mat->get(E.name)); } } } - set_material(material); + set_material(mat); } void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, VisualShader::Type p_type, int p_node, int p_port) { @@ -6268,7 +6293,7 @@ void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, Visua } Size2 VisualShaderNodePortPreview::get_minimum_size() const { - int port_preview_size = EditorSettings::get_singleton()->get("editors/visual_editors/visual_shader/port_preview_size"); + int port_preview_size = EDITOR_GET("editors/visual_editors/visual_shader/port_preview_size"); return Size2(port_preview_size, port_preview_size) * EDSCALE; } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index f7e033d753..8afad9f668 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -32,23 +32,21 @@ #define VISUAL_SHADER_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" +#include "editor/editor_properties.h" #include "editor/plugins/editor_resource_conversion_plugin.h" +#include "scene/resources/syntax_highlighter.h" #include "scene/resources/visual_shader.h" -class Button; class CodeEdit; -class CodeHighlighter; class CurveEditor; class GraphEdit; class GraphNode; -class PopupMenu; +class MenuButton; class PopupPanel; class RichTextLabel; -class TextEdit; class Tree; class VisualShaderEditor; -class EditorUndoRedoManager; class VisualShaderNodePlugin : public RefCounted { GDCLASS(VisualShaderNodePlugin, RefCounted); @@ -172,8 +170,7 @@ class VisualShaderEditor : public VBoxContainer { Ref<VisualShader> visual_shader; GraphEdit *graph = nullptr; Button *add_node = nullptr; - Button *varying_button = nullptr; - PopupMenu *varying_options = nullptr; + MenuButton *varying_button = nullptr; Button *preview_shader = nullptr; OptionButton *edit_type = nullptr; @@ -193,7 +190,6 @@ class VisualShaderEditor : public VBoxContainer { PanelContainer *error_panel = nullptr; Label *error_label = nullptr; - Ref<EditorUndoRedoManager> undo_redo; Point2 saved_node_pos; bool saved_node_pos_dirty = false; @@ -290,7 +286,6 @@ class VisualShaderEditor : public VBoxContainer { void _tools_menu_option(int p_idx); void _show_members_dialog(bool at_mouse_pos, VisualShaderNode::PortType p_input_port_type = VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PortType p_output_port_type = VisualShaderNode::PORT_TYPE_MAX); - void _show_varying_menu(); void _varying_menu_id_pressed(int p_idx); void _show_add_varying_dialog(); void _show_remove_varying_dialog(); diff --git a/editor/plugins/voxel_gi_editor_plugin.h b/editor/plugins/voxel_gi_editor_plugin.h index 43d6f71e26..feff3b4f35 100644 --- a/editor/plugins/voxel_gi_editor_plugin.h +++ b/editor/plugins/voxel_gi_editor_plugin.h @@ -37,6 +37,7 @@ class EditorFileDialog; struct EditorProgress; +class HBoxContainer; class VoxelGIEditorPlugin : public EditorPlugin { GDCLASS(VoxelGIEditorPlugin, EditorPlugin); diff --git a/editor/pot_generator.cpp b/editor/pot_generator.cpp index a00df0ef40..d6b69e10db 100644 --- a/editor/pot_generator.cpp +++ b/editor/pot_generator.cpp @@ -63,7 +63,7 @@ void POTGenerator::generate_pot(const String &p_file) { // Clear all_translation_strings of the previous round. all_translation_strings.clear(); - Vector<String> files = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); + Vector<String> files = GLOBAL_GET("internationalization/locale/translations_pot_files"); // Collect all translatable strings according to files order in "POT Generation" setting. for (int i = 0; i < files.size(); i++) { @@ -99,8 +99,8 @@ void POTGenerator::_write_to_pot(const String &p_file) { return; } - String project_name = ProjectSettings::get_singleton()->get("application/config/name"); - Vector<String> files = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"); + String project_name = GLOBAL_GET("application/config/name"); + Vector<String> files = GLOBAL_GET("internationalization/locale/translations_pot_files"); String extracted_files = ""; for (int i = 0; i < files.size(); i++) { extracted_files += "# " + files[i] + "\n"; diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index 39b30b31fb..d42dc3c3bf 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -38,6 +38,7 @@ const int ERROR_CODE = 77; #include "modules/regex/regex.h" +#include "core/io/dir_access.h" #include "core/os/time.h" #include "core/templates/hash_map.h" #include "core/templates/list.h" @@ -216,6 +217,7 @@ static const char *gdscript_function_renames[][2] = { { "_get_configuration_warning", "_get_configuration_warnings" }, // Node { "_set_current", "set_current" }, // Camera2D { "_set_editor_description", "set_editor_description" }, // Node + { "_set_playing", "set_playing" }, // AnimatedSprite3D { "_toplevel_raise_self", "_top_level_raise_self" }, // CanvasItem { "_update_wrap_at", "_update_wrap_at_column" }, // TextEdit { "add_animation", "add_animation_library" }, // AnimationPlayer @@ -228,8 +230,10 @@ static const char *gdscript_function_renames[][2] = { { "add_force", "apply_force" }, //RigidBody2D { "add_icon_override", "add_theme_icon_override" }, // Control { "add_scene_import_plugin", "add_scene_format_importer_plugin" }, //EditorPlugin + { "add_spatial_gizmo_plugin", "add_node_3d_gizmo_plugin" }, // EditorPlugin { "add_stylebox_override", "add_theme_stylebox_override" }, // Control { "add_torque", "apply_torque" }, //RigidBody2D + { "agent_set_neighbor_dist", "agent_set_neighbor_distance" }, // NavigationServer2D, NavigationServer3D { "apply_changes", "_apply_changes" }, // EditorPlugin { "body_add_force", "body_apply_force" }, // PhysicsServer2D { "body_add_torque", "body_apply_torque" }, // PhysicsServer2D @@ -280,7 +284,7 @@ static const char *gdscript_function_renames[][2] = { { "get_applied_torque", "get_constant_torque" }, //RigidBody2D { "get_audio_bus", "get_audio_bus_name" }, // Area3D { "get_bound_child_nodes_to_bone", "get_bone_children" }, // Skeleton3D - { "get_camera", "get_camera_3d" }, // Viewport -> this is also convertable to get_camera_2d, broke GLTFNode + { "get_camera", "get_camera_3d" }, // Viewport -> this is also convertible to get_camera_2d, broke GLTFNode { "get_cancel", "get_cancel_button" }, // ConfirmationDialog { "get_caption", "_get_caption" }, // AnimationNode { "get_cast_to", "get_target_position" }, // RayCast2D, RayCast3D @@ -298,6 +302,7 @@ static const char *gdscript_function_renames[][2] = { { "get_cull_mask_bit", "get_cull_mask_value" }, // Camera3D { "get_cursor_position", "get_caret_column" }, // LineEdit { "get_d", "get_distance" }, // LineShape2D + { "get_depth_bias_enable", "get_depth_bias_enabled" }, // RDPipelineRasterizationState { "get_drag_data", "_get_drag_data" }, // Control { "get_drag_data_fw", "_get_drag_data_fw" }, // ScriptEditor { "get_editor_viewport", "get_editor_main_screen" }, // EditorPlugin @@ -306,6 +311,7 @@ static const char *gdscript_function_renames[][2] = { { "get_error_string", "get_error_message" }, // JSON { "get_filename", "get_scene_file_path" }, // Node, WARNING, this may be used in a lot of other places { "get_focus_neighbour", "get_focus_neighbor" }, // Control + { "get_follow_smoothing", "get_position_smoothing_speed" }, // Camera2D { "get_font_types", "get_font_type_list" }, // Theme { "get_frame_color", "get_color" }, // ColorRect { "get_global_rate_scale", "get_playback_speed_scale" }, // AudioServer @@ -331,6 +337,7 @@ static const char *gdscript_function_renames[][2] = { { "get_metakey", "is_meta_pressed" }, // InputEventWithModifiers { "get_mid_height", "get_height" }, // CapsuleMesh { "get_motion_remainder", "get_remainder" }, // PhysicsTestMotionResult2D + { "get_neighbor_dist", "get_neighbor_distance" }, // NavigationAgent2D, NavigationAgent3D { "get_network_connected_peers", "get_peers" }, // Multiplayer API { "get_network_master", "get_multiplayer_authority" }, // Node { "get_network_peer", "get_multiplayer_peer" }, // Multiplayer API @@ -353,16 +360,19 @@ static const char *gdscript_function_renames[][2] = { { "get_render_targetsize", "get_render_target_size" }, // XRInterface { "get_resource_type", "_get_resource_type" }, // ResourceFormatLoader { "get_result", "get_data" }, //JSON + { "get_reverb_bus", "set_reverb_bus_name" }, // Area3D { "get_rpc_sender_id", "get_remote_sender_id" }, // Multiplayer API { "get_save_extension", "_get_save_extension" }, // EditorImportPlugin { "get_scancode", "get_keycode" }, // InputEventKey { "get_scancode_string", "get_keycode_string" }, // OS { "get_scancode_with_modifiers", "get_keycode_with_modifiers" }, // InputEventKey + { "get_selected_path", "get_current_directory" }, // EditorInterface { "get_shift", "is_shift_pressed" }, // InputEventWithModifiers { "get_size_override", "get_size_2d_override" }, // SubViewport { "get_slide_count", "get_slide_collision_count" }, // CharacterBody2D, CharacterBody3D { "get_slips_on_slope", "get_slide_on_slope" }, // SeparationRayShape2D, SeparationRayShape3D { "get_space_override_mode", "get_gravity_space_override_mode" }, // Area2D + { "get_spatial_node", "get_node_3d" }, // EditorNode3DGizmo { "get_speed", "get_velocity" }, // InputEventMouseMotion { "get_stylebox_types", "get_stylebox_type_list" }, // Theme { "get_surface_material", "get_surface_override_material" }, // MeshInstance3D broke ImporterMesh @@ -373,6 +383,7 @@ static const char *gdscript_function_renames[][2] = { { "get_theme_item_types", "get_theme_item_type_list" }, // Theme { "get_timer_process_mode", "get_timer_process_callback" }, // Timer { "get_translation", "get_position" }, // Node3D broke GLTFNode which is used rarely + { "get_unit_db", "get_volume_db" }, // AudioStreamPlayer3D { "get_unit_offset", "get_progress_ratio" }, // PathFollow2D, PathFollow3D { "get_use_in_baked_light", "is_baking_navigation" }, // GridMap { "get_used_cells_by_id", "get_used_cells" }, // TileMap @@ -410,6 +421,7 @@ static const char *gdscript_function_renames[][2] = { { "is_commiting_action", "is_committing_action" }, // UndoRedo { "is_doubleclick", "is_double_click" }, // InputEventMouseButton { "is_draw_red", "is_draw_warning" }, // EditorProperty + { "is_follow_smoothing_enabled", "is_position_smoothing_enabled" }, // Camera2D { "is_h_drag_enabled", "is_drag_horizontal_enabled" }, // Camera2D { "is_handle_highlighted", "_is_handle_highlighted" }, // EditorNode3DGizmo, EditorNode3DGizmoPlugin { "is_inverting_faces", "get_flip_faces" }, // CSGPrimitive3D @@ -418,6 +430,7 @@ static const char *gdscript_function_renames[][2] = { { "is_normalmap", "is_normal_map" }, // NoiseTexture { "is_refusing_new_network_connections", "is_refusing_new_connections" }, // Multiplayer API { "is_region", "is_region_enabled" }, // Sprite2D + { "is_rotating", "is_ignoring_rotation" }, // Camera2D { "is_scancode_unicode", "is_keycode_unicode" }, // OS { "is_selectable_when_hidden", "_is_selectable_when_hidden" }, // EditorNode3DGizmoPlugin { "is_set_as_toplevel", "is_set_as_top_level" }, // CanvasItem @@ -452,6 +465,7 @@ static const char *gdscript_function_renames[][2] = { { "post_import", "_post_import" }, // EditorScenePostImport { "print_stray_nodes", "print_orphan_nodes" }, // Node { "property_list_changed_notify", "notify_property_list_changed" }, // Object + { "raise", "move_to_front" }, // CanvasItem { "recognize", "_recognize" }, // ResourceFormatLoader { "regen_normalmaps", "regen_normal_maps" }, // ArrayMesh { "remove", "remove_at" }, // Array, broke Directory @@ -461,6 +475,7 @@ static const char *gdscript_function_renames[][2] = { { "remove_font_override", "remove_theme_font_override" }, // Control { "remove_icon_override", "remove_theme_icon_override" }, // Control { "remove_scene_import_plugin", "remove_scene_format_importer_plugin" }, //EditorPlugin + { "remove_spatial_gizmo_plugin", "remove_node_3d_gizmo_plugin" }, // EditorPlugin { "remove_stylebox_override", "remove_theme_stylebox_override" }, // Control { "rename_animation", "rename_animation_library" }, // AnimationPlayer { "rename_dependencies", "_rename_dependencies" }, // ResourceFormatLoader @@ -486,13 +501,16 @@ static const char *gdscript_function_renames[][2] = { { "set_cull_mask_bit", "set_cull_mask_value" }, // Camera3D { "set_cursor_position", "set_caret_column" }, // LineEdit { "set_d", "set_distance" }, // WorldMarginShape2D + { "set_depth_bias_enable", "set_depth_bias_enabled" }, // RDPipelineRasterizationState { "set_doubleclick", "set_double_click" }, // InputEventMouseButton { "set_draw_red", "set_draw_warning" }, // EditorProperty + { "set_enable_follow_smoothing", "set_position_smoothing_enabled" }, // Camera2D { "set_enabled_focus_mode", "set_focus_mode" }, // BaseButton { "set_endian_swap", "set_big_endian" }, // File { "set_expand_to_text_length", "set_expand_to_text_length_enabled" }, // LineEdit { "set_filename", "set_scene_file_path" }, // Node, WARNING, this may be used in a lot of other places { "set_focus_neighbour", "set_focus_neighbor" }, // Control + { "set_follow_smoothing", "set_position_smoothing_speed" }, // Camera2D { "set_frame_color", "set_color" }, // ColorRect { "set_global_rate_scale", "set_playback_speed_scale" }, // AudioServer { "set_gravity_distance_scale", "set_gravity_point_distance_scale" }, // Area2D @@ -510,14 +528,17 @@ static const char *gdscript_function_renames[][2] = { { "set_max_atlas_size", "set_max_texture_size" }, // LightmapGI { "set_metakey", "set_meta_pressed" }, // InputEventWithModifiers { "set_mid_height", "set_height" }, // CapsuleMesh + { "set_neighbor_dist", "set_neighbor_distance" }, // NavigationAgent2D, NavigationAgent3D { "set_network_master", "set_multiplayer_authority" }, // Node { "set_network_peer", "set_multiplayer_peer" }, // Multiplayer API { "set_oneshot", "set_one_shot" }, // AnimatedTexture { "set_pause_mode", "set_process_mode" }, // Node { "set_physical_scancode", "set_physical_keycode" }, // InputEventKey + { "set_proximity_fade", "set_proximity_fade_enabled" }, // Material { "set_refuse_new_network_connections", "set_refuse_new_connections" }, // Multiplayer API { "set_region", "set_region_enabled" }, // Sprite2D, Sprite broke AtlasTexture { "set_region_filter_clip", "set_region_filter_clip_enabled" }, // Sprite2D + { "set_reverb_bus", "set_reverb_bus_name" }, // Area3D { "set_rotate", "set_rotates" }, // PathFollow2D { "set_scancode", "set_keycode" }, // InputEventKey { "set_shift", "set_shift_pressed" }, // InputEventWithModifiers @@ -526,6 +547,7 @@ static const char *gdscript_function_renames[][2] = { { "set_slips_on_slope", "set_slide_on_slope" }, // SeparationRayShape2D, SeparationRayShape3D { "set_sort_enabled", "set_y_sort_enabled" }, // Node2D { "set_space_override_mode", "set_gravity_space_override_mode" }, // Area2D + { "set_spatial_node", "set_node_3d" }, // EditorNode3DGizmo { "set_speed", "set_velocity" }, // InputEventMouseMotion { "set_ssao_edge_sharpness", "set_ssao_sharpness" }, // Environment { "set_surface_material", "set_surface_override_material" }, // MeshInstance3D broke ImporterMesh @@ -534,6 +556,7 @@ static const char *gdscript_function_renames[][2] = { { "set_text_align", "set_text_alignment" }, // Button { "set_timer_process_mode", "set_timer_process_callback" }, // Timer { "set_translation", "set_position" }, // Node3D - this broke GLTFNode which is used rarely + { "set_unit_db", "set_volume_db" }, // AudioStreamPlayer3D { "set_unit_offset", "set_progress_ratio" }, // PathFollow2D, PathFollow3D { "set_uv2", "surface_set_uv2" }, // ImmediateMesh broke Surffacetool { "set_v_drag_enabled", "set_drag_vertical_enabled" }, // Camera2D @@ -570,6 +593,7 @@ static const char *gdscript_function_renames[][2] = { { "is_abs_path", "is_absolute_path" }, // String { "is_valid_integer", "is_valid_int" }, // String { "linear_interpolate", "lerp" }, // Color + { "find_last", "rfind" }, // Array, String { "to_ascii", "to_ascii_buffer" }, // String { "to_utf8", "to_utf8_buffer" }, // String { "to_wchar", "to_utf32_buffer" }, // String // TODO - utf32 or utf16? @@ -645,11 +669,13 @@ static const char *csharp_function_renames[][2] = { // { "SetVOffset", "SetDragVerticalOffset" }, // Camera2D broke Camera3D, PathFollow3D, PathFollow2D // {"GetPoints","GetPointsId"},// Astar, broke Line2D, Convexpolygonshape // {"GetVScroll","GetVScrollBar"},//ItemList, broke TextView + { "AddSpatialGizmoPlugin", "AddNode3dGizmoPlugin" }, // EditorPlugin { "RenderingServer", "GetTabAlignment" }, // Tab { "_AboutToShow", "_AboutToPopup" }, // ColorPickerButton { "_GetConfigurationWarning", "_GetConfigurationWarnings" }, // Node { "_SetCurrent", "SetCurrent" }, // Camera2D { "_SetEditorDescription", "SetEditorDescription" }, // Node + { "_SetPlaying", "SetPlaying" }, // AnimatedSprite3D { "_ToplevelRaiseSelf", "_TopLevelRaiseSelf" }, // CanvasItem { "_UpdateWrapAt", "_UpdateWrapAtColumn" }, // TextEdit { "AddAnimation", "AddAnimationLibrary" }, // AnimationPlayer @@ -664,6 +690,7 @@ static const char *csharp_function_renames[][2] = { { "AddSceneImportPlugin", "AddSceneFormatImporterPlugin" }, //EditorPlugin { "AddStyleboxOverride", "AddThemeStyleboxOverride" }, // Control { "AddTorque", "AddConstantTorque" }, //RigidBody2D + { "AgentSetNeighborDist", "AgentSetNeighborDistance" }, // NavigationServer2D, NavigationServer3D { "BindChildNodeToBone", "SetBoneChildren" }, // Skeleton3D { "BumpmapToNormalmap", "BumpMapToNormalMap" }, // Image { "CanBeHidden", "_CanBeHidden" }, // EditorNode3DGizmoPlugin @@ -708,7 +735,7 @@ static const char *csharp_function_renames[][2] = { { "GetAppliedTorque", "GetConstantTorque" }, //RigidBody2D { "GetAudioBus", "GetAudioBusName" }, // Area3D { "GetBoundChildNodesToBone", "GetBoneChildren" }, // Skeleton3D - { "GetCamera", "GetCamera3d" }, // Viewport -> this is also convertable to getCamera2d, broke GLTFNode + { "GetCamera", "GetCamera3d" }, // Viewport -> this is also convertible to getCamera2d, broke GLTFNode { "GetCancel", "GetCancelButton" }, // ConfirmationDialog { "GetCaption", "_GetCaption" }, // AnimationNode { "GetCastTo", "GetTargetPosition" }, // RayCast2D, RayCast3D @@ -726,12 +753,14 @@ static const char *csharp_function_renames[][2] = { { "GetCullMaskBit", "GetCullMaskValue" }, // Camera3D { "GetCursorPosition", "GetCaretColumn" }, // LineEdit { "GetD", "GetDistance" }, // LineShape2D + { "GetDepthBiasEnable", "GetDepthBiasEnabled" }, // RDPipelineRasterizationState { "GetDragDataFw", "_GetDragDataFw" }, // ScriptEditor { "GetEditorViewport", "GetViewport" }, // EditorPlugin { "GetEnabledFocusMode", "GetFocusMode" }, // BaseButton { "GetEndianSwap", "IsBigEndian" }, // File { "GetErrorString", "GetErrorMessage" }, // JSON { "GetFocusNeighbour", "GetFocusNeighbor" }, // Control + { "GetFollowSmoothing", "GetFollowSmoothingSpeed" }, // Camera2D { "GetFontTypes", "GetFontTypeList" }, // Theme { "GetFrameColor", "GetColor" }, // ColorRect { "GetGlobalRateScale", "GetPlaybackSpeedScale" }, // AudioServer @@ -757,6 +786,7 @@ static const char *csharp_function_renames[][2] = { { "GetMetakey", "IsMetaPressed" }, // InputEventWithModifiers { "GetMidHeight", "GetHeight" }, // CapsuleMesh { "GetMotionRemainder", "GetRemainder" }, // PhysicsTestMotionResult2D + { "GetNeighborDist", "GetNeighborDistance" }, // NavigationAgent2D, NavigationAgent3D { "GetNetworkConnectedPeers", "GetPeers" }, // Multiplayer API { "GetNetworkMaster", "GetMultiplayerAuthority" }, // Node { "GetNetworkPeer", "GetMultiplayerPeer" }, // Multiplayer API @@ -778,6 +808,7 @@ static const char *csharp_function_renames[][2] = { { "GetRenderTargetsize", "GetRenderTargetSize" }, // XRInterface { "GetResourceType", "_GetResourceType" }, // ResourceFormatLoader { "GetResult", "GetData" }, //JSON + { "GetReverbBus", "GetReverbBusName" }, // Area3D { "GetRpcSenderId", "GetRemoteSenderId" }, // Multiplayer API { "GetSaveExtension", "_GetSaveExtension" }, // EditorImportPlugin { "GetScancode", "GetKeycode" }, // InputEventKey @@ -787,6 +818,7 @@ static const char *csharp_function_renames[][2] = { { "GetSizeOverride", "GetSize2dOverride" }, // SubViewport { "GetSlipsOnSlope", "GetSlideOnSlope" }, // SeparationRayShape2D, SeparationRayShape3D { "GetSpaceOverrideMode", "GetGravitySpaceOverrideMode" }, // Area2D + { "GetSpatialNode", "GetNode3d" }, // EditorNode3DGizmo { "GetSpeed", "GetVelocity" }, // InputEventMouseMotion { "GetStyleboxTypes", "GetStyleboxTypeList" }, // Theme { "GetSurfaceMaterial", "GetSurfaceOverrideMaterial" }, // MeshInstance3D broke ImporterMesh @@ -797,6 +829,7 @@ static const char *csharp_function_renames[][2] = { { "GetThemeItemTypes", "GetThemeItemTypeList" }, // Theme { "GetTimerProcessMode", "GetTimerProcessCallback" }, // Timer { "GetTranslation", "GetPosition" }, // Node3D broke GLTFNode which is used rarely + { "GetUnitDb", "GetVolumeDb" }, // AudioStreamPlayer3D { "GetUnitOffset", "GetProgressRatio" }, // PathFollow2D, PathFollow3D { "GetUseInBakedLight", "IsBakingNavigation" }, // GridMap { "GetUsedCellsById", "GetUsedCells" }, // TileMap @@ -833,6 +866,7 @@ static const char *csharp_function_renames[][2] = { { "IsAParentOf", "IsAncestorOf" }, // Node { "IsCommitingAction", "IsCommittingAction" }, // UndoRedo { "IsDoubleclick", "IsDoubleClick" }, // InputEventMouseButton + { "IsFollowSmoothingEnabled", "IsPositionSmoothingEnabled" }, // Camera2D { "IsHDragEnabled", "IsDragHorizontalEnabled" }, // Camera2D { "IsHandleHighlighted", "_IsHandleHighlighted" }, // EditorNode3DGizmo, EditorNode3DGizmoPlugin { "IsNetworkMaster", "IsMultiplayerAuthority" }, // Node @@ -840,6 +874,7 @@ static const char *csharp_function_renames[][2] = { { "IsNormalmap", "IsNormalMap" }, // NoiseTexture { "IsRefusingNewNetworkConnections", "IsRefusingNewConnections" }, // Multiplayer API { "IsRegion", "IsRegionEnabled" }, // Sprite2D + { "IsRotating", "IsIgnoringRotation" }, // Camera2D { "IsScancodeUnicode", "IsKeycodeUnicode" }, // OS { "IsSelectableWhenHidden", "_IsSelectableWhenHidden" }, // EditorNode3DGizmoPlugin { "IsSetAsToplevel", "IsSetAsTopLevel" }, // CanvasItem @@ -880,6 +915,7 @@ static const char *csharp_function_renames[][2] = { { "RemoveConstantOverride", "RemoveThemeConstantOverride" }, // Control { "RemoveFontOverride", "RemoveThemeFontOverride" }, // Control { "RemoveSceneImportPlugin", "RemoveSceneFormatImporterPlugin" }, //EditorPlugin + { "RemoveSpatialGizmoPlugin", "RemoveNode3dGizmoPlugin" }, // EditorPlugin { "RemoveStyleboxOverride", "RemoveThemeStyleboxOverride" }, // Control { "RenameAnimation", "RenameAnimationLibrary" }, // AnimationPlayer { "RenameDependencies", "_RenameDependencies" }, // ResourceFormatLoader @@ -905,11 +941,14 @@ static const char *csharp_function_renames[][2] = { { "SetCullMaskBit", "SetCullMaskValue" }, // Camera3D { "SetCursorPosition", "SetCaretColumn" }, // LineEdit { "SetD", "SetDistance" }, // WorldMarginShape2D + { "SetDepthBiasEnable", "SetDepthBiasEnabled" }, // RDPipelineRasterizationState { "SetDoubleclick", "SetDoubleClick" }, // InputEventMouseButton + { "SetEnableFollowSmoothing", "SetFollowSmoothingEnabled" }, // Camera2D { "SetEnabledFocusMode", "SetFocusMode" }, // BaseButton { "SetEndianSwap", "SetBigEndian" }, // File { "SetExpandToTextLength", "SetExpandToTextLengthEnabled" }, // LineEdit { "SetFocusNeighbour", "SetFocusNeighbor" }, // Control + { "SetFollowSmoothing", "SetFollowSmoothingSpeed" }, // Camera2D { "SetFrameColor", "SetColor" }, // ColorRect { "SetGlobalRateScale", "SetPlaybackSpeedScale" }, // AudioServer { "SetGravityDistanceScale", "SetGravityPointDistanceScale" }, // Area2D @@ -926,13 +965,16 @@ static const char *csharp_function_renames[][2] = { { "SetMaxAtlasSize", "SetMaxTextureSize" }, // LightmapGI { "SetMetakey", "SetMetaPressed" }, // InputEventWithModifiers { "SetMidHeight", "SetHeight" }, // CapsuleMesh + { "SetNeighborDist", "SetNeighborDistance" }, // NavigationAgent2D, NavigationAgent3D { "SetNetworkMaster", "SetMultiplayerAuthority" }, // Node { "SetNetworkPeer", "SetMultiplayerPeer" }, // Multiplayer API { "SetOneshot", "SetOneShot" }, // AnimatedTexture { "SetPhysicalScancode", "SetPhysicalKeycode" }, // InputEventKey + { "SetProximityFade", "SetProximityFadeEnabled" }, // Material { "SetRefuseNewNetworkConnections", "SetRefuseNewConnections" }, // Multiplayer API { "SetRegion", "SetRegionEnabled" }, // Sprite2D, Sprite broke AtlasTexture { "SetRegionFilterClip", "SetRegionFilterClipEnabled" }, // Sprite2D + { "SetReverbBus", "SetReverbBusName" }, // Area3D { "SetRotate", "SetRotates" }, // PathFollow2D { "SetScancode", "SetKeycode" }, // InputEventKey { "SetShift", "SetShiftPressed" }, // InputEventWithModifiers @@ -941,6 +983,7 @@ static const char *csharp_function_renames[][2] = { { "SetSlipsOnSlope", "SetSlideOnSlope" }, // SeparationRayShape2D, SeparationRayShape3D { "SetSortEnabled", "SetYSortEnabled" }, // Node2D { "SetSpaceOverrideMode", "SetGravitySpaceOverrideMode" }, // Area2D + { "SetSpatialNode", "SetNode3d" }, // EditorNode3DGizmo { "SetSpeed", "SetVelocity" }, // InputEventMouseMotion { "SetSsaoEdgeSharpness", "SetSsaoSharpness" }, // Environment { "SetSurfaceMaterial", "SetSurfaceOverrideMaterial" }, // MeshInstance3D broke ImporterMesh @@ -950,6 +993,7 @@ static const char *csharp_function_renames[][2] = { { "SetTimerProcessMode", "SetTimerProcessCallback" }, // Timer { "SetTonemapAutoExposure", "SetTonemapAutoExposureEnabled" }, // Environment { "SetTranslation", "SetPosition" }, // Node3D - this broke GLTFNode which is used rarely + { "SetUnitDb", "SetVolumeDb" }, // AudioStreamPlayer3D { "SetUnitOffset", "SetProgressRatio" }, // PathFollow2D, PathFollow3D { "SetUv2", "SurfaceSetUv2" }, // ImmediateMesh broke Surffacetool { "SetVDragEnabled", "SetDragVerticalEnabled" }, // Camera2D @@ -1048,6 +1092,7 @@ static const char *gdscript_properties_renames[][2] = { { "close_v_ofs", "close_v_offset" }, // Theme { "commentfocus", "comment_focus" }, // Theme { "contacts_reported", "max_contacts_reported" }, // RigidBody + { "depth_bias_enable", "depth_bias_enabled" }, // RDPipelineRasterizationState { "drag_margin_bottom", "drag_bottom_margin" }, // Camera2D { "drag_margin_h_enabled", "drag_horizontal_enabled" }, // Camera2D { "drag_margin_left", "drag_left_margin" }, // Camera2D @@ -1061,6 +1106,7 @@ static const char *gdscript_properties_renames[][2] = { { "focus_neighbour_left", "focus_neighbor_left" }, // Control { "focus_neighbour_right", "focus_neighbor_right" }, // Control { "focus_neighbour_top", "focus_neighbor_top" }, // Control + { "follow_viewport_enable", "follow_viewport_enabled" }, // CanvasItem { "file_icon_modulate", "file_icon_color" }, // Theme { "files_disabled", "file_disabled_color" }, // Theme { "folder_icon_modulate", "folder_icon_color" }, // Theme @@ -1076,6 +1122,7 @@ static const char *gdscript_properties_renames[][2] = { { "margin_right", "offset_right" }, // Control broke NinePatchRect, StyleBox { "margin_top", "offset_top" }, // Control broke NinePatchRect, StyleBox { "mid_height", "height" }, // CapsuleMesh + { "neighbor_dist", "neighbor_distance" }, // NavigationAgent2D, NavigationAgent3D { "offset_h", "drag_horizontal_offset" }, // Camera2D { "offset_v", "drag_vertical_offset" }, // Camera2D { "off", "unchecked" }, // Theme @@ -1088,6 +1135,7 @@ static const char *gdscript_properties_renames[][2] = { { "pause_mode", "process_mode" }, // Node { "physical_scancode", "physical_keycode" }, // InputEventKey { "popup_exclusive", "exclusive" }, // Window + { "proximity_fade_enable", "proximity_fade_enabled" }, // Material { "rect_position", "position" }, // Control { "rect_global_position", "global_position" }, // Control { "rect_size", "size" }, // Control @@ -1098,9 +1146,12 @@ static const char *gdscript_properties_renames[][2] = { { "rect_clip_content", "clip_contents" }, // Control { "refuse_new_network_connections", "refuse_new_connections" }, // MultiplayerAPI { "region_filter_clip", "region_filter_clip_enabled" }, // Sprite2D + { "reverb_bus_enable", "reverb_bus_enabled" }, // Area3D { "selectedframe", "selected_frame" }, // Theme { "size_override_stretch", "size_2d_override_stretch" }, // SubViewport { "slips_on_slope", "slide_on_slope" }, // SeparationRayShape2D + { "smoothing_enabled", "follow_smoothing_enabled" }, // Camera2D + { "smoothing_speed", "position_smoothing_speed" }, // Camera2D { "ss_reflections_depth_tolerance", "ssr_depth_tolerance" }, // Environment { "ss_reflections_enabled", "ssr_enabled" }, // Environment { "ss_reflections_fade_in", "ssr_fade_in" }, // Environment @@ -1112,6 +1163,7 @@ static const char *gdscript_properties_renames[][2] = { { "table_hseparation", "table_h_separation" }, // Theme { "table_vseparation", "table_v_separation" }, // Theme { "translation", "position" }, // Node3D - broke GLTFNode + { "unit_db", "volume_db" }, // AudioStreamPlayer3D { "unit_offset", "progress_ratio" }, // PathFollow2D, PathFollow3D { "vseparation", "v_separation" }, // Theme @@ -1151,6 +1203,7 @@ static const char *csharp_properties_renames[][2] = { { "CloseHOfs", "CloseHOffset" }, // Theme { "CloseVOfs", "CloseVOffset" }, // Theme { "Commentfocus", "CommentFocus" }, // Theme + { "DepthBiasEnable", "DepthBiasEnabled" }, // RDPipelineRasterizationState { "DragMarginBottom", "DragBottomMargin" }, // Camera2D { "DragMarginHEnabled", "DragHorizontalEnabled" }, // Camera2D { "DragMarginLeft", "DragLeftMargin" }, // Camera2D @@ -1164,6 +1217,7 @@ static const char *csharp_properties_renames[][2] = { { "FocusNeighbourLeft", "FocusNeighborLeft" }, // Control { "FocusNeighbourRight", "FocusNeighborRight" }, // Control { "FocusNeighbourTop", "FocusNeighborTop" }, // Control + { "FollowViewportEnable", "FollowViewportEnabled" }, // CanvasItem { "GlobalRateScale", "PlaybackSpeedScale" }, // AudioServer { "GravityDistanceScale", "GravityPointDistanceScale" }, // Area2D { "GravityVec", "GravityDirection" }, // Area2D @@ -1176,6 +1230,7 @@ static const char *csharp_properties_renames[][2] = { { "MarginRight", "OffsetRight" }, // Control broke NinePatchRect, StyleBox { "MarginTop", "OffsetTop" }, // Control broke NinePatchRect, StyleBox { "MidHeight", "Height" }, // CapsuleMesh + { "NeighborDist", "NeighborDistance" }, // NavigationAgent2D, NavigationAgent3D { "OffsetH", "DragHorizontalOffset" }, // Camera2D { "OffsetV", "DragVerticalOffset" }, // Camera2D { "Ofs", "Offset" }, // Theme @@ -1184,11 +1239,15 @@ static const char *csharp_properties_renames[][2] = { { "PauseMode", "ProcessMode" }, // Node { "PhysicalScancode", "PhysicalKeycode" }, // InputEventKey { "PopupExclusive", "Exclusive" }, // Window + { "ProximityFadeEnable", "ProximityFadeEnabled" }, // Material { "RefuseNewNetworkConnections", "RefuseNewConnections" }, // MultiplayerAPI { "RegionFilterClip", "RegionFilterClipEnabled" }, // Sprite2D + { "ReverbBusEnable", "ReverbBusEnabled" }, // Area3D { "Selectedframe", "SelectedFrame" }, // Theme { "SizeOverrideStretch", "Size2dOverrideStretch" }, // SubViewport { "SlipsOnSlope", "SlideOnSlope" }, // SeparationRayShape2D + { "SmoothingEnabled", "FollowSmoothingEnabled" }, // Camera2D + { "SmoothingSpeed", "FollowSmoothingSpeed" }, // Camera2D { "SsReflectionsDepthTolerance", "SsrDepthTolerance" }, // Environment { "SsReflectionsEnabled", "SsrEnabled" }, // Environment { "SsReflectionsFadeIn", "SsrFadeIn" }, // Environment @@ -1200,6 +1259,7 @@ static const char *csharp_properties_renames[][2] = { { "TableHseparation", "TableHSeparation" }, // Theme { "TableVseparation", "TableVSeparation" }, // Theme { "Translation", "Position" }, // Node3D - broke GLTFNode + { "UnitDb", "VolumeDb" }, // AudioStreamPlayer3D { "UnitOffset", "ProgressRatio" }, // PathFollow2D, PathFollow3D { "Vseparation", "VSeparation" }, // Theme @@ -1713,6 +1773,7 @@ public: RegEx reg_json_to = RegEx("\\bto_json\\b"); RegEx reg_json_parse = RegEx("([\t ]{0,})([^\n]+)parse_json\\(([^\n]+)"); RegEx reg_json_non_new = RegEx("([\t ]{0,})([^\n]+)JSON\\.parse\\(([^\n]+)"); + RegEx reg_json_print = RegEx("\\bJSON\\b\\.print\\("); RegEx reg_export = RegEx("export\\(([a-zA-Z0-9_]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)"); RegEx reg_export_advanced = RegEx("export\\(([^)^\n]+)\\)[ ]+var[ ]+([a-zA-Z0-9_]+)([^\n]+)"); RegEx reg_setget_setget = RegEx("var[ ]+([a-zA-Z0-9_]+)([^\n]+)setget[ \t]+([a-zA-Z0-9_]+)[ \t]*,[ \t]*([a-zA-Z0-9_]+)"); @@ -2112,7 +2173,7 @@ int ProjectConverter3To4::validate_conversion() { lines.append(line); } } - print_line(vformat("Checking for conversion - %d/%d file - \"%s\" with size - %d KB"), i + 1, collected_files.size(), file_name.trim_prefix("res://"), file_size / 1024); + print_line(vformat("Checking for conversion - %d/%d file - \"%s\" with size - %d KB", i + 1, collected_files.size(), file_name.trim_prefix("res://"), file_size / 1024)); Vector<String> changed_elements; Vector<String> reason; @@ -2229,22 +2290,23 @@ Vector<String> ProjectConverter3To4::check_for_files() { Vector<String> directories_to_check = Vector<String>(); directories_to_check.push_back("res://"); - core_bind::Directory dir = core_bind::Directory(); while (!directories_to_check.is_empty()) { String path = directories_to_check.get(directories_to_check.size() - 1); // Is there any pop_back function? - directories_to_check.resize(directories_to_check.size() - 1); // Remove last element. - if (dir.open(path) == OK) { - dir.set_include_hidden(true); - dir.list_dir_begin(); - String current_dir = dir.get_current_dir(); - String file_name = dir.get_next(); + directories_to_check.resize(directories_to_check.size() - 1); // Remove last element + + Ref<DirAccess> dir = DirAccess::open(path); + if (dir.is_valid()) { + dir->set_include_hidden(true); + dir->list_dir_begin(); + String current_dir = dir->get_current_dir(); + String file_name = dir->_get_next(); while (file_name != "") { if (file_name == ".git" || file_name == ".import" || file_name == ".godot") { - file_name = dir.get_next(); + file_name = dir->_get_next(); continue; } - if (dir.current_is_dir()) { + if (dir->current_is_dir()) { directories_to_check.append(current_dir.path_join(file_name) + "/"); } else { bool proper_extension = false; @@ -2255,7 +2317,7 @@ Vector<String> ProjectConverter3To4::check_for_files() { collected_files.append(current_dir.path_join(file_name)); } } - file_name = dir.get_next(); + file_name = dir->_get_next(); } } else { print_verbose("Failed to open " + path); @@ -2331,12 +2393,13 @@ bool ProjectConverter3To4::test_conversion(RegExContainer ®_container) { valid = valid && test_conversion_with_regex("[Master]", "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container); valid = valid && test_conversion_with_regex("[MasterSync]", "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n[RPC(CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container); - valid = valid && test_conversion_gdscript_builtin("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\"display/window/size/fullscreen\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid && test_conversion_gdscript_builtin("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\\\"display/window/size/fullscreen\\\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, true); + valid = valid && test_conversion_gdscript_builtin("OS.window_fullscreen = Settings.fullscreen", "if Settings.fullscreen:\n\tDisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)\nelse:\n\tDisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("OS.get_window_safe_area()", "DisplayServer.get_display_safe_area()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("\tvar aa = roman(r.move_and_slide( a, b, c, d, e, f )) # Roman", "\tr.set_velocity(a)\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tr.move_and_slide()\n\tvar aa = roman(r.velocity) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("\tmove_and_slide( a, b, c, d, e, f ) # Roman", "\tset_velocity(a)\n\tset_up_direction(b)\n\tset_floor_stop_on_slope_enabled(c)\n\tset_max_slides(d)\n\tset_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tmove_and_slide() # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("\tvar aa = roman(r.move_and_slide_with_snap( a, g, b, c, d, e, f )) # Roman", "\tr.set_velocity(a)\n\t# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `g`\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tr.move_and_slide()\n\tvar aa = roman(r.velocity) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("\tmove_and_slide_with_snap( a, g, b, c, d, e, f ) # Roman", "\tset_velocity(a)\n\t# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `g`\n\tset_up_direction(b)\n\tset_floor_stop_on_slope_enabled(c)\n\tset_max_slides(d)\n\tset_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tmove_and_slide() # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("list_dir_begin( a , b )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("list_dir_begin( a )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); @@ -2382,10 +2445,10 @@ bool ProjectConverter3To4::test_conversion(RegExContainer ®_container) { valid = valid && test_conversion_with_regex("\n\nmaster func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container); valid = valid && test_conversion_with_regex("\n\nmastersync func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc(call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container); - valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function\n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , ", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); - valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function \n set(mod_value):\n mod_value # TODOConverter40 Non existent set function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , get_function", "var size : Vector2 = Vector2() : get = get_function, set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , ", "var size : Vector2 = Vector2() : set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function", "var size : Vector2 = Vector2() : set = set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget , get_function", "var size : Vector2 = Vector2() : get = get_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("get_node(@", "get_node(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); @@ -2617,7 +2680,7 @@ bool ProjectConverter3To4::test_array_names() { // List of excluded functions from builtin types and global namespace, because currently it is not possible to get list of functions from them. // This will be available when https://github.com/godotengine/godot/pull/49053 or similar will be included into Godot. - static const char *builtin_types_excluded_functions[] = { "dict_to_inst", "inst_to_dict", "bytes_to_var", "bytes_to_var_with_objects", "db_to_linear", "deg_to_rad", "linear_to_db", "rad_to_deg", "randf_range", "snapped", "str_to_var", "var_to_str", "var_to_bytes", "var_to_bytes_with_objects", "move_toward", "uri_encode", "uri_decode", "remove_at", "get_rotation_quaternion", "clamp", "grow_side", "is_absolute_path", "is_valid_int", "lerp", "to_ascii_buffer", "to_utf8_buffer", "to_utf32_buffer", "snapped", "remap", nullptr }; + static const char *builtin_types_excluded_functions[] = { "dict_to_inst", "inst_to_dict", "bytes_to_var", "bytes_to_var_with_objects", "db_to_linear", "deg_to_rad", "linear_to_db", "rad_to_deg", "randf_range", "snapped", "str_to_var", "var_to_str", "var_to_bytes", "var_to_bytes_with_objects", "move_toward", "uri_encode", "uri_decode", "remove_at", "get_rotation_quaternion", "clamp", "grow_side", "is_absolute_path", "is_valid_int", "lerp", "to_ascii_buffer", "to_utf8_buffer", "to_utf32_buffer", "snapped", "remap", "rfind", nullptr }; for (int current_index = 0; builtin_types_excluded_functions[current_index]; current_index++) { all_functions.insert(builtin_types_excluded_functions[current_index]); } @@ -3043,7 +3106,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai // -- \t.func() -> \tsuper.func() Object if (line.contains("(") && line.contains(".")) { - line = reg_container.reg_super.sub(line, "$1super.$2", true); // TODO, not sure if possible, but for now this broke String text e.g. "Choosen .gitignore" -> "Choosen super.gitignore" + line = reg_container.reg_super.sub(line, "$1super.$2", true); // TODO, not sure if possible, but for now this broke String text e.g. "Chosen .gitignore" -> "Chosen super.gitignore" } // -- JSON.parse(a) -> JSON.new().parse(a) etc. JSON @@ -3059,6 +3122,10 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai if (line.contains("parse_json")) { line = reg_container.reg_json_parse.sub(line, "$1var test_json_conv = JSON.new()\n$1test_json_conv.parse($3\n$1$2test_json_conv.get_data()", true); } + // -- JSON.print( -> JSON.stringify( + if (line.contains("JSON.print(")) { + line = reg_container.reg_json_print.sub(line, "JSON.stringify(", true); + } // -- get_node(@ -> get_node( Node if (line.contains("get_node")) { @@ -3077,26 +3144,22 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai // Setget Setget if (line.contains("setget")) { - line = reg_container.reg_setget_setget.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Copy here content of $4\n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Copy here content of $3", true); + line = reg_container.reg_setget_setget.sub(line, "var $1$2: get = $4, set = $3", true); } // Setget set if (line.contains("setget")) { - line = reg_container.reg_setget_set.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Non existent get function \n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Copy here content of $3", true); + line = reg_container.reg_setget_set.sub(line, "var $1$2: set = $3", true); } // Setget get if (line.contains("setget")) { - line = reg_container.reg_setget_get.sub(line, "var $1$2:\n\tget:\n\t\treturn $1 # TODOConverter40 Copy here content of $3 \n\tset(mod_value):\n\t\tmod_value # TODOConverter40 Non existent set function", true); + line = reg_container.reg_setget_get.sub(line, "var $1$2: get = $3", true); } - // OS.window_fullscreen = true -> ProjectSettings.set("display/window/size/fullscreen",true) + // OS.window_fullscreen = a -> if a: DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) else: DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) if (line.contains("window_fullscreen")) { - if (builtin) { - line = reg_container.reg_os_fullscreen.sub(line, "ProjectSettings.set(\\\"display/window/size/fullscreen\\\", $1)", true); - } else { - line = reg_container.reg_os_fullscreen.sub(line, "ProjectSettings.set(\"display/window/size/fullscreen\", $1)", true); - } + line = reg_container.reg_os_fullscreen.sub(line, "if $1:\n\tDisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)\nelse:\n\tDisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)", true); } // Instantiate @@ -3144,8 +3207,13 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[5] + "`\n"; } - line_new += starting_space + base_obj + "move_and_slide()\n"; - line = line_new + line.substr(0, start) + "velocity" + line.substr(end + start); + line_new += starting_space + base_obj + "move_and_slide()"; + + if (!line.begins_with(starting_space + "move_and_slide")) { + line = line_new + "\n" + line.substr(0, start) + "velocity" + line.substr(end + start); + } else { + line = line_new + line.substr(end + start); + } } } } @@ -3195,8 +3263,13 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[6] + "`\n"; } - line_new += starting_space + base_obj + "move_and_slide()\n"; - line = line_new + line.substr(0, start) + "velocity" + line.substr(end + start); // move_and_slide used to return velocity + line_new += starting_space + base_obj + "move_and_slide()"; + + if (!line.begins_with(starting_space + "move_and_slide_with_snap")) { + line = line_new + "\n" + line.substr(0, start) + "velocity" + line.substr(end + start); + } else { + line = line_new + line.substr(end + start); + } } } } @@ -3490,6 +3563,20 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai } } } + + // set_rotating(true) -> set_ignore_rotation(false) + if (line.contains("set_rotating(")) { + int start = line.find("set_rotating("); + int end = get_end_parenthesis(line.substr(start)) + 1; + if (end > -1) { + Vector<String> parts = parse_arguments(line.substr(start, end)); + if (parts.size() == 1) { + String opposite = parts[0] == "true" ? "false" : "true"; + line = line.substr(0, start) + "set_ignore_rotation(" + opposite + ")"; + } + } + } + // OS.get_window_safe_area() -> DisplayServer.get_display_safe_area() if (line.contains("OS.get_window_safe_area(")) { int start = line.find("OS.get_window_safe_area("); @@ -3537,6 +3624,29 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai } } + // rotating = true -> ignore_rotation = false # reversed "rotating" for Camera2D + if (line.contains("rotating")) { + int start = line.find("rotating"); + bool foundNextEqual = false; + String line_to_check = line.substr(start + String("rotating").length()); + String assigned_value; + for (int current_index = 0; line_to_check.length() > current_index; current_index++) { + char32_t chr = line_to_check.get(current_index); + if (chr == '\t' || chr == ' ') { + continue; + } else if (chr == '=') { + foundNextEqual = true; + assigned_value = line.right(current_index).strip_edges(); + assigned_value = assigned_value == "true" ? "false" : "true"; + } else { + break; + } + } + if (foundNextEqual) { + line = line.substr(0, start) + "ignore_rotation =" + assigned_value + " # reversed \"rotating\" for Camera2D"; + } + } + // OS -> Time functions if (line.contains("OS.get_ticks_msec")) { line = line.replace("OS.get_ticks_msec", "Time.get_ticks_msec"); @@ -3547,6 +3657,9 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai if (line.contains("OS.get_unix_time")) { line = line.replace("OS.get_unix_time", "Time.get_unix_time_from_system"); } + if (line.contains("OS.get_datetime")) { + line = line.replace("OS.get_datetime", "Time.get_datetime_dict_from_system"); + } } void ProjectConverter3To4::process_csharp_line(String &line, const RegExContainer ®_container) { @@ -3950,6 +4063,8 @@ String ProjectConverter3To4::collect_string_from_vector(Vector<String> &vector) #else // No RegEx. +ProjectConverter3To4::ProjectConverter3To4(int _p_maximum_file_size_kb, int _p_maximum_line_length) {} + int ProjectConverter3To4::convert() { ERR_FAIL_V_MSG(ERROR_CODE, "Can't run converter for Godot 3.x projects, because RegEx module is disabled."); } diff --git a/editor/project_converter_3_to_4.h b/editor/project_converter_3_to_4.h index 2cecb9da79..d03e645ac7 100644 --- a/editor/project_converter_3_to_4.h +++ b/editor/project_converter_3_to_4.h @@ -31,7 +31,6 @@ #ifndef PROJECT_CONVERTER_3_TO_4_H #define PROJECT_CONVERTER_3_TO_4_H -#include "core/core_bind.h" #include "core/io/file_access.h" #include "core/object/ref_counted.h" #include "core/string/ustring.h" diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 69a2670418..b7cca72624 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -49,6 +49,7 @@ #include "editor/editor_vcs_interface.h" #include "main/main.h" #include "scene/gui/center_container.h" +#include "scene/gui/check_box.h" #include "scene/gui/line_edit.h" #include "scene/gui/margin_container.h" #include "scene/gui/panel_container.h" @@ -92,9 +93,9 @@ private: Container *name_container; Container *path_container; Container *install_path_container; - Container *rasterizer_container; + Container *renderer_container; HBoxContainer *default_files_container; - Ref<ButtonGroup> rasterizer_button_group; + Ref<ButtonGroup> renderer_button_group; Label *msg; LineEdit *project_path; LineEdit *project_name; @@ -143,7 +144,11 @@ private: install_status_rect->set_texture(new_icon); } - set_size(Size2(500, 0) * EDSCALE); + Size2i window_size = get_size(); + Size2 contents_min_size = get_contents_minimum_size(); + if (window_size.x < contents_min_size.x || window_size.y < contents_min_size.y) { + set_size(window_size.max(contents_min_size)); + } } String _test_path() { @@ -431,17 +436,17 @@ private: return; } - ProjectSettings *current = memnew(ProjectSettings); - - int err = current->setup(dir2, ""); + // Load project.godot as ConfigFile to set the new name. + ConfigFile cfg; + String project_godot = dir2.path_join("project.godot"); + Error err = cfg.load(project_godot); if (err != OK) { - set_message(vformat(TTR("Couldn't load project.godot in project path (error %d). It may be missing or corrupted."), err), MESSAGE_ERROR); + set_message(vformat(TTR("Couldn't load project at '%s' (error %d). It may be missing or corrupted."), project_godot, err), MESSAGE_ERROR); } else { - ProjectSettings::CustomMap edited_settings; - edited_settings["application/config/name"] = project_name->get_text().strip_edges(); - - if (current->save_custom(dir2.path_join("project.godot"), edited_settings, Vector<String>(), true) != OK) { - set_message(TTR("Couldn't edit project.godot in project path."), MESSAGE_ERROR); + cfg.set_value("application", "config/name", project_name->get_text().strip_edges()); + err = cfg.save(project_godot); + if (err != OK) { + set_message(vformat(TTR("Couldn't save project at '%s' (error %d)."), project_godot, err), MESSAGE_ERROR); } } @@ -473,16 +478,19 @@ private: } PackedStringArray project_features = ProjectSettings::get_required_features(); ProjectSettings::CustomMap initial_settings; + // Be sure to change this code if/when renderers are changed. - int renderer_type = rasterizer_button_group->get_pressed_button()->get_meta(SNAME("driver_name")); - initial_settings["rendering/vulkan/rendering/back_end"] = renderer_type; - if (renderer_type == 0) { - project_features.push_back("Vulkan Clustered"); - } else if (renderer_type == 1) { - project_features.push_back("Vulkan Mobile"); + String renderer_type = renderer_button_group->get_pressed_button()->get_meta(SNAME("rendering_method")); + initial_settings["rendering/renderer/rendering_method"] = renderer_type; + + if (renderer_type == "forward_plus") { + project_features.push_back("Forward Plus"); + } else if (renderer_type == "mobile") { + project_features.push_back("Mobile"); } else { WARN_PRINT("Unknown renderer type. Please report this as a bug on GitHub."); } + project_features.sort(); initial_settings["application/config/features"] = project_features; initial_settings["application/config/name"] = project_name->get_text().strip_edges(); @@ -539,7 +547,6 @@ private: Vector<String> failed_files; - int idx = 0; while (ret == UNZ_OK) { //get filename unz_file_info info; @@ -560,25 +567,24 @@ private: Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); da->make_dir(dir.path_join(rel_path)); } else { - Vector<uint8_t> data; - data.resize(info.uncompressed_size); + Vector<uint8_t> uncomp_data; + uncomp_data.resize(info.uncompressed_size); String rel_path = path.substr(zip_root.length()); //read unzOpenCurrentFile(pkg); - ret = unzReadCurrentFile(pkg, data.ptrw(), data.size()); + ret = unzReadCurrentFile(pkg, uncomp_data.ptrw(), uncomp_data.size()); ERR_BREAK_MSG(ret < 0, vformat("An error occurred while attempting to read from file: %s. This file will not be used.", rel_path)); unzCloseCurrentFile(pkg); Ref<FileAccess> f = FileAccess::open(dir.path_join(rel_path), FileAccess::WRITE); if (f.is_valid()) { - f->store_buffer(data.ptr(), data.size()); + f->store_buffer(uncomp_data.ptr(), uncomp_data.size()); } else { failed_files.push_back(rel_path); } } - idx++; ret = unzGoToNextFile(pkg); } @@ -684,22 +690,23 @@ public: msg->hide(); install_path_container->hide(); install_status_rect->hide(); - rasterizer_container->hide(); + renderer_container->hide(); default_files_container->hide(); get_ok_button()->set_disabled(false); - ProjectSettings *current = memnew(ProjectSettings); - - int err = current->setup(project_path->get_text(), ""); + // Fetch current name from project.godot to prefill the text input. + ConfigFile cfg; + String project_godot = project_path->get_text().path_join("project.godot"); + Error err = cfg.load(project_godot); if (err != OK) { - set_message(vformat(TTR("Couldn't load project.godot in project path (error %d). It may be missing or corrupted."), err), MESSAGE_ERROR); + set_message(vformat(TTR("Couldn't load project at '%s' (error %d). It may be missing or corrupted."), project_godot, err), MESSAGE_ERROR); status_rect->show(); msg->show(); get_ok_button()->set_disabled(true); - } else if (current->has_setting("application/config/name")) { - String proj = current->get("application/config/name"); - project_name->set_text(proj); - _text_changed(proj); + } else { + String cur_name = cfg.get_value("application", "config/name", ""); + project_name->set_text(cur_name); + _text_changed(cur_name); } project_name->call_deferred(SNAME("grab_focus")); @@ -707,7 +714,7 @@ public: create_dir->hide(); } else { - fav_dir = EditorSettings::get_singleton()->get("filesystem/directories/default_project_path"); + fav_dir = EDITOR_GET("filesystem/directories/default_project_path"); if (!fav_dir.is_empty()) { project_path->set_text(fav_dir); fdialog->set_current_dir(fav_dir); @@ -735,7 +742,7 @@ public: set_ok_button_text(TTR("Import & Edit")); name_container->hide(); install_path_container->hide(); - rasterizer_container->hide(); + renderer_container->hide(); default_files_container->hide(); project_path->grab_focus(); @@ -744,7 +751,7 @@ public: set_ok_button_text(TTR("Create & Edit")); name_container->show(); install_path_container->hide(); - rasterizer_container->show(); + renderer_container->show(); default_files_container->show(); project_name->call_deferred(SNAME("grab_focus")); project_name->call_deferred(SNAME("select_all")); @@ -755,7 +762,7 @@ public: project_name->set_text(zip_title); name_container->show(); install_path_container->hide(); - rasterizer_container->hide(); + renderer_container->hide(); default_files_container->hide(); project_path->grab_focus(); } @@ -843,23 +850,23 @@ public: msg->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); vb->add_child(msg); - // rasterizer selection - rasterizer_container = memnew(VBoxContainer); - vb->add_child(rasterizer_container); + // Renderer selection. + renderer_container = memnew(VBoxContainer); + vb->add_child(renderer_container); l = memnew(Label); l->set_text(TTR("Renderer:")); - rasterizer_container->add_child(l); - Container *rshb = memnew(HBoxContainer); - rasterizer_container->add_child(rshb); - rasterizer_button_group.instantiate(); + renderer_container->add_child(l); + HBoxContainer *rshc = memnew(HBoxContainer); + renderer_container->add_child(rshc); + renderer_button_group.instantiate(); Container *rvb = memnew(VBoxContainer); rvb->set_h_size_flags(Control::SIZE_EXPAND_FILL); - rshb->add_child(rvb); + rshc->add_child(rvb); Button *rs_button = memnew(CheckBox); - rs_button->set_button_group(rasterizer_button_group); - rs_button->set_text(TTR("Vulkan Clustered")); - rs_button->set_meta(SNAME("driver_name"), 0); // Vulkan backend "Forward Clustered" + rs_button->set_button_group(renderer_button_group); + rs_button->set_text(TTR("Forward+")); + rs_button->set_meta(SNAME("rendering_method"), "forward_plus"); rs_button->set_pressed(true); rvb->add_child(rs_button); l = memnew(Label); @@ -871,15 +878,15 @@ public: l->set_modulate(Color(1, 1, 1, 0.7)); rvb->add_child(l); - rshb->add_child(memnew(VSeparator)); + rshc->add_child(memnew(VSeparator)); rvb = memnew(VBoxContainer); rvb->set_h_size_flags(Control::SIZE_EXPAND_FILL); - rshb->add_child(rvb); + rshc->add_child(rvb); rs_button = memnew(CheckBox); - rs_button->set_button_group(rasterizer_button_group); - rs_button->set_text(TTR("Vulkan Mobile")); - rs_button->set_meta(SNAME("driver_name"), 1); // Vulkan backend "Forward Mobile" + rs_button->set_button_group(renderer_button_group); + rs_button->set_text(TTR("Mobile")); + rs_button->set_meta(SNAME("rendering_method"), "mobile"); rvb->add_child(rs_button); l = memnew(Label); l->set_text( @@ -897,7 +904,7 @@ public: l->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); l->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); l->set_modulate(Color(1, 1, 1, 0.7)); - rasterizer_container->add_child(l); + renderer_container->add_child(l); default_files_container = memnew(HBoxContainer); vb->add_child(default_files_container); @@ -1258,7 +1265,7 @@ void ProjectList::migrate_config() { continue; } - String path = EditorSettings::get_singleton()->get(property_key); + String path = EDITOR_GET(property_key); String favoriteKey = "favorite_projects/" + property_key.get_slice("/", 1); bool favorite = EditorSettings::get_singleton()->has_setting(favoriteKey); add_project(path, favorite); @@ -1371,7 +1378,7 @@ void ProjectList::create_project_item_control(int p_index) { favorite_box->set_name("FavoriteBox"); TextureButton *favorite = memnew(TextureButton); favorite->set_name("FavoriteButton"); - favorite->set_normal_texture(favorite_icon); + favorite->set_texture_normal(favorite_icon); // This makes the project's "hover" style display correctly when hovering the favorite icon. favorite->set_mouse_filter(MOUSE_FILTER_PASS); favorite->connect("pressed", callable_mp(this, &ProjectList::_favorite_pressed).bind(hb)); @@ -1487,7 +1494,7 @@ void ProjectList::sort_projects() { for (int i = 0; i < _projects.size(); ++i) { Item &item = _projects.write[i]; - bool visible = true; + bool item_visible = true; if (!_search_term.is_empty()) { String search_path; if (_search_term.contains("/")) { @@ -1499,10 +1506,10 @@ void ProjectList::sort_projects() { } // When searching, display projects whose name or path contain the search term - visible = item.project_name.findn(_search_term) != -1 || search_path.findn(_search_term) != -1; + item_visible = item.project_name.findn(_search_term) != -1 || search_path.findn(_search_term) != -1; } - item.control->set_visible(visible); + item.control->set_visible(item_visible); } for (int i = 0; i < _projects.size(); ++i) { @@ -1909,7 +1916,7 @@ void ProjectManager::_notification(int p_what) { } break; case NOTIFICATION_READY: { - int default_sorting = (int)EditorSettings::get_singleton()->get("project_manager/sorting_order"); + int default_sorting = (int)EDITOR_GET("project_manager/sorting_order"); filter_option->select(default_sorting); _project_list->set_order_option(default_sorting); @@ -2554,7 +2561,7 @@ ProjectManager::ProjectManager() { EditorSettings::get_singleton()->set_optimize_save(false); //just write settings as they came { - int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale"); + int display_scale = EDITOR_GET("interface/editor/display_scale"); switch (display_scale) { case 0: @@ -2580,7 +2587,7 @@ ProjectManager::ProjectManager() { editor_set_scale(2.0); break; default: - editor_set_scale(EditorSettings::get_singleton()->get("interface/editor/custom_display_scale")); + editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale")); break; } EditorFileDialog::get_icon_func = &ProjectManager::_file_dialog_get_icon; @@ -2589,7 +2596,13 @@ ProjectManager::ProjectManager() { // TRANSLATORS: This refers to the application where users manage their Godot projects. DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager", "Application")); - EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); + EditorFileDialog::set_default_show_hidden_files(EDITOR_GET("filesystem/file_dialog/show_hidden_files")); + + int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons"); + if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on DisplayServer. + // Swap on means OK first. + AcceptDialog::set_swap_cancel_ok(swap_cancel_ok == 2); + } set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); set_theme(create_custom_theme()); @@ -2802,7 +2815,7 @@ ProjectManager::ProjectManager() { } } - String current_lang = EditorSettings::get_singleton()->get("interface/editor/editor_language"); + String current_lang = EDITOR_GET("interface/editor/editor_language"); language_btn->set_text(current_lang); for (int i = 0; i < editor_languages.size(); i++) { @@ -2841,7 +2854,7 @@ ProjectManager::ProjectManager() { scan_dir->set_access(EditorFileDialog::ACCESS_FILESYSTEM); scan_dir->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); scan_dir->set_title(TTR("Select a Folder to Scan")); // must be after mode or it's overridden - scan_dir->set_current_dir(EditorSettings::get_singleton()->get("filesystem/directories/default_project_path")); + scan_dir->set_current_dir(EDITOR_GET("filesystem/directories/default_project_path")); add_child(scan_dir); scan_dir->connect("dir_selected", callable_mp(this, &ProjectManager::_scan_begin)); @@ -2923,7 +2936,7 @@ ProjectManager::ProjectManager() { Ref<DirAccess> dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM); - String default_project_path = EditorSettings::get_singleton()->get("filesystem/directories/default_project_path"); + String default_project_path = EDITOR_GET("filesystem/directories/default_project_path"); if (!dir_access->dir_exists(default_project_path)) { Error error = dir_access->make_dir_recursive(default_project_path); if (error != OK) { @@ -2931,7 +2944,7 @@ ProjectManager::ProjectManager() { } } - String autoscan_path = EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path"); + String autoscan_path = EDITOR_GET("filesystem/directories/autoscan_project_path"); if (!autoscan_path.is_empty()) { if (dir_access->dir_exists(autoscan_path)) { _scan_begin(autoscan_path); diff --git a/editor/project_manager.h b/editor/project_manager.h index 7c05429dde..de4db2944f 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -38,6 +38,7 @@ #include "scene/gui/scroll_container.h" #include "scene/gui/tree.h" +class CheckBox; class ProjectDialog; class ProjectList; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 2da49f11cc..28111bed58 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -36,6 +36,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "scene/gui/check_button.h" #include "servers/movie_writer/movie_writer.h" ProjectSettingsEditor *ProjectSettingsEditor::singleton = nullptr; @@ -72,6 +73,11 @@ void ProjectSettingsEditor::set_plugins_page() { tab_container->set_current_tab(tab_container->get_tab_idx_from_control(plugin_settings)); } +void ProjectSettingsEditor::set_general_page(const String &p_category) { + tab_container->set_current_tab(tab_container->get_tab_idx_from_control(general_editor)); + general_settings_inspector->set_current_section(p_category); +} + void ProjectSettingsEditor::update_plugins() { plugin_settings->update_plugins(); } @@ -108,6 +114,7 @@ void ProjectSettingsEditor::_add_setting() { Variant value; Variant::construct(Variant::Type(type_box->get_selected_id()), value, nullptr, 0, ce); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Project Setting")); undo_redo->add_do_property(ps, setting, value); undo_redo->add_undo_property(ps, setting, ps->has_setting(setting) ? ps->get(setting) : Variant()); @@ -127,6 +134,7 @@ void ProjectSettingsEditor::_delete_setting() { Variant value = ps->get(setting); int order = ps->get_order(setting); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Delete Item")); undo_redo->add_do_method(ps, "clear", setting); @@ -215,9 +223,9 @@ void ProjectSettingsEditor::_select_type(Variant::Type p_type) { void ProjectSettingsEditor::shortcut_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); const Ref<InputEventKey> k = p_event; - if (k.is_valid() && k->is_pressed()) { bool handled = false; @@ -333,6 +341,7 @@ void ProjectSettingsEditor::_action_added(const String &p_name) { action["events"] = Array(); action["deadzone"] = 0.5f; + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Add Input Action")); undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name); @@ -346,8 +355,9 @@ void ProjectSettingsEditor::_action_added(const String &p_name) { void ProjectSettingsEditor::_action_edited(const String &p_name, const Dictionary &p_action) { const String property_name = "input/" + p_name; - Dictionary old_val = ProjectSettings::get_singleton()->get(property_name); + Dictionary old_val = GLOBAL_GET(property_name); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (old_val["deadzone"] != p_action["deadzone"]) { // Deadzone Changed undo_redo->create_action(TTR("Change Action deadzone")); @@ -356,12 +366,12 @@ void ProjectSettingsEditor::_action_edited(const String &p_name, const Dictionar } else { // Events changed - int event_count = ((Array)p_action["events"]).size(); + int act_event_count = ((Array)p_action["events"]).size(); int old_event_count = ((Array)old_val["events"]).size(); - if (event_count == old_event_count) { + if (act_event_count == old_event_count) { undo_redo->create_action(TTR("Edit Input Action Event")); - } else if (event_count > old_event_count) { + } else if (act_event_count > old_event_count) { undo_redo->create_action(TTR("Add Input Action Event")); } else { undo_redo->create_action(TTR("Remove Input Action Event")); @@ -381,9 +391,10 @@ void ProjectSettingsEditor::_action_edited(const String &p_name, const Dictionar void ProjectSettingsEditor::_action_removed(const String &p_name) { const String property_name = "input/" + p_name; - Dictionary old_val = ProjectSettings::get_singleton()->get(property_name); + Dictionary old_val = GLOBAL_GET(property_name); int order = ProjectSettings::get_singleton()->get_order(property_name); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Erase Input Action")); undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", property_name); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val); @@ -404,8 +415,9 @@ void ProjectSettingsEditor::_action_renamed(const String &p_old_name, const Stri "An action with this name already exists."); int order = ProjectSettings::get_singleton()->get_order(old_property_name); - Dictionary action = ProjectSettings::get_singleton()->get(old_property_name); + Dictionary action = GLOBAL_GET(old_property_name); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Rename Input Action Event")); // Do: clear old, set new undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", old_property_name); @@ -435,6 +447,7 @@ void ProjectSettingsEditor::_action_reordered(const String &p_action_name, const HashMap<String, Variant> action_values; ProjectSettings::get_singleton()->get_property_list(&props); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Update Input Action Order")); for (const PropertyInfo &prop : props) { @@ -499,7 +512,7 @@ void ProjectSettingsEditor::_update_action_map_editor() { // Strip the "input/" from the left. String display_name = property_name.substr(String("input/").size() - 1); - Dictionary action = ProjectSettings::get_singleton()->get(property_name); + Dictionary action = GLOBAL_GET(property_name); ActionMapEditor::ActionInfo action_info; action_info.action = action; @@ -567,7 +580,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { set_title(TTR("Project Settings (project.godot)")); ps = ProjectSettings::get_singleton(); - undo_redo = p_data->get_undo_redo(); data = p_data; tab_container = memnew(TabContainer); @@ -575,7 +587,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { tab_container->set_theme_type_variation("TabContainerOdd"); add_child(tab_container); - VBoxContainer *general_editor = memnew(VBoxContainer); + general_editor = memnew(VBoxContainer); general_editor->set_name(TTR("General")); general_editor->set_alignment(BoxContainer::ALIGNMENT_BEGIN); general_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -626,7 +638,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { custom_properties->add_child(del_button); general_settings_inspector = memnew(SectionedInspector); - general_settings_inspector->get_inspector()->set_undo_redo(EditorNode::get_undo_redo()); general_settings_inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL); general_settings_inspector->register_search_box(search_box); general_settings_inspector->get_inspector()->set_use_filter(true); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index 040d992e40..7f6dd1b692 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -42,7 +42,6 @@ #include "editor/shader_globals_editor.h" #include "scene/gui/tab_container.h" -class EditorUndoRedoManager; class FileSystemDock; class ProjectSettingsEditor : public AcceptDialog { @@ -53,6 +52,7 @@ class ProjectSettingsEditor : public AcceptDialog { Timer *timer = nullptr; TabContainer *tab_container = nullptr; + VBoxContainer *general_editor = nullptr; SectionedInspector *general_settings_inspector = nullptr; ActionMapEditor *action_map_editor = nullptr; LocalizationEditor *localization_editor = nullptr; @@ -77,7 +77,6 @@ class ProjectSettingsEditor : public AcceptDialog { ImportDefaultsEditor *import_defaults_editor = nullptr; EditorData *data = nullptr; - Ref<EditorUndoRedoManager> undo_redo; void _advanced_toggled(bool p_button_pressed); void _update_advanced(bool p_is_advanced); @@ -116,6 +115,7 @@ public: static ProjectSettingsEditor *get_singleton() { return singleton; } void popup_project_settings(); void set_plugins_page(); + void set_general_page(const String &p_category); void update_plugins(); EditorAutoloadSettings *get_autoload_settings() { return autoload_settings; } diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp new file mode 100644 index 0000000000..f301ff5c6b --- /dev/null +++ b/editor/register_editor_types.cpp @@ -0,0 +1,220 @@ +/*************************************************************************/ +/* register_editor_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "register_editor_types.h" + +#include "editor/animation_track_editor.h" +#include "editor/debugger/debug_adapter/debug_adapter_server.h" +#include "editor/editor_command_palette.h" +#include "editor/editor_feature_profile.h" +#include "editor/editor_file_dialog.h" +#include "editor/editor_file_system.h" +#include "editor/editor_node.h" +#include "editor/editor_paths.h" +#include "editor/editor_resource_picker.h" +#include "editor/editor_resource_preview.h" +#include "editor/editor_run_script.h" +#include "editor/editor_settings.h" +#include "editor/editor_translation_parser.h" +#include "editor/editor_undo_redo_manager.h" +#include "editor/filesystem_dock.h" +#include "editor/import/editor_import_plugin.h" +#include "editor/import/resource_importer_scene.h" +#include "editor/plugins/animation_tree_editor_plugin.h" +#include "editor/plugins/audio_stream_randomizer_editor_plugin.h" +#include "editor/plugins/bit_map_editor_plugin.h" +#include "editor/plugins/bone_map_editor_plugin.h" +#include "editor/plugins/camera_3d_editor_plugin.h" +#include "editor/plugins/cast_2d_editor_plugin.h" +#include "editor/plugins/collision_polygon_2d_editor_plugin.h" +#include "editor/plugins/collision_shape_2d_editor_plugin.h" +#include "editor/plugins/control_editor_plugin.h" +#include "editor/plugins/cpu_particles_2d_editor_plugin.h" +#include "editor/plugins/cpu_particles_3d_editor_plugin.h" +#include "editor/plugins/curve_editor_plugin.h" +#include "editor/plugins/editor_debugger_plugin.h" +#include "editor/plugins/font_config_plugin.h" +#include "editor/plugins/gpu_particles_2d_editor_plugin.h" +#include "editor/plugins/gpu_particles_3d_editor_plugin.h" +#include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h" +#include "editor/plugins/gradient_editor_plugin.h" +#include "editor/plugins/gradient_texture_2d_editor_plugin.h" +#include "editor/plugins/input_event_editor_plugin.h" +#include "editor/plugins/light_occluder_2d_editor_plugin.h" +#include "editor/plugins/lightmap_gi_editor_plugin.h" +#include "editor/plugins/line_2d_editor_plugin.h" +#include "editor/plugins/material_editor_plugin.h" +#include "editor/plugins/mesh_editor_plugin.h" +#include "editor/plugins/mesh_instance_3d_editor_plugin.h" +#include "editor/plugins/mesh_library_editor_plugin.h" +#include "editor/plugins/multimesh_editor_plugin.h" +#include "editor/plugins/navigation_link_2d_editor_plugin.h" +#include "editor/plugins/navigation_polygon_editor_plugin.h" +#include "editor/plugins/node_3d_editor_gizmos.h" +#include "editor/plugins/occluder_instance_3d_editor_plugin.h" +#include "editor/plugins/path_2d_editor_plugin.h" +#include "editor/plugins/path_3d_editor_plugin.h" +#include "editor/plugins/physical_bone_3d_editor_plugin.h" +#include "editor/plugins/polygon_2d_editor_plugin.h" +#include "editor/plugins/polygon_3d_editor_plugin.h" +#include "editor/plugins/resource_preloader_editor_plugin.h" +#include "editor/plugins/script_editor_plugin.h" +#include "editor/plugins/shader_editor_plugin.h" +#include "editor/plugins/shader_file_editor_plugin.h" +#include "editor/plugins/skeleton_2d_editor_plugin.h" +#include "editor/plugins/skeleton_3d_editor_plugin.h" +#include "editor/plugins/skeleton_ik_3d_editor_plugin.h" +#include "editor/plugins/sprite_2d_editor_plugin.h" +#include "editor/plugins/sprite_frames_editor_plugin.h" +#include "editor/plugins/style_box_editor_plugin.h" +#include "editor/plugins/sub_viewport_preview_editor_plugin.h" +#include "editor/plugins/texture_3d_editor_plugin.h" +#include "editor/plugins/texture_editor_plugin.h" +#include "editor/plugins/texture_layered_editor_plugin.h" +#include "editor/plugins/texture_region_editor_plugin.h" +#include "editor/plugins/theme_editor_plugin.h" +#include "editor/plugins/tiles/tiles_editor_plugin.h" +#include "editor/plugins/version_control_editor_plugin.h" +#include "editor/plugins/visual_shader_editor_plugin.h" +#include "editor/plugins/voxel_gi_editor_plugin.h" + +void register_editor_types() { + ResourceLoader::set_timestamp_on_load(true); + ResourceSaver::set_timestamp_on_save(true); + + GDREGISTER_CLASS(EditorPaths); + GDREGISTER_CLASS(EditorPlugin); + GDREGISTER_CLASS(EditorTranslationParserPlugin); + GDREGISTER_CLASS(EditorImportPlugin); + GDREGISTER_CLASS(EditorScript); + GDREGISTER_CLASS(EditorSelection); + GDREGISTER_CLASS(EditorFileDialog); + GDREGISTER_ABSTRACT_CLASS(EditorSettings); + GDREGISTER_CLASS(EditorNode3DGizmo); + GDREGISTER_CLASS(EditorNode3DGizmoPlugin); + GDREGISTER_ABSTRACT_CLASS(EditorResourcePreview); + GDREGISTER_CLASS(EditorResourcePreviewGenerator); + GDREGISTER_ABSTRACT_CLASS(EditorFileSystem); + GDREGISTER_CLASS(EditorFileSystemDirectory); + GDREGISTER_CLASS(EditorVCSInterface); + GDREGISTER_ABSTRACT_CLASS(ScriptEditor); + GDREGISTER_ABSTRACT_CLASS(ScriptEditorBase); + GDREGISTER_CLASS(EditorSyntaxHighlighter); + GDREGISTER_ABSTRACT_CLASS(EditorInterface); + GDREGISTER_CLASS(EditorExportPlugin); + GDREGISTER_ABSTRACT_CLASS(EditorExportPlatform); + GDREGISTER_CLASS(EditorResourceConversionPlugin); + GDREGISTER_CLASS(EditorSceneFormatImporter); + GDREGISTER_CLASS(EditorScenePostImportPlugin); + GDREGISTER_CLASS(EditorInspector); + GDREGISTER_CLASS(EditorInspectorPlugin); + GDREGISTER_CLASS(EditorProperty); + GDREGISTER_CLASS(AnimationTrackEditPlugin); + GDREGISTER_CLASS(ScriptCreateDialog); + GDREGISTER_CLASS(EditorFeatureProfile); + GDREGISTER_CLASS(EditorSpinSlider); + GDREGISTER_CLASS(EditorResourcePicker); + GDREGISTER_CLASS(EditorScriptPicker); + GDREGISTER_ABSTRACT_CLASS(EditorUndoRedoManager); + + GDREGISTER_ABSTRACT_CLASS(FileSystemDock); + GDREGISTER_VIRTUAL_CLASS(EditorFileSystemImportFormatSupportQuery); + + GDREGISTER_CLASS(EditorScenePostImport); + GDREGISTER_CLASS(EditorCommandPalette); + GDREGISTER_CLASS(EditorDebuggerPlugin); + GDREGISTER_ABSTRACT_CLASS(EditorDebuggerSession); + + // This list is alphabetized, and plugins that depend on Node2D are in their own section below. + EditorPlugins::add_by_type<AnimationTreeEditorPlugin>(); + EditorPlugins::add_by_type<AudioStreamRandomizerEditorPlugin>(); + EditorPlugins::add_by_type<BitMapEditorPlugin>(); + EditorPlugins::add_by_type<BoneMapEditorPlugin>(); + EditorPlugins::add_by_type<Camera3DEditorPlugin>(); + EditorPlugins::add_by_type<ControlEditorPlugin>(); + EditorPlugins::add_by_type<CPUParticles3DEditorPlugin>(); + EditorPlugins::add_by_type<CurveEditorPlugin>(); + EditorPlugins::add_by_type<DebugAdapterServer>(); + EditorPlugins::add_by_type<FontEditorPlugin>(); + EditorPlugins::add_by_type<GPUParticles3DEditorPlugin>(); + EditorPlugins::add_by_type<GPUParticlesCollisionSDF3DEditorPlugin>(); + EditorPlugins::add_by_type<GradientEditorPlugin>(); + EditorPlugins::add_by_type<GradientTexture2DEditorPlugin>(); + EditorPlugins::add_by_type<InputEventEditorPlugin>(); + EditorPlugins::add_by_type<LightmapGIEditorPlugin>(); + EditorPlugins::add_by_type<MaterialEditorPlugin>(); + EditorPlugins::add_by_type<MeshEditorPlugin>(); + EditorPlugins::add_by_type<MeshInstance3DEditorPlugin>(); + EditorPlugins::add_by_type<MeshLibraryEditorPlugin>(); + EditorPlugins::add_by_type<MultiMeshEditorPlugin>(); + EditorPlugins::add_by_type<OccluderInstance3DEditorPlugin>(); + EditorPlugins::add_by_type<Path3DEditorPlugin>(); + EditorPlugins::add_by_type<PhysicalBone3DEditorPlugin>(); + EditorPlugins::add_by_type<Polygon3DEditorPlugin>(); + EditorPlugins::add_by_type<ResourcePreloaderEditorPlugin>(); + EditorPlugins::add_by_type<ShaderEditorPlugin>(); + EditorPlugins::add_by_type<ShaderFileEditorPlugin>(); + EditorPlugins::add_by_type<Skeleton3DEditorPlugin>(); + EditorPlugins::add_by_type<SkeletonIK3DEditorPlugin>(); + EditorPlugins::add_by_type<SpriteFramesEditorPlugin>(); + EditorPlugins::add_by_type<StyleBoxEditorPlugin>(); + EditorPlugins::add_by_type<SubViewportPreviewEditorPlugin>(); + EditorPlugins::add_by_type<Texture3DEditorPlugin>(); + EditorPlugins::add_by_type<TextureEditorPlugin>(); + EditorPlugins::add_by_type<TextureLayeredEditorPlugin>(); + EditorPlugins::add_by_type<TextureRegionEditorPlugin>(); + EditorPlugins::add_by_type<ThemeEditorPlugin>(); + EditorPlugins::add_by_type<VoxelGIEditorPlugin>(); + + // 2D + EditorPlugins::add_by_type<CollisionPolygon2DEditorPlugin>(); + EditorPlugins::add_by_type<CollisionShape2DEditorPlugin>(); + EditorPlugins::add_by_type<CPUParticles2DEditorPlugin>(); + EditorPlugins::add_by_type<GPUParticles2DEditorPlugin>(); + EditorPlugins::add_by_type<LightOccluder2DEditorPlugin>(); + EditorPlugins::add_by_type<Line2DEditorPlugin>(); + EditorPlugins::add_by_type<NavigationLink2DEditorPlugin>(); + EditorPlugins::add_by_type<NavigationPolygonEditorPlugin>(); + EditorPlugins::add_by_type<Path2DEditorPlugin>(); + EditorPlugins::add_by_type<Polygon2DEditorPlugin>(); + EditorPlugins::add_by_type<Cast2DEditorPlugin>(); + EditorPlugins::add_by_type<Skeleton2DEditorPlugin>(); + EditorPlugins::add_by_type<Sprite2DEditorPlugin>(); + EditorPlugins::add_by_type<TilesEditorPlugin>(); +} + +void unregister_editor_types() { + EditorNode::cleanup(); + if (EditorPaths::get_singleton()) { + EditorPaths::free(); + } + + EditorResourcePicker::clear_caches(); +} diff --git a/editor/register_editor_types.h b/editor/register_editor_types.h new file mode 100644 index 0000000000..f53e7e3649 --- /dev/null +++ b/editor/register_editor_types.h @@ -0,0 +1,37 @@ +/*************************************************************************/ +/* register_editor_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef REGISTER_EDITOR_TYPES_H +#define REGISTER_EDITOR_TYPES_H + +void register_editor_types(); +void unregister_editor_types(); + +#endif // REGISTER_EDITOR_TYPES_H diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 300a3d0f05..40683e2938 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -42,13 +42,13 @@ #include "modules/regex/regex.h" #include "plugins/script_editor_plugin.h" #include "scene/gui/control.h" +#include "scene/gui/grid_container.h" #include "scene/gui/label.h" #include "scene/gui/separator.h" #include "scene/gui/tab_container.h" -RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, Ref<EditorUndoRedoManager> p_undo_redo) { +RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor) { scene_tree_editor = p_scene_tree_editor; - undo_redo = p_undo_redo; preview_node = nullptr; set_title(TTR("Batch Rename")); @@ -582,7 +582,8 @@ void RenameDialog::rename() { // Forward recursive as opposed to the actual renaming. _iterate_scene(root_node, selected_node_list, &global_count); - if (undo_redo.is_valid() && !to_rename.is_empty()) { + if (!to_rename.is_empty()) { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Batch Rename")); // Make sure to iterate reversed so that child nodes will find parents. @@ -652,9 +653,9 @@ void RenameDialog::_features_toggled(bool pressed) { } // Adjust to minimum size in y - Size2i size = get_size(); - size.y = 0; - set_size(size); + Size2i new_size = get_size(); + new_size.y = 0; + set_size(new_size); } #endif // MODULE_REGEX_ENABLED diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index dac73b13b8..2a3fda59a4 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -42,8 +42,6 @@ #include "scene/gui/spin_box.h" #include "scene/gui/tab_container.h" -class EditorUndoRedoManager; - class RenameDialog : public ConfirmationDialog { GDCLASS(RenameDialog, ConfirmationDialog); @@ -64,7 +62,6 @@ class RenameDialog : public ConfirmationDialog { static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type); SceneTreeEditor *scene_tree_editor = nullptr; - Ref<EditorUndoRedoManager> undo_redo; int global_count = 0; LineEdit *lne_search = nullptr; @@ -110,8 +107,7 @@ public: void reset(); void rename(); - RenameDialog(SceneTreeEditor *p_scene_tree_editor, Ref<EditorUndoRedoManager> p_undo_redo = Ref<EditorUndoRedoManager>()); - ~RenameDialog() {} + RenameDialog(SceneTreeEditor *p_scene_tree_editor); }; #endif // MODULE_REGEX_ENABLED diff --git a/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp index 75098b25b1..37712d4197 100644 --- a/editor/reparent_dialog.cpp +++ b/editor/reparent_dialog.cpp @@ -33,6 +33,7 @@ #include "core/string/print_string.h" #include "scene/gui/box_container.h" #include "scene/gui/label.h" +#include "scene/gui/tree.h" void ReparentDialog::_notification(int p_what) { switch (p_what) { diff --git a/editor/scene_create_dialog.cpp b/editor/scene_create_dialog.cpp index 573e57ca04..9f3ce26a59 100644 --- a/editor/scene_create_dialog.cpp +++ b/editor/scene_create_dialog.cpp @@ -133,7 +133,7 @@ void SceneCreateDialog::update_dialog() { root_name = scene_name.get_file().get_basename(); } - if (!root_name.is_valid_identifier()) { + if (root_name.is_empty() || root_name.validate_node_name().size() != root_name.size()) { update_error(node_error_label, MSG_ERROR, TTR("Invalid root node name.")); is_valid = false; } @@ -170,12 +170,12 @@ Node *SceneCreateDialog::create_scene_root() { root = memnew(Node3D); break; case ROOT_USER_INTERFACE: { - Control *gui = memnew(Control); - gui->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - root = gui; + Control *gui_ctl = memnew(Control); + gui_ctl->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); + root = gui_ctl; } break; case ROOT_OTHER: - root = Object::cast_to<Node>(select_node_dialog->instance_selected()); + root = Object::cast_to<Node>(select_node_dialog->instantiate_selected()); break; } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index a437245c57..0ebd8e610a 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/io/resource_saver.h" +#include "core/object/class_db.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" @@ -40,13 +41,17 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" +#include "editor/editor_quick_open.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/editor_undo_redo_manager.h" +#include "editor/inspector_dock.h" #include "editor/multi_node_edit.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" +#include "editor/reparent_dialog.h" #include "editor/shader_create_dialog.h" #include "scene/main/window.h" #include "scene/property_utils.h" @@ -105,7 +110,7 @@ void SceneTreeDock::shortcut_input(const Ref<InputEvent> &p_event) { #endif // MODULE_REGEX_ENABLED } else if (ED_IS_SHORTCUT("scene_tree/add_child_node", p_event)) { _tool_selected(TOOL_NEW); - } else if (ED_IS_SHORTCUT("scene_tree/instance_scene", p_event)) { + } else if (ED_IS_SHORTCUT("scene_tree/instantiate_scene", p_event)) { _tool_selected(TOOL_INSTANTIATE); } else if (ED_IS_SHORTCUT("scene_tree/expand_collapse_all", p_event)) { _tool_selected(TOOL_EXPAND_COLLAPSE); @@ -135,6 +140,8 @@ void SceneTreeDock::shortcut_input(const Ref<InputEvent> &p_event) { _tool_selected(TOOL_ERASE, true); } else if (ED_IS_SHORTCUT("scene_tree/copy_node_path", p_event)) { _tool_selected(TOOL_COPY_NODE_PATH); + } else if (ED_IS_SHORTCUT("scene_tree/toggle_unique_name", p_event)) { + _tool_selected(TOOL_TOGGLE_SCENE_UNIQUE_NAME); } else if (ED_IS_SHORTCUT("scene_tree/delete", p_event)) { _tool_selected(TOOL_ERASE); } else { @@ -195,7 +202,7 @@ void SceneTreeDock::_perform_instantiate_scenes(const Vector<String> &p_files, N Node *instantiated_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!instantiated_scene) { current_option = -1; - accept->set_text(vformat(TTR("Error instancing scene from %s"), p_files[i])); + accept->set_text(vformat(TTR("Error instantiating scene from %s"), p_files[i])); accept->popup_centered(); error = true; break; @@ -203,7 +210,7 @@ void SceneTreeDock::_perform_instantiate_scenes(const Vector<String> &p_files, N if (!edited_scene->get_scene_file_path().is_empty()) { if (_cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) { - accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."), p_files[i])); + accept->set_text(vformat(TTR("Cannot instantiate the scene '%s' because the current scene exists within one of its nodes."), p_files[i])); accept->popup_centered(); error = true; break; @@ -222,28 +229,29 @@ void SceneTreeDock::_perform_instantiate_scenes(const Vector<String> &p_files, N return; } - editor_data->get_undo_redo()->create_action(TTR("Instance Scene(s)")); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Instantiate Scene(s)")); for (int i = 0; i < instances.size(); i++) { Node *instantiated_scene = instances[i]; - editor_data->get_undo_redo()->add_do_method(parent, "add_child", instantiated_scene, true); + undo_redo->add_do_method(parent, "add_child", instantiated_scene, true); if (p_pos >= 0) { - editor_data->get_undo_redo()->add_do_method(parent, "move_child", instantiated_scene, p_pos + i); + undo_redo->add_do_method(parent, "move_child", instantiated_scene, p_pos + i); } - editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_owner", edited_scene); - editor_data->get_undo_redo()->add_do_method(editor_selection, "clear"); - editor_data->get_undo_redo()->add_do_method(editor_selection, "add_node", instantiated_scene); - editor_data->get_undo_redo()->add_do_reference(instantiated_scene); - editor_data->get_undo_redo()->add_undo_method(parent, "remove_child", instantiated_scene); + undo_redo->add_do_method(instantiated_scene, "set_owner", edited_scene); + undo_redo->add_do_method(editor_selection, "clear"); + undo_redo->add_do_method(editor_selection, "add_node", instantiated_scene); + undo_redo->add_do_reference(instantiated_scene); + undo_redo->add_undo_method(parent, "remove_child", instantiated_scene); String new_name = parent->validate_child_name(instantiated_scene); EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); - editor_data->get_undo_redo()->add_do_method(ed, "live_debug_instance_node", edited_scene->get_path_to(parent), p_files[i], new_name); - editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).path_join(new_name))); + undo_redo->add_do_method(ed, "live_debug_instantiate_node", edited_scene->get_path_to(parent), p_files[i], new_name); + undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).path_join(new_name))); } - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); _push_item(instances[instances.size() - 1]); for (int i = 0; i < instances.size(); i++) { emit_signal(SNAME("node_created"), instances[i]); @@ -260,12 +268,12 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) Node *instantiated_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!instantiated_scene) { - accept->set_text(vformat(TTR("Error instancing scene from %s"), p_file)); + accept->set_text(vformat(TTR("Error instantiating scene from %s"), p_file)); accept->popup_centered(); return; } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Replace with Branch Scene")); Node *parent = base->get_parent(); @@ -328,9 +336,9 @@ bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_de Ref<SceneState> ss = p->get_scene_inherited_state(); if (ss.is_valid()) { String path = ss->get_path(); - Ref<PackedScene> data = ResourceLoader::load(path); - if (data.is_valid()) { - p = data->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); + Ref<PackedScene> pack_data = ResourceLoader::load(path); + if (pack_data.is_valid()) { + p = pack_data->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!p) { continue; } @@ -439,8 +447,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } } - bool collapsed = _is_collapsed_recursive(selected_item); - _set_collapsed_recursive(selected_item, !collapsed); + bool collapsed = selected_item->is_any_collapsed(); + selected_item->set_collapsed_recursive(!collapsed); tree->ensure_cursor_is_visible(); @@ -530,23 +538,24 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { return; } - editor_data->get_undo_redo()->create_action(TTR("Detach Script"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene()); - editor_data->get_undo_redo()->add_do_method(EditorNode::get_singleton(), "push_item", (Script *)nullptr); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Detach Script"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene()); + undo_redo->add_do_method(EditorNode::get_singleton(), "push_item", (Script *)nullptr); for (int i = 0; i < selection.size(); i++) { Node *n = Object::cast_to<Node>(selection[i]); Ref<Script> existing = n->get_script(); Ref<Script> empty = EditorNode::get_singleton()->get_object_custom_type_base(n); if (existing != empty) { - editor_data->get_undo_redo()->add_do_method(n, "set_script", empty); - editor_data->get_undo_redo()->add_undo_method(n, "set_script", existing); + undo_redo->add_do_method(n, "set_script", empty); + undo_redo->add_undo_method(n, "set_script", existing); } } - editor_data->get_undo_redo()->add_do_method(this, "_update_script_button"); - editor_data->get_undo_redo()->add_undo_method(this, "_update_script_button"); + undo_redo->add_do_method(this, "_update_script_button"); + undo_redo->add_undo_method(this, "_update_script_button"); - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); } break; case TOOL_MOVE_UP: case TOOL_MOVE_DOWN: { @@ -600,11 +609,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { break; // one or more nodes can not be moved } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (selection.size() == 1) { - editor_data->get_undo_redo()->create_action(TTR("Move Node In Parent")); + undo_redo->create_action(TTR("Move Node In Parent")); } if (selection.size() > 1) { - editor_data->get_undo_redo()->create_action(TTR("Move Nodes In Parent")); + undo_redo->create_action(TTR("Move Nodes In Parent")); } for (int i = 0; i < selection.size(); i++) { @@ -617,11 +627,11 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { int bottom_node_pos = bottom_node->get_index(); int top_node_pos_next = top_node->get_index() + (MOVING_DOWN ? 1 : -1); - editor_data->get_undo_redo()->add_do_method(top_node->get_parent(), "move_child", top_node, top_node_pos_next); - editor_data->get_undo_redo()->add_undo_method(bottom_node->get_parent(), "move_child", bottom_node, bottom_node_pos); + undo_redo->add_do_method(top_node->get_parent(), "move_child", top_node, top_node_pos_next); + undo_redo->add_undo_method(bottom_node->get_parent(), "move_child", bottom_node, bottom_node_pos); } - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); } break; case TOOL_DUPLICATE: { @@ -649,8 +659,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { break; } - editor_data->get_undo_redo()->create_action(TTR("Duplicate Node(s)"), UndoRedo::MERGE_DISABLE, selection.front()->get()); - editor_data->get_undo_redo()->add_do_method(editor_selection, "clear"); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Duplicate Node(s)"), UndoRedo::MERGE_DISABLE, selection.front()->get()); + undo_redo->add_do_method(editor_selection, "clear"); Node *dupsingle = nullptr; @@ -675,28 +686,28 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { dup->set_name(parent->validate_child_name(dup)); - editor_data->get_undo_redo()->add_do_method(add_below_node, "add_sibling", dup, true); + undo_redo->add_do_method(add_below_node, "add_sibling", dup, true); for (Node *F : owned) { if (!duplimap.has(F)) { continue; } Node *d = duplimap[F]; - editor_data->get_undo_redo()->add_do_method(d, "set_owner", node->get_owner()); + undo_redo->add_do_method(d, "set_owner", node->get_owner()); } - editor_data->get_undo_redo()->add_do_method(editor_selection, "add_node", dup); - editor_data->get_undo_redo()->add_undo_method(parent, "remove_child", dup); - editor_data->get_undo_redo()->add_do_reference(dup); + undo_redo->add_do_method(editor_selection, "add_node", dup); + undo_redo->add_undo_method(parent, "remove_child", dup); + undo_redo->add_do_reference(dup); EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); - editor_data->get_undo_redo()->add_do_method(ed, "live_debug_duplicate_node", edited_scene->get_path_to(node), dup->get_name()); - editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).path_join(dup->get_name()))); + undo_redo->add_do_method(ed, "live_debug_duplicate_node", edited_scene->get_path_to(node), dup->get_name()); + undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).path_join(dup->get_name()))); add_below_node = dup; } - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); if (dupsingle) { _push_item(dupsingle); @@ -765,29 +776,30 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { return; } - editor_data->get_undo_redo()->create_action(TTR("Make node as Root")); - editor_data->get_undo_redo()->add_do_method(node->get_parent(), "remove_child", node); - editor_data->get_undo_redo()->add_do_method(EditorNode::get_singleton(), "set_edited_scene", node); - editor_data->get_undo_redo()->add_do_method(node, "add_child", root, true); - editor_data->get_undo_redo()->add_do_method(node, "set_scene_file_path", root->get_scene_file_path()); - editor_data->get_undo_redo()->add_do_method(root, "set_scene_file_path", String()); - editor_data->get_undo_redo()->add_do_method(node, "set_owner", (Object *)nullptr); - editor_data->get_undo_redo()->add_do_method(root, "set_owner", node); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Make node as Root")); + undo_redo->add_do_method(node->get_parent(), "remove_child", node); + undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", node); + undo_redo->add_do_method(node, "add_child", root, true); + undo_redo->add_do_method(node, "set_scene_file_path", root->get_scene_file_path()); + undo_redo->add_do_method(root, "set_scene_file_path", String()); + undo_redo->add_do_method(node, "set_owner", (Object *)nullptr); + undo_redo->add_do_method(root, "set_owner", node); _node_replace_owner(root, root, node, MODE_DO); - editor_data->get_undo_redo()->add_undo_method(root, "set_scene_file_path", root->get_scene_file_path()); - editor_data->get_undo_redo()->add_undo_method(node, "set_scene_file_path", String()); - editor_data->get_undo_redo()->add_undo_method(node, "remove_child", root); - editor_data->get_undo_redo()->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", root); - editor_data->get_undo_redo()->add_undo_method(node->get_parent(), "add_child", node, true); - editor_data->get_undo_redo()->add_undo_method(node->get_parent(), "move_child", node, node->get_index()); - editor_data->get_undo_redo()->add_undo_method(root, "set_owner", (Object *)nullptr); - editor_data->get_undo_redo()->add_undo_method(node, "set_owner", root); + undo_redo->add_undo_method(root, "set_scene_file_path", root->get_scene_file_path()); + undo_redo->add_undo_method(node, "set_scene_file_path", String()); + undo_redo->add_undo_method(node, "remove_child", root); + undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", root); + undo_redo->add_undo_method(node->get_parent(), "add_child", node, true); + undo_redo->add_undo_method(node->get_parent(), "move_child", node, node->get_index()); + undo_redo->add_undo_method(root, "set_owner", (Object *)nullptr); + undo_redo->add_undo_method(node, "set_owner", root); _node_replace_owner(root, root, root, MODE_UNDO); - editor_data->get_undo_redo()->add_do_method(scene_tree, "update_tree"); - editor_data->get_undo_redo()->add_undo_method(scene_tree, "update_tree"); - editor_data->get_undo_redo()->commit_action(); + undo_redo->add_do_method(scene_tree, "update_tree"); + undo_redo->add_undo_method(scene_tree, "update_tree"); + undo_redo->commit_action(); } break; case TOOL_MULTI_EDIT: { if (!profile_allow_editing) { @@ -916,6 +928,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { String existing; if (extensions.size()) { String root_name(tocopy->get_name()); + root_name = EditorNode::adjust_scene_name_casing(root_name); existing = root_name + "." + extensions.front()->get().to_lower(); } new_scene_from_dialog->set_current_path(existing); @@ -943,7 +956,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); } break; case TOOL_AUTO_EXPAND: { - scene_tree->set_auto_expand_selected(!EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected"), true); + scene_tree->set_auto_expand_selected(!EDITOR_GET("docks/scene_tree/auto_expand_to_selected"), true); } break; case TOOL_SCENE_EDITABLE_CHILDREN: { if (!profile_allow_editing) { @@ -1008,7 +1021,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *node = e->get(); if (node) { Node *root = EditorNode::get_singleton()->get_edited_scene(); - Ref<EditorUndoRedoManager> undo_redo = editor_data->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (!root) { break; } @@ -1073,10 +1086,18 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (first_selected == nullptr) { return; } + if (first_selected->get() == EditorNode::get_singleton()->get_edited_scene()) { + // Exclude Root Node. It should never be unique name in its own scene! + editor_selection->remove_node(first_selected->get()); + first_selected = editor_selection->get_selected_node_list().front(); + if (first_selected == nullptr) { + return; + } + } bool enabling = !first_selected->get()->is_unique_name_in_owner(); List<Node *> full_selection = editor_selection->get_full_selected_node_list(); - Ref<EditorUndoRedoManager> undo_redo = editor_data->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (enabling) { Vector<Node *> new_unique_nodes; @@ -1135,11 +1156,13 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (TOOL_CREATE_FAVORITE == p_tool) { String name = selected_favorite_root.get_slicec(' ', 0); if (ScriptServer::is_global_class(name)) { - new_node = Object::cast_to<Node>(ClassDB::instantiate(ScriptServer::get_global_class_native_base(name))); - Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(name), "Script"); - if (new_node && script.is_valid()) { - new_node->set_script(script); - new_node->set_name(name); + Ref<Script> scr = ResourceLoader::load(ScriptServer::get_global_class_path(name), "Script"); + if (scr.is_valid()) { + new_node = Object::cast_to<Node>(ClassDB::instantiate(scr->get_instance_base_type())); + if (new_node) { + new_node->set_script(scr); + new_node->set_name(name); + } } } else { new_node = Object::cast_to<Node>(ClassDB::instantiate(selected_favorite_root)); @@ -1176,6 +1199,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } break; default: { + _filter_option_selected(p_tool); + if (p_tool >= EDIT_SUBRESOURCE_BASE) { int idx = p_tool - EDIT_SUBRESOURCE_BASE; @@ -1197,30 +1222,21 @@ void SceneTreeDock::_property_selected(int p_idx) { } void SceneTreeDock::_perform_property_drop(Node *p_node, String p_property, Ref<Resource> p_res) { - editor_data->get_undo_redo()->create_action(vformat(TTR("Set %s"), p_property)); - editor_data->get_undo_redo()->add_do_property(p_node, p_property, p_res); - editor_data->get_undo_redo()->add_undo_property(p_node, p_property, p_node->get(p_property)); - editor_data->get_undo_redo()->commit_action(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(vformat(TTR("Set %s"), p_property)); + undo_redo->add_do_property(p_node, p_property, p_res); + undo_redo->add_undo_property(p_node, p_property, p_node->get(p_property)); + undo_redo->commit_action(); } void SceneTreeDock::add_root_node(Node *p_node) { - editor_data->get_undo_redo()->create_action_for_history(TTR("New Scene Root"), editor_data->get_current_edited_scene_history_id()); - editor_data->get_undo_redo()->add_do_method(EditorNode::get_singleton(), "set_edited_scene", p_node); - editor_data->get_undo_redo()->add_do_method(scene_tree, "update_tree"); - editor_data->get_undo_redo()->add_do_reference(p_node); - editor_data->get_undo_redo()->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr); - editor_data->get_undo_redo()->commit_action(); -} - -void SceneTreeDock::_node_collapsed(Object *p_obj) { - TreeItem *ti = Object::cast_to<TreeItem>(p_obj); - if (!ti) { - return; - } - - if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) { - _set_collapsed_recursive(ti, ti->is_collapsed()); - } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action_for_history(TTR("New Scene Root"), editor_data->get_current_edited_scene_history_id()); + undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", p_node); + undo_redo->add_do_method(scene_tree, "update_tree"); + undo_redo->add_do_reference(p_node); + undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr); + undo_redo->commit_action(); } void SceneTreeDock::_notification(int p_what) { @@ -1235,14 +1251,14 @@ void SceneTreeDock::_notification(int p_what) { CanvasItemEditorPlugin *canvas_item_plugin = Object::cast_to<CanvasItemEditorPlugin>(editor_data->get_editor("2D")); if (canvas_item_plugin) { - canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", Callable(scene_tree, "_update_tree")); - canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", Callable(scene_tree, "_update_tree")); + canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", callable_mp(scene_tree, &SceneTreeEditor::_update_tree).bind(false)); + canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", callable_mp(scene_tree, &SceneTreeEditor::_update_tree).bind(false)); scene_tree->connect("node_changed", callable_mp((CanvasItem *)canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), &CanvasItem::queue_redraw)); } Node3DEditorPlugin *spatial_editor_plugin = Object::cast_to<Node3DEditorPlugin>(editor_data->get_editor("3D")); - spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", Callable(scene_tree, "_update_tree")); - spatial_editor_plugin->get_spatial_editor()->connect("item_group_status_changed", Callable(scene_tree, "_update_tree")); + spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", callable_mp(scene_tree, &SceneTreeEditor::_update_tree).bind(false)); + spatial_editor_plugin->get_spatial_editor()->connect("item_group_status_changed", callable_mp(scene_tree, &SceneTreeEditor::_update_tree).bind(false)); button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); button_instance->set_icon(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); @@ -1323,7 +1339,7 @@ void SceneTreeDock::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { clear_inherit_confirm->connect("confirmed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM, false)); - scene_tree->set_auto_expand_selected(EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected"), false); + scene_tree->set_auto_expand_selected(EDITOR_GET("docks/scene_tree/auto_expand_to_selected"), false); } break; case NOTIFICATION_EXIT_TREE: { @@ -1331,7 +1347,7 @@ void SceneTreeDock::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - scene_tree->set_auto_expand_selected(EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected"), false); + scene_tree->set_auto_expand_selected(EDITOR_GET("docks/scene_tree/auto_expand_to_selected"), false); button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); button_instance->set_icon(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); button_create_script->set_icon(get_theme_icon(SNAME("ScriptCreate"), SNAME("EditorIcons"))); @@ -1365,7 +1381,7 @@ void SceneTreeDock::_notification(int p_what) { void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode) { if (p_node->get_owner() == p_base && p_node != p_root) { - Ref<EditorUndoRedoManager> undo_redo = editor_data->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); switch (p_mode) { case MODE_BIDI: { bool disable_unique = p_node->is_unique_name_in_owner() && p_root->get_node_or_null(UNIQUE_NODE_PREFIX + String(p_node->get_name())) != nullptr; @@ -1399,6 +1415,7 @@ void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root void SceneTreeDock::_load_request(const String &p_path) { EditorNode::get_singleton()->open_request(p_path); + _local_tree_selected(); } void SceneTreeDock::_script_open_request(const Ref<Script> &p_script) { @@ -1598,8 +1615,9 @@ void SceneTreeDock::perform_node_renames(Node *p_base, HashMap<Node *, NodePath> Variant old_variant = p_base->get(propertyname); Variant updated_variant = old_variant; if (_check_node_path_recursive(p_base, updated_variant, p_renames)) { - editor_data->get_undo_redo()->add_do_property(p_base, propertyname, updated_variant); - editor_data->get_undo_redo()->add_undo_property(p_base, propertyname, old_variant); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->add_do_property(p_base, propertyname, updated_variant); + undo_redo->add_undo_property(p_base, propertyname, old_variant); p_base->set(propertyname, updated_variant); } } @@ -1644,6 +1662,7 @@ void SceneTreeDock::perform_node_renames(Node *p_base, HashMap<Node *, NodePath> } HashMap<Node *, NodePath>::Iterator found_path = p_renames->find(n); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (found_path) { if (found_path->value == NodePath()) { //will be erased @@ -1657,12 +1676,12 @@ void SceneTreeDock::perform_node_renames(Node *p_base, HashMap<Node *, NodePath> ERR_FAIL_COND(!EI); //another bug } - editor_data->get_undo_redo()->add_do_method(anim.ptr(), "remove_track", idx); - editor_data->get_undo_redo()->add_undo_method(anim.ptr(), "add_track", anim->track_get_type(i), idx); - editor_data->get_undo_redo()->add_undo_method(anim.ptr(), "track_set_path", idx, track_np); - editor_data->get_undo_redo()->add_undo_method(anim.ptr(), "track_set_interpolation_type", idx, anim->track_get_interpolation_type(i)); + undo_redo->add_do_method(anim.ptr(), "remove_track", idx); + undo_redo->add_undo_method(anim.ptr(), "add_track", anim->track_get_type(i), idx); + undo_redo->add_undo_method(anim.ptr(), "track_set_path", idx, track_np); + undo_redo->add_undo_method(anim.ptr(), "track_set_interpolation_type", idx, anim->track_get_interpolation_type(i)); for (int j = 0; j < anim->track_get_key_count(i); j++) { - editor_data->get_undo_redo()->add_undo_method(anim.ptr(), "track_insert_key", idx, anim->track_get_key_time(i, j), anim->track_get_key_value(i, j), anim->track_get_key_transition(i, j)); + undo_redo->add_undo_method(anim.ptr(), "track_insert_key", idx, anim->track_get_key_time(i, j), anim->track_get_key_value(i, j), anim->track_get_key_transition(i, j)); } ran.erase(i); //byebye channel @@ -1675,8 +1694,8 @@ void SceneTreeDock::perform_node_renames(Node *p_base, HashMap<Node *, NodePath> if (new_path == track_np) { continue; //bleh } - editor_data->get_undo_redo()->add_do_method(anim.ptr(), "track_set_path", i, new_path); - editor_data->get_undo_redo()->add_undo_method(anim.ptr(), "track_set_path", i, track_np); + undo_redo->add_do_method(anim.ptr(), "track_set_path", i, new_path); + undo_redo->add_undo_method(anim.ptr(), "track_set_path", i, track_np); } } } @@ -1810,7 +1829,8 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V // Sort by tree order, so re-adding is easy. p_nodes.sort_custom<Node::Comparator>(); - editor_data->get_undo_redo()->create_action(TTR("Reparent Node")); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Reparent Node"), UndoRedo::MERGE_DISABLE, p_nodes[0]); HashMap<Node *, NodePath> path_renames; Vector<StringName> former_names; @@ -1831,15 +1851,18 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V owners.push_back(E); } - if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni) { + bool same_parent = new_parent == node->get_parent(); + if (same_parent && node->get_index() < p_position_in_parent + ni) { inc--; // If the child will generate a gap when moved, adjust. } - editor_data->get_undo_redo()->add_do_method(node->get_parent(), "remove_child", node); - editor_data->get_undo_redo()->add_do_method(new_parent, "add_child", node, true); + if (!same_parent) { + undo_redo->add_do_method(node->get_parent(), "remove_child", node); + undo_redo->add_do_method(new_parent, "add_child", node, true); + } - if (p_position_in_parent >= 0) { - editor_data->get_undo_redo()->add_do_method(new_parent, "move_child", node, p_position_in_parent + inc); + if (p_position_in_parent >= 0 || same_parent) { + undo_redo->add_do_method(new_parent, "move_child", node, p_position_in_parent + inc); } EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); @@ -1869,29 +1892,29 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V } } - editor_data->get_undo_redo()->add_do_method(ed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, p_position_in_parent + inc); - editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)).path_join(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index()); + undo_redo->add_do_method(ed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, p_position_in_parent + inc); + undo_redo->add_undo_method(ed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)).path_join(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index()); if (p_keep_global_xform) { if (Object::cast_to<Node2D>(node)) { - editor_data->get_undo_redo()->add_do_method(node, "set_global_transform", Object::cast_to<Node2D>(node)->get_global_transform()); + undo_redo->add_do_method(node, "set_global_transform", Object::cast_to<Node2D>(node)->get_global_transform()); } if (Object::cast_to<Node3D>(node)) { - editor_data->get_undo_redo()->add_do_method(node, "set_global_transform", Object::cast_to<Node3D>(node)->get_global_transform()); + undo_redo->add_do_method(node, "set_global_transform", Object::cast_to<Node3D>(node)->get_global_transform()); } if (Object::cast_to<Control>(node)) { - editor_data->get_undo_redo()->add_do_method(node, "set_global_position", Object::cast_to<Control>(node)->get_global_position()); + undo_redo->add_do_method(node, "set_global_position", Object::cast_to<Control>(node)->get_global_position()); } } - editor_data->get_undo_redo()->add_do_method(this, "_set_owners", edited_scene, owners); + undo_redo->add_do_method(this, "_set_owners", edited_scene, owners); if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == node) { - editor_data->get_undo_redo()->add_do_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", node); + undo_redo->add_do_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", node); } - editor_data->get_undo_redo()->add_undo_method(new_parent, "remove_child", node); - editor_data->get_undo_redo()->add_undo_method(node, "set_name", former_names[ni]); + undo_redo->add_undo_method(new_parent, "remove_child", node); + undo_redo->add_undo_method(node, "set_name", former_names[ni]); inc++; } @@ -1909,71 +1932,29 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V int child_pos = node->get_index(); - editor_data->get_undo_redo()->add_undo_method(node->get_parent(), "add_child", node, true); - editor_data->get_undo_redo()->add_undo_method(node->get_parent(), "move_child", node, child_pos); - editor_data->get_undo_redo()->add_undo_method(this, "_set_owners", edited_scene, owners); + undo_redo->add_undo_method(node->get_parent(), "add_child", node, true); + undo_redo->add_undo_method(node->get_parent(), "move_child", node, child_pos); + undo_redo->add_undo_method(this, "_set_owners", edited_scene, owners); if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == node) { - editor_data->get_undo_redo()->add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", node); + undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", node); } if (p_keep_global_xform) { if (Object::cast_to<Node2D>(node)) { - editor_data->get_undo_redo()->add_undo_method(node, "set_transform", Object::cast_to<Node2D>(node)->get_transform()); + undo_redo->add_undo_method(node, "set_transform", Object::cast_to<Node2D>(node)->get_transform()); } if (Object::cast_to<Node3D>(node)) { - editor_data->get_undo_redo()->add_undo_method(node, "set_transform", Object::cast_to<Node3D>(node)->get_transform()); + undo_redo->add_undo_method(node, "set_transform", Object::cast_to<Node3D>(node)->get_transform()); } if (Object::cast_to<Control>(node)) { - editor_data->get_undo_redo()->add_undo_method(node, "set_position", Object::cast_to<Control>(node)->get_position()); + undo_redo->add_undo_method(node, "set_position", Object::cast_to<Control>(node)->get_position()); } } } perform_node_renames(nullptr, &path_renames); - editor_data->get_undo_redo()->commit_action(); -} - -bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const { - bool is_branch_collapsed = false; - - List<TreeItem *> needs_check; - needs_check.push_back(p_item); - - while (!needs_check.is_empty()) { - TreeItem *item = needs_check.back()->get(); - needs_check.pop_back(); - - TreeItem *child = item->get_first_child(); - is_branch_collapsed = item->is_collapsed() && child; - - if (is_branch_collapsed) { - break; - } - while (child) { - needs_check.push_back(child); - child = child->get_next(); - } - } - return is_branch_collapsed; -} - -void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed) { - List<TreeItem *> to_collapse; - to_collapse.push_back(p_item); - - while (!to_collapse.is_empty()) { - TreeItem *item = to_collapse.back()->get(); - to_collapse.pop_back(); - - item->set_collapsed(p_collapsed); - - TreeItem *child = item->get_first_child(); - while (child) { - to_collapse.push_back(child); - child = child->get_next(); - } - } + undo_redo->commit_action(); } void SceneTreeDock::_script_created(Ref<Script> p_script) { @@ -1983,34 +1964,35 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { return; } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (selected.size() == 1) { Node *node = selected.front()->get(); Ref<Script> existing = node->get_script(); - editor_data->get_undo_redo()->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, node); - editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "store_script_properties", node); - editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", node); - editor_data->get_undo_redo()->add_do_method(node, "set_script", p_script); - editor_data->get_undo_redo()->add_undo_method(node, "set_script", existing); - editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "apply_script_properties", node); - editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", node); - editor_data->get_undo_redo()->add_do_method(this, "_update_script_button"); - editor_data->get_undo_redo()->add_undo_method(this, "_update_script_button"); - editor_data->get_undo_redo()->commit_action(); + undo_redo->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, node); + undo_redo->add_do_method(InspectorDock::get_singleton(), "store_script_properties", node); + undo_redo->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", node); + undo_redo->add_do_method(node, "set_script", p_script); + undo_redo->add_undo_method(node, "set_script", existing); + undo_redo->add_do_method(InspectorDock::get_singleton(), "apply_script_properties", node); + undo_redo->add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", node); + undo_redo->add_do_method(this, "_update_script_button"); + undo_redo->add_undo_method(this, "_update_script_button"); + undo_redo->commit_action(); } else { - editor_data->get_undo_redo()->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, selected.front()->get()); + undo_redo->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, selected.front()->get()); for (Node *E : selected) { Ref<Script> existing = E->get_script(); - editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "store_script_properties", E); - editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", E); - editor_data->get_undo_redo()->add_do_method(E, "set_script", p_script); - editor_data->get_undo_redo()->add_undo_method(E, "set_script", existing); - editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "apply_script_properties", E); - editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", E); - editor_data->get_undo_redo()->add_do_method(this, "_update_script_button"); - editor_data->get_undo_redo()->add_undo_method(this, "_update_script_button"); + undo_redo->add_do_method(InspectorDock::get_singleton(), "store_script_properties", E); + undo_redo->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", E); + undo_redo->add_do_method(E, "set_script", p_script); + undo_redo->add_undo_method(E, "set_script", existing); + undo_redo->add_do_method(InspectorDock::get_singleton(), "apply_script_properties", E); + undo_redo->add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", E); + undo_redo->add_do_method(this, "_update_script_button"); + undo_redo->add_undo_method(this, "_update_script_button"); } - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); } _push_item(p_script.operator->()); @@ -2024,10 +2006,11 @@ void SceneTreeDock::_shader_created(Ref<Shader> p_shader) { Ref<Shader> existing = selected_shader_material->get_shader(); - editor_data->get_undo_redo()->create_action(TTR("Set Shader")); - editor_data->get_undo_redo()->add_do_method(selected_shader_material.ptr(), "set_shader", p_shader); - editor_data->get_undo_redo()->add_undo_method(selected_shader_material.ptr(), "set_shader", existing); - editor_data->get_undo_redo()->commit_action(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Set Shader")); + undo_redo->add_do_method(selected_shader_material.ptr(), "set_shader", p_shader); + undo_redo->add_undo_method(selected_shader_material.ptr(), "set_shader", existing); + undo_redo->commit_action(); } void SceneTreeDock::_script_creation_closed() { @@ -2092,11 +2075,8 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { EditorNode::get_singleton()->get_editor_plugins_over()->make_visible(false); - if (p_cut) { - editor_data->get_undo_redo()->create_action(TTR("Cut Node(s)"), UndoRedo::MERGE_DISABLE, remove_list.front()->get()); - } else { - editor_data->get_undo_redo()->create_action(TTR("Remove Node(s)"), UndoRedo::MERGE_DISABLE, remove_list.front()->get()); - } + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(p_cut ? TTR("Cut Node(s)") : TTR("Remove Node(s)"), UndoRedo::MERGE_DISABLE, remove_list.front()->get()); bool entire_scene = false; @@ -2108,11 +2088,11 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { } if (entire_scene) { - editor_data->get_undo_redo()->add_do_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr); - editor_data->get_undo_redo()->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", edited_scene); - editor_data->get_undo_redo()->add_undo_method(edited_scene, "set_owner", edited_scene->get_owner()); - editor_data->get_undo_redo()->add_undo_method(scene_tree, "update_tree"); - editor_data->get_undo_redo()->add_undo_reference(edited_scene); + undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr); + undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", edited_scene); + undo_redo->add_undo_method(edited_scene, "set_owner", edited_scene->get_owner()); + undo_redo->add_undo_method(scene_tree, "update_tree"); + undo_redo->add_undo_reference(edited_scene); } else { remove_list.sort_custom<Node::Comparator>(); //sort nodes to keep positions @@ -2141,21 +2121,21 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { owners.push_back(F); } - editor_data->get_undo_redo()->add_do_method(n->get_parent(), "remove_child", n); - editor_data->get_undo_redo()->add_undo_method(n->get_parent(), "add_child", n, true); - editor_data->get_undo_redo()->add_undo_method(n->get_parent(), "move_child", n, n->get_index()); + undo_redo->add_do_method(n->get_parent(), "remove_child", n); + undo_redo->add_undo_method(n->get_parent(), "add_child", n, true); + undo_redo->add_undo_method(n->get_parent(), "move_child", n, n->get_index()); if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == n) { - editor_data->get_undo_redo()->add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", n); + undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", n); } - editor_data->get_undo_redo()->add_undo_method(this, "_set_owners", edited_scene, owners); - editor_data->get_undo_redo()->add_undo_reference(n); + undo_redo->add_undo_method(this, "_set_owners", edited_scene, owners); + undo_redo->add_undo_reference(n); EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); - editor_data->get_undo_redo()->add_do_method(ed, "live_debug_remove_and_keep_node", edited_scene->get_path_to(n), n->get_instance_id()); - editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_restore_node", n->get_instance_id(), edited_scene->get_path_to(n->get_parent()), n->get_index()); + undo_redo->add_do_method(ed, "live_debug_remove_and_keep_node", edited_scene->get_path_to(n), n->get_instance_id()); + undo_redo->add_undo_method(ed, "live_debug_restore_node", n->get_instance_id(), edited_scene->get_path_to(n->get_parent()), n->get_index()); } } - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); // hack, force 2d editor viewport to refresh after deletion if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton()) { @@ -2215,35 +2195,39 @@ void SceneTreeDock::_selection_changed() { } void SceneTreeDock::_do_create(Node *p_parent) { - Variant c = create_dialog->instance_selected(); - - ERR_FAIL_COND(!c); + Variant c = create_dialog->instantiate_selected(); Node *child = Object::cast_to<Node>(c); ERR_FAIL_COND(!child); - editor_data->get_undo_redo()->create_action_for_history(TTR("Create Node"), editor_data->get_current_edited_scene_history_id()); + String new_name = p_parent->validate_child_name(child); + if (GLOBAL_GET("editor/node_naming/name_casing").operator int() != NAME_CASING_PASCAL_CASE) { + new_name = adjust_name_casing(new_name); + } + child->set_name(new_name); + + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action_for_history(TTR("Create Node"), editor_data->get_current_edited_scene_history_id()); if (edited_scene) { - editor_data->get_undo_redo()->add_do_method(p_parent, "add_child", child, true); - editor_data->get_undo_redo()->add_do_method(child, "set_owner", edited_scene); - editor_data->get_undo_redo()->add_do_method(editor_selection, "clear"); - editor_data->get_undo_redo()->add_do_method(editor_selection, "add_node", child); - editor_data->get_undo_redo()->add_do_reference(child); - editor_data->get_undo_redo()->add_undo_method(p_parent, "remove_child", child); - - String new_name = p_parent->validate_child_name(child); + undo_redo->add_do_method(p_parent, "add_child", child, true); + undo_redo->add_do_method(child, "set_owner", edited_scene); + undo_redo->add_do_method(editor_selection, "clear"); + undo_redo->add_do_method(editor_selection, "add_node", child); + undo_redo->add_do_reference(child); + undo_redo->add_undo_method(p_parent, "remove_child", child); + EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); - editor_data->get_undo_redo()->add_do_method(ed, "live_debug_create_node", edited_scene->get_path_to(p_parent), child->get_class(), new_name); - editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(p_parent)).path_join(new_name))); + undo_redo->add_do_method(ed, "live_debug_create_node", edited_scene->get_path_to(p_parent), child->get_class(), new_name); + undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(p_parent)).path_join(new_name))); } else { - editor_data->get_undo_redo()->add_do_method(EditorNode::get_singleton(), "set_edited_scene", child); - editor_data->get_undo_redo()->add_do_method(scene_tree, "update_tree"); - editor_data->get_undo_redo()->add_do_reference(child); - editor_data->get_undo_redo()->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr); + undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", child); + undo_redo->add_do_method(scene_tree, "update_tree"); + undo_redo->add_do_reference(child); + undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr); } - editor_data->get_undo_redo()->commit_action(); + undo_redo->commit_action(); _push_item(c); editor_selection->clear(); editor_selection->add_node(child); @@ -2296,7 +2280,7 @@ void SceneTreeDock::_create() { for (Node *n : selection) { ERR_FAIL_COND(!n); - Variant c = create_dialog->instance_selected(); + Variant c = create_dialog->instantiate_selected(); ERR_FAIL_COND(!c); Node *newnode = Object::cast_to<Node>(c); @@ -2424,7 +2408,7 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop } //p_remove_old was added to support undo if (p_remove_old) { - editor_data->get_undo_redo()->clear_history(); + EditorNode::get_undo_redo()->clear_history(); } newnode->set_name(newname); @@ -2484,7 +2468,7 @@ void SceneTreeDock::_new_scene_from(String p_file) { } int flg = 0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) { + if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; } @@ -2637,17 +2621,50 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) { Ref<Script> scr = ResourceLoader::load(p_file); ERR_FAIL_COND(!scr.is_valid()); - if (Node *n = get_node(p_to)) { - editor_data->get_undo_redo()->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, n); - editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "store_script_properties", n); - editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", n); - editor_data->get_undo_redo()->add_do_method(n, "set_script", scr); - editor_data->get_undo_redo()->add_undo_method(n, "set_script", n->get_script()); - editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "apply_script_properties", n); - editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", n); - editor_data->get_undo_redo()->add_do_method(this, "_update_script_button"); - editor_data->get_undo_redo()->add_undo_method(this, "_update_script_button"); - editor_data->get_undo_redo()->commit_action(); + Node *n = get_node(p_to); + + if (!n) { + return; + } + + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); + if (Input::get_singleton()->is_key_pressed(Key::CTRL)) { + Object *obj = ClassDB::instantiate(scr->get_instance_base_type()); + ERR_FAIL_NULL(obj); + + Node *new_node = Object::cast_to<Node>(obj); + if (!new_node) { + if (!obj->is_ref_counted()) { + memdelete(obj); + } + ERR_FAIL_MSG("Script does not extend Node-derived type."); + } + new_node->set_name(Node::adjust_name_casing(p_file.get_file().get_basename())); + new_node->set_script(scr); + + undo_redo->create_action(TTR("Instantiate Script")); + undo_redo->add_do_method(n, "add_child", new_node, true); + undo_redo->add_do_method(new_node, "set_owner", edited_scene); + undo_redo->add_do_method(editor_selection, "clear"); + undo_redo->add_do_method(editor_selection, "add_node", new_node); + undo_redo->add_do_reference(new_node); + undo_redo->add_undo_method(n, "remove_child", new_node); + + EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); + undo_redo->add_do_method(ed, "live_debug_create_node", edited_scene->get_path_to(n), new_node->get_class(), new_node->get_name()); + undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(n)).path_join(new_node->get_name()))); + undo_redo->commit_action(); + } else { + undo_redo->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, n); + undo_redo->add_do_method(InspectorDock::get_singleton(), "store_script_properties", n); + undo_redo->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", n); + undo_redo->add_do_method(n, "set_script", scr); + undo_redo->add_undo_method(n, "set_script", n->get_script()); + undo_redo->add_do_method(InspectorDock::get_singleton(), "apply_script_properties", n); + undo_redo->add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", n); + undo_redo->add_do_method(this, "_update_script_button"); + undo_redo->add_undo_method(this, "_update_script_button"); + undo_redo->commit_action(); } } @@ -2721,7 +2738,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->clear(); if (profile_allow_editing) { menu->add_icon_shortcut(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); - menu->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANTIATE); + menu->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/instantiate_scene"), TOOL_INSTANTIATE); } menu->reset_size(); @@ -2754,7 +2771,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { } menu->add_icon_shortcut(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); - menu->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANTIATE); + menu->add_icon_shortcut(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/instantiate_scene"), TOOL_INSTANTIATE); } menu->add_icon_shortcut(get_theme_icon(SNAME("Collapse"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/expand_collapse_all"), TOOL_EXPAND_COLLAPSE); menu->add_separator(); @@ -2865,10 +2882,13 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { } } if (all_owned) { - menu->add_separator(); - menu->add_icon_check_item(get_theme_icon(SNAME("SceneUniqueName"), SNAME("EditorIcons")), TTR("Access as Scene Unique Name"), TOOL_TOGGLE_SCENE_UNIQUE_NAME); - // Checked based on `selection[0]` because `full_selection` has undesired ordering. - menu->set_item_checked(menu->get_item_index(TOOL_TOGGLE_SCENE_UNIQUE_NAME), selection[0]->is_unique_name_in_owner()); + // Group "toggle_unique_name" with "copy_node_path", if it is available. + if (menu->get_item_index(TOOL_COPY_NODE_PATH) == -1) { + menu->add_separator(); + } + Node *node = full_selection[0]; + menu->add_icon_shortcut(get_theme_icon(SNAME("SceneUniqueName"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/toggle_unique_name"), TOOL_TOGGLE_SCENE_UNIQUE_NAME); + menu->set_item_text(menu->get_item_index(TOOL_TOGGLE_SCENE_UNIQUE_NAME), node->is_unique_name_in_owner() ? TTR("Revoke Unique Name") : TTR("Access as Unique Name")); } } @@ -2922,11 +2942,83 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { void SceneTreeDock::_update_tree_menu() { PopupMenu *tree_menu = button_tree_menu->get_popup(); - tree_menu->set_item_checked(tree_menu->get_item_idx_from_text(TTR("Auto Expand to Selected")), EditorSettings::get_singleton()->get("docks/scene_tree/auto_expand_to_selected")); + tree_menu->clear(); + + _append_filter_options_to(tree_menu); + + tree_menu->add_separator(); + tree_menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND); + tree_menu->set_item_checked(tree_menu->get_item_index(TOOL_AUTO_EXPAND), EDITOR_GET("docks/scene_tree/auto_expand_to_selected")); +} + +void SceneTreeDock::_update_filter_menu() { + _append_filter_options_to(filter->get_menu()); } void SceneTreeDock::_filter_changed(const String &p_filter) { scene_tree->set_filter(p_filter); + + String warning = scene_tree->get_filter_term_warning(); + if (!warning.is_empty()) { + filter->add_theme_icon_override(SNAME("clear"), get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"))); + filter->set_tooltip_text(warning); + } else { + filter->remove_theme_icon_override(SNAME("clear")); + filter->set_tooltip_text(""); + } +} + +void SceneTreeDock::_filter_gui_input(const Ref<InputEvent> &p_event) { + Ref<InputEventMouseButton> mb = p_event; + if (mb.is_null()) { + return; + } + + if (mb->is_pressed() && mb->get_button_index() == MouseButton::MIDDLE) { + filter_quick_menu->clear(); + + _append_filter_options_to(filter_quick_menu, false); + filter_quick_menu->set_position(get_screen_position() + get_local_mouse_position()); + filter_quick_menu->reset_size(); + filter_quick_menu->popup(); + filter_quick_menu->grab_focus(); + accept_event(); + } +} + +void SceneTreeDock::_filter_option_selected(int p_option) { + String filter_parameter; + switch (p_option) { + case FILTER_BY_TYPE: { + filter_parameter = "type"; + } break; + case FILTER_BY_GROUP: { + filter_parameter = "group"; + } break; + } + + if (!filter_parameter.is_empty()) { + set_filter((get_filter() + " " + filter_parameter + ":").strip_edges()); + filter->set_caret_column(filter->get_text().length()); + filter->grab_focus(); + } +} + +void SceneTreeDock::_append_filter_options_to(PopupMenu *p_menu, bool p_include_separator) { + if (p_include_separator) { + p_menu->add_separator(); + + p_menu->set_item_text(-1, TTR("Filters")); + p_menu->set_item_icon(-1, get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); + p_menu->set_item_indent(-1, -2); + } + + p_menu->add_item(TTR("Filter by Type"), FILTER_BY_TYPE); + p_menu->add_item(TTR("Filter by Group"), FILTER_BY_GROUP); + p_menu->set_item_icon(p_menu->get_item_index(FILTER_BY_TYPE), get_theme_icon(SNAME("Node"), SNAME("EditorIcons"))); + p_menu->set_item_icon(p_menu->get_item_index(FILTER_BY_GROUP), get_theme_icon(SNAME("Groups"), SNAME("EditorIcons"))); + p_menu->set_item_tooltip(p_menu->get_item_index(FILTER_BY_TYPE), TTR("Selects all Nodes of the given type.")); + p_menu->set_item_tooltip(p_menu->get_item_index(FILTER_BY_GROUP), TTR("Selects all Nodes belonging to the given group.\nIf empty, selects any Node belonging to any group.")); } String SceneTreeDock::get_filter() { @@ -3107,7 +3199,7 @@ List<Node *> SceneTreeDock::paste_nodes() { owner = paste_parent; } - Ref<EditorUndoRedoManager> &ur = editor_data->get_undo_redo(); + Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo(); ur->create_action(TTR("Paste Node(s)"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene()); ur->add_do_method(editor_selection, "clear"); @@ -3180,6 +3272,7 @@ void SceneTreeDock::add_remote_tree_editor(Control *p_remote) { add_child(p_remote); remote_tree = p_remote; remote_tree->hide(); + remote_tree->connect("open", callable_mp(this, &SceneTreeDock::_load_request)); } void SceneTreeDock::show_remote_tree() { @@ -3226,7 +3319,7 @@ void SceneTreeDock::_update_create_root_dialog() { EditorSettings::get_singleton()->save(); if (node_shortcuts_toggle->is_pressed()) { for (int i = 0; i < favorite_node_shortcuts->get_child_count(); i++) { - favorite_node_shortcuts->get_child(i)->queue_delete(); + favorite_node_shortcuts->get_child(i)->queue_free(); } Ref<FileAccess> f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().path_join("favorites.Node"), FileAccess::READ); @@ -3404,7 +3497,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec ED_SHORTCUT_OVERRIDE("scene_tree/batch_rename", "macos", KeyModifierMask::SHIFT | Key::ENTER); ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KeyModifierMask::CMD_OR_CTRL | Key::A); - ED_SHORTCUT("scene_tree/instance_scene", TTR("Instantiate Child Scene"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::A); + ED_SHORTCUT("scene_tree/instantiate_scene", TTR("Instantiate Child Scene"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::A); ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse Branch")); ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KeyModifierMask::CMD_OR_CTRL | Key::X); ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KeyModifierMask::CMD_OR_CTRL | Key::C); @@ -3421,6 +3514,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root")); ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene")); ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::C); + ED_SHORTCUT("scene_tree/toggle_unique_name", TTR("Toggle Access as Unique Name")); ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KeyModifierMask::SHIFT | Key::KEY_DELETE); ED_SHORTCUT("scene_tree/delete", TTR("Delete"), Key::KEY_DELETE); @@ -3435,16 +3529,24 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec button_instance->set_flat(true); button_instance->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_INSTANTIATE, false)); button_instance->set_tooltip_text(TTR("Instantiate a scene file as a Node. Creates an inherited scene if no root node exists.")); - button_instance->set_shortcut(ED_GET_SHORTCUT("scene_tree/instance_scene")); + button_instance->set_shortcut(ED_GET_SHORTCUT("scene_tree/instantiate_scene")); filter_hbc->add_child(button_instance); - vbc->add_child(filter_hbc); + + // The "Filter Nodes" text input above the Scene Tree Editor. filter = memnew(LineEdit); filter->set_h_size_flags(SIZE_EXPAND_FILL); filter->set_placeholder(TTR("Filter Nodes")); filter_hbc->add_child(filter); filter->add_theme_constant_override("minimum_character_width", 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDock::_filter_changed)); + filter->connect("gui_input", callable_mp(this, &SceneTreeDock::_filter_gui_input)); + filter->get_menu()->connect("about_to_popup", callable_mp(this, &SceneTreeDock::_update_filter_menu)); + filter->get_menu()->connect("id_pressed", callable_mp(this, &SceneTreeDock::_filter_option_selected)); + + filter_quick_menu = memnew(PopupMenu); + filter_quick_menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_filter_option_selected)); + filter->add_child(filter_quick_menu); button_create_script = memnew(Button); button_create_script->set_flat(true); @@ -3464,11 +3566,11 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec button_tree_menu = memnew(MenuButton); button_tree_menu->set_flat(true); + button_tree_menu->set_tooltip_text(TTR("Extra scene options.")); button_tree_menu->connect("about_to_popup", callable_mp(this, &SceneTreeDock::_update_tree_menu)); filter_hbc->add_child(button_tree_menu); PopupMenu *tree_menu = button_tree_menu->get_popup(); - tree_menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND); tree_menu->connect("id_pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(false)); button_hb = memnew(HBoxContainer); @@ -3517,11 +3619,10 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec scene_tree->connect("nodes_dragged", callable_mp(this, &SceneTreeDock::_nodes_drag_begin)); scene_tree->get_scene_tree()->connect("item_double_clicked", callable_mp(this, &SceneTreeDock::_focus_node)); - scene_tree->get_scene_tree()->connect("item_collapsed", callable_mp(this, &SceneTreeDock::_node_collapsed)); editor_selection->connect("selection_changed", callable_mp(this, &SceneTreeDock::_selection_changed)); - scene_tree->set_undo_redo(editor_data->get_undo_redo()); + scene_tree->set_as_scene_tree_dock(); scene_tree->set_editor_selection(editor_selection); create_dialog = memnew(CreateDialog); @@ -3531,7 +3632,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec create_dialog->connect("favorites_updated", callable_mp(this, &SceneTreeDock::_update_create_root_dialog)); #ifdef MODULE_REGEX_ENABLED - rename_dialog = memnew(RenameDialog(scene_tree, editor_data->get_undo_redo())); + rename_dialog = memnew(RenameDialog(scene_tree)); add_child(rename_dialog); #endif // MODULE_REGEX_ENABLED diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index dc228e1c93..ac368e1aab 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -31,28 +31,24 @@ #ifndef SCENE_TREE_DOCK_H #define SCENE_TREE_DOCK_H -#include "editor/create_dialog.h" +#include "scene_tree_editor.h" + #include "editor/editor_data.h" -#include "editor/editor_quick_open.h" -#include "editor/groups_editor.h" -#include "editor/reparent_dialog.h" #include "editor/script_create_dialog.h" -#include "scene/animation/animation_player.h" #include "scene/gui/box_container.h" -#include "scene/gui/button.h" -#include "scene/gui/control.h" -#include "scene/gui/label.h" -#include "scene/gui/popup_menu.h" -#include "scene/gui/tree.h" -#include "scene_tree_editor.h" +#include "scene/resources/animation.h" + +class EditorQuickOpen; +class MenuButton; +class ReparentDialog; +class ShaderCreateDialog; +class TextureRect; #include "modules/modules_enabled.gen.h" // For regex. #ifdef MODULE_REGEX_ENABLED class RenameDialog; #endif // MODULE_REGEX_ENABLED -class ShaderCreateDialog; - class SceneTreeDock : public VBoxContainer { GDCLASS(SceneTreeDock, VBoxContainer); @@ -137,7 +133,6 @@ class SceneTreeDock : public VBoxContainer { HBoxContainer *tool_hbc = nullptr; void _tool_selected(int p_tool, bool p_confirm_override = false); void _property_selected(int p_idx); - void _node_collapsed(Object *p_obj); Node *property_drop_node = nullptr; String resource_drop_path; @@ -161,7 +156,13 @@ class SceneTreeDock : public VBoxContainer { EditorQuickOpen *quick_open = nullptr; EditorFileDialog *new_scene_from_dialog = nullptr; + enum FilterMenuItems { + FILTER_BY_TYPE = 64, // Used in the same menus as the Tool enum. + FILTER_BY_GROUP, + }; + LineEdit *filter = nullptr; + PopupMenu *filter_quick_menu = nullptr; TextureRect *filter_icon = nullptr; PopupMenu *menu = nullptr; @@ -188,9 +189,6 @@ class SceneTreeDock : public VBoxContainer { void _node_reparent(NodePath p_path, bool p_keep_global_xform); void _do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform); - bool _is_collapsed_recursive(TreeItem *p_item) const; - void _set_collapsed_recursive(TreeItem *p_item, bool p_collapsed); - void _set_owners(Node *p_owner, const Array &p_nodes); enum ReplaceOwnerMode { @@ -228,8 +226,6 @@ class SceneTreeDock : public VBoxContainer { virtual void input(const Ref<InputEvent> &p_event) override; virtual void shortcut_input(const Ref<InputEvent> &p_event) override; - void _import_subscene(); - void _new_scene_from(String p_file); void _set_node_owner_recursive(Node *p_node, Node *p_owner); @@ -249,8 +245,12 @@ class SceneTreeDock : public VBoxContainer { void _tree_rmb(const Vector2 &p_menu_pos); void _update_tree_menu(); + void _update_filter_menu(); void _filter_changed(const String &p_filter); + void _filter_gui_input(const Ref<InputEvent> &p_event); + void _filter_option_selected(int option); + void _append_filter_options_to(PopupMenu *p_menu, bool p_include_separator = true); void _perform_instantiate_scenes(const Vector<String> &p_files, Node *parent, int p_pos); void _replace_with_branch_scene(const String &p_file, Node *base); @@ -292,7 +292,6 @@ public: void _focus_node(); - void import_subscene(); void add_root_node(Node *p_node); void set_edited_scene(Node *p_scene); void instantiate(const String &p_file); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 137574640e..092ef30678 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -30,11 +30,12 @@ #include "scene_tree_editor.h" +#include "core/config/project_settings.h" #include "core/object/message_queue.h" -#include "core/string/print_string.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" #include "editor/node_dock.h" #include "editor/plugins/animation_player_editor_plugin.h" @@ -67,6 +68,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i Node *n = get_node(np); ERR_FAIL_COND(!n); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); if (p_id == BUTTON_SUBSCENE) { if (n == get_scene_node()) { if (n && n->get_scene_inherited_state().is_valid()) { @@ -166,6 +168,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i void SceneTreeEditor::_toggle_visible(Node *p_node) { if (p_node->has_method("is_visible") && p_node->has_method("set_visible")) { bool v = bool(p_node->call("is_visible")); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->add_do_method(p_node, "set_visible", !v); undo_redo->add_undo_method(p_node, "set_visible", v); } @@ -214,8 +217,8 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (connect_to_script_mode) { Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor")); - Ref<Script> script = p_node->get_script(); - if (!script.is_null() && EditorNode::get_singleton()->get_object_custom_type_base(p_node) != script) { + Ref<Script> scr = p_node->get_script(); + if (!scr.is_null() && EditorNode::get_singleton()->get_object_custom_type_base(p_node) != scr) { //has script item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT); } else { @@ -223,7 +226,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->set_custom_color(0, get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); item->set_selectable(0, false); - if (!script.is_null()) { // make sure to mark the script if a custom type + if (!scr.is_null()) { // make sure to mark the script if a custom type item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT); item->set_button_disabled(0, item->get_button_count(0) - 1, true); } @@ -267,8 +270,8 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (can_rename) { //should be can edit.. - String warning = p_node->get_configuration_warnings_as_string(); - if (!warning.is_empty()) { + String conf_warning = p_node->get_configuration_warnings_as_string(); + if (!conf_warning.is_empty()) { const int num_warnings = p_node->get_configuration_warnings().size(); String warning_icon; if (num_warnings == 1) { @@ -283,15 +286,15 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { const String bullet_point = String::utf8("• "); int next_newline = 0; while (next_newline != -1) { - next_newline = warning.find("\n", next_newline + 2); - if (warning.substr(next_newline + 1, bullet_point.length()) != bullet_point) { - warning = warning.insert(next_newline + 1, " "); + next_newline = conf_warning.find("\n", next_newline + 2); + if (conf_warning.substr(next_newline + 1, bullet_point.length()) != bullet_point) { + conf_warning = conf_warning.insert(next_newline + 1, " "); } } String newline = (num_warnings == 1 ? "\n" : "\n\n"); - item->add_button(0, get_theme_icon(warning_icon, SNAME("EditorIcons")), BUTTON_WARNING, false, TTR("Node configuration warning:") + newline + warning); + item->add_button(0, get_theme_icon(warning_icon, SNAME("EditorIcons")), BUTTON_WARNING, false, TTR("Node configuration warning:") + newline + conf_warning); } if (p_node->is_unique_name_in_owner()) { @@ -378,26 +381,25 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->set_tooltip_text(0, tooltip); } - if (can_open_instance && undo_redo.is_valid()) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes - + if (can_open_instance && is_scene_tree_dock) { // Show buttons only when necessary (SceneTreeDock) to avoid crashes. if (!p_node->is_connected("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed))) { p_node->connect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed).bind(p_node)); } - Ref<Script> script = p_node->get_script(); - if (!script.is_null()) { + Ref<Script> scr = p_node->get_script(); + if (!scr.is_null()) { String additional_notes; Color button_color = Color(1, 1, 1); // Can't set tooltip after adding button, need to do it before. - if (script->is_tool()) { + if (scr->is_tool()) { additional_notes += "\n" + TTR("This script is currently running in the editor."); button_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); } - if (EditorNode::get_singleton()->get_object_custom_type_base(p_node) == script) { + if (EditorNode::get_singleton()->get_object_custom_type_base(p_node) == scr) { additional_notes += "\n" + TTR("This script is a custom type."); button_color.a = 0.5; } - item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path() + additional_notes); + item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + scr->get_path() + additional_notes); item->set_button_color(0, item->get_button_count(0) - 1, button_color); } @@ -482,8 +484,9 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (valid_types.size()) { bool valid = false; - for (int i = 0; i < valid_types.size(); i++) { - if (p_node->is_class(valid_types[i])) { + for (const StringName &E : valid_types) { + if (p_node->is_class(E) || + EditorNode::get_singleton()->is_object_of_custom_type(p_node, E)) { valid = true; break; } @@ -510,16 +513,16 @@ void SceneTreeEditor::_node_visibility_changed(Node *p_node) { int idx = item->get_button_by_id(0, BUTTON_VISIBILITY); ERR_FAIL_COND(idx == -1); - bool visible = false; + bool node_visible = false; if (p_node->is_class("CanvasItem") || p_node->is_class("CanvasLayer") || p_node->is_class("Window")) { - visible = p_node->call("is_visible"); + node_visible = p_node->call("is_visible"); CanvasItemEditor::get_singleton()->get_viewport_control()->queue_redraw(); } else if (p_node->is_class("Node3D")) { - visible = p_node->call("is_visible"); + node_visible = p_node->call("is_visible"); } - if (visible) { + if (node_visible) { item->set_button(0, idx, get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); } else { item->set_button(0, idx, get_theme_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons"))); @@ -611,6 +614,7 @@ void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) { bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_selected) { if (!p_parent) { p_parent = tree->get_root(); + filter_term_warning.clear(); } if (!p_parent) { @@ -672,27 +676,37 @@ bool SceneTreeEditor::_item_matches_all_terms(TreeItem *p_item, PackedStringArra if (parameter == "type" || parameter == "t") { // Filter by Type. - String node_type = get_node(p_item->get_metadata(0))->get_class().to_lower(); + String type = get_node(p_item->get_metadata(0))->get_class(); + bool term_in_inherited_class = false; + // Every Node is is a Node, duh! + while (type != "Node") { + if (type.to_lower().contains(argument)) { + term_in_inherited_class = true; + break; + } - if (!node_type.contains(argument)) { + type = ClassDB::get_parent_class(type); + } + if (!term_in_inherited_class) { return false; } } else if (parameter == "group" || parameter == "g") { // Filter by Group. Node *node = get_node(p_item->get_metadata(0)); - List<Node::GroupInfo> group_info_list; - node->get_groups(&group_info_list); - if (group_info_list.is_empty()) { - return false; - } - // When argument is empty, match all Nodes belonging to any group. - if (!argument.is_empty()) { + if (argument.is_empty()) { + // When argument is empty, match all Nodes belonging to any exposed group. + if (node->get_persistent_group_count() == 0) { + return false; + } + } else { + List<Node::GroupInfo> group_info_list; + node->get_groups(&group_info_list); + bool term_in_groups = false; for (int j = 0; j < group_info_list.size(); j++) { - // Ignore private groups. - if (String(group_info_list[j].name).begins_with("__")) { - continue; + if (!group_info_list[j].persistent) { + continue; // Ignore internal groups. } if (String(group_info_list[j].name).to_lower().contains(argument)) { term_in_groups = true; @@ -703,8 +717,8 @@ bool SceneTreeEditor::_item_matches_all_terms(TreeItem *p_item, PackedStringArra return false; } } - } else { - WARN_PRINT(vformat(TTR("Special Node filter \"%s\" is not recognised. Available filters include \"type\" and \"group\"."), parameter)); + } else if (filter_term_warning.is_empty()) { + filter_term_warning = vformat(TTR("\"%s\" is not a known filter."), parameter); continue; } } else { @@ -803,6 +817,10 @@ void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_ TreeItem *item = Object::cast_to<TreeItem>(p_object); ERR_FAIL_COND(!item); + if (!item->is_visible()) { + return; + } + NodePath np = item->get_metadata(0); Node *n = get_node(np); @@ -835,7 +853,7 @@ void SceneTreeEditor::_notification(int p_what) { get_tree()->connect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed)); get_tree()->connect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed)); get_tree()->connect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed)); - get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed), CONNECT_DEFERRED); + get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed)); tree->connect("item_collapsed", callable_mp(this, &SceneTreeEditor::_cell_collapsed)); @@ -942,14 +960,16 @@ void SceneTreeEditor::_renamed() { Node *n = get_node(np); ERR_FAIL_COND(!n); - // Empty node names are not allowed, so resets it to previous text and show warning - if (which->get_text(0).strip_edges().is_empty()) { - which->set_text(0, n->get_name()); - EditorNode::get_singleton()->show_warning(TTR("No name provided.")); - return; + String raw_new_name = which->get_text(0); + if (raw_new_name.strip_edges().is_empty()) { + // If name is empty, fallback to class name. + if (GLOBAL_GET("editor/node_naming/name_casing").operator int() != NAME_CASING_PASCAL_CASE) { + raw_new_name = Node::adjust_name_casing(n->get_class()); + } else { + raw_new_name = n->get_class(); + } } - String raw_new_name = which->get_text(0); String new_name = raw_new_name.validate_node_name(); if (new_name != raw_new_name) { @@ -978,11 +998,12 @@ void SceneTreeEditor::_renamed() { return; } - if (!undo_redo.is_valid()) { + if (!is_scene_tree_dock) { n->set_name(new_name); which->set_metadata(0, n->get_path()); emit_signal(SNAME("node_renamed")); } else { + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Rename Node")); emit_signal(SNAME("node_prerename"), n, new_name); undo_redo->add_do_method(this, "_rename_node", n->get_instance_id(), new_name); @@ -1022,8 +1043,12 @@ String SceneTreeEditor::get_filter() const { return filter; } -void SceneTreeEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) { - undo_redo = p_undo_redo; +String SceneTreeEditor::get_filter_term_warning() { + return filter_term_warning; +} + +void SceneTreeEditor::set_as_scene_tree_dock() { + is_scene_tree_dock = true; } void SceneTreeEditor::set_display_foreign_nodes(bool p_display) { @@ -1116,7 +1141,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from return Variant(); //dragging from button } - Vector<Node *> selected; + Vector<Node *> selected_nodes; Vector<Ref<Texture2D>> icons; TreeItem *next = tree->get_next_selected(nullptr); while (next) { @@ -1126,14 +1151,14 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from if (n) { // Only allow selection if not part of an instantiated scene. if (!n->get_owner() || n->get_owner() == get_scene_node() || n->get_owner()->get_scene_file_path().is_empty()) { - selected.push_back(n); + selected_nodes.push_back(n); icons.push_back(next->get_icon(0)); } } next = tree->get_next_selected(next); } - if (selected.is_empty()) { + if (selected_nodes.is_empty()) { return Variant(); } @@ -1142,20 +1167,20 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from int list_max = 10; float opacity_step = 1.0f / list_max; float opacity_item = 1.0f; - for (int i = 0; i < selected.size(); i++) { + for (int i = 0; i < selected_nodes.size(); i++) { if (i < list_max) { HBoxContainer *hb = memnew(HBoxContainer); TextureRect *tf = memnew(TextureRect); tf->set_texture(icons[i]); tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); hb->add_child(tf); - Label *label = memnew(Label(selected[i]->get_name())); + Label *label = memnew(Label(selected_nodes[i]->get_name())); hb->add_child(label); vb->add_child(hb); hb->set_modulate(Color(1, 1, 1, opacity_item)); opacity_item -= opacity_step; } - NodePath p = selected[i]->get_path(); + NodePath p = selected_nodes[i]->get_path(); objs.push_back(p); } @@ -1332,7 +1357,7 @@ void SceneTreeEditor::set_connecting_signal(bool p_enable) { } void SceneTreeEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_update_tree"), &SceneTreeEditor::_update_tree, DEFVAL(false)); // Still used by some connect_compat. + ClassDB::bind_method(D_METHOD("_update_tree"), &SceneTreeEditor::_update_tree, DEFVAL(false)); // Still used by UndoRedo. ClassDB::bind_method("_rename_node", &SceneTreeEditor::_rename_node); ClassDB::bind_method("_test_update_tree", &SceneTreeEditor::_test_update_tree); @@ -1434,6 +1459,9 @@ void SceneTreeDialog::_notification(int p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { if (is_visible()) { tree->update_tree(); + + // Select the search bar by default. + filter->call_deferred(SNAME("grab_focus")); } } break; diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 28ffa4b11b..c1afcf0f45 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -32,13 +32,9 @@ #define SCENE_TREE_EDITOR_H #include "editor/editor_data.h" -#include "editor/editor_settings.h" -#include "scene/gui/button.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" -class EditorUndoRedoManager; - class SceneTreeEditor : public Control { GDCLASS(SceneTreeEditor, Control); @@ -62,6 +58,7 @@ class SceneTreeEditor : public Control { ObjectID instance_node; String filter; + String filter_term_warning; AcceptDialog *error = nullptr; AcceptDialog *warning = nullptr; @@ -76,7 +73,6 @@ class SceneTreeEditor : public Control { void _add_nodes(Node *p_node, TreeItem *p_parent); void _test_update_tree(); - void _update_tree(bool p_scroll_to_selected = false); bool _update_filter(TreeItem *p_parent = nullptr, bool p_scroll_to_selected = false); bool _item_matches_all_terms(TreeItem *p_item, PackedStringArray p_terms); void _tree_changed(); @@ -98,9 +94,9 @@ class SceneTreeEditor : public Control { bool can_open_instance; bool updating_tree = false; bool show_enabled_subscene = false; + bool is_scene_tree_dock = false; void _renamed(); - Ref<EditorUndoRedoManager> undo_redo; HashSet<Node *> marked; bool marked_selectable = false; @@ -138,10 +134,14 @@ class SceneTreeEditor : public Control { Vector<StringName> valid_types; public: + // Public for use with callable_mp. + void _update_tree(bool p_scroll_to_selected = false); + void set_filter(const String &p_filter); String get_filter() const; + String get_filter_term_warning(); - void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo); + void set_as_scene_tree_dock(); void set_display_foreign_nodes(bool p_display); void set_marked(const HashSet<Node *> &p_marked, bool p_selectable = false, bool p_children_selectable = true); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index f57dfe4827..4a3b0e979f 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -275,7 +275,6 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must bool found = false; bool match = false; - int index = 0; for (const String &E : extensions) { if (E.nocasecmp_to(extension) == 0) { found = true; @@ -284,7 +283,6 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must } break; } - index++; } if (!found) { @@ -373,7 +371,7 @@ void ScriptCreateDialog::_create_new() { const ScriptLanguage::ScriptTemplate sinfo = _get_current_template(); String parent_class = parent_name->get_text(); - if (!ClassDB::class_exists(parent_class) && !ScriptServer::is_global_class(parent_class)) { + if (!parent_name->get_text().is_quoted() && !ClassDB::class_exists(parent_class) && !ScriptServer::is_global_class(parent_class)) { // If base is a custom type, replace with script path instead. const EditorData::CustomType *type = EditorNode::get_editor_data().get_custom_type_by_name(parent_class); ERR_FAIL_NULL(type); @@ -828,9 +826,9 @@ ScriptLanguage::ScriptTemplate ScriptCreateDialog::_get_current_template() const return ScriptLanguage::ScriptTemplate(); } -Vector<ScriptLanguage::ScriptTemplate> ScriptCreateDialog::_get_user_templates(const ScriptLanguage *language, const StringName &p_object, const String &p_dir, const ScriptLanguage::TemplateLocation &p_origin) const { +Vector<ScriptLanguage::ScriptTemplate> ScriptCreateDialog::_get_user_templates(const ScriptLanguage *p_language, const StringName &p_object, const String &p_dir, const ScriptLanguage::TemplateLocation &p_origin) const { Vector<ScriptLanguage::ScriptTemplate> user_templates; - String extension = language->get_extension(); + String extension = p_language->get_extension(); String dir_path = p_dir.path_join(p_object); @@ -840,7 +838,7 @@ Vector<ScriptLanguage::ScriptTemplate> ScriptCreateDialog::_get_user_templates(c String file = d->get_next(); while (file != String()) { if (file.get_extension() == extension) { - user_templates.append(_parse_template(language, dir_path, file, p_origin, p_object)); + user_templates.append(_parse_template(p_language, dir_path, file, p_origin, p_object)); } file = d->get_next(); } @@ -849,15 +847,15 @@ Vector<ScriptLanguage::ScriptTemplate> ScriptCreateDialog::_get_user_templates(c return user_templates; } -ScriptLanguage::ScriptTemplate ScriptCreateDialog::_parse_template(const ScriptLanguage *language, const String &p_path, const String &p_filename, const ScriptLanguage::TemplateLocation &p_origin, const String &p_inherits) const { +ScriptLanguage::ScriptTemplate ScriptCreateDialog::_parse_template(const ScriptLanguage *p_language, const String &p_path, const String &p_filename, const ScriptLanguage::TemplateLocation &p_origin, const String &p_inherits) const { ScriptLanguage::ScriptTemplate script_template = ScriptLanguage::ScriptTemplate(); script_template.origin = p_origin; script_template.inherit = p_inherits; String space_indent = " "; // Get meta delimiter - String meta_delimiter = String(); + String meta_delimiter; List<String> comment_delimiters; - language->get_comment_delimiters(&comment_delimiters); + p_language->get_comment_delimiters(&comment_delimiters); for (const String &script_delimiter : comment_delimiters) { if (!script_delimiter.contains(" ")) { meta_delimiter = script_delimiter; diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index c7d8cfc38a..fb1a49a1ca 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -119,8 +119,8 @@ class ScriptCreateDialog : public ConfirmationDialog { void _update_template_menu(); void _update_dialog(); ScriptLanguage::ScriptTemplate _get_current_template() const; - Vector<ScriptLanguage::ScriptTemplate> _get_user_templates(const ScriptLanguage *language, const StringName &p_object, const String &p_dir, const ScriptLanguage::TemplateLocation &p_origin) const; - ScriptLanguage::ScriptTemplate _parse_template(const ScriptLanguage *language, const String &p_path, const String &p_filename, const ScriptLanguage::TemplateLocation &p_origin, const String &p_inherits) const; + Vector<ScriptLanguage::ScriptTemplate> _get_user_templates(const ScriptLanguage *p_language, const StringName &p_object, const String &p_dir, const ScriptLanguage::TemplateLocation &p_origin) const; + ScriptLanguage::ScriptTemplate _parse_template(const ScriptLanguage *p_language, const String &p_path, const String &p_filename, const ScriptLanguage::TemplateLocation &p_origin, const String &p_inherits) const; String _get_script_origin_label(const ScriptLanguage::TemplateLocation &p_origin) const; protected: diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index ae533b5b75..cdbe88b99e 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -96,20 +96,20 @@ void ShaderCreateDialog::_update_language_info() { type_data.clear(); for (int i = 0; i < SHADER_TYPE_MAX; i++) { - ShaderTypeData data; + ShaderTypeData shader_type_data; if (i == int(SHADER_TYPE_TEXT)) { - data.use_templates = true; - data.extensions.push_back("gdshader"); - data.default_extension = "gdshader"; + shader_type_data.use_templates = true; + shader_type_data.extensions.push_back("gdshader"); + shader_type_data.default_extension = "gdshader"; } else if (i == int(SHADER_TYPE_INC)) { - data.extensions.push_back("gdshaderinc"); - data.default_extension = "gdshaderinc"; + shader_type_data.extensions.push_back("gdshaderinc"); + shader_type_data.default_extension = "gdshaderinc"; } else { - data.default_extension = "tres"; + shader_type_data.default_extension = "tres"; } - data.extensions.push_back("res"); - data.extensions.push_back("tres"); - type_data.push_back(data); + shader_type_data.extensions.push_back("res"); + shader_type_data.extensions.push_back("tres"); + type_data.push_back(shader_type_data); } } @@ -261,9 +261,9 @@ void ShaderCreateDialog::_load_exist() { void ShaderCreateDialog::_type_changed(int p_language) { current_type = p_language; - ShaderTypeData data = type_data[p_language]; + ShaderTypeData shader_type_data = type_data[p_language]; - String selected_ext = "." + data.default_extension; + String selected_ext = "." + shader_type_data.default_extension; String path = file_path->get_text(); String extension = ""; @@ -284,10 +284,10 @@ void ShaderCreateDialog::_type_changed(int p_language) { type_menu->set_item_disabled(int(SHADER_TYPE_INC), load_enabled); mode_menu->set_disabled(p_language == SHADER_TYPE_INC); - template_menu->set_disabled(!data.use_templates); + template_menu->set_disabled(!shader_type_data.use_templates); template_menu->clear(); - if (data.use_templates) { + if (shader_type_data.use_templates) { int last_template = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_template", 0); template_menu->add_item(TTR("Default")); @@ -437,8 +437,6 @@ String ShaderCreateDialog::_validate_path(const String &p_path) { } } - ShaderTypeData data = type_data[type_menu->get_selected()]; - bool found = false; bool match = false; diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index eef0f3eae1..22a1d49422 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -86,7 +86,7 @@ protected: return false; } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Shader Global Variable")); undo_redo->add_do_method(RS::get_singleton(), "global_shader_parameter_set", p_name, p_value); @@ -107,11 +107,11 @@ protected: String path = "shader_globals/" + String(p_name); undo_redo->add_do_property(ProjectSettings::get_singleton(), path, gv); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), path, ProjectSettings::get_singleton()->get(path)); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), path, GLOBAL_GET(path)); undo_redo->add_do_method(this, "_var_changed"); undo_redo->add_undo_method(this, "_var_changed"); block_update = true; - undo_redo->commit_action(); + undo_redo->commit_action(false); block_update = false; return true; @@ -394,7 +394,7 @@ void ShaderGlobalsEditor::_variable_added() { return; } - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); Variant value = create_var(RS::GlobalShaderParameterType(variable_type->get_selected())); @@ -413,14 +413,14 @@ void ShaderGlobalsEditor::_variable_added() { } void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) { - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo(); + Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(TTR("Add Shader Global Parameter")); undo_redo->add_do_method(RS::get_singleton(), "global_shader_parameter_remove", p_variable); undo_redo->add_undo_method(RS::get_singleton(), "global_shader_parameter_add", p_variable, RS::get_singleton()->global_shader_parameter_get_type(p_variable), RS::get_singleton()->global_shader_parameter_get(p_variable)); undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, Variant()); - undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, ProjectSettings::get_singleton()->get("shader_globals/" + p_variable)); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, GLOBAL_GET("shader_globals/" + p_variable)); undo_redo->add_do_method(this, "_changed"); undo_redo->add_undo_method(this, "_changed"); undo_redo->commit_action(); @@ -483,7 +483,7 @@ ShaderGlobalsEditor::ShaderGlobalsEditor() { inspector->connect("property_deleted", callable_mp(this, &ShaderGlobalsEditor::_variable_deleted), CONNECT_DEFERRED); interface = memnew(ShaderGlobalsEditorInterface); - interface->connect("var_changed", Callable(this, "_changed")); + interface->connect("var_changed", callable_mp(this, &ShaderGlobalsEditor::_changed)); } ShaderGlobalsEditor::~ShaderGlobalsEditor() { diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 46640b0b55..a6a8b72ea5 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -15,13 +15,15 @@ # Ziv D <wizdavid@gmail.com>, 2020. # Violin Iliev <violin.developer@gmail.com>, 2021. # Ivan Gechev <ivan_banov@abv.bg>, 2022. +# BigHomieDripDrop <bartu.bali@gmail.com>, 2022. +# xaio <xaio666@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-04-28 11:11+0000\n" -"Last-Translator: Любомир Василев <lyubomirv@gmx.com>\n" +"PO-Revision-Date: 2022-09-22 15:26+0000\n" +"Last-Translator: xaio <xaio666@gmail.com>\n" "Language-Team: Bulgarian <https://hosted.weblate.org/projects/godot-engine/" "godot/bg/>\n" "Language: bg\n" @@ -29,67 +31,59 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.12.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" -msgstr "" +msgstr "Драйвер за таблет" #: core/bind/core_bind.cpp -#, fuzzy msgid "Clipboard" -msgstr "Отрязване над" +msgstr "Клипборд" #: core/bind/core_bind.cpp -#, fuzzy msgid "Current Screen" -msgstr "Текущо име на сцената" +msgstr "Текуща Сцена" #: core/bind/core_bind.cpp msgid "Exit Code" -msgstr "" +msgstr "Изходен Код" #: core/bind/core_bind.cpp -#, fuzzy msgid "V-Sync Enabled" -msgstr "Включване" +msgstr "V-Sync Включено" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" -msgstr "" +msgstr "V-Sync Чрез Композитора" #: core/bind/core_bind.cpp main/main.cpp msgid "Delta Smoothing" -msgstr "" +msgstr "Делта Изглаждане" #: core/bind/core_bind.cpp -#, fuzzy msgid "Low Processor Usage Mode" -msgstr "Режим на преместване" +msgstr "Режим на Ниско Натоварване на Процесора" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" -msgstr "" +msgstr "Заспиване в Режим на Ниско Натоварване на Процесора (µsec)" #: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp -#, fuzzy msgid "Keep Screen On" -msgstr "Дебъгерът да остане отворен" +msgstr "Дръж Екрана Включен" #: core/bind/core_bind.cpp -#, fuzzy msgid "Min Window Size" -msgstr "Размер на контура:" +msgstr "Минимален Размер на Екрана" #: core/bind/core_bind.cpp -#, fuzzy msgid "Max Window Size" -msgstr "Размер на контура:" +msgstr "Максимален Размер на Екрана" #: core/bind/core_bind.cpp -#, fuzzy msgid "Screen Orientation" -msgstr "Отваряне на документацията" +msgstr "Ориентация на Екрана" #: core/bind/core_bind.cpp core/project_settings.cpp main/main.cpp #: platform/uwp/os_uwp.cpp @@ -102,7 +96,7 @@ msgstr "Без граници" #: core/bind/core_bind.cpp msgid "Per Pixel Transparency Enabled" -msgstr "" +msgstr "Попикселова Прозрачност Включено" #: core/bind/core_bind.cpp core/project_settings.cpp msgid "Fullscreen" @@ -110,26 +104,24 @@ msgstr "Цял екран" #: core/bind/core_bind.cpp msgid "Maximized" -msgstr "" +msgstr "Максимизиран" #: core/bind/core_bind.cpp -#, fuzzy msgid "Minimized" -msgstr "Инициализиране" +msgstr "Минимизиран" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp msgid "Resizable" -msgstr "" +msgstr "Преоразмеряване е Възможно" #: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp #: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp #: scene/3d/physics_body.cpp scene/3d/remote_transform.cpp #: scene/gui/control.cpp scene/gui/line_edit.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Position" -msgstr "Създаване на функция" +msgstr "Позиция" #: core/bind/core_bind.cpp core/project_settings.cpp editor/editor_settings.cpp #: main/main.cpp modules/gridmap/grid_map.cpp @@ -140,60 +132,52 @@ msgstr "Създаване на функция" #: scene/resources/primitive_meshes.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp #: scene/resources/visual_shader.cpp servers/visual_server.cpp -#, fuzzy msgid "Size" -msgstr "Размер:" +msgstr "Размер" #: core/bind/core_bind.cpp msgid "Endian Swap" -msgstr "" +msgstr "Размяна на Байтова Крайност" #: core/bind/core_bind.cpp -#, fuzzy msgid "Editor Hint" -msgstr "Тема на редактора" +msgstr "Съвет за Редактора" #: core/bind/core_bind.cpp msgid "Print Error Messages" -msgstr "Принирай съобщения за грешки" +msgstr "Принтирай съобщения за грешки" #: core/bind/core_bind.cpp -#, fuzzy msgid "Iterations Per Second" -msgstr "Режим на интерполация" +msgstr "Итерации в Секунда" #: core/bind/core_bind.cpp -#, fuzzy msgid "Target FPS" -msgstr "Принудително изпращане" +msgstr "Целеви FPS" #: core/bind/core_bind.cpp -#, fuzzy msgid "Time Scale" -msgstr "Текстурна област" +msgstr "Времева Скала" #: core/bind/core_bind.cpp main/main.cpp msgid "Physics Jitter Fix" -msgstr "" +msgstr "Корекция на Физично Трептене" #: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Error" msgstr "Грешка" #: core/bind/core_bind.cpp -#, fuzzy msgid "Error String" -msgstr "Грешка при запазване" +msgstr "Низ на Грешката" #: core/bind/core_bind.cpp -#, fuzzy msgid "Error Line" -msgstr "Грешка при запазване" +msgstr "Линия на Грешката" #: core/bind/core_bind.cpp -#, fuzzy msgid "Result" -msgstr "Резултати от търсенето" +msgstr "Резултат" #: core/command_queue_mt.cpp core/message_queue.cpp main/main.cpp msgid "Memory" @@ -208,16 +192,15 @@ msgstr "Памет" #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: servers/visual_server.cpp msgid "Limits" -msgstr "" +msgstr "Ограничения" #: core/command_queue_mt.cpp -#, fuzzy msgid "Command Queue" -msgstr "Command: завъртане" +msgstr "Oпашка от Kоманди" #: core/command_queue_mt.cpp msgid "Multithreading Queue Size (KB)" -msgstr "" +msgstr "Размер на Многонишковата Опашка (KB)" #: core/func_ref.cpp modules/visual_script/visual_script_builtin_funcs.cpp #: modules/visual_script/visual_script_func_nodes.cpp @@ -236,101 +219,92 @@ msgstr "Данни" #: modules/gdscript/language_server/gdscript_language_server.cpp #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: scene/gui/file_dialog.cpp -#, fuzzy msgid "Network" -msgstr "Профилиране на мрежата" +msgstr "Мрежа" #: core/io/file_access_network.cpp msgid "Remote FS" -msgstr "Отдалечена ФС" +msgstr "Дистанционна ФС" #: core/io/file_access_network.cpp msgid "Page Size" -msgstr "Размер на страница" +msgstr "Размер на Страница" #: core/io/file_access_network.cpp msgid "Page Read Ahead" -msgstr "" +msgstr "Кеширане на Страницата" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" -msgstr "" +msgstr "Блокиращ Режим Включен" #: core/io/http_client.cpp -#, fuzzy msgid "Connection" -msgstr "Свързване" +msgstr "Връзка" #: core/io/http_client.cpp msgid "Read Chunk Size" -msgstr "" +msgstr "Размер на Прочетеното Парче" #: core/io/marshalls.cpp -#, fuzzy msgid "Object ID" -msgstr "Изчертани обекти:" +msgstr "Обект ID" #: core/io/multiplayer_api.cpp core/io/packet_peer.cpp -#, fuzzy msgid "Allow Object Decoding" -msgstr "Показване на избледняващи кадри" +msgstr "Разреши Декодирането на Обекта" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp msgid "Refuse New Network Connections" msgstr "Отказ на нови мрежови връзки" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Network Peer" -msgstr "Профилиране на мрежата" +msgstr "Мрежов Връстник" #: core/io/multiplayer_api.cpp scene/animation/animation_player.cpp -#, fuzzy msgid "Root Node" -msgstr "Име на коренния обект" +msgstr "Коренен Връх" #: core/io/networked_multiplayer_peer.cpp -#, fuzzy msgid "Refuse New Connections" -msgstr "Свързване" +msgstr "Отказ на нови връзки" #: core/io/networked_multiplayer_peer.cpp -#, fuzzy msgid "Transfer Mode" -msgstr "Панорамен режим" +msgstr "Режим на трансфер" #: core/io/packet_peer.cpp msgid "Encode Buffer Max Size" -msgstr "" +msgstr "Максимален размер на буфера за кодиране" #: core/io/packet_peer.cpp msgid "Input Buffer Max Size" -msgstr "" +msgstr "Максимален размер на входния буфер" #: core/io/packet_peer.cpp msgid "Output Buffer Max Size" -msgstr "" +msgstr "Максимален размер на изходния буфер" #: core/io/packet_peer.cpp msgid "Stream Peer" -msgstr "" +msgstr "Поточен връстник" #: core/io/stream_peer.cpp msgid "Big Endian" -msgstr "" +msgstr "Биг-Ендиан" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Масив от Данни" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" -msgstr "" +msgstr "Блокиращ Handshake" #: core/io/udp_server.cpp -#, fuzzy msgid "Max Pending Connections" -msgstr "Редактиране на Връзката:" +msgstr "Максимален брой чакащи връзки" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -350,9 +324,8 @@ msgid "Not enough bytes for decoding bytes, or invalid format." msgstr "Недостатъчно байтове за разкодиране или неправилен формат." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" -msgstr "Неправилен входен параметър %i (не е подаден) в израза" +msgstr "Неправилен входен параметър %d (не е подаден) в израза" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -385,13 +358,12 @@ msgid "Seed" msgstr "" #: core/math/random_number_generator.cpp -#, fuzzy msgid "State" -msgstr "Ротация" +msgstr "Състояние" #: core/message_queue.cpp msgid "Message Queue" -msgstr "" +msgstr "Опашка на съобщения" #: core/message_queue.cpp msgid "Max Size (KB)" @@ -404,7 +376,7 @@ msgstr "Режим на преместване" #: core/os/input.cpp msgid "Use Accumulated Input" -msgstr "" +msgstr "Ползвай акумулиран вход" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -432,9 +404,8 @@ msgid "Command" msgstr "Command" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr "Включване" +msgstr "Физически" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -445,19 +416,20 @@ msgstr "Натиснат" #: core/os/input_event.cpp #, fuzzy msgid "Scancode" -msgstr "Сканиране" +msgstr "Сканкод" #: core/os/input_event.cpp msgid "Physical Scancode" -msgstr "" +msgstr "Физически сканкод" #: core/os/input_event.cpp msgid "Unicode" msgstr "Уникод" #: core/os/input_event.cpp +#, fuzzy msgid "Echo" -msgstr "" +msgstr "Echo" #: core/os/input_event.cpp scene/gui/base_button.cpp #, fuzzy @@ -485,7 +457,7 @@ msgstr "Двоен клик" #: core/os/input_event.cpp msgid "Tilt" -msgstr "" +msgstr "Наклон" #: core/os/input_event.cpp msgid "Pressure" @@ -493,11 +465,11 @@ msgstr "Натиск" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Писалка обърната" #: core/os/input_event.cpp msgid "Relative" -msgstr "" +msgstr "Относително" #: core/os/input_event.cpp scene/2d/camera_2d.cpp scene/2d/cpu_particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/interpolated_camera.cpp @@ -632,15 +604,15 @@ msgstr "Заключен елемент" #: core/project_settings.cpp msgid "Use Hidden Project Data Directory" -msgstr "" +msgstr "Ползвай скрита дата директория на проекта" #: core/project_settings.cpp msgid "Use Custom User Dir" -msgstr "" +msgstr "Ползвай персоналната директория на потребителя" #: core/project_settings.cpp msgid "Custom User Dir Name" -msgstr "" +msgstr "Име на персонална потребителска категория" #: core/project_settings.cpp main/main.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp @@ -653,7 +625,7 @@ msgstr "Показване на всичко" #: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp #: scene/3d/label_3d.cpp scene/gui/text_edit.cpp scene/resources/texture.cpp msgid "Width" -msgstr "" +msgstr "Широчина" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/gltf/gltf_node.cpp modules/opensimplex/noise_texture.cpp @@ -662,20 +634,19 @@ msgstr "" #: scene/resources/font.cpp scene/resources/navigation_mesh.cpp #: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp msgid "Height" -msgstr "" +msgstr "Височина" #: core/project_settings.cpp msgid "Always On Top" -msgstr "" +msgstr "Винаги отгоре" #: core/project_settings.cpp msgid "Test Width" -msgstr "" +msgstr "Тестова широчина" #: core/project_settings.cpp -#, fuzzy msgid "Test Height" -msgstr "Тестово" +msgstr "Тестова височина" #: core/project_settings.cpp editor/animation_track_editor.cpp #: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp @@ -684,14 +655,14 @@ msgstr "Аудио" #: core/project_settings.cpp msgid "Default Bus Layout" -msgstr "" +msgstr "Bus Layout по подразбиране" #: core/project_settings.cpp editor/editor_export.cpp #: editor/editor_file_system.cpp editor/editor_node.cpp #: editor/editor_settings.cpp editor/script_create_dialog.cpp #: scene/2d/camera_2d.cpp scene/3d/light.cpp scene/main/node.cpp msgid "Editor" -msgstr "" +msgstr "Редактор" #: core/project_settings.cpp msgid "Main Run Args" @@ -704,11 +675,11 @@ msgstr "Път на сцената:" #: core/project_settings.cpp msgid "Search In File Extensions" -msgstr "" +msgstr "Търси във файловите окончания" #: core/project_settings.cpp msgid "Script Templates Search Path" -msgstr "" +msgstr "Път за търсене на скриптови шаблони" #: core/project_settings.cpp #, fuzzy @@ -727,7 +698,7 @@ msgstr "Вход" #: core/project_settings.cpp msgid "UI Accept" -msgstr "" +msgstr "UI Приемам" #: core/project_settings.cpp #, fuzzy @@ -741,38 +712,35 @@ msgstr "Отказ" #: core/project_settings.cpp msgid "UI Focus Next" -msgstr "" +msgstr "UI фокус следващ" #: core/project_settings.cpp msgid "UI Focus Prev" -msgstr "" +msgstr "UI фокус предишен" #: core/project_settings.cpp -#, fuzzy msgid "UI Left" -msgstr "Горе вляво" +msgstr "UI наляво" #: core/project_settings.cpp -#, fuzzy msgid "UI Right" -msgstr "Горе вдясно" +msgstr "UI надясно" #: core/project_settings.cpp msgid "UI Up" -msgstr "" +msgstr "UI нагоре" #: core/project_settings.cpp -#, fuzzy msgid "UI Down" -msgstr "Надолу" +msgstr "UI надолу" #: core/project_settings.cpp msgid "UI Page Up" -msgstr "" +msgstr "UI страница нагоре" #: core/project_settings.cpp msgid "UI Page Down" -msgstr "" +msgstr "UI страница надолу" #: core/project_settings.cpp msgid "UI Home" @@ -792,7 +760,7 @@ msgstr "На края" #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Physics" -msgstr "" +msgstr "Физика" #: core/project_settings.cpp editor/editor_settings.cpp #: editor/import/resource_importer_layered_texture.cpp @@ -802,11 +770,11 @@ msgstr "" #: scene/3d/physics_body.cpp scene/resources/world.cpp #: servers/physics/space_sw.cpp servers/physics_server.cpp msgid "3D" -msgstr "" +msgstr "3D" #: core/project_settings.cpp msgid "Smooth Trimesh Collision" -msgstr "" +msgstr "Плавен тримеш сблъсък" #: core/project_settings.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles2/rasterizer_scene_gles2.cpp @@ -818,7 +786,7 @@ msgstr "" #: scene/main/viewport.cpp servers/visual/visual_server_scene.cpp #: servers/visual_server.cpp msgid "Rendering" -msgstr "" +msgstr "Рендериране" #: core/project_settings.cpp drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp @@ -828,18 +796,17 @@ msgstr "" #: scene/resources/multimesh.cpp servers/visual/visual_server_scene.cpp #: servers/visual_server.cpp msgid "Quality" -msgstr "" +msgstr "Качество" #: core/project_settings.cpp scene/gui/file_dialog.cpp #: scene/main/scene_tree.cpp scene/resources/navigation_mesh.cpp #: servers/visual_server.cpp -#, fuzzy msgid "Filters" -msgstr "Филтри:" +msgstr "Филтри" #: core/project_settings.cpp scene/main/viewport.cpp msgid "Sharpen Intensity" -msgstr "" +msgstr "Интензивност на изострянето" #: core/project_settings.cpp editor/editor_export.cpp editor/editor_node.cpp #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp @@ -855,19 +822,18 @@ msgstr "Дебъгване" #: core/project_settings.cpp main/main.cpp modules/gdscript/gdscript.cpp #: modules/visual_script/visual_script.cpp scene/resources/dynamic_font.cpp -#, fuzzy msgid "Settings" -msgstr "Настройки:" +msgstr "Настройки" #: core/project_settings.cpp editor/script_editor_debugger.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp msgid "Profiler" -msgstr "" +msgstr "Профайлър" #: core/project_settings.cpp #, fuzzy msgid "Max Functions" -msgstr "Преобразуване във функция" +msgstr "Макс функции" #: core/project_settings.cpp scene/3d/vehicle_body.cpp msgid "Compression" @@ -875,31 +841,31 @@ msgstr "Компресиране" #: core/project_settings.cpp msgid "Formats" -msgstr "" +msgstr "Формати" #: core/project_settings.cpp msgid "Zstd" -msgstr "" +msgstr "Zstd" #: core/project_settings.cpp msgid "Long Distance Matching" -msgstr "" +msgstr "Съвпадение на дълги разстояния" #: core/project_settings.cpp msgid "Compression Level" -msgstr "" +msgstr "Ниво на компресия" #: core/project_settings.cpp msgid "Window Log Size" -msgstr "" +msgstr "Размер на лог прозореца" #: core/project_settings.cpp msgid "Zlib" -msgstr "" +msgstr "Zlib" #: core/project_settings.cpp msgid "Gzip" -msgstr "" +msgstr "Gzip" #: core/project_settings.cpp platform/android/export/export.cpp msgid "Android" @@ -914,26 +880,24 @@ msgid "TCP" msgstr "TCP" #: core/register_core_types.cpp -#, fuzzy msgid "Connect Timeout Seconds" -msgstr "Връзки към метода:" +msgstr "Време за свързване Секунди" #: core/register_core_types.cpp msgid "Packet Peer Stream" -msgstr "" +msgstr "Брой пакети на стрийм" #: core/register_core_types.cpp msgid "Max Buffer (Power of 2)" -msgstr "" +msgstr "Максимален размер на буфера (степен от 2)" #: core/register_core_types.cpp editor/editor_settings.cpp main/main.cpp msgid "SSL" -msgstr "" +msgstr "SSL" #: core/register_core_types.cpp main/main.cpp -#, fuzzy msgid "Certificates" -msgstr "Вертекси:" +msgstr "Сертификати" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_resource_picker.cpp @@ -942,9 +906,8 @@ msgid "Resource" msgstr "Ресурс" #: core/resource.cpp -#, fuzzy msgid "Local To Scene" -msgstr "Затваряне на сцената" +msgstr "Локално на сцената" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp @@ -954,22 +917,20 @@ msgid "Path" msgstr "Път" #: core/script_language.cpp -#, fuzzy msgid "Source Code" -msgstr "Източник за полигонна мрежа:" +msgstr "Изходен код" #: core/translation.cpp editor/project_settings_editor.cpp msgid "Locale" -msgstr "" +msgstr "Локал" #: core/translation.cpp -#, fuzzy msgid "Test" -msgstr "Тестово" +msgstr "Тест" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "" +msgstr "Резервен вариант" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -1005,12 +966,12 @@ msgstr "ЕиБ" #: drivers/gles3/rasterizer_scene_gles3.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp modules/gltf/gltf_state.cpp msgid "Buffers" -msgstr "" +msgstr "Буфери" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Buffer Size (KB)" -msgstr "" +msgstr "Размер на буфера на полигона на канавата (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -1027,7 +988,7 @@ msgstr "" #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/visual_server.cpp msgid "2D" -msgstr "" +msgstr "2D" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -1055,28 +1016,27 @@ msgstr "Изпичане на карти на осветеност" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Use Bicubic Sampling" -msgstr "" +msgstr "Ползвай Bicubic семплиране" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Elements" -msgstr "" +msgstr "Макс. рендерируеми елементи" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Lights" -msgstr "" +msgstr "Максимум рендерируеми светлини" #: drivers/gles3/rasterizer_scene_gles3.cpp -#, fuzzy msgid "Max Renderable Reflections" -msgstr "Центриране върху избраното" +msgstr "Макс рендерируеми отражения" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Lights Per Object" -msgstr "" +msgstr "Максимум светлини на обект" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Subsurface Scattering" -msgstr "" +msgstr "Подповърхностно разсейване" #: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1105,7 +1065,7 @@ msgstr "" #: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp msgid "High Quality" -msgstr "" +msgstr "Високо качество" #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Blend Shape Max Buffer Size (KB)" @@ -1138,7 +1098,7 @@ msgstr "Вмъкване на ключ тук" #: editor/animation_bezier_editor.cpp msgid "Duplicate Selected Key(s)" -msgstr "Копиране на избран(и) ключ(ове)" +msgstr "Дупликат на избран(и) ключ(ове)" #: editor/animation_bezier_editor.cpp msgid "Delete Selected Key(s)" @@ -1192,7 +1152,7 @@ msgstr "Добавяне на кадър" #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp #: scene/resources/particles_material.cpp servers/visual_server.cpp msgid "Time" -msgstr "" +msgstr "Време" #: editor/animation_track_editor.cpp editor/import/resource_importer_scene.cpp #: platform/osx/export/export.cpp @@ -1220,29 +1180,31 @@ msgstr "Добавяне на входящ порт" #: editor/animation_track_editor.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp msgid "Args" -msgstr "" +msgstr "Аргументи" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp #: modules/gltf/gltf_light.cpp modules/visual_script/visual_script_nodes.cpp #: scene/3d/physics_body.cpp scene/resources/visual_shader_nodes.cpp msgid "Type" -msgstr "" +msgstr "Тип" #: editor/animation_track_editor.cpp +#, fuzzy msgid "In Handle" -msgstr "" +msgstr "In Handle" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Out Handle" -msgstr "" +msgstr "Out Handle" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp msgid "Stream" -msgstr "" +msgstr "Поток" #: editor/animation_track_editor.cpp #, fuzzy @@ -1265,8 +1227,9 @@ msgid "Animation" msgstr "Анимация" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Easing" -msgstr "" +msgstr "Easing" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -2126,7 +2089,7 @@ msgstr "" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" -msgstr "" +msgstr "Сигнали" #: editor/connections_dialog.cpp msgid "Filter signals" @@ -3730,7 +3693,7 @@ msgstr "" #: editor/editor_network_profiler.cpp editor/editor_node.cpp #: scene/main/node.cpp scene/resources/default_theme/default_theme.cpp msgid "Node" -msgstr "Обект" +msgstr "Връх" #: editor/editor_network_profiler.cpp msgid "Incoming RPC" @@ -6950,7 +6913,7 @@ msgstr "" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp msgid "sRGB" -msgstr "" +msgstr "sRGB" #: editor/import/resource_importer_layered_texture.cpp #, fuzzy @@ -8206,6 +8169,7 @@ msgstr "Режим на възпроизвеждане:" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp +#, fuzzy msgid "AnimationTree" msgstr "AnimationTree" @@ -18769,14 +18733,13 @@ msgid "Code Signing" msgstr "Сигнал" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "'apksigner' could not be found. Please check that the command is available " "in the Android SDK build-tools directory. The resulting %s is unsigned." msgstr "" -"Командата „apksigner“ не може да бъде намерена.\n" -"Проверете дали командата е налична в папката „build-tools“ на Android SDK.\n" -"Резултатният файл „%s“ не е подписан." +"Командата „apksigner“ не може да бъде намерена. Проверете дали командата е " +"налична в папката „build-tools“ на Android SDK. Резултатният файл „%s“ не е " +"подписан." #: platform/android/export/export_plugin.cpp msgid "Signing debug %s..." @@ -18823,9 +18786,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension." msgstr "Неправилно име! Android APK изисква разширение *.apk." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Unsupported export format!" -msgstr "Неподдържан формат за изнасяне!\n" +msgstr "Неподдържан формат за изнасяне!" #: platform/android/export/export_plugin.cpp msgid "" @@ -18848,10 +18810,8 @@ msgstr "" "името на проекта" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "" -"Файловете на проекта не могат да бъдат изнесени като проект на gradle.\n" +msgstr "Файловете на проекта не могат да бъдат изнесени като проект на gradle." #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -18862,15 +18822,13 @@ msgid "Building Android Project (gradle)" msgstr "Компилиране на проект за Android (gradle)" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Building of Android project failed, check output for the error. " "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" "Компилирането на проекта за Android беше неуспешно. Вижте изхода за " -"грешката.\n" -"Може също да разгледате документацията за компилиране за Android на docs." -"godotengine.org." +"грешката. Може също да разгледате документацията за компилиране за Android " +"на docs.godotengine.org." #: platform/android/export/export_plugin.cpp msgid "Moving output" @@ -18894,22 +18852,18 @@ msgid "Creating APK..." msgstr "Създаване на APK…" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not find template APK to export: \"%s\"." -msgstr "" -"Не е намерен шаблонен файл APK за изнасяне:\n" -"%s" +msgstr "Не е намерен шаблонен файл APK за изнасяне: %s" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Missing libraries in the export template for the selected architectures: %s. " "Please build a template with all required libraries, or uncheck the missing " "architectures in the export preset." msgstr "" -"В шаблона за изнасяне липсват библиотеки за избраните архитектури: %s.\n" -"Моля, създайте шаблон с всички необходими библиотеки или махнете отметките " -"от липсващите архитектури в конфигурацията за изнасяне." +"В шаблона за изнасяне липсват библиотеки за избраните архитектури: %s. Моля, " +"създайте шаблон с всички необходими библиотеки или махнете отметките от " +"липсващите архитектури в конфигурацията за изнасяне." #: platform/android/export/export_plugin.cpp msgid "Adding files..." @@ -19762,10 +19716,8 @@ msgid "ZIP Creation" msgstr "Проект" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not open file to read from path \"%s\"." -msgstr "" -"Файловете на проекта не могат да бъдат изнесени като проект на gradle.\n" +msgstr "Файловете на проекта не могат да бъдат изнесени като проект на gradle." #: platform/osx/export/export.cpp msgid "Invalid bundle identifier:" @@ -25772,16 +25724,15 @@ msgstr "Цветове" #: scene/resources/default_theme/default_theme.cpp #, fuzzy msgid "Preset BG" -msgstr "Конфигурация…" +msgstr "Предварителна настройка BG" #: scene/resources/default_theme/default_theme.cpp msgid "Overbright Indicator" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Preset FG" -msgstr "Конфигурация…" +msgstr "Предварителна настройка FG" #: scene/resources/default_theme/default_theme.cpp msgid "Preset BG Icon" diff --git a/editor/translations/cs.po b/editor/translations/cs.po index ed04f66e4b..01c28b207e 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -31,13 +31,14 @@ # Petr Voparil <voparil.petr96@gmail.com>, 2022. # JoeMoos <josephmoose13@gmail.com>, 2022. # Mirinek <mirek.nozicka77@gmail.com>, 2022. +# Lubomír Baloun <lubosbaloun@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-08-30 03:11+0000\n" -"Last-Translator: Petr Voparil <voparil.petr96@gmail.com>\n" +"PO-Revision-Date: 2022-09-19 05:22+0000\n" +"Last-Translator: Lubomír Baloun <lubosbaloun@gmail.com>\n" "Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/" "cs/>\n" "Language: cs\n" @@ -45,11 +46,11 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" -msgstr "" +msgstr "Ovladač Grafického Tabletu" #: core/bind/core_bind.cpp msgid "Clipboard" @@ -70,7 +71,7 @@ msgstr "V-Sync Zapnutý" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" -msgstr "" +msgstr "V-Sync Pomocí Kompozitoru" #: core/bind/core_bind.cpp main/main.cpp msgid "Delta Smoothing" @@ -28525,9 +28526,8 @@ msgid "Ninepatch Mode" msgstr "Interpolační režim" #: servers/visual_server.cpp -#, fuzzy msgid "OpenGL" -msgstr "Otevřít" +msgstr "OpenGL" #: servers/visual_server.cpp msgid "Batching Send Null" diff --git a/editor/translations/de.po b/editor/translations/de.po index a34395385c..7244c02cc1 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -91,8 +91,8 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-08-30 03:11+0000\n" -"Last-Translator: Felix Bitsch <felix.a.bitsch@gmail.com>\n" +"PO-Revision-Date: 2022-09-11 22:22+0000\n" +"Last-Translator: So Wieso <sowieso@dukun.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" "Language: de\n" @@ -15364,20 +15364,18 @@ msgid "Make Local" msgstr "Lokal machen" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name(s)" -msgstr "Szenen-eindeutigen Namen aktivieren" +msgstr "Szenen-eindeutige(n) Namen aktivieren" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Unique names already used by another node in the scene:" msgstr "" -"Ein anderes Node nutzt schon diesen einzigartigen Namen in dieser Szene." +"Einzigartige Namen, die bereits von anderen Nodes dieser Szene verwendet " +"werden:" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Disable Scene Unique Name(s)" -msgstr "Szenen-eindeutigen Namen deaktivieren" +msgstr "Szenen-eindeutige(n) Namen deaktivieren" #: editor/scene_tree_dock.cpp msgid "New Scene Root" @@ -17444,19 +17442,16 @@ msgid "Auto Update Project" msgstr "Projekt automatisch aktualisieren" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Assembly Name" -msgstr "Anzeigename" +msgstr "Assembly-Name" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Solution Directory" -msgstr "Wähle ein Verzeichnis" +msgstr "Solution-Verzeichnis" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "C# Project Directory" -msgstr "Wähle ein Verzeichnis" +msgstr "C#-Projektverzeichnis" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -19224,9 +19219,8 @@ msgid "Custom BG Color" msgstr "Eigene Hintergrundfarbe" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Icons" -msgstr "Export-Icon" +msgstr "Export-Icons" #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp @@ -20062,6 +20056,9 @@ msgid "" "Godot's Mono version does not support the UWP platform. Use the standard " "build (no C# support) if you wish to target UWP." msgstr "" +"Die von Godot genutzte Mono-Version unterstützt die UWP-Plattform nicht. " +"Falls UWP-Unterstützung erforderlich ist, muss Standard-Godot (ohne C#-" +"Unterstützung) verwendet werden." #: platform/uwp/export/export.cpp msgid "Invalid package short name." diff --git a/editor/translations/es.po b/editor/translations/es.po index 2788483a33..629b36eea7 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -94,7 +94,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-09-07 21:02+0000\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" "Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" @@ -103,7 +103,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -5564,7 +5564,7 @@ msgstr "Ancho del Minimapa" #: editor/editor_settings.cpp msgid "Mouse Extra Buttons Navigate History" -msgstr "Botones Extra del Ratón Navegar por el Historial" +msgstr "Botones Extra del Mouse para Navegar por el Historial" #: editor/editor_settings.cpp msgid "Drag And Drop Selection" @@ -8638,7 +8638,7 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" -msgstr "Calcular Lightmaps" +msgstr "Bakear Lightmaps" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "LightMap Bake" @@ -9507,7 +9507,7 @@ msgstr "Clic derecho para añadir punto" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" -msgstr "Calcular GI Probe" +msgstr "Bakear GI Probe" #: editor/plugins/gradient_editor_plugin.cpp msgid "Gradient Edited" @@ -15357,19 +15357,16 @@ msgid "Make Local" msgstr "Crear Local" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name(s)" -msgstr "Activar Nombre Único de Escena" +msgstr "Activar Nombre(s) Único(s) de Escena" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Unique names already used by another node in the scene:" -msgstr "Otro nodo ya utiliza este nombre único en la escena." +msgstr "Nombres únicos ya utilizados por otro nodo en la escena:" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Disable Scene Unique Name(s)" -msgstr "Desactivar Nombre Único de Escena" +msgstr "Desactivar Nombre(s) Único(s) de Escena" #: editor/scene_tree_dock.cpp msgid "New Scene Root" @@ -16813,7 +16810,7 @@ msgstr "Color de la Ruta del Nodo" #: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp msgid "Max Call Stack" -msgstr "" +msgstr "Pila de llamadas Máxima" #: modules/gdscript/gdscript.cpp msgid "Treat Warnings As Errors" @@ -16953,7 +16950,7 @@ msgstr "Longitud de Bytes" #: modules/gltf/gltf_buffer_view.cpp msgid "Byte Stride" -msgstr "" +msgstr "Cadencia de Byte" #: modules/gltf/gltf_buffer_view.cpp msgid "Indices" @@ -17089,11 +17086,11 @@ msgstr "Factor Specular" #: modules/gltf/gltf_spec_gloss.cpp msgid "Spec Gloss Img" -msgstr "" +msgstr "Espec. Brillo Img" #: modules/gltf/gltf_state.cpp msgid "Json" -msgstr "" +msgstr "Json" #: modules/gltf/gltf_state.cpp msgid "Major Version" @@ -17109,7 +17106,7 @@ msgstr "Datos GLB" #: modules/gltf/gltf_state.cpp msgid "Use Named Skin Binds" -msgstr "" +msgstr "Usar Vínculos de Skins con Nombre" #: modules/gltf/gltf_state.cpp msgid "Buffer Views" @@ -17117,7 +17114,7 @@ msgstr "Vistas del Buffer" #: modules/gltf/gltf_state.cpp msgid "Accessors" -msgstr "" +msgstr "Accesos" #: modules/gltf/gltf_state.cpp msgid "Scene Name" @@ -17138,7 +17135,7 @@ msgstr "Imágenes" #: modules/gltf/gltf_state.cpp msgid "Cameras" -msgstr "" +msgstr "Cámaras" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp msgid "Lights" @@ -17178,7 +17175,7 @@ msgstr "Uso en Luz Bakeada" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" -msgstr "" +msgstr "Celda" #: modules/gridmap/grid_map.cpp msgid "Octant Size" @@ -17200,7 +17197,7 @@ msgstr "Centro Z" #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp #: scene/resources/material.cpp msgid "Mask" -msgstr "" +msgstr "Máscara" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Bake Navigation" @@ -17376,19 +17373,19 @@ msgstr "CPU Lightmapper" #: modules/lightmapper_cpu/register_types.cpp msgid "Low Quality Ray Count" -msgstr "" +msgstr "Conteo de Rayos de Baja Calidad" #: modules/lightmapper_cpu/register_types.cpp msgid "Medium Quality Ray Count" -msgstr "" +msgstr "Conteo de Rayos de Calidad Media" #: modules/lightmapper_cpu/register_types.cpp msgid "High Quality Ray Count" -msgstr "" +msgstr "Conteo de Rayos de Calidad Alta" #: modules/lightmapper_cpu/register_types.cpp msgid "Ultra Quality Ray Count" -msgstr "" +msgstr "Conteo de Rayos de Calidad Ultra" #: modules/minimp3/audio_stream_mp3.cpp #: modules/minimp3/resource_importer_mp3.cpp @@ -17399,11 +17396,11 @@ msgstr "Offset de Bucle" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Eye Height" -msgstr "" +msgstr "Altura Ocular" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "IOD" -msgstr "" +msgstr "IOD" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Display Width" @@ -17415,15 +17412,15 @@ msgstr "Pantalla a Lente" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Oversample" -msgstr "" +msgstr "Sobremuestreo" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "K1" -msgstr "" +msgstr "K1" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "K2" -msgstr "" +msgstr "K2" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -17438,23 +17435,20 @@ msgid "Auto Update Project" msgstr "Actualización Automática del Proyecto" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Assembly Name" -msgstr "Nombre a Mostrar" +msgstr "Nombre del Conjunto" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Solution Directory" -msgstr "Selecciona un directorio" +msgstr "Directorio de Soluciones" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "C# Project Directory" -msgstr "Selecciona un directorio" +msgstr "Directorio de Proyectos C#" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" -msgstr "Fin del reporte de la pila de excepciones" +msgstr "Fin de la pila de excepciones internas" #: modules/navigation/navigation_mesh_editor_plugin.cpp #: scene/3d/navigation_mesh_instance.cpp @@ -17465,7 +17459,7 @@ msgstr "" #: modules/navigation/navigation_mesh_editor_plugin.cpp msgid "Bake NavMesh" -msgstr "Calcular NavMesh" +msgstr "Bakear NavMesh" #: modules/navigation/navigation_mesh_editor_plugin.cpp msgid "Clear the navigation mesh." @@ -17525,7 +17519,7 @@ msgstr "¡Hecho!" #: modules/opensimplex/noise_texture.cpp msgid "Seamless" -msgstr "" +msgstr "Sin costuras" #: modules/opensimplex/noise_texture.cpp msgid "As Normal Map" @@ -17533,11 +17527,11 @@ msgstr "Como Mapa Normal" #: modules/opensimplex/noise_texture.cpp msgid "Bump Strength" -msgstr "" +msgstr "Fuerza de Choque" #: modules/opensimplex/noise_texture.cpp msgid "Noise" -msgstr "" +msgstr "Ruido" #: modules/opensimplex/noise_texture.cpp msgid "Noise Offset" @@ -17545,11 +17539,11 @@ msgstr "Offset de Ruido" #: modules/opensimplex/open_simplex_noise.cpp msgid "Octaves" -msgstr "" +msgstr "Octavas" #: modules/opensimplex/open_simplex_noise.cpp msgid "Period" -msgstr "" +msgstr "Periodo" #: modules/opensimplex/open_simplex_noise.cpp msgid "Persistence" @@ -17557,11 +17551,11 @@ msgstr "Persistencia" #: modules/opensimplex/open_simplex_noise.cpp msgid "Lacunarity" -msgstr "" +msgstr "Lacunaridad" #: modules/regex/regex.cpp msgid "Subject" -msgstr "" +msgstr "Asunto" #: modules/regex/regex.cpp msgid "Names" @@ -17573,15 +17567,15 @@ msgstr "Cadenas" #: modules/upnp/upnp.cpp msgid "Discover Multicast If" -msgstr "" +msgstr "Descubrir Multicast si" #: modules/upnp/upnp.cpp msgid "Discover Local Port" -msgstr "" +msgstr "Descubrir Puerto Local" #: modules/upnp/upnp.cpp msgid "Discover IPv6" -msgstr "" +msgstr "Descubrir IPV6" #: modules/upnp/upnp_device.cpp msgid "Description URL" @@ -17593,7 +17587,7 @@ msgstr "Tipo de Servicio" #: modules/upnp/upnp_device.cpp msgid "IGD Control URL" -msgstr "" +msgstr "IGD Control URL" #: modules/upnp/upnp_device.cpp msgid "IGD Service Type" @@ -17601,7 +17595,7 @@ msgstr "Tipo de Servicio IGD" #: modules/upnp/upnp_device.cpp msgid "IGD Our Addr" -msgstr "" +msgstr "Dirección de IGD" #: modules/upnp/upnp_device.cpp msgid "IGD Status" @@ -18261,7 +18255,7 @@ msgstr "SubCall" #: modules/visual_script/visual_script_nodes.cpp scene/gui/graph_node.cpp msgid "Title" -msgstr "" +msgstr "Título" #: modules/visual_script/visual_script_nodes.cpp msgid "Construct %s" @@ -18329,7 +18323,7 @@ msgstr "Modo de Escritura" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" -msgstr "" +msgstr "WebRTC" #: modules/webrtc/webrtc_data_channel.h msgid "Max Channel In Buffer (KB)" @@ -18337,11 +18331,11 @@ msgstr "Buffer de Canal Máximo (KB)" #: modules/websocket/websocket_client.cpp msgid "Verify SSL" -msgstr "" +msgstr "Verificar SSL" #: modules/websocket/websocket_client.cpp msgid "Trusted SSL Certificate" -msgstr "" +msgstr "Certificado SSL de Confianza" #: modules/websocket/websocket_macros.h msgid "WebSocket Client" @@ -18353,7 +18347,7 @@ msgstr "Buffer de Entrada Máximo (KB)" #: modules/websocket/websocket_macros.h msgid "Max In Packets" -msgstr "" +msgstr "Paquetes Máximos de Entrada" #: modules/websocket/websocket_macros.h msgid "Max Out Buffer (KB)" @@ -18361,7 +18355,7 @@ msgstr "Buffer de Salida Máximo (KB)" #: modules/websocket/websocket_macros.h msgid "Max Out Packets" -msgstr "" +msgstr "Paquetes Máximos de Salida" #: modules/websocket/websocket_macros.h msgid "WebSocket Server" @@ -18369,7 +18363,7 @@ msgstr "Servidor WebSocket" #: modules/websocket/websocket_server.cpp msgid "Bind IP" -msgstr "" +msgstr "Vincular IP" #: modules/websocket/websocket_server.cpp msgid "Private Key" @@ -18377,7 +18371,7 @@ msgstr "Clave Privada" #: modules/websocket/websocket_server.cpp platform/javascript/export/export.cpp msgid "SSL Certificate" -msgstr "" +msgstr "Certificado SSL" #: modules/websocket/websocket_server.cpp msgid "CA Chain" @@ -18401,11 +18395,11 @@ msgstr "Características Opcionales" #: modules/webxr/webxr_interface.cpp msgid "Requested Reference Space Types" -msgstr "" +msgstr "Tipos de Espacios de Referencia Requeridos" #: modules/webxr/webxr_interface.cpp msgid "Reference Space Type" -msgstr "" +msgstr "Tipo de Espacio de Referencia" #: modules/webxr/webxr_interface.cpp msgid "Visibility State" @@ -18421,7 +18415,7 @@ msgstr "Mapeo Estándar XR" #: platform/android/export/export.cpp msgid "Android SDK Path" -msgstr "" +msgstr "Ruta del SDK de Android" #: platform/android/export/export.cpp msgid "Debug Keystore" @@ -18429,35 +18423,35 @@ msgstr "Debug Keystore" #: platform/android/export/export.cpp msgid "Debug Keystore User" -msgstr "" +msgstr "Usuario Debug Keystore" #: platform/android/export/export.cpp msgid "Debug Keystore Pass" -msgstr "" +msgstr "Contraseña Debug Keystore" #: platform/android/export/export.cpp msgid "Force System User" -msgstr "" +msgstr "Forzar Usuario del Sistema" #: platform/android/export/export.cpp msgid "Shutdown ADB On Exit" -msgstr "" +msgstr "Apagar el ADB al Salir" #: platform/android/export/export_plugin.cpp msgid "Launcher Icons" -msgstr "" +msgstr "Iconos del Launcher" #: platform/android/export/export_plugin.cpp msgid "Main 192 X 192" -msgstr "" +msgstr "Principal 192 X 192" #: platform/android/export/export_plugin.cpp msgid "Adaptive Foreground 432 X 432" -msgstr "" +msgstr "Primer Plano Adaptable 432 X 432" #: platform/android/export/export_plugin.cpp msgid "Adaptive Background 432 X 432" -msgstr "" +msgstr "Fondo Adaptable 432 X 432" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -18532,7 +18526,7 @@ msgstr "Contraseña de Release" #: platform/android/export/export_plugin.cpp msgid "One Click Deploy" -msgstr "" +msgstr "Despliegue con Un Clic" #: platform/android/export/export_plugin.cpp msgid "Clear Previous Install" @@ -18540,7 +18534,7 @@ msgstr "Limpiar Instalación Previa" #: platform/android/export/export_plugin.cpp msgid "Code" -msgstr "" +msgstr "Código" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp msgid "Package" @@ -18560,7 +18554,7 @@ msgstr "Clasificar Como Juego" #: platform/android/export/export_plugin.cpp msgid "Retain Data On Uninstall" -msgstr "" +msgstr "Conservar Datos al Desinstalar" #: platform/android/export/export_plugin.cpp msgid "Exclude From Recents" @@ -18588,11 +18582,11 @@ msgstr "Seguimiento de Manos" #: platform/android/export/export_plugin.cpp msgid "Hand Tracking Frequency" -msgstr "" +msgstr "Frecuencia de Seguimiento de la Mano" #: platform/android/export/export_plugin.cpp msgid "Passthrough" -msgstr "" +msgstr "Pasar por" #: platform/android/export/export_plugin.cpp msgid "Immersive Mode" @@ -18620,7 +18614,7 @@ msgstr "Backup de Datos del Usuario" #: platform/android/export/export_plugin.cpp msgid "Allow" -msgstr "" +msgstr "Permitir" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp msgid "Command Line" @@ -18636,7 +18630,7 @@ msgstr "Expansión del APK" #: platform/android/export/export_plugin.cpp msgid "Salt" -msgstr "" +msgstr "Sal" #: platform/android/export/export_plugin.cpp msgid "Public Key" @@ -18808,12 +18802,15 @@ msgstr "" #: platform/android/export/export_plugin.cpp msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid." msgstr "" +"\"Min SDK\" debería ser un entero válido, pero obtuvo \"%s\" que es inválido." #: platform/android/export/export_plugin.cpp msgid "" "\"Min SDK\" cannot be lower than %d, which is the version needed by the " "Godot library." msgstr "" +"\"Min SDK\" no puede ser inferior a %d, que es la versión que necesita la " +"librería de Godot." #: platform/android/export/export_plugin.cpp msgid "" @@ -19012,67 +19009,67 @@ msgstr "El carácter '% s' no está permitido en el Identificador." #: platform/iphone/export/export.cpp msgid "Landscape Launch Screens" -msgstr "" +msgstr "Pantalla de Inicio Landscape" #: platform/iphone/export/export.cpp msgid "iPhone 2436 X 1125" -msgstr "" +msgstr "iPhone 2436 X 1125" #: platform/iphone/export/export.cpp msgid "iPhone 2208 X 1242" -msgstr "" +msgstr "iPhone 2208 X 1242" #: platform/iphone/export/export.cpp msgid "iPad 1024 X 768" -msgstr "" +msgstr "iPad 1024 X 768" #: platform/iphone/export/export.cpp msgid "iPad 2048 X 1536" -msgstr "" +msgstr "iPad 2048 X 1536" #: platform/iphone/export/export.cpp msgid "Portrait Launch Screens" -msgstr "" +msgstr "Pantalla de Inicio Portrait" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 960" -msgstr "" +msgstr "iPhone 640 X 960" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 1136" -msgstr "" +msgstr "iPhone 640 X 1136" #: platform/iphone/export/export.cpp msgid "iPhone 750 X 1334" -msgstr "" +msgstr "iPhone 750 X 1334" #: platform/iphone/export/export.cpp msgid "iPhone 1125 X 2436" -msgstr "" +msgstr "iPhone 1125 X 2436" #: platform/iphone/export/export.cpp msgid "iPad 768 X 1024" -msgstr "" +msgstr "iPad 768 X 1024" #: platform/iphone/export/export.cpp msgid "iPad 1536 X 2048" -msgstr "" +msgstr "iPad 1536 X 2048" #: platform/iphone/export/export.cpp msgid "iPhone 1242 X 2208" -msgstr "" +msgstr "iPhone 1242 X 2208" #: platform/iphone/export/export.cpp msgid "App Store Team ID" -msgstr "" +msgstr "ID del Equipo de la App Store" #: platform/iphone/export/export.cpp msgid "Provisioning Profile UUID Debug" -msgstr "" +msgstr "Depuración del Perfil de Aprovisionamiento UUID" #: platform/iphone/export/export.cpp msgid "Code Sign Identity Debug" -msgstr "" +msgstr "Depuración de la Identidad del Código" #: platform/iphone/export/export.cpp msgid "Export Method Debug" @@ -19080,11 +19077,11 @@ msgstr "Exportar Método de Depuración" #: platform/iphone/export/export.cpp msgid "Provisioning Profile UUID Release" -msgstr "" +msgstr "Release UUID del Perfil de Aprovisionamiento" #: platform/iphone/export/export.cpp msgid "Code Sign Identity Release" -msgstr "" +msgstr "Release de Código de Identidad" #: platform/iphone/export/export.cpp msgid "Export Method Release" @@ -19092,11 +19089,11 @@ msgstr "Método de Exportación de Release" #: platform/iphone/export/export.cpp msgid "Targeted Device Family" -msgstr "" +msgstr "Familia de Dispositivos de Destino" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Info" -msgstr "" +msgstr "Información" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Identifier" @@ -19133,11 +19130,11 @@ msgstr "Datos de Usuario" #: platform/iphone/export/export.cpp msgid "Accessible From Files App" -msgstr "" +msgstr "Accesible desde la Aplicación de Archivos" #: platform/iphone/export/export.cpp msgid "Accessible From iTunes Sharing" -msgstr "" +msgstr "Accesible desde iTunes Sharing" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Privacy" @@ -19157,43 +19154,43 @@ msgstr "Descripción del Uso de la Fotolibrería" #: platform/iphone/export/export.cpp msgid "iPhone 120 X 120" -msgstr "" +msgstr "iPhone 120 X 120" #: platform/iphone/export/export.cpp msgid "iPhone 180 X 180" -msgstr "" +msgstr "iPhone 180 X 180" #: platform/iphone/export/export.cpp msgid "iPad 76 X 76" -msgstr "" +msgstr "iPad 76 X 76" #: platform/iphone/export/export.cpp msgid "iPad 152 X 152" -msgstr "" +msgstr "iPad 152 X 152" #: platform/iphone/export/export.cpp msgid "iPad 167 X 167" -msgstr "" +msgstr "iPad 167 X 167" #: platform/iphone/export/export.cpp msgid "App Store 1024 X 1024" -msgstr "" +msgstr "App Store 1024 X 1024" #: platform/iphone/export/export.cpp msgid "Spotlight 40 X 40" -msgstr "" +msgstr "Spotlight 40 X 40" #: platform/iphone/export/export.cpp msgid "Spotlight 80 X 80" -msgstr "" +msgstr "Spotlight 80 X 80" #: platform/iphone/export/export.cpp msgid "Storyboard" -msgstr "" +msgstr "Storyboard" #: platform/iphone/export/export.cpp msgid "Use Launch Screen Storyboard" -msgstr "" +msgstr "Usar Storyboard en la Pantalla de Inicio" #: platform/iphone/export/export.cpp msgid "Image Scale Mode" @@ -19216,9 +19213,8 @@ msgid "Custom BG Color" msgstr "Color de Fondo Personalizado" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Icons" -msgstr "Icono de Exportación" +msgstr "Iconos de Exportación" #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp @@ -19272,7 +19268,7 @@ msgstr "No se pudo leer el archivo: \"%s\"." #: platform/javascript/export/export.cpp msgid "PWA" -msgstr "" +msgstr "PWA" #: platform/javascript/export/export.cpp msgid "Variant" @@ -19288,15 +19284,15 @@ msgstr "Compresión de Texturas en la VRAM" #: platform/javascript/export/export.cpp msgid "For Desktop" -msgstr "" +msgstr "Para Escritorio" #: platform/javascript/export/export.cpp msgid "For Mobile" -msgstr "" +msgstr "Para Móviles" #: platform/javascript/export/export.cpp msgid "HTML" -msgstr "" +msgstr "HTML" #: platform/javascript/export/export.cpp msgid "Export Icon" @@ -19308,15 +19304,15 @@ msgstr "HTML Shell Personalizado" #: platform/javascript/export/export.cpp msgid "Head Include" -msgstr "" +msgstr "Incluyendo Cabecera" #: platform/javascript/export/export.cpp msgid "Canvas Resize Policy" -msgstr "" +msgstr "Política de Redimensionamiento del Canvas" #: platform/javascript/export/export.cpp msgid "Focus Canvas On Start" -msgstr "" +msgstr "Enfocar Lienzo Al Inicio" #: platform/javascript/export/export.cpp msgid "Experimental Virtual Keyboard" @@ -19324,23 +19320,23 @@ msgstr "Teclado Virtual Experimental" #: platform/javascript/export/export.cpp msgid "Progressive Web App" -msgstr "" +msgstr "App Web Progresiva" #: platform/javascript/export/export.cpp msgid "Offline Page" -msgstr "" +msgstr "Página Offline" #: platform/javascript/export/export.cpp msgid "Icon 144 X 144" -msgstr "" +msgstr "Icono 144 X 144" #: platform/javascript/export/export.cpp msgid "Icon 180 X 180" -msgstr "" +msgstr "Icono 180 X 180" #: platform/javascript/export/export.cpp msgid "Icon 512 X 512" -msgstr "" +msgstr "Icono 512 X 512" #: platform/javascript/export/export.cpp msgid "Could not read HTML shell: \"%s\"." @@ -19356,15 +19352,15 @@ msgstr "Error al iniciar el servidor HTTP: %d." #: platform/javascript/export/export.cpp msgid "Web" -msgstr "" +msgstr "Web" #: platform/javascript/export/export.cpp msgid "HTTP Host" -msgstr "" +msgstr "HTTP Host" #: platform/javascript/export/export.cpp msgid "HTTP Port" -msgstr "" +msgstr "Puerto HTTP" #: platform/javascript/export/export.cpp msgid "Use SSL" @@ -19372,7 +19368,7 @@ msgstr "Usar SSL" #: platform/javascript/export/export.cpp msgid "SSL Key" -msgstr "" +msgstr "Clave SSL" #: platform/osx/export/codesign.cpp msgid "Can't get filesystem access." @@ -19452,7 +19448,7 @@ msgstr "Categoría De La Aplicación" #: platform/osx/export/export.cpp msgid "High Res" -msgstr "" +msgstr "Alta Resolución" #: platform/osx/export/export.cpp msgid "Location Usage Description" @@ -19460,7 +19456,7 @@ msgstr "Ubicación de la Descripción de Uso" #: platform/osx/export/export.cpp msgid "Address Book Usage Description" -msgstr "" +msgstr "Descripción de Uso de la Libreta de Direcciones" #: platform/osx/export/export.cpp msgid "Calendar Usage Description" @@ -19480,15 +19476,15 @@ msgstr "Descripción de Uso de la Carpeta de Documentos" #: platform/osx/export/export.cpp msgid "Downloads Folder Usage Description" -msgstr "" +msgstr "Descripción de Uso de la Carpeta de Descargas" #: platform/osx/export/export.cpp msgid "Network Volumes Usage Description" -msgstr "" +msgstr "Descripción de Uso de Volúmenes de Red" #: platform/osx/export/export.cpp msgid "Removable Volumes Usage Description" -msgstr "" +msgstr "Descripción de Uso de Volúmenes Extraíbles" #: platform/osx/export/export.cpp platform/windows/export/export.cpp msgid "Codesign" @@ -19521,15 +19517,15 @@ msgstr "Archivo Personalizado" #: platform/osx/export/export.cpp msgid "Allow JIT Code Execution" -msgstr "" +msgstr "Permitir Ejecución de Código JIT" #: platform/osx/export/export.cpp msgid "Allow Unsigned Executable Memory" -msgstr "" +msgstr "Permitir Memoria Ejecutable Desfasada" #: platform/osx/export/export.cpp msgid "Allow Dyld Environment Variables" -msgstr "" +msgstr "Permitir Variables de Entorno Dyld" #: platform/osx/export/export.cpp msgid "Disable Library Validation" @@ -19541,11 +19537,11 @@ msgstr "Entrada de Audio" #: platform/osx/export/export.cpp msgid "Address Book" -msgstr "" +msgstr "Libreta de Direcciones" #: platform/osx/export/export.cpp msgid "Calendars" -msgstr "" +msgstr "Calendarios" #: platform/osx/export/export.cpp msgid "Photos Library" @@ -19561,7 +19557,7 @@ msgstr "Depuración" #: platform/osx/export/export.cpp msgid "App Sandbox" -msgstr "" +msgstr "App Sandbox" #: platform/osx/export/export.cpp msgid "Network Server" @@ -19577,7 +19573,7 @@ msgstr "Dispositivo USB" #: platform/osx/export/export.cpp msgid "Device Bluetooth" -msgstr "" +msgstr "Dispositivo Bluetooth" #: platform/osx/export/export.cpp msgid "Files Downloads" @@ -19605,7 +19601,7 @@ msgstr "Notarización" #: platform/osx/export/export.cpp msgid "Apple ID Name" -msgstr "" +msgstr "Nombre del ID de Apple" #: platform/osx/export/export.cpp msgid "Apple ID Password" @@ -19613,7 +19609,7 @@ msgstr "Contraseña del ID de Apple" #: platform/osx/export/export.cpp msgid "Apple Team ID" -msgstr "" +msgstr "ID del Equipo Apple" #: platform/osx/export/export.cpp msgid "Could not open icon file \"%s\"." @@ -19629,7 +19625,7 @@ msgstr "La notarización ha fallado." #: platform/osx/export/export.cpp msgid "Notarization request UUID: \"%s\"" -msgstr "" +msgstr "Solicitud de notarización UUID: \"%s\"" #: platform/osx/export/export.cpp msgid "" @@ -19668,11 +19664,11 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Built-in CodeSign failed with error \"%s\"." -msgstr "" +msgstr "El CodeSign incorporado falló con el error \"%s\"." #: platform/osx/export/export.cpp msgid "Built-in CodeSign require regex module." -msgstr "" +msgstr "El CodeSign incorporado requiere un módulo regex." #: platform/osx/export/export.cpp msgid "" @@ -20049,6 +20045,8 @@ msgid "" "Godot's Mono version does not support the UWP platform. Use the standard " "build (no C# support) if you wish to target UWP." msgstr "" +"La versión Mono de Godot no es compatible con la plataforma UWP. Utiliza la " +"compilación estándar (sin soporte para C#) si deseas enfocarte en UWP." #: platform/uwp/export/export.cpp msgid "Invalid package short name." diff --git a/editor/translations/et.po b/editor/translations/et.po index 20da09ffc5..0a4ab2fe0b 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -6,118 +6,111 @@ # Mattias Aabmets <mattias.aabmets@gmail.com>, 2019. # StReef <streef.gtx@gmail.com>, 2020, 2021. # René <renepiik@gmail.com>, 2020. -# Kritzmensch <streef.gtx@gmail.com>, 2021. +# Kritzmensch <streef.gtx@gmail.com>, 2021, 2022. +# dogyx <aaronloit@zohomail.eu>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-07-16 05:47+0000\n" -"Last-Translator: Kritzmensch <streef.gtx@gmail.com>\n" +"PO-Revision-Date: 2022-09-16 07:12+0000\n" +"Last-Translator: dogyx <aaronloit@zohomail.eu>\n" "Language-Team: Estonian <https://hosted.weblate.org/projects/godot-engine/" "godot/et/>\n" "Language: et\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.7.2-dev\n" +"X-Generator: Weblate 4.14.1-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" -msgstr "" +msgstr "Graafikatahvli draiver" #: core/bind/core_bind.cpp msgid "Clipboard" -msgstr "" +msgstr "Lõikelaud" #: core/bind/core_bind.cpp -#, fuzzy msgid "Current Screen" -msgstr "Virnakaadrid" +msgstr "Avatud Ekraan" #: core/bind/core_bind.cpp msgid "Exit Code" -msgstr "" +msgstr "Lõpukood" #: core/bind/core_bind.cpp -#, fuzzy msgid "V-Sync Enabled" -msgstr "Luba" +msgstr "V-Sync Sees" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" -msgstr "" +msgstr "V-sync komposiitori kaudu" #: core/bind/core_bind.cpp main/main.cpp msgid "Delta Smoothing" -msgstr "" +msgstr "Delta silumine" #: core/bind/core_bind.cpp -#, fuzzy msgid "Low Processor Usage Mode" -msgstr "Liigutamisrežiim" +msgstr "Protsessori madala võimsuse režiim" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" -msgstr "" +msgstr "Protsessori madala võimsuse režiimi puhkeaeg (µsek)" #: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp msgid "Keep Screen On" -msgstr "" +msgstr "Hoia ekraan sees" #: core/bind/core_bind.cpp -#, fuzzy msgid "Min Window Size" -msgstr "Suurus: " +msgstr "Minimaalne akna suurus" #: core/bind/core_bind.cpp -#, fuzzy msgid "Max Window Size" -msgstr "Suurus: " +msgstr "Maksimaalne akna suurus" #: core/bind/core_bind.cpp -#, fuzzy msgid "Screen Orientation" -msgstr "Ava dokumentatsioon" +msgstr "Ekraani orientatsioon" #: core/bind/core_bind.cpp core/project_settings.cpp main/main.cpp #: platform/uwp/os_uwp.cpp -#, fuzzy msgid "Window" -msgstr "Uus aken" +msgstr "Aken" #: core/bind/core_bind.cpp core/project_settings.cpp msgid "Borderless" -msgstr "" +msgstr "Ääriseta" #: core/bind/core_bind.cpp msgid "Per Pixel Transparency Enabled" -msgstr "" +msgstr "Läbipaistvus piksli kohta lubatud" #: core/bind/core_bind.cpp core/project_settings.cpp msgid "Fullscreen" -msgstr "" +msgstr "Täisekraan" #: core/bind/core_bind.cpp msgid "Maximized" -msgstr "" +msgstr "Maksimeeritud" #: core/bind/core_bind.cpp msgid "Minimized" -msgstr "" +msgstr "Minimeeritud" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp msgid "Resizable" -msgstr "" +msgstr "Suurust muudetav" #: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp #: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp #: scene/3d/physics_body.cpp scene/3d/remote_transform.cpp #: scene/gui/control.cpp scene/gui/line_edit.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Position" -msgstr "Doki asukoht" +msgstr "Asend" #: core/bind/core_bind.cpp core/project_settings.cpp editor/editor_settings.cpp #: main/main.cpp modules/gridmap/grid_map.cpp @@ -128,63 +121,56 @@ msgstr "Doki asukoht" #: scene/resources/primitive_meshes.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp #: scene/resources/visual_shader.cpp servers/visual_server.cpp -#, fuzzy msgid "Size" -msgstr "Suurus: " +msgstr "Suurus" #: core/bind/core_bind.cpp msgid "Endian Swap" -msgstr "" +msgstr "Endiani vahetus" #: core/bind/core_bind.cpp -#, fuzzy msgid "Editor Hint" -msgstr "Redaktor" +msgstr "Toimeti vihje" #: core/bind/core_bind.cpp msgid "Print Error Messages" -msgstr "" +msgstr "Trüki veateated" #: core/bind/core_bind.cpp -#, fuzzy msgid "Iterations Per Second" -msgstr "Interpolatsiooni režiim" +msgstr "Iteratsioone sekundis" #: core/bind/core_bind.cpp -#, fuzzy msgid "Target FPS" -msgstr "Ressursi tee" +msgstr "Kaadrisageduse eesmärk" #: core/bind/core_bind.cpp -#, fuzzy msgid "Time Scale" -msgstr "Skaleerimisrežiim" +msgstr "Ajaskaala" #: core/bind/core_bind.cpp main/main.cpp msgid "Physics Jitter Fix" -msgstr "" +msgstr "Füüsika värisemise parandus" #: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Error" -msgstr "" +msgstr "Viga" #: core/bind/core_bind.cpp -#, fuzzy msgid "Error String" -msgstr "Redaktori sätted" +msgstr "Veasõne" #: core/bind/core_bind.cpp -#, fuzzy msgid "Error Line" -msgstr "Viga:" +msgstr "Vearida" #: core/bind/core_bind.cpp msgid "Result" -msgstr "" +msgstr "Tulemus" #: core/command_queue_mt.cpp core/message_queue.cpp main/main.cpp msgid "Memory" -msgstr "" +msgstr "Mälu" #: core/command_queue_mt.cpp core/message_queue.cpp #: core/register_core_types.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp @@ -195,128 +181,119 @@ msgstr "" #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: servers/visual_server.cpp msgid "Limits" -msgstr "" +msgstr "Limiidid" #: core/command_queue_mt.cpp msgid "Command Queue" -msgstr "" +msgstr "Käskude järjekord" #: core/command_queue_mt.cpp msgid "Multithreading Queue Size (KB)" -msgstr "" +msgstr "Lõimtöötluse järjekorra suurus (KB)" #: core/func_ref.cpp modules/visual_script/visual_script_builtin_funcs.cpp #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Function" -msgstr "Funktsioonid" +msgstr "Funktsioon" #: core/image.cpp core/packed_data_container.cpp scene/2d/polygon_2d.cpp #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Data" -msgstr "" +msgstr "Andmed" #: core/io/file_access_network.cpp core/register_core_types.cpp #: editor/editor_file_dialog.cpp editor/editor_settings.cpp main/main.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: scene/gui/file_dialog.cpp -#, fuzzy msgid "Network" -msgstr "Võrgu profileerija" +msgstr "Võrk" #: core/io/file_access_network.cpp -#, fuzzy msgid "Remote FS" -msgstr "Eemalda" +msgstr "Kaugfailisüsteem" #: core/io/file_access_network.cpp msgid "Page Size" -msgstr "" +msgstr "Lehekülje suurus" #: core/io/file_access_network.cpp msgid "Page Read Ahead" -msgstr "" +msgstr "Lehekülje ettelaadimine" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" -msgstr "" +msgstr "Blokeerimisrežiim lubatud" #: core/io/http_client.cpp -#, fuzzy msgid "Connection" -msgstr "Ühenda" +msgstr "Ühendus" #: core/io/http_client.cpp msgid "Read Chunk Size" -msgstr "" +msgstr "Loe tüki suurust" #: core/io/marshalls.cpp -#, fuzzy msgid "Object ID" -msgstr "Objekte kuvatud" +msgstr "Objekti ID" #: core/io/multiplayer_api.cpp core/io/packet_peer.cpp msgid "Allow Object Decoding" -msgstr "" +msgstr "Luba objekti dekodeerimine" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp msgid "Refuse New Network Connections" -msgstr "" +msgstr "Keeldu uutest võrguühendustest" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Network Peer" -msgstr "Võrgu profileerija" +msgstr "Võrgukaaslane" #: core/io/multiplayer_api.cpp scene/animation/animation_player.cpp -#, fuzzy msgid "Root Node" -msgstr "Sõlm" +msgstr "Juur Node" #: core/io/networked_multiplayer_peer.cpp -#, fuzzy msgid "Refuse New Connections" -msgstr "Ühenda" +msgstr "Keeldu uutest ühendustest" #: core/io/networked_multiplayer_peer.cpp -#, fuzzy msgid "Transfer Mode" -msgstr "Skaleerimisrežiim" +msgstr "Ülekanderežiim" #: core/io/packet_peer.cpp msgid "Encode Buffer Max Size" -msgstr "" +msgstr "Kodeerimispuhvri maksimaalne suurus" #: core/io/packet_peer.cpp msgid "Input Buffer Max Size" -msgstr "" +msgstr "Sisendpuhvri maksimaalne suurus" #: core/io/packet_peer.cpp msgid "Output Buffer Max Size" -msgstr "" +msgstr "Väljundpuhvri maksimaalne suurus" #: core/io/packet_peer.cpp msgid "Stream Peer" -msgstr "" +msgstr "Voogedastuskaaslane" #: core/io/stream_peer.cpp msgid "Big Endian" -msgstr "" +msgstr "Suur Endian" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Andmemassiiv" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" -msgstr "" +msgstr "Käepigistuse blokeerimine" #: core/io/udp_server.cpp msgid "Max Pending Connections" -msgstr "" +msgstr "Maksimaalne ootel ühenduste arv" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -326,7 +303,7 @@ msgstr "" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "Eeldati sõne pikkusega 1 (trükimärk)." +msgstr "Eeldati sõne pikkusega 1 (tähemärk)." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -335,7 +312,6 @@ msgid "Not enough bytes for decoding bytes, or invalid format." msgstr "Ebapiisav kogus baite nende dekodeerimiseks või kehtetu formaat." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" msgstr "Väljendis on kehtetu sisend %i (mitte edastatud)" @@ -366,209 +342,193 @@ msgstr "'%' kutsudes:" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp msgid "Seed" -msgstr "" +msgstr "Seeme" #: core/math/random_number_generator.cpp -#, fuzzy msgid "State" msgstr "Olek" #: core/message_queue.cpp msgid "Message Queue" -msgstr "" +msgstr "Sõnumijärjekord" #: core/message_queue.cpp msgid "Max Size (KB)" -msgstr "" +msgstr "Maksimaalne suurus (KB)" #: core/os/input.cpp -#, fuzzy msgid "Mouse Mode" -msgstr "Liigutamisrežiim" +msgstr "Hiire režiim" #: core/os/input.cpp msgid "Use Accumulated Input" -msgstr "" +msgstr "Kasuta akumuleeritud sisendit" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp msgid "Device" -msgstr "" +msgstr "Seade" #: core/os/input_event.cpp -#, fuzzy msgid "Alt" -msgstr "Tähelepanu!" +msgstr "Alt" #: core/os/input_event.cpp msgid "Shift" -msgstr "" +msgstr "Shift" #: core/os/input_event.cpp msgid "Control" -msgstr "" +msgstr "Control" #: core/os/input_event.cpp msgid "Meta" -msgstr "" +msgstr "Meta" #: core/os/input_event.cpp -#, fuzzy msgid "Command" -msgstr "Kogukond" +msgstr "Command" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr "Luba" +msgstr "Füüsiline" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Pressed" -msgstr "Eelseadistus" +msgstr "Vajutatud" #: core/os/input_event.cpp -#, fuzzy msgid "Scancode" -msgstr "Otsi" +msgstr "Klahvikood" #: core/os/input_event.cpp msgid "Physical Scancode" -msgstr "" +msgstr "Füüsiline klahvikood" #: core/os/input_event.cpp msgid "Unicode" -msgstr "" +msgstr "Unicode" #: core/os/input_event.cpp msgid "Echo" -msgstr "" +msgstr "Kaja" #: core/os/input_event.cpp scene/gui/base_button.cpp msgid "Button Mask" -msgstr "" +msgstr "Nupu mask" #: core/os/input_event.cpp scene/2d/node_2d.cpp scene/gui/control.cpp -#, fuzzy msgid "Global Position" -msgstr "Konstant" +msgstr "Globaalne positsioon" #: core/os/input_event.cpp msgid "Factor" -msgstr "" +msgstr "Faktor" #: core/os/input_event.cpp msgid "Button Index" -msgstr "" +msgstr "Nupu indeks" #: core/os/input_event.cpp msgid "Doubleclick" -msgstr "" +msgstr "Topeltklõps" #: core/os/input_event.cpp msgid "Tilt" -msgstr "" +msgstr "Kallutus" #: core/os/input_event.cpp -#, fuzzy msgid "Pressure" -msgstr "Eelseadistus" +msgstr "Surve" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Pliiats ümberpööratud" #: core/os/input_event.cpp msgid "Relative" -msgstr "" +msgstr "Suhteline" #: core/os/input_event.cpp scene/2d/camera_2d.cpp scene/2d/cpu_particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/interpolated_camera.cpp #: scene/animation/animation_player.cpp scene/resources/environment.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed" -msgstr "Skaleerimisrežiim" +msgstr "Kiirus" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: scene/3d/sprite_3d.cpp msgid "Axis" -msgstr "" +msgstr "Telg" #: core/os/input_event.cpp -#, fuzzy msgid "Axis Value" -msgstr "(väärtus)" +msgstr "Telje väärtus" #: core/os/input_event.cpp modules/visual_script/visual_script_func_nodes.cpp msgid "Index" -msgstr "" +msgstr "Indeks" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: modules/visual_script/visual_script_nodes.cpp #: scene/2d/touch_screen_button.cpp msgid "Action" -msgstr "" +msgstr "Tegevus" #: core/os/input_event.cpp scene/resources/environment.cpp #: scene/resources/material.cpp msgid "Strength" -msgstr "" +msgstr "Tugevus" #: core/os/input_event.cpp msgid "Delta" -msgstr "" +msgstr "Delta" #: core/os/input_event.cpp -#, fuzzy msgid "Channel" -msgstr "Muuda" +msgstr "Kanal" #: core/os/input_event.cpp main/main.cpp -#, fuzzy msgid "Message" -msgstr "Kasutus" +msgstr "Sõnum" #: core/os/input_event.cpp -#, fuzzy msgid "Pitch" -msgstr "Frontaal" +msgstr "Helikõrgus" #: core/os/input_event.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/physics_body_2d.cpp scene/3d/cpu_particles.cpp #: scene/3d/physics_body.cpp scene/resources/particles_material.cpp msgid "Velocity" -msgstr "" +msgstr "Kiirus" #: core/os/input_event.cpp msgid "Instrument" -msgstr "" +msgstr "Instrument" #: core/os/input_event.cpp msgid "Controller Number" -msgstr "" +msgstr "Kontrolleri number" #: core/os/input_event.cpp msgid "Controller Value" -msgstr "" +msgstr "Kontrolleri väärtus" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Application" -msgstr "Animatsioon" +msgstr "Rakendus" #: core/project_settings.cpp main/main.cpp msgid "Config" -msgstr "" +msgstr "Konfiig" #: core/project_settings.cpp -#, fuzzy msgid "Project Settings Override" -msgstr "Projekti sätted..." +msgstr "Projekti seadete ülekirjutamine" #: core/project_settings.cpp core/resource.cpp #: editor/animation_track_editor.cpp editor/editor_autoload_settings.cpp @@ -599,40 +559,39 @@ msgstr "Käivita" #: core/project_settings.cpp editor/editor_node.cpp #: editor/run_settings_dialog.cpp main/main.cpp msgid "Main Scene" -msgstr "" +msgstr "Peamine stseen" #: core/project_settings.cpp msgid "Disable stdout" -msgstr "" +msgstr "Lülita stdout välja" #: core/project_settings.cpp msgid "Disable stderr" -msgstr "" +msgstr "Lülita stderr välja" #: core/project_settings.cpp msgid "Use Hidden Project Data Directory" -msgstr "" +msgstr "Kasuta varjatud projektiandmete kausta" #: core/project_settings.cpp msgid "Use Custom User Dir" -msgstr "" +msgstr "Kasuta kohandatud kasutaja kausta" #: core/project_settings.cpp msgid "Custom User Dir Name" -msgstr "" +msgstr "Kohandatud kasutaja kausta nimi" #: core/project_settings.cpp main/main.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #: platform/uwp/os_uwp.cpp -#, fuzzy msgid "Display" -msgstr "Kuva kõik" +msgstr "Ekraan" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp #: scene/3d/label_3d.cpp scene/gui/text_edit.cpp scene/resources/texture.cpp msgid "Width" -msgstr "" +msgstr "Laius" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/gltf/gltf_node.cpp modules/opensimplex/noise_texture.cpp @@ -641,20 +600,19 @@ msgstr "" #: scene/resources/font.cpp scene/resources/navigation_mesh.cpp #: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp msgid "Height" -msgstr "" +msgstr "Kõrgus" #: core/project_settings.cpp msgid "Always On Top" -msgstr "" +msgstr "Alati pealmine" #: core/project_settings.cpp msgid "Test Width" -msgstr "" +msgstr "Testimise laius" #: core/project_settings.cpp -#, fuzzy msgid "Test Height" -msgstr "Testimine" +msgstr "Testimise kõrgus" #: core/project_settings.cpp editor/animation_track_editor.cpp #: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp @@ -662,9 +620,8 @@ msgid "Audio" msgstr "Heli" #: core/project_settings.cpp -#, fuzzy msgid "Default Bus Layout" -msgstr "Lae vaikimise siini paigutus." +msgstr "Siini vaikepaigutus" #: core/project_settings.cpp editor/editor_export.cpp #: editor/editor_file_system.cpp editor/editor_node.cpp @@ -675,90 +632,84 @@ msgstr "Redaktor" #: core/project_settings.cpp msgid "Main Run Args" -msgstr "" +msgstr "Peamised jooksuargumendid" #: core/project_settings.cpp -#, fuzzy msgid "Scene Naming" -msgstr "Stseeni tee:" +msgstr "Stseeni nimetamine" #: core/project_settings.cpp msgid "Search In File Extensions" -msgstr "" +msgstr "Otsi faililaienditest" #: core/project_settings.cpp msgid "Script Templates Search Path" -msgstr "" +msgstr "Skriptimallide otsingutee" #: core/project_settings.cpp msgid "Version Control Autoload On Startup" -msgstr "" +msgstr "Versioonikontrolli automaatne laadimine käivitamisel" #: core/project_settings.cpp msgid "Version Control Plugin Name" -msgstr "" +msgstr "Versioonikontrolli plugina nimi" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp msgid "Input" -msgstr "" +msgstr "Sisend" #: core/project_settings.cpp msgid "UI Accept" -msgstr "" +msgstr "UI Aktsepteeri" #: core/project_settings.cpp -#, fuzzy msgid "UI Select" -msgstr "Vali" +msgstr "UI Vali" #: core/project_settings.cpp -#, fuzzy msgid "UI Cancel" -msgstr "Tühista" +msgstr "UI Tühista" #: core/project_settings.cpp -#, fuzzy msgid "UI Focus Next" -msgstr "Fookuse tee" +msgstr "UI Fokusseeri järgmine" #: core/project_settings.cpp -#, fuzzy msgid "UI Focus Prev" -msgstr "Fookuse tee" +msgstr "UI fokusseeri eelmine" #: core/project_settings.cpp msgid "UI Left" -msgstr "" +msgstr "UI Vasakule" #: core/project_settings.cpp msgid "UI Right" -msgstr "" +msgstr "UI Paremale" #: core/project_settings.cpp msgid "UI Up" -msgstr "" +msgstr "UI Üles" #: core/project_settings.cpp -#, fuzzy msgid "UI Down" -msgstr "Alla" +msgstr "UI Alla" #: core/project_settings.cpp msgid "UI Page Up" -msgstr "" +msgstr "UI Leht üles" #: core/project_settings.cpp msgid "UI Page Down" -msgstr "" +msgstr "UI leht alla" #: core/project_settings.cpp msgid "UI Home" -msgstr "" +msgstr "UI Kodu" #: core/project_settings.cpp msgid "UI End" -msgstr "" +msgstr "UI Lõpp" #: core/project_settings.cpp main/main.cpp modules/bullet/register_types.cpp #: modules/bullet/space_bullet.cpp scene/2d/physics_body_2d.cpp @@ -769,7 +720,7 @@ msgstr "" #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Physics" -msgstr "" +msgstr "Füüsika" #: core/project_settings.cpp editor/editor_settings.cpp #: editor/import/resource_importer_layered_texture.cpp @@ -779,11 +730,11 @@ msgstr "" #: scene/3d/physics_body.cpp scene/resources/world.cpp #: servers/physics/space_sw.cpp servers/physics_server.cpp msgid "3D" -msgstr "" +msgstr "3D" #: core/project_settings.cpp msgid "Smooth Trimesh Collision" -msgstr "" +msgstr "Sujuv Trimeshi kokkupõrge" #: core/project_settings.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles2/rasterizer_scene_gles2.cpp @@ -795,7 +746,7 @@ msgstr "" #: scene/main/viewport.cpp servers/visual/visual_server_scene.cpp #: servers/visual_server.cpp msgid "Rendering" -msgstr "" +msgstr "Renderdamine" #: core/project_settings.cpp drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp @@ -805,18 +756,17 @@ msgstr "" #: scene/resources/multimesh.cpp servers/visual/visual_server_scene.cpp #: servers/visual_server.cpp msgid "Quality" -msgstr "" +msgstr "Kvaliteet" #: core/project_settings.cpp scene/gui/file_dialog.cpp #: scene/main/scene_tree.cpp scene/resources/navigation_mesh.cpp #: servers/visual_server.cpp -#, fuzzy msgid "Filters" -msgstr "Filtreeri sõlmed" +msgstr "Filtrid" #: core/project_settings.cpp scene/main/viewport.cpp msgid "Sharpen Intensity" -msgstr "" +msgstr "Teravdamise intensiivsus" #: core/project_settings.cpp editor/editor_export.cpp editor/editor_node.cpp #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp @@ -832,9 +782,8 @@ msgstr "Silumine" #: core/project_settings.cpp main/main.cpp modules/gdscript/gdscript.cpp #: modules/visual_script/visual_script.cpp scene/resources/dynamic_font.cpp -#, fuzzy msgid "Settings" -msgstr "Sätted..." +msgstr "Seaded" #: core/project_settings.cpp editor/script_editor_debugger.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp @@ -842,22 +791,20 @@ msgid "Profiler" msgstr "Profileerija" #: core/project_settings.cpp -#, fuzzy msgid "Max Functions" -msgstr "Loo funktsioon" +msgstr "Funktsioone maksimaalselt" #: core/project_settings.cpp scene/3d/vehicle_body.cpp msgid "Compression" -msgstr "" +msgstr "Kompressioon" #: core/project_settings.cpp -#, fuzzy msgid "Formats" -msgstr "Formaat" +msgstr "Formaadid" #: core/project_settings.cpp msgid "Zstd" -msgstr "" +msgstr "Zstd" #: core/project_settings.cpp msgid "Long Distance Matching" @@ -865,35 +812,36 @@ msgstr "" #: core/project_settings.cpp msgid "Compression Level" -msgstr "" +msgstr "Kompressiooni tase" #: core/project_settings.cpp +#, fuzzy msgid "Window Log Size" -msgstr "" +msgstr "Akna logi suurus" #: core/project_settings.cpp msgid "Zlib" -msgstr "" +msgstr "Zlib" #: core/project_settings.cpp msgid "Gzip" -msgstr "" +msgstr "Gzip" #: core/project_settings.cpp platform/android/export/export.cpp msgid "Android" -msgstr "" +msgstr "Android" #: core/project_settings.cpp msgid "Modules" -msgstr "" +msgstr "Moodulid" #: core/register_core_types.cpp msgid "TCP" -msgstr "" +msgstr "TCP" #: core/register_core_types.cpp msgid "Connect Timeout Seconds" -msgstr "" +msgstr "Ühendamise aegumistähtaeg sekundites" #: core/register_core_types.cpp msgid "Packet Peer Stream" @@ -905,12 +853,11 @@ msgstr "" #: core/register_core_types.cpp editor/editor_settings.cpp main/main.cpp msgid "SSL" -msgstr "" +msgstr "SSL" #: core/register_core_types.cpp main/main.cpp -#, fuzzy msgid "Certificates" -msgstr "Tipud" +msgstr "Sertifikaadid" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_resource_picker.cpp @@ -919,9 +866,8 @@ msgid "Resource" msgstr "Ressurss" #: core/resource.cpp -#, fuzzy msgid "Local To Scene" -msgstr "Sule stseen" +msgstr "Kohalik stseenile" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp @@ -932,20 +878,19 @@ msgstr "Tee" #: core/script_language.cpp msgid "Source Code" -msgstr "" +msgstr "Lähtekood" #: core/translation.cpp editor/project_settings_editor.cpp msgid "Locale" -msgstr "" +msgstr "Lokaal" #: core/translation.cpp -#, fuzzy msgid "Test" -msgstr "Testimine" +msgstr "Test" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "" +msgstr "Varuvariant" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -981,17 +926,17 @@ msgstr "EiB" #: drivers/gles3/rasterizer_scene_gles3.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp modules/gltf/gltf_state.cpp msgid "Buffers" -msgstr "" +msgstr "Puhvrid" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Buffer Size (KB)" -msgstr "" +msgstr "Lõuendipolügooni puhvri suurus (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Index Buffer Size (KB)" -msgstr "" +msgstr "Lõuendipolügoonide indekspuhvri suurus (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp @@ -1003,54 +948,52 @@ msgstr "" #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/visual_server.cpp msgid "2D" -msgstr "" +msgstr "2D" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Snapping" -msgstr "Intervall:" +msgstr "Naksamine" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Use GPU Pixel Snap" -msgstr "Kasuta ruudustiku naksamist" +msgstr "Kasuta GPU piksli naksamist" #: drivers/gles2/rasterizer_scene_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Immediate Buffer Size (KB)" -msgstr "" +msgstr "Kohene puhvri suurus (KB)" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Lightmapping" -msgstr "" +msgstr "Valguskaardistamine" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Use Bicubic Sampling" -msgstr "" +msgstr "Kasutage bikuubilist proovivõtmist" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Elements" -msgstr "" +msgstr "Max renderdatavaid elemente" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Lights" -msgstr "" +msgstr "Max renderdatavaid tulesid" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Reflections" -msgstr "" +msgstr "Max renderdatavaid peegeldusi" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Lights Per Object" -msgstr "" +msgstr "Max tulesid objekti kohta" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Subsurface Scattering" -msgstr "" +msgstr "Pinnaalune hajumine" #: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1062,29 +1005,28 @@ msgstr "" #: scene/animation/animation_blend_tree.cpp scene/gui/control.cpp #: scene/main/canvas_layer.cpp scene/resources/environment.cpp #: scene/resources/material.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Scale" -msgstr "Skaleerimisrežiim" +msgstr "Skaala" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Follow Surface" -msgstr "" +msgstr "Jälgi pinda" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Weight Samples" -msgstr "" +msgstr "Kaalu proovid" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Voxel Cone Tracing" -msgstr "" +msgstr "Vokseli koonuse jälgimine" #: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp msgid "High Quality" -msgstr "" +msgstr "Kõrge kvaliteet" #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Blend Shape Max Buffer Size (KB)" -msgstr "" +msgstr "Segu kuju max puhvri suurus (KB)" #. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror). #: editor/animation_bezier_editor.cpp @@ -1128,12 +1070,14 @@ msgid "Move Bezier Points" msgstr "Liiguta Bezieri punkte" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Duplicate Keys" -msgstr "" +msgstr "Anim duplikaatvõtmed" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Delete Keys" -msgstr "" +msgstr "Anim kustuta võtmed" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Time" @@ -1158,9 +1102,8 @@ msgstr "" #: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Frame" -msgstr "Kaadri %" +msgstr "Kaader" #: editor/animation_track_editor.cpp editor/editor_profiler.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp @@ -1171,16 +1114,14 @@ msgstr "Aeg" #: editor/animation_track_editor.cpp editor/import/resource_importer_scene.cpp #: platform/osx/export/export.cpp -#, fuzzy msgid "Location" -msgstr "Tõlked" +msgstr "Asukoht" #: editor/animation_track_editor.cpp modules/gltf/gltf_node.cpp #: scene/2d/polygon_2d.cpp scene/2d/remote_transform_2d.cpp #: scene/3d/remote_transform.cpp scene/3d/spatial.cpp scene/gui/control.cpp -#, fuzzy msgid "Rotation" -msgstr "Pööramisrežiim" +msgstr "Pööramine" #: editor/animation_track_editor.cpp editor/script_editor_debugger.cpp #: modules/visual_script/visual_script_nodes.cpp scene/gui/range.cpp @@ -1188,14 +1129,13 @@ msgid "Value" msgstr "Väärtus" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Arg Count" -msgstr "Sisesta võti siia" +msgstr "Arg kogus" #: editor/animation_track_editor.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp msgid "Args" -msgstr "" +msgstr "Argumendid" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp @@ -1206,28 +1146,26 @@ msgstr "Tüüp" #: editor/animation_track_editor.cpp msgid "In Handle" -msgstr "" +msgstr "Käepidemes" #: editor/animation_track_editor.cpp msgid "Out Handle" -msgstr "" +msgstr "Väljas käepide" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp msgid "Stream" -msgstr "" +msgstr "Voog" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start Offset" -msgstr "Liigutamisrežiim" +msgstr "Algnihe" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End Offset" -msgstr "Kustuta sõlm(ed)" +msgstr "Lõpunihe" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #: editor/import/resource_importer_scene.cpp @@ -1241,7 +1179,7 @@ msgstr "Animatsioon" #: editor/animation_track_editor.cpp msgid "Easing" -msgstr "" +msgstr "Lõdvendamine" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1270,7 +1208,7 @@ msgstr "Muuda animatsiooni pikkust" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation Loop" -msgstr "Muuda animatsiooni silmust" +msgstr "Muuda animatsiooni tsüklit" #: editor/animation_track_editor.cpp msgid "Property Track" @@ -1278,23 +1216,23 @@ msgstr "Atribuudi rada" #: editor/animation_track_editor.cpp msgid "3D Transform Track" -msgstr "3D muundus rada" +msgstr "3D transformatsiooni rada" #: editor/animation_track_editor.cpp msgid "Call Method Track" -msgstr "" +msgstr "Meetodi kutsumise rada" #: editor/animation_track_editor.cpp msgid "Bezier Curve Track" -msgstr "Bezieri kurvi rada" +msgstr "Bezier-kõvera rada" #: editor/animation_track_editor.cpp msgid "Audio Playback Track" -msgstr "Heli taasesituse rada" +msgstr "Helimängimise rada" #: editor/animation_track_editor.cpp msgid "Animation Playback Track" -msgstr "Animatsiooni taasesituse rada" +msgstr "Animatsiooni mängimise rada" #: editor/animation_track_editor.cpp msgid "Animation length (frames)" @@ -1335,40 +1273,38 @@ msgstr "Lülita see rada sisse/välja." #: editor/animation_track_editor.cpp msgid "Update Mode (How this property is set)" -msgstr "Uuendusrežiim (kuidas see omadus on seatud)" +msgstr "Uuendusrežiim (kuidas see atribuut on määratud)" #: editor/animation_track_editor.cpp scene/resources/gradient.cpp msgid "Interpolation Mode" msgstr "Interpolatsiooni režiim" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" -msgstr "Korduse mähise režiim (nterpoleeri lõpp silmuse alguses)" +msgstr "Korduse mähise režiim (interpoleeri lõpp algusega tsükli kordudes)" #: editor/animation_track_editor.cpp msgid "Remove this track." msgstr "Eemalda see rada." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Time (s):" -msgstr "Aeg (sek): " +msgstr "Aeg (s):" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Position:" -msgstr "Doki asukoht" +msgstr "Asukoht:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Rotation:" -msgstr "Pööramisrežiim" +msgstr "Pööramine:" #: editor/animation_track_editor.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Scale:" -msgstr "" +msgstr "Skaala:" #: editor/animation_track_editor.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp @@ -1379,13 +1315,12 @@ msgid "Type:" msgstr "Tüüp:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "(Invalid, expected type: %s)" -msgstr "Vigane nimi." +msgstr "(Kehtetu, eeldatav tüüp: %s)" #: editor/animation_track_editor.cpp msgid "Easing:" -msgstr "" +msgstr "Lõdvestumine:" #: editor/animation_track_editor.cpp msgid "In-Handle:" @@ -1401,22 +1336,20 @@ msgid "Stream:" msgstr "Heli kuulaja" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start (s):" -msgstr "Käivita" +msgstr "Algus (s):" #: editor/animation_track_editor.cpp msgid "End (s):" -msgstr "" +msgstr "Lõpp (s):" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Clip:" -msgstr "Animatsiooni klipid:" +msgstr "Animatsiooni klipp:" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" -msgstr "Lülita rada sisse" +msgstr "Lülita raja seesolekut" #: editor/animation_track_editor.cpp msgid "Continuous" @@ -1496,14 +1429,12 @@ msgstr "Eemalda animatsiooni rada" #: editor/plugins/tile_map_editor_plugin.cpp editor/scene_tree_dock.cpp #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Editors" -msgstr "Redaktor" +msgstr "Toimetid" #: editor/animation_track_editor.cpp editor/editor_settings.cpp -#, fuzzy msgid "Confirm Insert Track" -msgstr "Sisesta animatsiooni rada ja võti" +msgstr "Kinnitage raja lisamine" #. TRANSLATORS: %s will be replaced by a phrase describing the target of track. #: editor/animation_track_editor.cpp @@ -1512,7 +1443,7 @@ msgstr "Loo uus rada %s-le ja sisesta võti?" #: editor/animation_track_editor.cpp msgid "Create %d NEW tracks and insert keys?" -msgstr "" +msgstr "Kas luua %d UUT rada ja sisestada võtmed?" #: editor/animation_track_editor.cpp editor/create_dialog.cpp #: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp @@ -1528,6 +1459,7 @@ msgid "Create" msgstr "Loo" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Insert" msgstr "Animatsiooni sisestus" @@ -1698,7 +1630,7 @@ msgstr "Vali AnimationPlayer sõlm, et luua ja redigeerida animatsioone." #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." -msgstr "" +msgstr "Näita ainult radu puus valitud node'idelt." #: editor/animation_track_editor.cpp msgid "Group tracks by node or display them as plain list." @@ -1884,31 +1816,31 @@ msgstr "" #: editor/code_editor.cpp msgid "Go to Line" -msgstr "" +msgstr "Mine reale" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "" +msgstr "Reanumber:" #: editor/code_editor.cpp msgid "%d replaced." -msgstr "" +msgstr "%d asendatud." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." -msgstr "" +msgstr "%d vaste." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d matches." -msgstr "" +msgstr "%d vastet." #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" -msgstr "" +msgstr "Sobita suur- ja väiketähed" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" -msgstr "" +msgstr "Terved sõnad" #: editor/code_editor.cpp msgid "Replace" @@ -1916,76 +1848,78 @@ msgstr "Asenda" #: editor/code_editor.cpp msgid "Replace All" -msgstr "" +msgstr "Asenda kõik" #: editor/code_editor.cpp msgid "Selection Only" -msgstr "" +msgstr "Ainult valik" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Standard" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" -msgstr "" +msgstr "Lülita skriptide paneel sisse/välja" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp msgid "Zoom In" -msgstr "" +msgstr "Suurenda" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp msgid "Zoom Out" -msgstr "" +msgstr "Vähenda" #: editor/code_editor.cpp msgid "Reset Zoom" -msgstr "" +msgstr "Lähtesta suum" #: editor/code_editor.cpp modules/gdscript/gdscript.cpp msgid "Warnings" -msgstr "" +msgstr "Hoiatused" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "" +msgstr "Rea- ja veerunumbrid." #: editor/connections_dialog.cpp msgid "Method in target node must be specified." -msgstr "" +msgstr "Tuleb täpsustada siht-node'i meetod." #: editor/connections_dialog.cpp msgid "Method name must be a valid identifier." -msgstr "" +msgstr "Meetodi nimi peab olema kehtiv identifikaator." #: editor/connections_dialog.cpp msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" +"Sihtmeetodit ei leitud. Määrake kehtiv meetod või lisage siht-node'ile " +"skript." #: editor/connections_dialog.cpp msgid "Connect to Node:" -msgstr "" +msgstr "Ühenda node'iga:" #: editor/connections_dialog.cpp msgid "Connect to Script:" -msgstr "" +msgstr "Ühenda skriptiga:" #: editor/connections_dialog.cpp msgid "From Signal:" -msgstr "" +msgstr "Signaalilt:" #: editor/connections_dialog.cpp msgid "Scene does not contain any script." -msgstr "" +msgstr "Stseen ei sisalda skripti." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp @@ -2007,15 +1941,15 @@ msgstr "Eemalda" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "" +msgstr "Lisa ekstra kutsumisargument:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" -msgstr "" +msgstr "Ekstra kutsumisargumendid:" #: editor/connections_dialog.cpp msgid "Receiver Method:" -msgstr "" +msgstr "Vastuvõtjameetod:" #: editor/connections_dialog.cpp scene/3d/room_manager.cpp #: servers/visual_server.cpp @@ -2024,12 +1958,14 @@ msgstr "Täpsem" #: editor/connections_dialog.cpp msgid "Deferred" -msgstr "" +msgstr "Edasi lükatud" #: editor/connections_dialog.cpp msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Lükkab signaali edasi, salvestades selle järjekorda ja väljastab seda ainult " +"tühikäigul." #: editor/connections_dialog.cpp scene/resources/texture.cpp msgid "Oneshot" @@ -2037,11 +1973,11 @@ msgstr "Ainulaadne" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Ühendab signaali lahti pärast selle esimest väljastamist." #: editor/connections_dialog.cpp msgid "Cannot connect signal" -msgstr "" +msgstr "Signaali ei saa ühendada" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -2064,19 +2000,19 @@ msgstr "Ühenda" #: editor/connections_dialog.cpp msgid "Signal:" -msgstr "" +msgstr "Signaal:" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" -msgstr "" +msgstr "Ühenda '%s' ja '%s'" #: editor/connections_dialog.cpp msgid "Disconnect '%s' from '%s'" -msgstr "" +msgstr "Ühenda '%s' ja '%s' lahti" #: editor/connections_dialog.cpp msgid "Disconnect all from signal: '%s'" -msgstr "" +msgstr "Ühenda kõik lahti signaalist: %s" #: editor/connections_dialog.cpp msgid "Connect..." @@ -2089,45 +2025,45 @@ msgstr "Katkesta ühendus" #: editor/connections_dialog.cpp msgid "Connect a Signal to a Method" -msgstr "" +msgstr "Signaali ühendamine meetodiga" #: editor/connections_dialog.cpp msgid "Edit Connection:" -msgstr "" +msgstr "Muuda ühendust:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" msgstr "" +"Kas olete kindel, et soovite eemaldada kõik ühendused signaalist \"%s\"?" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" msgstr "Signaalid" #: editor/connections_dialog.cpp -#, fuzzy msgid "Filter signals" -msgstr "Filtreeri sõlmed" +msgstr "Filtreeri signaale" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from this signal?" msgstr "" +"Kas olete kindel, et soovite sellest signaalist kõik ühendused eemaldada?" #: editor/connections_dialog.cpp msgid "Disconnect All" -msgstr "" +msgstr "Ühenda kõik lahti" #: editor/connections_dialog.cpp msgid "Edit..." msgstr "Muuda..." #: editor/connections_dialog.cpp -#, fuzzy msgid "Go to Method" -msgstr "Mine järmisesse kausta." +msgstr "Mine meetodi juurde" #: editor/create_dialog.cpp msgid "Change %s Type" -msgstr "" +msgstr "Muuda %s tüüpi" #: editor/create_dialog.cpp editor/project_settings_editor.cpp msgid "Change" @@ -2135,15 +2071,15 @@ msgstr "Muuda" #: editor/create_dialog.cpp msgid "Create New %s" -msgstr "" +msgstr "Loo uus %s" #: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "No results for \"%s\"." -msgstr "" +msgstr "Päringule \"%s\" pole tulemusi." #: editor/create_dialog.cpp editor/property_selector.cpp msgid "No description available for %s." -msgstr "" +msgstr "%s jaoks kirjeldus puudub." #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -2177,23 +2113,27 @@ msgstr "Kirjeldus:" #: editor/dependency_editor.cpp msgid "Search Replacement For:" -msgstr "" +msgstr "Otsi asendust järgnevale:" #: editor/dependency_editor.cpp msgid "Dependencies For:" -msgstr "" +msgstr "Sõltuvused järgneva jaoks:" #: editor/dependency_editor.cpp msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" +"Stseeni '%s' redigeeritakse praegu.\n" +"Muudatused jõustuvad ainult uuesti laadimisel." #: editor/dependency_editor.cpp msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" +"Ressurss '%s' on kasutusel.\n" +"Muudatused jõustuvad ainult uuesti laadimisel." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -2206,15 +2146,15 @@ msgstr "Sõltuvused:" #: editor/dependency_editor.cpp msgid "Fix Broken" -msgstr "" +msgstr "Paranda katkised" #: editor/dependency_editor.cpp msgid "Dependency Editor" -msgstr "" +msgstr "Sõltuvuste toimeti" #: editor/dependency_editor.cpp msgid "Search Replacement Resource:" -msgstr "" +msgstr "Otsi asendusressurssi:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp @@ -2228,7 +2168,7 @@ msgstr "Ava" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Omanikud: %s (Kokku: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2236,6 +2176,9 @@ msgid "" "Depending on your filesystem configuration, the files will either be moved " "to the system trash or deleted permanently." msgstr "" +"Kas eemaldada valitud failid projektist? (Ei saa tagasi võtta.)\n" +"Sõltuvalt teie failisüsteemi konfiguratsioonist teisaldatakse failid " +"süsteemi prügikasti või kustutatakse jäädavalt." #: editor/dependency_editor.cpp msgid "" @@ -2245,46 +2188,50 @@ msgid "" "Depending on your filesystem configuration, the files will either be moved " "to the system trash or deleted permanently." msgstr "" +"Eemaldatavaid faile vajavad toimimiseks muud ressursid.\n" +"Eemaldage need ikkagi? (Ei saa tagasi võtta.)\n" +"Sõltuvalt teie failisüsteemi konfiguratsioonist teisaldatakse failid " +"süsteemi prügikasti või kustutatakse jäädavalt." #: editor/dependency_editor.cpp msgid "Cannot remove:" -msgstr "" +msgstr "Ei saa eemaldada:" #: editor/dependency_editor.cpp msgid "Error loading:" -msgstr "" +msgstr "Viga laadimisel:" #: editor/dependency_editor.cpp msgid "Load failed due to missing dependencies:" -msgstr "" +msgstr "Laadimine ebaõnnestus puuduvate sõltuvuste tõttu:" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Open Anyway" -msgstr "" +msgstr "Ava ikkagi" #: editor/dependency_editor.cpp msgid "Which action should be taken?" -msgstr "" +msgstr "Mida tuleks teha?" #: editor/dependency_editor.cpp msgid "Fix Dependencies" -msgstr "" +msgstr "Paranda sõltuvused" #: editor/dependency_editor.cpp msgid "Errors loading!" -msgstr "" +msgstr "Laadimisel ilmnesid vead!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" -msgstr "" +msgstr "Kas kustutada jäädavalt %d üksus(t)? (Ei saa tagasi võtta!)" #: editor/dependency_editor.cpp msgid "Show Dependencies" -msgstr "" +msgstr "Näita sõltuvusi" #: editor/dependency_editor.cpp msgid "Orphan Resource Explorer" -msgstr "" +msgstr "Orbressursside haldur" #: editor/dependency_editor.cpp editor/editor_audio_buses.cpp #: editor/editor_file_dialog.cpp editor/editor_node.cpp @@ -2296,19 +2243,19 @@ msgstr "Kustuta" #: editor/dependency_editor.cpp msgid "Owns" -msgstr "" +msgstr "Omab" #: editor/dependency_editor.cpp msgid "Resources Without Explicit Ownership:" -msgstr "" +msgstr "Ressursid ilma selge omandiõiguseta:" #: editor/dictionary_property_edit.cpp msgid "Change Dictionary Key" -msgstr "" +msgstr "Muuda sõnastiku võtit" #: editor/dictionary_property_edit.cpp msgid "Change Dictionary Value" -msgstr "" +msgstr "Muuda sõnastiku väärtust" #: editor/editor_about.cpp msgid "Thanks from the Godot community!" @@ -2332,10 +2279,9 @@ msgstr "Juhtiv arendaja" #. TRANSLATORS: This refers to a job title. #: editor/editor_about.cpp -#, fuzzy msgctxt "Job Title" msgid "Project Manager" -msgstr "projektihaldur" +msgstr "Projekti juht" #: editor/editor_about.cpp msgid "Developers" @@ -2415,35 +2361,35 @@ msgstr "Litsensid" #: editor/editor_asset_installer.cpp msgid "Error opening asset file for \"%s\" (not in ZIP format)." -msgstr "" +msgstr "Viga varade faili \"%s\" avamisel (pole ZIP-formaadis)." #: editor/editor_asset_installer.cpp msgid "%s (already exists)" -msgstr "" +msgstr "%s (juba olemas)" #: editor/editor_asset_installer.cpp msgid "Contents of asset \"%s\" - %d file(s) conflict with your project:" -msgstr "" +msgstr "Vara \"%s\" - %d faili(de) sisu on vastuolus teie projektiga:" #: editor/editor_asset_installer.cpp msgid "Contents of asset \"%s\" - No files conflict with your project:" -msgstr "" +msgstr "Vara \"%s\" sisu - ükski fail ei ole teie projektiga vastuolus:" #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" -msgstr "" +msgstr "Varade lahtipakkimine" #: editor/editor_asset_installer.cpp msgid "The following files failed extraction from asset \"%s\":" -msgstr "" +msgstr "Järgmised failid ebaõnnestusid varast \"%s\" väljavõtmisel:" #: editor/editor_asset_installer.cpp msgid "(and %s more files)" -msgstr "" +msgstr "(ja veel %s faili)" #: editor/editor_asset_installer.cpp msgid "Asset \"%s\" installed successfully!" -msgstr "" +msgstr "Vara \"%s\" paigaldatud edukalt!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -2455,9 +2401,8 @@ msgid "Install" msgstr "Paigalda" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Asset Installer" -msgstr "Paigalda" +msgstr "Varade paigaldaja" #: editor/editor_audio_buses.cpp msgid "Speakers" @@ -2469,19 +2414,19 @@ msgstr "Lisa efekt" #: editor/editor_audio_buses.cpp msgid "Rename Audio Bus" -msgstr "" +msgstr "Nimeta ümber audiosiin" #: editor/editor_audio_buses.cpp msgid "Change Audio Bus Volume" -msgstr "" +msgstr "Muuda audiosiini helitugevust" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" -msgstr "" +msgstr "Lülita audiosiini soolo sisse/välja" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Mute" -msgstr "" +msgstr "Lülita helisiini vaigistamine sisse/välja" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" @@ -2505,7 +2450,7 @@ msgstr "" #: editor/editor_audio_buses.cpp msgid "Drag & drop to rearrange." -msgstr "" +msgstr "Ümberkorraldamiseks lohistage." #: editor/editor_audio_buses.cpp msgid "Solo" @@ -2520,9 +2465,8 @@ msgid "Bypass" msgstr "Jäta vahele" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Bus Options" -msgstr "Klassi valikud" +msgstr "Siinivalikud" #: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp #: editor/project_export.cpp editor/scene_tree_dock.cpp @@ -2535,23 +2479,23 @@ msgstr "Lähtesta valjus" #: editor/editor_audio_buses.cpp msgid "Delete Effect" -msgstr "" +msgstr "Kustuta efekt" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" -msgstr "" +msgstr "Lisa audiosiin" #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" -msgstr "" +msgstr "Põhisiini ei saa kustutada!" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" -msgstr "" +msgstr "Kustuta audiosiin" #: editor/editor_audio_buses.cpp msgid "Duplicate Audio Bus" -msgstr "" +msgstr "Duplikeeri audiosiin" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" @@ -2559,15 +2503,15 @@ msgstr "Lähtesta siini valjus" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" -msgstr "" +msgstr "Liiguta audiosiin" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As..." -msgstr "" +msgstr "Salvesta audiosiini paigutus kui..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout..." -msgstr "" +msgstr "Uue paigutuse asukoht..." #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" @@ -2578,9 +2522,8 @@ msgid "There is no '%s' file." msgstr "Faili '%s' ei ole eksisteeri." #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Layout:" -msgstr "Paigutus" +msgstr "Paigutus:" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -2629,9 +2572,8 @@ msgid "Create a new Bus Layout." msgstr "Loo uus siini paigutus." #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Audio Bus Layout" -msgstr "Ava heliliinide paigutus" +msgstr "Audiosiini paigutus" #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -2639,7 +2581,7 @@ msgstr "Vigane nimi." #: editor/editor_autoload_settings.cpp msgid "Cannot begin with a digit." -msgstr "" +msgstr "Ei saa alata numbriga." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -2651,11 +2593,11 @@ msgstr "Ei tohi kokkupõrkuda mängumootori juba olemasoleva klassi nimega." #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing built-in type name." -msgstr "" +msgstr "Ei tohi põrkuda olemasoleva sisse-ehitatud tüübinimega." #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing global constant name." -msgstr "" +msgstr "Ei tohi põrkuda olemasoleva globaalse konstandi nimega." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." @@ -2663,11 +2605,11 @@ msgstr "Võtmesõnu ei saa kasutada automaatsete nimedena." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "" +msgstr "Automaatlaadimine '%s' on juba olemas!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" -msgstr "" +msgstr "Nimeta automaatlaadimine ümber" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" @@ -2675,11 +2617,11 @@ msgstr "" #: editor/editor_autoload_settings.cpp msgid "Move Autoload" -msgstr "" +msgstr "Liiguta automaatlaadimist" #: editor/editor_autoload_settings.cpp msgid "Remove Autoload" -msgstr "" +msgstr "Eemalda automaatlaadimine" #: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp #: modules/gdscript/gdscript.cpp platform/android/export/export_plugin.cpp @@ -2692,31 +2634,30 @@ msgstr "Luba" #: editor/editor_autoload_settings.cpp msgid "Rearrange Autoloads" -msgstr "" +msgstr "Paiguta automaatlaadimised ümber" #: editor/editor_autoload_settings.cpp msgid "Can't add autoload:" -msgstr "" +msgstr "Ei saa lisada automaatlaadimist:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "%s is an invalid path. File does not exist." -msgstr "Faili ei ole olemas." +msgstr "%s on kehtetu failitee. Faili pole olemas." #: editor/editor_autoload_settings.cpp msgid "%s is an invalid path. Not in resource path (res://)." -msgstr "" +msgstr "%s on kehtetu failitee. Ei ole ressursiteel (res://)." #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" -msgstr "" +msgstr "Lisa automaatlaadimine" #: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp msgid "Path:" -msgstr "Tee:" +msgstr "Failitee:" #: editor/editor_autoload_settings.cpp msgid "Node Name:" @@ -2724,7 +2665,7 @@ msgstr "Sõlme nimi:" #: editor/editor_autoload_settings.cpp msgid "Global Variable" -msgstr "" +msgstr "Globaalne muutuja" #: editor/editor_data.cpp msgid "Paste Params" @@ -2732,11 +2673,11 @@ msgstr "Kleebi parameetrid" #: editor/editor_data.cpp msgid "Updating Scene" -msgstr "Värskendan stseeni" +msgstr "Stseeni värskendamine" #: editor/editor_data.cpp msgid "Storing local changes..." -msgstr "Salvestan kohalikud muudatused..." +msgstr "Kohalike muudatuste salvestamine..." #: editor/editor_data.cpp msgid "Updating scene..." @@ -2754,11 +2695,11 @@ msgstr "[salvestamata]" #: editor/editor_dir_dialog.cpp msgid "Please select a base directory first." -msgstr "Palun valige kõigepealt baaskataloog." +msgstr "Palun valige kõigepealt baaskaust." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" -msgstr "Vali kataloog" +msgstr "Valige kaust" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp @@ -2785,20 +2726,19 @@ msgstr "Vali" #: editor/editor_export.cpp msgid "Project export for platform:" -msgstr "" +msgstr "Projekti eksportimine platvormi jaoks:" #: editor/editor_export.cpp -#, fuzzy msgid "Completed with warnings." -msgstr "Kopeeri sõlme tee" +msgstr "Lõpetas koos hoiatustega." #: editor/editor_export.cpp msgid "Completed successfully." -msgstr "" +msgstr "Lõpetas edukalt." #: editor/editor_export.cpp msgid "Failed." -msgstr "" +msgstr "Ebaõnnestus." #: editor/editor_export.cpp msgid "Storing File:" @@ -2813,29 +2753,24 @@ msgid "Packing" msgstr "Pakin" #: editor/editor_export.cpp -#, fuzzy msgid "Save PCK" -msgstr "Salvesta kui" +msgstr "Salvesta PCK" #: editor/editor_export.cpp -#, fuzzy msgid "Cannot create file \"%s\"." -msgstr "Ei saanud luua kausta." +msgstr "Ei saa luua faili \"%s\"." #: editor/editor_export.cpp -#, fuzzy msgid "Failed to export project files." -msgstr "Ei saanud luua kausta." +msgstr "Projektifailide eksportimine ebaõnnestus." #: editor/editor_export.cpp -#, fuzzy msgid "Can't open file to read from path \"%s\"." -msgstr "Faili ei saa kirjutamiseks avada:" +msgstr "Faili ei saa avada lugemiseks teelt \"%s\"." #: editor/editor_export.cpp -#, fuzzy msgid "Save ZIP" -msgstr "Salvesta kui" +msgstr "Salvesta ZIP" #: editor/editor_export.cpp msgid "" @@ -2865,22 +2800,20 @@ msgstr "" "tagasilangemine lubatud”." #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'PVRTC' texture compression for GLES2. Enable " "'Import Pvrtc' in Project Settings." msgstr "" -"Sihtplatvorm nõuab GLES2 jaoks 'ETC' tekstuuri tihendamist. Projekti " -"seadetes lubage „Impordi ETC”." +"Sihtplatvorm nõuab GLES2 jaoks 'PVRTC' tekstuuri tihendamist. Projekti " +"seadetes lubage „Impordi PVRTC”." #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" -"Sihtplatvorm nõuab GLES3 jaoks 'ETC2' tekstuuri tihendamist. Projekti " -"seadetes lubage „Impordi ETC2”." +"Sihtplatvorm nõuab GLES3 jaoks \"ETC2\" või \"PVRTC\" tekstuuri tihendamist. " +"Lubage projekti seadetes \"Impordi Etc 2\" või \"Impordi Pvrtc\"." #: editor/editor_export.cpp #, fuzzy @@ -2890,103 +2823,100 @@ msgid "" "Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" -"Sihtplatvorm nõuab juhi varundamiseks GLES2-ga 'ETC' tekstuuri tihendamist.\n" -"Lülitage projekti sätetes sisse „Impordi ETC” või keelake „Draiveri " -"tagasilangemine lubatud”." +"Sihtplatvorm nõuab 'PVRTC' tekstuuride tihendamist, et draiver saaks tagasi " +"pöörduda GLES2-le.\n" +"Lülitage projekti seadetes sisse 'Import Pvrtc' või lülitage välja 'Driver " +"Fallback Enabled'." #: editor/editor_export.cpp platform/android/export/export_plugin.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Custom Template" -msgstr "Redaktor" +msgstr "Kohandatud mall" #: editor/editor_export.cpp editor/project_export.cpp #: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #: platform/uwp/export/export.cpp msgid "Release" -msgstr "" +msgstr "Avalda" #: editor/editor_export.cpp -#, fuzzy msgid "Binary Format" -msgstr "Formaat" +msgstr "Binaarne formaat" #: editor/editor_export.cpp msgid "64 Bits" -msgstr "" +msgstr "64 bitti" #: editor/editor_export.cpp msgid "Embed PCK" -msgstr "" +msgstr "Manusta PCK" #: editor/editor_export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Texture Format" -msgstr "Pööramisrežiim" +msgstr "Tekstuuriformaat" #: editor/editor_export.cpp msgid "BPTC" -msgstr "" +msgstr "BPTC" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "S3TC" -msgstr "" +msgstr "S3TC" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "ETC" -msgstr "" +msgstr "ETC" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "ETC2" -msgstr "" +msgstr "ETC2" #: editor/editor_export.cpp msgid "No BPTC Fallbacks" -msgstr "" +msgstr "Puuduvad BPTC varuvariandid" #: editor/editor_export.cpp platform/android/export/export_plugin.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom debug template not found." -msgstr "" +msgstr "Kohandatud silumismalli ei leitud." #: editor/editor_export.cpp platform/android/export/export_plugin.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom release template not found." -msgstr "" +msgstr "Kohandatud väljalaskemalli ei leitud." #: editor/editor_export.cpp msgid "Prepare Template" -msgstr "" +msgstr "Malli ettevalmistamine" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "The given export path doesn't exist." -msgstr "" +msgstr "Antud eksporditee ei ole olemas." #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found: \"%s\"." -msgstr "Mallifaili ei leitud:" +msgstr "Mallifaili ei leitud: \"%s\"." #: editor/editor_export.cpp msgid "Failed to copy export template." -msgstr "" +msgstr "Eksportmalli kopeerimine ebaõnnestus." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp msgid "PCK Embedding" -msgstr "" +msgstr "PCK manustamine" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." -msgstr "" +msgstr "32-bitise ekspordi puhul ei saa manustatud PCK olla suurem kui 4 GiB." #: editor/editor_export.cpp msgid "Convert Text Resources To Binary On Export" -msgstr "" +msgstr "Teisenda tekstiressursid eksportimisel binaarseks" #: editor/editor_feature_profile.cpp msgid "3D Editor" @@ -3007,20 +2937,19 @@ msgstr "Stseenipuu redigeerimine" #: editor/editor_feature_profile.cpp msgid "Node Dock" -msgstr "" +msgstr "Node'i dokk" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "FileSystem Dock" -msgstr "Failikuvaja" +msgstr "Failisüsteemi dokk" #: editor/editor_feature_profile.cpp msgid "Import Dock" -msgstr "" +msgstr "Impordi dokk" #: editor/editor_feature_profile.cpp msgid "Allows to view and edit 3D scenes." -msgstr "" +msgstr "Võimaldab vaadata ja redigeerida 3D stseene." #: editor/editor_feature_profile.cpp msgid "Allows to edit scripts using the integrated script editor." @@ -3439,7 +3368,7 @@ msgstr "Klass:" #: editor/editor_help.cpp editor/scene_tree_editor.cpp #: editor/script_create_dialog.cpp msgid "Inherits:" -msgstr "Pärib:" +msgstr "Pärandub:" #: editor/editor_help.cpp msgid "Inherited by:" @@ -3491,7 +3420,7 @@ msgstr "" #: editor/editor_help.cpp msgid "Enumerations" -msgstr "Loetelu" +msgstr "Loendused" #: editor/editor_help.cpp msgid "Property Descriptions" @@ -3509,7 +3438,7 @@ msgstr "" #: editor/editor_help.cpp msgid "Method Descriptions" -msgstr "Meetodi kirjeldused" +msgstr "Meetodite kirjeldused" #: editor/editor_help.cpp msgid "" @@ -10191,7 +10120,7 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp modules/csg/csg_shape.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Snap" -msgstr "" +msgstr "Naksamine" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" @@ -14700,7 +14629,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Input Map" -msgstr "" +msgstr "Sisendikaart" #: editor/project_settings_editor.cpp msgid "Action:" @@ -14720,7 +14649,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Localization" -msgstr "Tõlked" +msgstr "Lokaliseerimine" #: editor/project_settings_editor.cpp msgid "Translations" @@ -15448,7 +15377,7 @@ msgstr "" #: editor/script_create_dialog.cpp msgid "File does not exist." -msgstr "Faili ei ole olemas." +msgstr "Faili pole olemas." #: editor/script_create_dialog.cpp msgid "Invalid extension." @@ -15492,7 +15421,7 @@ msgstr "" #: editor/script_create_dialog.cpp msgid "Invalid path." -msgstr "Kehtetu tee." +msgstr "Kehtetu failitee." #: editor/script_create_dialog.cpp msgid "Invalid class name." @@ -24597,9 +24526,8 @@ msgid "Draw 2D Outlines" msgstr "" #: scene/main/scene_tree.cpp servers/visual_server.cpp -#, fuzzy msgid "Reflections" -msgstr "Kopeeri valik" +msgstr "Peegeldused" #: scene/main/scene_tree.cpp msgid "Atlas Size" diff --git a/editor/translations/extract.py b/editor/translations/extract.py index 07026baee2..04661abcbd 100755 --- a/editor/translations/extract.py +++ b/editor/translations/extract.py @@ -8,6 +8,7 @@ import re import shutil import subprocess import sys +from typing import Dict, Tuple class Message: @@ -42,7 +43,7 @@ class Message: return "\n".join(lines) -messages_map = {} # (id, context) -> Message. +messages_map: Dict[Tuple[str, str], Message] = {} # (id, context) -> Message. line_nb = False @@ -51,11 +52,11 @@ for arg in sys.argv[1:]: print("Enabling line numbers in the context locations.") line_nb = True else: - os.sys.exit("Non supported argument '" + arg + "'. Aborting.") + sys.exit("Non supported argument '" + arg + "'. Aborting.") if not os.path.exists("editor"): - os.sys.exit("ERROR: This script should be started from the root of the git repo.") + sys.exit("ERROR: This script should be started from the root of the git repo.") matches = [] @@ -70,11 +71,24 @@ matches.sort() remaps = {} remap_re = re.compile(r'^\t*capitalize_string_remaps\["(?P<from>.+)"\] = (String::utf8\()?"(?P<to>.+)"') +stop_words = set() +stop_words_re = re.compile(r'^\t*"(?P<word>.+)",') +is_inside_stop_words = False with open("editor/editor_property_name_processor.cpp") as f: for line in f: - m = remap_re.search(line) - if m: - remaps[m.group("from")] = m.group("to") + if is_inside_stop_words: + m = stop_words_re.search(line) + if m: + stop_words.add(m.group("word")) + else: + is_inside_stop_words = False + else: + m = remap_re.search(line) + if m: + remaps[m.group("from")] = m.group("to") + + if not is_inside_stop_words and not stop_words: + is_inside_stop_words = "stop_words = " in line main_po = """ @@ -146,9 +160,12 @@ capitalize_re = re.compile(r"(?<=\D)(?=\d)|(?<=\d)(?=\D([a-z]|\d))") def _process_editor_string(name): # See EditorPropertyNameProcessor::process_string(). capitalized_parts = [] - for segment in name.split("_"): - if not segment: + parts = list(filter(bool, name.split("_"))) # Non-empty only. + for i, segment in enumerate(parts): + if i > 0 and i + 1 < len(parts) and segment in stop_words: + capitalized_parts.append(segment) continue + remapped = remaps.get(segment) if remapped: capitalized_parts.append(remapped) diff --git a/editor/translations/fa.po b/editor/translations/fa.po index 186ab7264e..28371fdd50 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -31,13 +31,14 @@ # LordProfo (Nima) <nimaentity30@gmail.com>, 2022. # John Smith <pkafsharix@gmail.com>, 2022. # Ali Jafari <ali.jafari.sn@gmail.com>, 2022. +# Ali Almasi <A710almasi@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-09-09 12:36+0000\n" -"Last-Translator: LordProfo (Nima) <nimaentity30@gmail.com>\n" +"PO-Revision-Date: 2022-09-19 05:22+0000\n" +"Last-Translator: Ali Jafari <ali.jafari.sn@gmail.com>\n" "Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/" "godot/fa/>\n" "Language: fa\n" @@ -45,7 +46,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -246,7 +247,7 @@ msgstr "اندازهٔ صفحه" #: core/io/file_access_network.cpp msgid "Page Read Ahead" -msgstr "" +msgstr "صفحه پیشرو را بخوانید" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" @@ -257,9 +258,8 @@ msgid "Connection" msgstr "اتصال" #: core/io/http_client.cpp -#, fuzzy msgid "Read Chunk Size" -msgstr "خواندن اندازه تکه" +msgstr "اندازه تکه خواندن" #: core/io/marshalls.cpp msgid "Object ID" @@ -524,7 +524,7 @@ msgstr "پیام" #: core/os/input_event.cpp msgid "Pitch" -msgstr "" +msgstr "پیچ" #: core/os/input_event.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/physics_body_2d.cpp scene/3d/cpu_particles.cpp @@ -591,14 +591,12 @@ msgid "Main Scene" msgstr "صحنهٔ اصلی" #: core/project_settings.cpp -#, fuzzy msgid "Disable stdout" -msgstr "غیرفعال شده" +msgstr "stdout غیرفعال شده" #: core/project_settings.cpp -#, fuzzy msgid "Disable stderr" -msgstr "غیرفعال شده" +msgstr "stderr غیرفعال شده" #: core/project_settings.cpp msgid "Use Hidden Project Data Directory" @@ -827,9 +825,8 @@ msgid "Profiler" msgstr "پروفایلر" #: core/project_settings.cpp -#, fuzzy msgid "Max Functions" -msgstr "تغییر نام نقش" +msgstr "تغییر نام توابع" #: core/project_settings.cpp scene/3d/vehicle_body.cpp msgid "Compression" @@ -841,7 +838,7 @@ msgstr "فرمتها" #: core/project_settings.cpp msgid "Zstd" -msgstr "" +msgstr "Zstd" #: core/project_settings.cpp msgid "Long Distance Matching" @@ -853,15 +850,15 @@ msgstr "سطح فشردهسازی" #: core/project_settings.cpp msgid "Window Log Size" -msgstr "" +msgstr "اندازهٔ پنجرهٔ ‹گزارش" #: core/project_settings.cpp msgid "Zlib" -msgstr "" +msgstr "Zlib" #: core/project_settings.cpp msgid "Gzip" -msgstr "" +msgstr "Gzip" #: core/project_settings.cpp platform/android/export/export.cpp msgid "Android" @@ -873,7 +870,7 @@ msgstr "ماژولها" #: core/register_core_types.cpp msgid "TCP" -msgstr "تیسیپی" +msgstr "TCP" #: core/register_core_types.cpp msgid "Connect Timeout Seconds" @@ -892,9 +889,8 @@ msgid "SSL" msgstr "SSL" #: core/register_core_types.cpp main/main.cpp -#, fuzzy msgid "Certificates" -msgstr "خصوصیات" +msgstr "مدارک" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_resource_picker.cpp @@ -968,15 +964,13 @@ msgstr "بافرها" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Canvas Polygon Buffer Size (KB)" -msgstr "اندازه بافر پرده چندضعلی (کیلوبایت)" +msgstr "اندازه بافر پرده چندضلعی (کیلوبایت)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Canvas Polygon Index Buffer Size (KB)" -msgstr "اندازه بافر شاخص پرده چندضعلی (کیلوبایت)" +msgstr "اندازه بافر شاخص پرده چندضلعی (کیلوبایت)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp @@ -992,9 +986,8 @@ msgstr "دو بعدی" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Snapping" -msgstr "چفت:" +msgstr "چفت" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -1188,9 +1181,8 @@ msgid "Type" msgstr "تایپ" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "دسته داخل" +msgstr "در دسته" #: editor/animation_track_editor.cpp msgid "Out Handle" @@ -1603,9 +1595,8 @@ msgid "Add Method Track Key" msgstr "افزودن تابع کلید میسر" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Method not found in object:" -msgstr "تابع در شئ یافت نشد: " +msgstr "تابع در آبجکت یافت نشد:" #: editor/animation_track_editor.cpp msgid "Anim Move Keys" @@ -1621,7 +1612,7 @@ msgstr "تبدیل" #: editor/animation_track_editor.cpp editor/editor_help.cpp msgid "Methods" -msgstr "روش ها" +msgstr "روشها" #: editor/animation_track_editor.cpp msgid "Bezier" @@ -2883,9 +2874,8 @@ msgstr "" #: editor/editor_export.cpp platform/android/export/export_plugin.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Custom Template" -msgstr "عضوها" +msgstr "قالب شخصی" #: editor/editor_export.cpp editor/project_export.cpp #: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp @@ -2895,9 +2885,8 @@ msgid "Release" msgstr "انتشار" #: editor/editor_export.cpp -#, fuzzy msgid "Binary Format" -msgstr "انتقال را در انیمیشن تغییر بده" +msgstr "باینری فرمت" #: editor/editor_export.cpp msgid "64 Bits" @@ -2950,19 +2939,16 @@ msgid "Prepare Template" msgstr "مدیریت صدور قالب ها" #: editor/editor_export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "The given export path doesn't exist." -msgstr "پرونده موجود نیست." +msgstr "مسیر خروجی وجود ندارد." #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found: \"%s\"." -msgstr "طول انیمیشن (به ثانیه)." +msgstr "فایل قالب پیدا نشد: \"%s\"" #: editor/editor_export.cpp -#, fuzzy msgid "Failed to copy export template." -msgstr "نام دارایی ایندکس نامعتبر." +msgstr "خطا در کپی قالب خروجی." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp @@ -3000,9 +2986,8 @@ msgid "Node Dock" msgstr "لنگرگاه گره:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "FileSystem Dock" -msgstr "سامانه پرونده" +msgstr "قایلسیستم داک" #: editor/editor_feature_profile.cpp msgid "Import Dock" @@ -3190,7 +3175,6 @@ msgid "Select Current Folder" msgstr "برگزیدن پوشه موجود" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "File exists, overwrite?" msgstr "فایل وجود دارد، آیا بازنویسی شود؟" @@ -3278,9 +3262,8 @@ msgid "Mode" msgstr "حالت" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Current Dir" -msgstr "دایرکتوری کنونی" +msgstr "مسیر کنونی" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Current File" @@ -3399,9 +3382,8 @@ msgid "(Re)Importing Assets" msgstr "(در حال) وارد کردن دوباره عست ها" #: editor/editor_file_system.cpp -#, fuzzy msgid "Reimport Missing Imported Files" -msgstr "وارد کردن دوباره فایل های وارد شده ناپیدا" +msgstr "وارد کردن دوباره فایل های وارد شده پیدانشده" #: editor/editor_help.cpp scene/2d/camera_2d.cpp scene/gui/control.cpp #: scene/gui/nine_patch_rect.cpp scene/resources/dynamic_font.cpp @@ -3450,7 +3432,7 @@ msgstr "رنگها" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp msgid "Constants" -msgstr "ثابت ها" +msgstr "ثابتها" #: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp msgid "Fonts" @@ -3467,7 +3449,7 @@ msgstr "استایلها" #: editor/editor_help.cpp msgid "Enumerations" -msgstr "شمارش ها" +msgstr "شمارشها" #: editor/editor_help.cpp msgid "Property Descriptions" @@ -3478,10 +3460,12 @@ msgid "(value)" msgstr "(مقدار)" #: editor/editor_help.cpp +#, fuzzy msgid "" "There is currently no description for this property. Please help us by " "[color=$color][url=$url]contributing one[/url][/color]!" msgstr "" +"این ویژگی هیچ تعریفی ندارد. لطفا به ما کمک کنید با [color=$color][url=$url]" #: editor/editor_help.cpp msgid "Method Descriptions" @@ -3492,6 +3476,8 @@ msgid "" "There is currently no description for this method. Please help us by " "[color=$color][url=$url]contributing one[/url][/color]!" msgstr "" +"در حال حاضر هیچ توضیحی برای این متد وجود ندارد. لطفاً به ما در [color=$color]" +"[url=$url]مشارکت در یکی[/url][/color] کمک کنید!" #: editor/editor_help.cpp editor/editor_settings.cpp #: editor/plugins/script_editor_plugin.cpp @@ -3764,6 +3750,8 @@ msgid "" "This resource can't be saved because it does not belong to the edited scene. " "Make it unique first." msgstr "" +"این منبع نمیتواند ذخیره شود زیرا به صحنهٔ ویرایش شده تعلق ندارد. ابتدا آن را " +"منحصر به فرد کنید." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." @@ -3795,7 +3783,7 @@ msgstr "پایان غیر منتظرهٔ فایل '%s'." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." -msgstr "" +msgstr "'%s' ناموجود یا وابستگیهای مربوط به آن وجود ندارد." #: editor/editor_node.cpp msgid "Error while loading '%s'." @@ -3852,11 +3840,11 @@ msgstr "خطا در ذخیره MeshLibrary!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" -msgstr "" +msgstr "نمیتوان TileSet را برای ادغام بارگیری کرد!" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "" +msgstr "خطا در ذخیرهٔ TileSet!" #: editor/editor_node.cpp msgid "" @@ -4839,12 +4827,12 @@ msgstr "استخراج پرونده های زیر از بسته بندی انج #: editor/plugins/shader_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Reload" -msgstr "" +msgstr "بارگذاری دوباره" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Resave" -msgstr "" +msgstr "ذخیره مجدد" #: editor/editor_node.cpp msgid "New Inherited" @@ -4890,7 +4878,7 @@ msgstr "" #: editor/editor_node.h msgid "Warning!" -msgstr "" +msgstr "هشدار!" #: editor/editor_path.cpp #, fuzzy @@ -4949,7 +4937,7 @@ msgstr "وضعیت:" #: editor/editor_profiler.cpp msgid "Measure:" -msgstr "" +msgstr "اندازه گیری:" #: editor/editor_profiler.cpp #, fuzzy @@ -4958,7 +4946,7 @@ msgstr "زمان(s): " #: editor/editor_profiler.cpp msgid "Average Time (ms)" -msgstr "" +msgstr "زمان متوسط (میلیثانیه)" #: editor/editor_profiler.cpp msgid "Frame %" @@ -4974,7 +4962,7 @@ msgstr "" #: editor/editor_profiler.cpp msgid "Self" -msgstr "" +msgstr "خود" #: editor/editor_profiler.cpp msgid "" @@ -4998,7 +4986,7 @@ msgstr "فراخوانی" #: editor/editor_profiler.cpp editor/plugins/script_editor_plugin.cpp #: editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "" +msgstr "دیباگِر" #: editor/editor_profiler.cpp msgid "Profiler Frame History Size" @@ -5017,7 +5005,7 @@ msgstr "عضوها" #: editor/editor_properties.cpp editor/script_create_dialog.cpp #: scene/resources/default_theme/default_theme.cpp msgid "On" -msgstr "" +msgstr "روشن" #: editor/editor_properties.cpp modules/gridmap/grid_map.cpp #: scene/2d/collision_object_2d.cpp scene/2d/tile_map.cpp @@ -5032,7 +5020,7 @@ msgstr "" #: editor/editor_properties.cpp msgid "[Empty]" -msgstr "" +msgstr "[خالی]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp msgid "Assign..." @@ -5069,7 +5057,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Size:" -msgstr "" +msgstr "اندازه:" #: editor/editor_properties_array_dict.cpp msgid "Page:" @@ -5272,8 +5260,9 @@ msgstr "" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp #: scene/register_scene_types.cpp +#, fuzzy msgid "Theme" -msgstr "" +msgstr "تم" #: editor/editor_settings.cpp editor/import_dock.cpp #, fuzzy @@ -5294,7 +5283,7 @@ msgstr "" #: editor/editor_settings.cpp scene/resources/environment.cpp msgid "Contrast" -msgstr "" +msgstr "تضاد" #: editor/editor_settings.cpp msgid "Relationship Line Opacity" @@ -5366,7 +5355,7 @@ msgstr "" #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "داکها" #: editor/editor_settings.cpp #, fuzzy @@ -5490,7 +5479,7 @@ msgstr "" #: editor/editor_settings.cpp msgid "Appearance" -msgstr "" +msgstr "ظاهر" #: editor/editor_settings.cpp scene/gui/text_edit.cpp #, fuzzy @@ -5578,8 +5567,9 @@ msgid "Sort Members Outline Alphabetically" msgstr "" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp +#, fuzzy msgid "Cursor" -msgstr "" +msgstr "اشارهگر" #: editor/editor_settings.cpp msgid "Scroll Past End Of File" @@ -5713,7 +5703,7 @@ msgstr "برداشتن نقطه" #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Shape" -msgstr "" +msgstr "شکل" #: editor/editor_settings.cpp msgid "Primary Grid Steps" @@ -5987,8 +5977,9 @@ msgstr "" #: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp #: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp #: scene/gui/control.cpp +#, fuzzy msgid "Rect" -msgstr "" +msgstr "مستطیل" #: editor/editor_settings.cpp #, fuzzy @@ -5997,7 +5988,7 @@ msgstr "برداشتن موج" #: editor/editor_settings.cpp platform/android/export/export_plugin.cpp msgid "Screen" -msgstr "" +msgstr "صفحه" #: editor/editor_settings.cpp #, fuzzy @@ -6035,13 +6026,14 @@ msgstr "" #: editor/editor_settings.cpp msgid "Host" -msgstr "" +msgstr "میزبان" #: editor/editor_settings.cpp editor/fileserver/editor_file_server.cpp #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp #: scene/resources/default_theme/default_theme.cpp +#, fuzzy msgid "Port" -msgstr "" +msgstr "پورت" #. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects. #: editor/editor_settings.cpp @@ -6231,7 +6223,7 @@ msgstr "انتخاب گره (ها) برای وارد شدن" #: editor/editor_sub_scene.cpp editor/project_manager.cpp msgid "Browse" -msgstr "" +msgstr "مرور کردن" #: editor/editor_sub_scene.cpp msgid "Scene Path:" @@ -6409,7 +6401,7 @@ msgstr "" #: editor/export_template_manager.cpp msgid "Importing:" -msgstr "" +msgstr "وارد کردن:" #: editor/export_template_manager.cpp msgid "Remove templates for the version '%s'?" @@ -6447,7 +6439,7 @@ msgstr "" #: editor/export_template_manager.cpp msgid "Uninstall" -msgstr "" +msgstr "حذف نصب" #: editor/export_template_manager.cpp msgid "Uninstall templates for the current version." @@ -6535,7 +6527,7 @@ msgstr "" #: editor/plugins/version_control_editor_plugin.cpp #: platform/uwp/export/export.cpp platform/windows/export/export.cpp msgid "Password" -msgstr "" +msgstr "گذرواژه" #: editor/filesystem_dock.cpp #, fuzzy @@ -6771,7 +6763,7 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Move" -msgstr "" +msgstr "حرکت" #: editor/filesystem_dock.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -6893,7 +6885,7 @@ msgstr "حذف گره(ها)" #: editor/groups_editor.cpp editor/node_dock.cpp msgid "Groups" -msgstr "گروه ها" +msgstr "گروهها" #: editor/groups_editor.cpp msgid "Nodes Not in Group" @@ -6937,7 +6929,7 @@ msgstr "ایجاد پوشه" #: editor/import/resource_importer_bitmask.cpp #: servers/audio/effects/audio_effect_compressor.cpp msgid "Threshold" -msgstr "" +msgstr "آستانه" #: editor/import/resource_importer_csv_translation.cpp #: editor/import/resource_importer_layered_texture.cpp @@ -6973,14 +6965,13 @@ msgstr "" #: editor/import/resource_importer_texture.cpp scene/animation/tween.cpp #: scene/resources/texture.cpp msgid "Repeat" -msgstr "" +msgstr "تکرار" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp #: scene/gui/control.cpp -#, fuzzy msgid "Filter" -msgstr "صافی:" +msgstr "صافی" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp @@ -6996,7 +6987,7 @@ msgstr "" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp msgid "sRGB" -msgstr "" +msgstr "sRGB" #: editor/import/resource_importer_layered_texture.cpp #, fuzzy @@ -7130,7 +7121,7 @@ msgstr "وارد کردن دوباره" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Meshes" -msgstr "" +msgstr "مشها" #: editor/import/resource_importer_scene.cpp #, fuzzy @@ -7147,8 +7138,9 @@ msgid "Lightmap Texel Size" msgstr "" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp +#, fuzzy msgid "Skins" -msgstr "" +msgstr "پوستهها" #: editor/import/resource_importer_scene.cpp #, fuzzy @@ -7229,7 +7221,7 @@ msgstr "" #: editor/import/resource_importer_scene.cpp #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Import Scene" -msgstr "" +msgstr "وارد کردن صحنه" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene..." @@ -7265,7 +7257,7 @@ msgstr "" #: editor/import/resource_importer_scene.cpp msgid "Saving..." -msgstr "" +msgstr "در حال ذخیره..." #: editor/import/resource_importer_texture.cpp msgid "" @@ -7373,7 +7365,7 @@ msgstr "" #: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp msgid "Force" -msgstr "" +msgstr "نیرو" #: editor/import/resource_importer_wav.cpp msgid "8 Bit" @@ -7858,7 +7850,7 @@ msgstr "" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend:" -msgstr "" +msgstr "درآمیختن:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #, fuzzy @@ -8086,7 +8078,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/version_control_editor_plugin.cpp msgid "New" -msgstr "" +msgstr "جدید" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste As Reference" @@ -8132,14 +8124,14 @@ msgstr "چسباندن" #. TRANSLATORS: Opposite of "Past", refers to a direction in animation onion skinning. #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "" +msgstr "آینده" #: editor/plugins/animation_player_editor_plugin.cpp modules/csg/csg_shape.cpp #: scene/3d/collision_polygon.cpp scene/main/scene_tree.cpp #: scene/resources/material.cpp scene/resources/primitive_meshes.cpp #: servers/audio/effects/audio_effect_phaser.cpp msgid "Depth" -msgstr "" +msgstr "عمق" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" @@ -8179,7 +8171,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp msgid "Error!" -msgstr "" +msgstr "خطا!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" @@ -8320,7 +8312,7 @@ msgstr "" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: scene/resources/style_box.cpp scene/resources/visual_shader.cpp msgid "Blend" -msgstr "" +msgstr "درآمیختن" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Auto Restart:" @@ -8336,12 +8328,12 @@ msgstr "" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Start!" -msgstr "" +msgstr "شروع!" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Amount:" -msgstr "" +msgstr "مقدار:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend 0:" @@ -8427,7 +8419,7 @@ msgstr "ویرایش صافی های گره" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Filters..." -msgstr "" +msgstr "فیلترها:" #: editor/plugins/asset_library_editor_plugin.cpp scene/main/http_request.cpp msgid "Use Threads" @@ -8442,8 +8434,9 @@ msgid "View Files" msgstr "نمایش پرونده ها" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Download" -msgstr "" +msgstr "دانلود" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connection error, please try again." @@ -8507,7 +8500,7 @@ msgstr "زمان:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed:" -msgstr "" +msgstr "ناموفق:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." @@ -8515,11 +8508,11 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Expected:" -msgstr "" +msgstr "انتظار میرود:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Got:" -msgstr "" +msgstr "گرفته شد:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed SHA-256 hash check" @@ -8549,8 +8542,9 @@ msgid "Error making request" msgstr "خطای بارگذاری قلم." #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Idle" -msgstr "" +msgstr "بیکار" #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy @@ -8559,7 +8553,7 @@ msgstr "نصب کردن" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Retry" -msgstr "" +msgstr "تلاش دوباره" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download Error" @@ -8646,7 +8640,7 @@ msgstr "وارد کردن" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Plugins..." -msgstr "" +msgstr "افزونهها..." #: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp msgid "Sort:" @@ -8732,7 +8726,7 @@ msgstr "انتخاب پرونده قالب" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp scene/resources/mesh_library.cpp msgid "Preview" -msgstr "" +msgstr "پیش نمایش" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" @@ -8752,7 +8746,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "steps" -msgstr "" +msgstr "گامها" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" @@ -8904,7 +8898,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center" -msgstr "" +msgstr "مرکز" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -9249,11 +9243,11 @@ msgstr "پخش سفارشی صحنه" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "View" -msgstr "" +msgstr "دیدن" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show" -msgstr "" +msgstr "نشان دادن" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show When Snapping" @@ -9261,7 +9255,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Hide" -msgstr "" +msgstr "مخفی کردن" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -9496,7 +9490,7 @@ msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp editor/spatial_editor_gizmos.cpp msgid "Particles" -msgstr "" +msgstr "ذرات" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -9554,7 +9548,7 @@ msgstr "" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 1" -msgstr "تخت 1" +msgstr "تخت ۱" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -9673,7 +9667,7 @@ msgstr "" #: editor/plugins/item_list_editor_plugin.cpp msgid "Items" -msgstr "" +msgstr "موارد" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item List Editor" @@ -9783,7 +9777,7 @@ msgstr "" #: scene/resources/multimesh.cpp scene/resources/primitive_meshes.cpp #: scene/resources/texture.cpp msgid "Mesh" -msgstr "" +msgstr "مِش" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" @@ -9989,15 +9983,15 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "X-Axis" -msgstr "" +msgstr "محور X" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Y-Axis" -msgstr "" +msgstr "محور Y" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Z-Axis" -msgstr "" +msgstr "محور Z" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh Up Axis:" @@ -10090,7 +10084,7 @@ msgstr "" #: editor/plugins/particles_editor_plugin.cpp scene/gui/video_player.cpp msgid "Volume" -msgstr "" +msgstr "حجم" #: editor/plugins/particles_editor_plugin.cpp #, fuzzy @@ -10688,7 +10682,7 @@ msgstr "زبانه قبلی" #: editor/plugins/script_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp msgid "File" -msgstr "پَروَندِه" +msgstr "فایل" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -10767,7 +10761,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp #: editor/script_editor_debugger.cpp msgid "Continue" -msgstr "" +msgstr "ادامه" #: editor/plugins/script_editor_plugin.cpp msgid "Keep Debugger Open" @@ -10822,7 +10816,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "External" -msgstr "" +msgstr "خارجی" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -10937,15 +10931,15 @@ msgstr "" #: scene/3d/label_3d.cpp scene/gui/label.cpp #: scene/resources/primitive_meshes.cpp msgid "Uppercase" -msgstr "" +msgstr "حروف بزرگ" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Lowercase" -msgstr "" +msgstr "حروف کوچک" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Capitalize" -msgstr "" +msgstr "بزرگ کردن حروف" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Syntax Highlighter" @@ -11100,7 +11094,7 @@ msgstr "" #: editor/plugins/shader_editor_plugin.cpp scene/resources/material.cpp msgid "Shader" -msgstr "" +msgstr "شیدر" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "This skeleton has no bones, create some children Bone2D nodes." @@ -11151,7 +11145,7 @@ msgstr "پخش" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" -msgstr "" +msgstr "قائم" #: editor/plugins/spatial_editor_plugin.cpp modules/gltf/gltf_camera.cpp msgid "Perspective" @@ -11209,7 +11203,7 @@ msgstr "" #. TRANSLATORS: This will be appended to the view name when Auto Orthogonal is enabled. #: editor/plugins/spatial_editor_plugin.cpp msgid " [auto]" -msgstr "" +msgstr " [خودکار]" #. TRANSLATORS: This will be appended to the view name when Portal Occulusion is enabled. #: editor/plugins/spatial_editor_plugin.cpp @@ -11713,11 +11707,11 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Pre" -msgstr "" +msgstr "پیش" #: editor/plugins/spatial_editor_plugin.cpp msgid "Post" -msgstr "" +msgstr "پس" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Size" @@ -11911,7 +11905,7 @@ msgstr "حالت صافی:" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" -msgstr "" +msgstr "سرعت:" #: editor/plugins/sprite_frames_editor_plugin.cpp #: modules/gltf/gltf_animation.cpp modules/minimp3/audio_stream_mp3.cpp @@ -11920,7 +11914,7 @@ msgstr "" #: modules/stb_vorbis/resource_importer_ogg_vorbis.cpp scene/2d/path_2d.cpp #: scene/3d/path.cpp scene/resources/animation.cpp scene/resources/material.cpp msgid "Loop" -msgstr "" +msgstr "حلقه" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy @@ -11988,7 +11982,7 @@ msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" -msgstr "" +msgstr "فریم های اسپرایت" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Set Region Rect" @@ -12016,7 +12010,7 @@ msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Step:" -msgstr "قدم:" +msgstr "گام:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "TextureRegion" @@ -13241,8 +13235,9 @@ msgstr "تغییر بده" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/canvas_item.cpp #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/style_box.cpp +#, fuzzy msgid "Modulate" -msgstr "" +msgstr "تعدیل" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13354,11 +13349,11 @@ msgstr "انجمن" #: editor/plugins/version_control_editor_plugin.cpp msgid "Date:" -msgstr "" +msgstr "تاریخ:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Subtitle:" -msgstr "" +msgstr "زیرنویس:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Do you want to remove the %s branch?" @@ -13397,7 +13392,7 @@ msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "SSH Passphrase" -msgstr "" +msgstr "عبارت عبور SSH" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -13500,7 +13495,7 @@ msgstr "" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" -msgstr "" +msgstr "تغییر کرده" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -13519,7 +13514,7 @@ msgstr "تغییر بده" #: editor/plugins/version_control_editor_plugin.cpp msgid "Unmerged" -msgstr "" +msgstr "ترکیب نشده" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -13533,7 +13528,7 @@ msgstr "ویرایش منحنی گره" #: editor/plugins/version_control_editor_plugin.cpp msgid "Unified" -msgstr "" +msgstr "متحد شده" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -13545,8 +13540,9 @@ msgid "Add Output" msgstr "خروجی" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Scalar" -msgstr "" +msgstr "اسکالر" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vector" @@ -14405,9 +14401,8 @@ msgid "Exporting All" msgstr "صدور" #: editor/project_export.cpp -#, fuzzy msgid "Export Path" -msgstr "صدور پروژه" +msgstr "مسیر خروجی" #: editor/project_export.cpp msgid "Presets" @@ -14941,7 +14936,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Key " -msgstr "" +msgstr "کلید " #: editor/project_settings_editor.cpp msgid "Joy Button" @@ -14986,7 +14981,7 @@ msgstr "دستگاه" #: editor/project_settings_editor.cpp msgid " (Physical)" -msgstr "" +msgstr " (فیزیکی)" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "Press a Key..." @@ -15187,8 +15182,9 @@ msgid "Input Map" msgstr "" #: editor/project_settings_editor.cpp +#, fuzzy msgid "Action:" -msgstr "" +msgstr "عمل:" #: editor/project_settings_editor.cpp scene/gui/scroll_container.cpp msgid "Deadzone" @@ -15196,7 +15192,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Device:" -msgstr "" +msgstr "دستگاه:" #: editor/project_settings_editor.cpp msgid "Index:" @@ -15268,7 +15264,7 @@ msgstr "" #: editor/property_editor.cpp msgid "Zero" -msgstr "" +msgstr "صفر" #: editor/property_editor.cpp msgid "Easing In-Out" @@ -15328,11 +15324,11 @@ msgstr "تغییر نام" #: editor/rename_dialog.cpp msgid "Prefix:" -msgstr "" +msgstr "پیشوند:" #: editor/rename_dialog.cpp msgid "Suffix:" -msgstr "" +msgstr "پسوند:" #: editor/rename_dialog.cpp #, fuzzy @@ -15642,9 +15638,8 @@ msgid "Make Local" msgstr "محلی" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name(s)" -msgstr "نام گره:" +msgstr "" #: editor/scene_tree_dock.cpp #, fuzzy @@ -15652,9 +15647,8 @@ msgid "Unique names already used by another node in the scene:" msgstr "نام هماکنون توسط تابع/متغیر/سیگنال استفاده شده است:" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Disable Scene Unique Name(s)" -msgstr "نام گره:" +msgstr "" #: editor/scene_tree_dock.cpp #, fuzzy @@ -16004,7 +15998,7 @@ msgstr "خطای بارگذاری قلم." #: editor/script_create_dialog.cpp msgid "Overrides" -msgstr "" +msgstr "بازنویسی میکند" #: editor/script_create_dialog.cpp msgid "N/A" @@ -16105,11 +16099,11 @@ msgstr "برداشتن" #: editor/script_editor_debugger.cpp msgid "Bytes:" -msgstr "" +msgstr "بایتها:" #: editor/script_editor_debugger.cpp msgid "Warning:" -msgstr "" +msgstr "هشدار:" #: editor/script_editor_debugger.cpp #, fuzzy @@ -16147,7 +16141,7 @@ msgstr "" #: editor/script_editor_debugger.cpp msgid "Errors" -msgstr "" +msgstr "خطاها" #: editor/script_editor_debugger.cpp #, fuzzy @@ -16208,11 +16202,11 @@ msgstr "صدور پروژه" #: editor/script_editor_debugger.cpp msgid "Monitor" -msgstr "" +msgstr "مانیتور" #: editor/script_editor_debugger.cpp msgid "Monitors" -msgstr "" +msgstr "مانیتورها" #: editor/script_editor_debugger.cpp msgid "Pick one or more items from the list to display the graph." @@ -16224,7 +16218,7 @@ msgstr "" #: editor/script_editor_debugger.cpp msgid "Total:" -msgstr "" +msgstr "کل:" #: editor/script_editor_debugger.cpp #, fuzzy @@ -16239,15 +16233,15 @@ msgstr "" #: editor/script_editor_debugger.cpp scene/resources/audio_stream_sample.cpp #: servers/audio/effects/audio_effect_record.cpp msgid "Format" -msgstr "" +msgstr "قالب" #: editor/script_editor_debugger.cpp scene/main/viewport.cpp msgid "Usage" -msgstr "" +msgstr "کاربرد:" #: editor/script_editor_debugger.cpp servers/visual_server.cpp msgid "Misc" -msgstr "" +msgstr "متفرقه" #: editor/script_editor_debugger.cpp msgid "Clicked Control:" @@ -16288,7 +16282,7 @@ msgstr "ویرایشگر ترجیحات" #: editor/settings_config_dialog.cpp msgid "Shortcuts" -msgstr "" +msgstr "میانبرها" #: editor/settings_config_dialog.cpp msgid "Binding" @@ -16310,7 +16304,7 @@ msgstr "" #: platform/osx/export/export.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Camera" -msgstr "" +msgstr "دوربین" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" @@ -16318,7 +16312,7 @@ msgstr "" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera Size" -msgstr "" +msgstr "تغییر اندازه دوربین" #: editor/spatial_editor_gizmos.cpp msgid "Visibility Notifier" @@ -16351,7 +16345,7 @@ msgstr "" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Sphere Shape Radius" -msgstr "" +msgstr "تغییر شعاع شکل کره" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Box Shape Extents" @@ -16359,11 +16353,11 @@ msgstr "" #: editor/spatial_editor_gizmos.cpp msgid "Change Capsule Shape Radius" -msgstr "" +msgstr "تغییر شعاع شکل کپسول" #: editor/spatial_editor_gizmos.cpp msgid "Change Capsule Shape Height" -msgstr "" +msgstr "تغییر ارتفاع شکل کپسول" #: editor/spatial_editor_gizmos.cpp msgid "Change Cylinder Shape Radius" @@ -16557,7 +16551,7 @@ msgstr "" #: main/main.cpp msgid "Driver" -msgstr "" +msgstr "درایور" #: main/main.cpp #, fuzzy @@ -16574,7 +16568,7 @@ msgstr "" #: main/main.cpp msgid "DPI" -msgstr "" +msgstr "دیپیآی" #: main/main.cpp msgid "Allow hiDPI" @@ -16582,7 +16576,7 @@ msgstr "" #: main/main.cpp msgid "V-Sync" -msgstr "" +msgstr "وی-سینک" #: main/main.cpp msgid "Use V-Sync" @@ -16594,7 +16588,7 @@ msgstr "" #: main/main.cpp msgid "Allowed" -msgstr "" +msgstr "مجاز" #: main/main.cpp msgid "Intended Usage" @@ -16653,7 +16647,7 @@ msgstr "" #: scene/gui/scroll_container.cpp scene/gui/text_edit.cpp scene/gui/tree.cpp #: scene/main/viewport.cpp scene/register_scene_types.cpp msgid "GUI" -msgstr "" +msgstr "رابط کاربری گرافیکی" #: main/main.cpp msgid "Drop Mouse On GUI Input Disabled" @@ -16696,7 +16690,7 @@ msgstr "" #: main/main.cpp msgid "iOS" -msgstr "" +msgstr "آیاواس" #: main/main.cpp msgid "Hide Home Indicator" @@ -16718,7 +16712,7 @@ msgstr "" #: main/main.cpp servers/visual_server.cpp msgid "GLES3" -msgstr "" +msgstr "جیالایاس۳" #: main/main.cpp servers/visual_server.cpp #, fuzzy @@ -16733,7 +16727,7 @@ msgstr "" #: scene/3d/world_environment.cpp scene/main/scene_tree.cpp #: scene/resources/world.cpp msgid "Environment" -msgstr "" +msgstr "محیط" #: main/main.cpp msgid "Default Clear Color" @@ -16749,11 +16743,11 @@ msgstr "" #: main/main.cpp msgid "Image" -msgstr "" +msgstr "عکس" #: main/main.cpp msgid "Fullsize" -msgstr "" +msgstr "اندازه کامل" #: main/main.cpp scene/resources/dynamic_font.cpp #, fuzzy @@ -16834,8 +16828,9 @@ msgstr "پیدا کردن نوع گره" #: main/main.cpp scene/gui/texture_progress.cpp #: scene/gui/viewport_container.cpp +#, fuzzy msgid "Stretch" -msgstr "" +msgstr "کشیدن" #: main/main.cpp msgid "Aspect" @@ -16843,7 +16838,7 @@ msgstr "" #: main/main.cpp msgid "Shrink" -msgstr "" +msgstr "کوچک کردن" #: main/main.cpp scene/main/scene_tree.cpp msgid "Auto Accept Quit" @@ -16930,7 +16925,7 @@ msgstr "اتصال به گره:" #: scene/resources/navigation_mesh.cpp scene/resources/primitive_meshes.cpp #: scene/resources/sphere_shape.cpp msgid "Radius" -msgstr "" +msgstr "شعاع" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp msgid "Radial Segments" @@ -16948,11 +16943,11 @@ msgstr "گام نرم" #: modules/csg/csg_shape.cpp msgid "Sides" -msgstr "" +msgstr "طرفین" #: modules/csg/csg_shape.cpp msgid "Cone" -msgstr "" +msgstr "مخروط" #: modules/csg/csg_shape.cpp msgid "Inner Radius" @@ -17116,12 +17111,14 @@ msgid "Double click to create a new entry" msgstr "" #: modules/gdnative/gdnative_library_editor_plugin.cpp +#, fuzzy msgid "Platform:" -msgstr "" +msgstr "سکو:" #: modules/gdnative/gdnative_library_editor_plugin.cpp +#, fuzzy msgid "Platform" -msgstr "" +msgstr "سکو" #: modules/gdnative/gdnative_library_editor_plugin.cpp #, fuzzy @@ -17295,7 +17292,7 @@ msgstr "مگابایت" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp msgid "Max" -msgstr "" +msgstr "حداکثر" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17324,7 +17321,7 @@ msgstr "" #: modules/gltf/gltf_buffer_view.cpp msgid "Buffer" -msgstr "" +msgstr "بافر" #: modules/gltf/gltf_buffer_view.cpp #, fuzzy @@ -17422,7 +17419,7 @@ msgstr "برداشتن نقطه" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp msgid "Roots" -msgstr "" +msgstr "ریشهها" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_state.cpp msgid "Unique Names" @@ -17485,7 +17482,7 @@ msgstr "" #: modules/gltf/gltf_state.cpp msgid "Json" -msgstr "" +msgstr "جیسان" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17531,15 +17528,15 @@ msgstr "ویژگیها" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" -msgstr "" +msgstr "تصاویر" #: modules/gltf/gltf_state.cpp msgid "Cameras" -msgstr "" +msgstr "دوربینها" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp msgid "Lights" -msgstr "" +msgstr "نورها" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17580,7 +17577,7 @@ msgstr "" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" -msgstr "" +msgstr "سلول" #: modules/gridmap/grid_map.cpp #, fuzzy @@ -17606,7 +17603,7 @@ msgstr "ساختن گره" #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp #: scene/resources/material.cpp msgid "Mask" -msgstr "" +msgstr "ماسک" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp #, fuzzy @@ -17633,7 +17630,7 @@ msgstr "زبانه قبلی" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Plane:" -msgstr "" +msgstr "سطح" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Floor" @@ -17866,19 +17863,16 @@ msgid "Auto Update Project" msgstr "پروژه بی نام" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Assembly Name" -msgstr "نشان دادن همه" +msgstr "" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Solution Directory" -msgstr "یک فهرست انتخاب کنید" +msgstr "" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "C# Project Directory" -msgstr "یک فهرست انتخاب کنید" +msgstr "" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17922,8 +17916,9 @@ msgid "Eroding walkable area..." msgstr "" #: modules/navigation/navigation_mesh_generator.cpp +#, fuzzy msgid "Partitioning..." -msgstr "" +msgstr "تقسیم بندی..." #: modules/navigation/navigation_mesh_generator.cpp msgid "Creating contours..." @@ -17947,11 +17942,11 @@ msgstr "" #: modules/navigation/navigation_mesh_generator.cpp msgid "Done!" -msgstr "" +msgstr "انجام شد!" #: modules/opensimplex/noise_texture.cpp msgid "Seamless" -msgstr "" +msgstr "یکپارچه" #: modules/opensimplex/noise_texture.cpp msgid "As Normal Map" @@ -17962,8 +17957,9 @@ msgid "Bump Strength" msgstr "" #: modules/opensimplex/noise_texture.cpp +#, fuzzy msgid "Noise" -msgstr "" +msgstr "نویز" #: modules/opensimplex/noise_texture.cpp msgid "Noise Offset" @@ -17975,11 +17971,11 @@ msgstr "" #: modules/opensimplex/open_simplex_noise.cpp msgid "Period" -msgstr "" +msgstr "دوره" #: modules/opensimplex/open_simplex_noise.cpp msgid "Persistence" -msgstr "" +msgstr "ماندگاری" #: modules/opensimplex/open_simplex_noise.cpp msgid "Lacunarity" @@ -17987,7 +17983,7 @@ msgstr "" #: modules/regex/regex.cpp msgid "Subject" -msgstr "" +msgstr "موضوع" #: modules/regex/regex.cpp #, fuzzy @@ -18456,8 +18452,9 @@ msgid "if (cond) is:" msgstr "" #: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy msgid "While" -msgstr "" +msgstr "هنگامی که" #: modules/visual_script/visual_script_flow_control.cpp msgid "while (cond):" @@ -18488,7 +18485,7 @@ msgstr "تکرارگر نامعتبر شد: " #: modules/visual_script/visual_script_flow_control.cpp msgid "Sequence" -msgstr "" +msgstr "دنباله" #: modules/visual_script/visual_script_flow_control.cpp #, fuzzy @@ -18649,7 +18646,7 @@ msgstr "آرایه را تغییر اندازه بده" #: modules/visual_script/visual_script_nodes.cpp scene/resources/material.cpp #: scene/resources/visual_shader_nodes.cpp msgid "Operator" -msgstr "" +msgstr "عملگر" #: modules/visual_script/visual_script_nodes.cpp #, fuzzy @@ -18758,7 +18755,7 @@ msgstr "فراخوانی" #: modules/visual_script/visual_script_nodes.cpp scene/gui/graph_node.cpp msgid "Title" -msgstr "" +msgstr "عنوان" #: modules/visual_script/visual_script_nodes.cpp #, fuzzy @@ -19056,7 +19053,7 @@ msgstr "زبانه قبلی" #: platform/android/export/export_plugin.cpp msgid "Code" -msgstr "" +msgstr "کد" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp #, fuzzy @@ -19732,9 +19729,8 @@ msgid "Custom BG Color" msgstr "ساختن گره" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Icons" -msgstr "خروجی" +msgstr "آیکونهای خروجی" #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp @@ -19886,8 +19882,9 @@ msgid "Error starting HTTP server: %d." msgstr "خطا در بارگذاری:" #: platform/javascript/export/export.cpp +#, fuzzy msgid "Web" -msgstr "" +msgstr "وب" #: platform/javascript/export/export.cpp msgid "HTTP Host" @@ -20447,7 +20444,7 @@ msgstr "" #: platform/osx/export/export.cpp msgid "macOS" -msgstr "" +msgstr "مکاواس" #: platform/osx/export/export.cpp msgid "Force Builtin Codesign" @@ -20881,11 +20878,11 @@ msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp msgid "Monitoring" -msgstr "" +msgstr "نظارت" #: scene/2d/area_2d.cpp scene/3d/area.cpp msgid "Monitorable" -msgstr "" +msgstr "قابل نظارت" #: scene/2d/area_2d.cpp scene/3d/area.cpp msgid "Physics Overrides" @@ -20912,7 +20909,7 @@ msgstr "بهروزرسانی از صحنه" #: scene/2d/area_2d.cpp scene/2d/cpu_particles_2d.cpp scene/3d/area.cpp #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp msgid "Gravity" -msgstr "" +msgstr "جاذبه" #: scene/2d/area_2d.cpp scene/3d/area.cpp #, fuzzy @@ -20930,7 +20927,7 @@ msgstr "افزودن کانل صوتی" #: scene/2d/area_2d.cpp scene/3d/area.cpp msgid "Override" -msgstr "" +msgstr "بازنویسی" #: scene/2d/audio_stream_player_2d.cpp scene/audio/audio_stream_player.cpp #: scene/gui/video_player.cpp servers/audio/effects/audio_effect_amplify.cpp @@ -21639,9 +21636,8 @@ msgid "Filter Smooth" msgstr "حالت صافی:" #: scene/2d/light_occluder_2d.cpp -#, fuzzy msgid "Closed" -msgstr "بستن" +msgstr "بسته" #: scene/2d/light_occluder_2d.cpp scene/resources/material.cpp #, fuzzy @@ -22050,7 +22046,7 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Damp" -msgstr "" +msgstr "مرطوب" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Angular" @@ -22062,7 +22058,7 @@ msgstr "" #: scene/2d/physics_body_2d.cpp msgid "Torque" -msgstr "" +msgstr "گشتاور" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Safe Margin" @@ -22089,7 +22085,7 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Remainder" -msgstr "" +msgstr "باقی مانده" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy @@ -22165,7 +22161,7 @@ msgstr "" #: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp msgid "Areas" -msgstr "" +msgstr "مناطق" #: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp msgid "Bodies" @@ -22430,7 +22426,7 @@ msgstr "" #: scene/3d/audio_stream_player_3d.cpp msgid "Degrees" -msgstr "" +msgstr "درجه" #: scene/3d/audio_stream_player_3d.cpp #, fuzzy @@ -22490,7 +22486,7 @@ msgstr "" #: scene/3d/baked_lightmap.cpp msgid "Done" -msgstr "" +msgstr "انجام شد" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/reflection_probe.cpp scene/resources/box_shape.cpp @@ -22851,7 +22847,7 @@ msgstr "انتخاب حالت" #: scene/3d/label_3d.cpp scene/resources/default_theme/default_theme.cpp #: scene/resources/dynamic_font.cpp scene/resources/primitive_meshes.cpp msgid "Font" -msgstr "" +msgstr "فونت" #: scene/3d/label_3d.cpp scene/resources/primitive_meshes.cpp #, fuzzy @@ -23548,7 +23544,7 @@ msgstr "اشکال یابی" #: scene/3d/ray_cast.cpp scene/resources/style_box.cpp msgid "Thickness" -msgstr "" +msgstr "ضخامت" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp #, fuzzy @@ -24250,7 +24246,7 @@ msgstr "" #: scene/animation/skeleton_ik.cpp msgid "Magnet" -msgstr "" +msgstr "آهنربا" #: scene/animation/skeleton_ik.cpp #, fuzzy @@ -24435,7 +24431,7 @@ msgstr "ثابت" #: scene/gui/control.cpp scene/resources/visual_shader_nodes.cpp msgid "Hint" -msgstr "" +msgstr "تذکر" #: scene/gui/control.cpp #, fuzzy @@ -24444,7 +24440,7 @@ msgstr "ابزارها" #: scene/gui/control.cpp scene/resources/default_theme/default_theme.cpp msgid "Focus" -msgstr "" +msgstr "تمرکز" #: scene/gui/control.cpp msgid "Neighbour Left" @@ -24473,7 +24469,7 @@ msgstr "زبانه قبلی" #: scene/gui/control.cpp msgid "Mouse" -msgstr "" +msgstr "موس" #: scene/gui/control.cpp #, fuzzy @@ -24503,8 +24499,9 @@ msgid "Window Title" msgstr "" #: scene/gui/dialogs.cpp +#, fuzzy msgid "Dialog" -msgstr "" +msgstr "دیالوگ" #: scene/gui/dialogs.cpp msgid "Hide On OK" @@ -24590,7 +24587,7 @@ msgstr "" #: scene/gui/grid_container.cpp scene/gui/item_list.cpp scene/gui/tree.cpp msgid "Columns" -msgstr "" +msgstr "ستونها" #: scene/gui/item_list.cpp scene/gui/popup_menu.cpp scene/gui/text_edit.cpp #: scene/gui/tree.cpp scene/main/viewport.cpp @@ -24727,15 +24724,15 @@ msgstr "بارگیری به عنوان جانگهدار" #: scene/gui/line_edit.cpp msgid "Alpha" -msgstr "" +msgstr "آلفا" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Caret" -msgstr "" +msgstr "کارت" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Blink" -msgstr "" +msgstr "پلک" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp #, fuzzy @@ -24744,7 +24741,7 @@ msgstr "پخش صحنه" #: scene/gui/link_button.cpp msgid "Underline" -msgstr "" +msgstr "زیرخط" #: scene/gui/menu_button.cpp #, fuzzy @@ -24777,12 +24774,13 @@ msgid "" msgstr "" #: scene/gui/popup.cpp +#, fuzzy msgid "Popup" -msgstr "" +msgstr "پاپآپ" #: scene/gui/popup.cpp msgid "Exclusive" -msgstr "" +msgstr "انحصاری" #: scene/gui/popup.cpp #, fuzzy @@ -24840,7 +24838,7 @@ msgstr "مقدار:" #: scene/gui/range.cpp msgid "Page" -msgstr "" +msgstr "صفحه" #: scene/gui/range.cpp #, fuzzy @@ -24965,7 +24963,7 @@ msgstr "" #: scene/gui/slider.cpp msgid "Scrollable" -msgstr "" +msgstr "قابل اسکرول" #: scene/gui/slider.cpp msgid "Tick Count" @@ -24978,7 +24976,7 @@ msgstr "ساختن پوشه" #: scene/gui/spin_box.cpp msgid "Prefix" -msgstr "" +msgstr "پیشوند" #: scene/gui/spin_box.cpp msgid "Suffix" @@ -25036,7 +25034,7 @@ msgstr "" #: scene/gui/text_edit.cpp msgid "Readonly" -msgstr "" +msgstr "فقط خواندنی" #: scene/gui/text_edit.cpp msgid "Bookmark Gutter" @@ -25120,11 +25118,11 @@ msgstr "" #: scene/gui/texture_progress.cpp msgid "Under" -msgstr "" +msgstr "زیر" #: scene/gui/texture_progress.cpp msgid "Over" -msgstr "" +msgstr "روی" #: scene/gui/texture_progress.cpp #, fuzzy @@ -25141,8 +25139,9 @@ msgid "Fill Mode" msgstr "حالت صدور:" #: scene/gui/texture_progress.cpp scene/resources/material.cpp +#, fuzzy msgid "Tint" -msgstr "" +msgstr "رنگ" #: scene/gui/texture_progress.cpp msgid "Radial Fill" @@ -25350,7 +25349,7 @@ msgstr "صحنه جدید" #: scene/main/scene_tree.cpp msgid "Root" -msgstr "" +msgstr "ریشه" #: scene/main/scene_tree.cpp #, fuzzy @@ -25360,7 +25359,7 @@ msgstr "تعیین چندگانه:" #: scene/main/scene_tree.cpp scene/resources/mesh_library.cpp #: scene/resources/shape_2d.cpp msgid "Shapes" -msgstr "" +msgstr "شکلها" #: scene/main/scene_tree.cpp msgid "Shape Color" @@ -25482,7 +25481,7 @@ msgstr "" #: scene/main/viewport.cpp scene/resources/world_2d.cpp msgid "World" -msgstr "" +msgstr "جهان" #: scene/main/viewport.cpp msgid "World 2D" @@ -25651,7 +25650,7 @@ msgstr "گره ترکیب" #: scene/resources/audio_stream_sample.cpp msgid "Stereo" -msgstr "" +msgstr "استریو" #: scene/resources/concave_polygon_shape_2d.cpp #, fuzzy @@ -26487,11 +26486,11 @@ msgstr "اتصال گرهها" #: scene/resources/environment.cpp msgid "Background" -msgstr "" +msgstr "پسزمینه" #: scene/resources/environment.cpp scene/resources/sky.cpp msgid "Sky" -msgstr "" +msgstr "آسمان" #: scene/resources/environment.cpp #, fuzzy @@ -26532,7 +26531,7 @@ msgstr "انیمیشن" #: scene/resources/environment.cpp msgid "Fog" -msgstr "" +msgstr "مه" #: scene/resources/environment.cpp #, fuzzy @@ -26605,7 +26604,7 @@ msgstr "خروجی" #: scene/resources/environment.cpp msgid "White" -msgstr "" +msgstr "سفید" #: scene/resources/environment.cpp msgid "Auto Exposure" @@ -26643,8 +26642,9 @@ msgid "Depth Tolerance" msgstr "بومی" #: scene/resources/environment.cpp scene/resources/material.cpp +#, fuzzy msgid "Roughness" -msgstr "" +msgstr "زبری" #: scene/resources/environment.cpp msgid "SSAO" @@ -26695,7 +26695,7 @@ msgstr "" #: scene/resources/environment.cpp msgid "Glow" -msgstr "" +msgstr "درخشش" #: scene/resources/environment.cpp #, fuzzy @@ -26756,12 +26756,13 @@ msgid "Bicubic Upscale" msgstr "" #: scene/resources/environment.cpp +#, fuzzy msgid "Adjustments" -msgstr "" +msgstr "تنظیمات" #: scene/resources/environment.cpp msgid "Brightness" -msgstr "" +msgstr "روشنایی" #: scene/resources/environment.cpp #, fuzzy @@ -26789,8 +26790,9 @@ msgid "Raw Data" msgstr "صادکردن فایل کتابخانه ای" #: scene/resources/gradient.cpp +#, fuzzy msgid "Offsets" -msgstr "" +msgstr "انحرافها" #: scene/resources/height_map_shape.cpp msgid "Map Width" @@ -26942,7 +26944,7 @@ msgstr "" #: scene/resources/material.cpp msgid "Metallic" -msgstr "" +msgstr "فلزی" #: scene/resources/material.cpp #, fuzzy @@ -27026,7 +27028,7 @@ msgstr "شمارش ها:" #: scene/resources/material.cpp msgid "Detail" -msgstr "" +msgstr "جزئیات" #: scene/resources/material.cpp msgid "UV Layer" @@ -27203,7 +27205,7 @@ msgstr "حذف قالب" #: scene/resources/occluder_shape.cpp msgid "Spheres" -msgstr "" +msgstr "کرهها" #: scene/resources/occluder_shape.cpp msgid "OccluderShapeSphere Set Spheres" @@ -27225,11 +27227,12 @@ msgstr "" #: scene/resources/particles_material.cpp msgid "Trail" -msgstr "" +msgstr "دنباله" #: scene/resources/particles_material.cpp +#, fuzzy msgid "Divisor" -msgstr "" +msgstr "مقسوم علیه" #: scene/resources/particles_material.cpp #, fuzzy @@ -27273,11 +27276,11 @@ msgstr "ویرایش منحنی گره" #: scene/resources/physics_material.cpp msgid "Rough" -msgstr "" +msgstr "زبری" #: scene/resources/physics_material.cpp msgid "Absorbent" -msgstr "" +msgstr "جاذب" #: scene/resources/plane_shape.cpp #, fuzzy @@ -27357,7 +27360,7 @@ msgstr "" #: scene/resources/sky.cpp msgid "Panorama" -msgstr "" +msgstr "پانوراما" #: scene/resources/sky.cpp #, fuzzy @@ -27385,8 +27388,9 @@ msgid "Sun" msgstr "اجرا" #: scene/resources/sky.cpp +#, fuzzy msgid "Latitude" -msgstr "" +msgstr "عرض" #: scene/resources/sky.cpp msgid "Longitude" @@ -27689,21 +27693,21 @@ msgstr "" #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Dry" -msgstr "" +msgstr "خشک" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Wet" -msgstr "" +msgstr "مرطوب" #: servers/audio/effects/audio_effect_chorus.cpp msgid "Voice" -msgstr "" +msgstr "صدا" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp msgid "Delay (ms)" -msgstr "" +msgstr "تأخیر (میلیثانیه)" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_phaser.cpp @@ -27718,7 +27722,7 @@ msgstr "بومی" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp msgid "Level dB" -msgstr "" +msgstr "سطح دسیبل" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp @@ -27742,7 +27746,7 @@ msgstr "" #: servers/audio/effects/audio_effect_compressor.cpp msgid "Mix" -msgstr "" +msgstr "ترکیب" #: servers/audio/effects/audio_effect_compressor.cpp msgid "Sidechain" @@ -27750,17 +27754,17 @@ msgstr "" #: servers/audio/effects/audio_effect_delay.cpp msgid "Tap 1" -msgstr "" +msgstr "ضربه ۱" #: servers/audio/effects/audio_effect_delay.cpp msgid "Tap 2" -msgstr "" +msgstr "ضربه ۲" #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_phaser.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Feedback" -msgstr "" +msgstr "بازخورد" #: servers/audio/effects/audio_effect_delay.cpp #, fuzzy @@ -28114,7 +28118,7 @@ msgstr "" #: servers/visual_server.cpp msgid "Shadows" -msgstr "" +msgstr "سایهها" #: servers/visual_server.cpp #, fuzzy @@ -28135,7 +28139,7 @@ msgstr "" #: servers/visual_server.cpp msgid "Shading" -msgstr "" +msgstr "سایهزنی" #: servers/visual_server.cpp msgid "Force Vertex Shading" @@ -28279,7 +28283,7 @@ msgstr "" #: servers/visual_server.cpp msgid "Compatibility" -msgstr "" +msgstr "سازگاری" #: servers/visual_server.cpp msgid "Disable Half Float" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index c560e51b01..bb73facb22 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -12,13 +12,14 @@ # Tuomas Lähteenmäki <lahtis@gmail.com>, 2019, 2022. # Matti Niskanen <matti.t.niskanen@gmail.com>, 2020. # Severi Vidnäs <severi.vidnas@gmail.com>, 2021. +# Akseli Pihlajamaa <akselijuhanipihlajamaa@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-03-17 13:58+0000\n" -"Last-Translator: Tuomas Lähteenmäki <lahtis@gmail.com>\n" +"PO-Revision-Date: 2022-09-11 22:22+0000\n" +"Last-Translator: Akseli Pihlajamaa <akselijuhanipihlajamaa@gmail.com>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" "Language: fi\n" @@ -26,30 +27,27 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.12-dev\n" +"X-Generator: Weblate 4.14.1-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "Clipboard" -msgstr "Leikepöytä on tyhjä!" +msgstr "Leikepöytä" #: core/bind/core_bind.cpp -#, fuzzy msgid "Current Screen" -msgstr "Nykyinen kohtaus" +msgstr "Nykyinen näkymä" #: core/bind/core_bind.cpp msgid "Exit Code" -msgstr "" +msgstr "Poistumiskoodi" #: core/bind/core_bind.cpp -#, fuzzy msgid "V-Sync Enabled" -msgstr "Ota käyttöön" +msgstr "V-Sync käytössä" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" @@ -60,9 +58,8 @@ msgid "Delta Smoothing" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "Low Processor Usage Mode" -msgstr "Siirtotila" +msgstr "Matala prosessorin käyttötila" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index b65ff797d7..e19c856222 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -104,13 +104,14 @@ # Helix Sir <vincentbarkmann@gmail.com>, 2022. # SCHUTZ Lucas <lucas.schutz0954@gmail.com>, 2022. # EGuillemot <Elouen.Guillemot@gmail.com>, 2022. +# Entiz <maxime.salido@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-09-02 23:49+0000\n" -"Last-Translator: DinosaurHorseSword <ewenlandry@mailfence.com>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: Entiz <maxime.salido@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -118,7 +119,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -150,7 +151,7 @@ msgstr "Lissage de Delta" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode" -msgstr "Mode d'utilisation faible du processeur" +msgstr "Mode d'utilisation du processeur bas en ressources" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" @@ -244,7 +245,7 @@ msgstr "Cible de FPS" #: core/bind/core_bind.cpp msgid "Time Scale" -msgstr "Echelle de temps" +msgstr "Échelle de temps" #: core/bind/core_bind.cpp main/main.cpp msgid "Physics Jitter Fix" @@ -5902,8 +5903,9 @@ msgid "Zoom Modifier" msgstr "Touche de combinaison : Zoom" #: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Warped Mouse Panning" -msgstr "" +msgstr "Panoramique déformé de la souris" #: editor/editor_settings.cpp msgid "Navigation Feel" @@ -15421,19 +15423,16 @@ msgid "Make Local" msgstr "Rendre local" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name(s)" -msgstr "Activer le nom unique de la scène" +msgstr "Activer le(s) nom(s) unique(s) de scène" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Unique names already used by another node in the scene:" -msgstr "Un autre Nœud utilise ce nom unique dans la scène." +msgstr "Noms uniques déjà utilisés par un autre nœud de la scène :" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Disable Scene Unique Name(s)" -msgstr "Désactiver le nom unique de la scène" +msgstr "Désactiver le(s) nom(s) unique(s) de la scène" #: editor/scene_tree_dock.cpp msgid "New Scene Root" @@ -16308,9 +16307,8 @@ msgid "Fallback To GLES2" msgstr "Se replier sur GLES2" #: main/main.cpp -#, fuzzy msgid "Use Nvidia Rect Flicker Workaround" -msgstr "Utiliser le contournement Nvidia pour éviter le clignotement" +msgstr "Utiliser la solution alternative Nvidia pour éviter le clignotement" #: main/main.cpp msgid "DPI" @@ -16357,9 +16355,8 @@ msgid "Thread Model" msgstr "Modèle de Parallélisme" #: main/main.cpp -#, fuzzy msgid "Thread Safe BVH" -msgstr "BVH avec Thread Sécurisés" +msgstr "BVH avec le parallélisme sécurisé" #: main/main.cpp msgid "Handheld" @@ -16598,7 +16595,7 @@ msgstr "Activer le support des SoftBody par le Monde" #: modules/csg/csg_gizmos.cpp msgid "CSG" -msgstr "" +msgstr "GCS" #: modules/csg/csg_gizmos.cpp msgid "Change Cylinder Radius" @@ -16988,17 +16985,16 @@ msgid "Max" msgstr "Max" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Sparse Count" -msgstr "Instance" +msgstr "Comptage épars" #: modules/gltf/gltf_accessor.cpp msgid "Sparse Indices Buffer View" -msgstr "" +msgstr "Affichage tampon des indices épars" #: modules/gltf/gltf_accessor.cpp msgid "Sparse Indices Byte Offset" -msgstr "" +msgstr "Décalage d'octet des indices épars" #: modules/gltf/gltf_accessor.cpp msgid "Sparse Indices Component Type" @@ -17006,11 +17002,11 @@ msgstr "Type de composant d'indices épars" #: modules/gltf/gltf_accessor.cpp msgid "Sparse Values Buffer View" -msgstr "" +msgstr "Affichage tampon des valeurs éparses" #: modules/gltf/gltf_accessor.cpp msgid "Sparse Values Byte Offset" -msgstr "" +msgstr "Décalage d'octet des valeurs éparses" #: modules/gltf/gltf_buffer_view.cpp msgid "Buffer" @@ -17018,11 +17014,11 @@ msgstr "Tampon" #: modules/gltf/gltf_buffer_view.cpp msgid "Byte Length" -msgstr "Longueur de byte" +msgstr "Longueur d'octet" #: modules/gltf/gltf_buffer_view.cpp msgid "Byte Stride" -msgstr "" +msgstr "Foulée d'octet" #: modules/gltf/gltf_buffer_view.cpp msgid "Indices" @@ -17157,8 +17153,9 @@ msgid "Specular Factor" msgstr "Facteur Spéculaire" #: modules/gltf/gltf_spec_gloss.cpp +#, fuzzy msgid "Spec Gloss Img" -msgstr "" +msgstr "Img Spéculaire Brillante" #: modules/gltf/gltf_state.cpp msgid "Json" @@ -17242,9 +17239,8 @@ msgid "Physics Material" msgstr "Matériau physique" #: modules/gridmap/grid_map.cpp scene/3d/visual_instance.cpp -#, fuzzy msgid "Use In Baked Light" -msgstr "Précalculer les lightmaps" +msgstr "Utiliser des lumières pré-calculées" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" @@ -17441,9 +17437,8 @@ msgid "Plotting lightmaps" msgstr "Tracer des lightmaps" #: modules/lightmapper_cpu/register_types.cpp -#, fuzzy msgid "CPU Lightmapper" -msgstr "Précalculer les lightmaps" +msgstr "Mappeur de lumière processeur" #: modules/lightmapper_cpu/register_types.cpp msgid "Low Quality Ray Count" @@ -17509,19 +17504,16 @@ msgid "Auto Update Project" msgstr "Mettre à jour le projet automatiquement" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Assembly Name" -msgstr "Afficher le nom" +msgstr "Nom de l'assembly" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Solution Directory" -msgstr "Choisir un répertoire" +msgstr "Choisir un répertoire pour la solution" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "C# Project Directory" -msgstr "Choisir un répertoire" +msgstr "Choisir un répertoire pour le projet C#" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17644,7 +17636,7 @@ msgstr "Paramètres" #: modules/upnp/upnp.cpp msgid "Discover Multicast If" -msgstr "" +msgstr "Révéler la multidiffusion si" #: modules/upnp/upnp.cpp msgid "Discover Local Port" @@ -17652,7 +17644,7 @@ msgstr "Révéler le port local" #: modules/upnp/upnp.cpp msgid "Discover IPv6" -msgstr "Découvrir IPv6" +msgstr "Révéler IPv6" #: modules/upnp/upnp_device.cpp msgid "Description URL" @@ -17672,7 +17664,7 @@ msgstr "Type de service IGD" #: modules/upnp/upnp_device.cpp msgid "IGD Our Addr" -msgstr "" +msgstr "Notre adresse PGI" #: modules/upnp/upnp_device.cpp msgid "IGD Status" @@ -18049,9 +18041,8 @@ msgid "Return" msgstr "Retour" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Return Enabled" -msgstr "Exécutable" +msgstr "Retour activé" #: modules/visual_script/visual_script_flow_control.cpp msgid "Return Type" @@ -18473,14 +18464,12 @@ msgid "Optional Features" msgstr "Fonctionnalités Optionnelles" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Requested Reference Space Types" -msgstr "Type d'espace référence requis" +msgstr "Types d'espaces référence requis" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Reference Space Type" -msgstr "Type d'espace référence" +msgstr "Type d'espace de référence" #: modules/webxr/webxr_interface.cpp msgid "Visibility State" @@ -18491,9 +18480,8 @@ msgid "Bounds Geometry" msgstr "Géométrie des limites" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "XR Standard Mapping" -msgstr "Mapping Standard AR/VR" +msgstr "Mappage Standard XR" #: platform/android/export/export.cpp msgid "Android SDK Path" @@ -18677,24 +18665,20 @@ msgid "Immersive Mode" msgstr "Mode immersif" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Small" -msgstr "Support" +msgstr "Supporte les petits écrans" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Normal" -msgstr "Support" +msgstr "Supporte les écrans normaux" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Large" -msgstr "Support" +msgstr "Supporte les grands écrans" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Xlarge" -msgstr "Support" +msgstr "Supporte les très grands écrans" #: platform/android/export/export_plugin.cpp msgid "User Data Backup" @@ -18713,9 +18697,8 @@ msgid "Extra Args" msgstr "Arguments Supplémentaires" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "APK Expansion" -msgstr "Expression" +msgstr "Expansion APK" #: platform/android/export/export_plugin.cpp msgid "Salt" @@ -19107,7 +19090,7 @@ msgstr "Le caractère « %s » n'est pas autorisé dans l'identifiant." #: platform/iphone/export/export.cpp msgid "Landscape Launch Screens" -msgstr "" +msgstr "Écrans de lancement en mode paysage" #: platform/iphone/export/export.cpp msgid "iPhone 2436 X 1125" @@ -19284,11 +19267,11 @@ msgstr "Projecteur 80 X 80" #: platform/iphone/export/export.cpp msgid "Storyboard" -msgstr "" +msgstr "Storyboard" #: platform/iphone/export/export.cpp msgid "Use Launch Screen Storyboard" -msgstr "" +msgstr "Utiliser le storyboard de l'écran de lancement" #: platform/iphone/export/export.cpp msgid "Image Scale Mode" @@ -19311,9 +19294,8 @@ msgid "Custom BG Color" msgstr "Couleur d'arrière-plan personnalisée" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Icons" -msgstr "Icône d'exportation" +msgstr "Exporter les icônes" #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp @@ -19366,7 +19348,7 @@ msgstr "Impossible de lire le fichier : «%s »." #: platform/javascript/export/export.cpp msgid "PWA" -msgstr "" +msgstr "PWA" #: platform/javascript/export/export.cpp msgid "Variant" @@ -19620,7 +19602,6 @@ msgid "Allow JIT Code Execution" msgstr "Autoriser l'exécution du code JIT" #: platform/osx/export/export.cpp -#, fuzzy msgid "Allow Unsigned Executable Memory" msgstr "Autoriser la mémoire exécutable non signée" @@ -19677,7 +19658,6 @@ msgid "Device Bluetooth" msgstr "Périphérique Bluetooth" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Downloads" msgstr "Téléchargement de fichiers" @@ -20154,6 +20134,8 @@ msgid "" "Godot's Mono version does not support the UWP platform. Use the standard " "build (no C# support) if you wish to target UWP." msgstr "" +"La version Mono de Godot ne supporte pas la plateforme UWP. Utilisé la " +"version standard (sans le support C#) si vous souhaitez cibler UWP." #: platform/uwp/export/export.cpp msgid "Invalid package short name." @@ -20249,9 +20231,8 @@ msgid "Timestamp Server URL" msgstr "URL du serveur d'horodatage" #: platform/windows/export/export.cpp -#, fuzzy msgid "Digest Algorithm" -msgstr "Débogueur" +msgstr "Fonction de hachage" #: platform/windows/export/export.cpp msgid "Modify Resources" @@ -20286,14 +20267,12 @@ msgid "Resources Modification" msgstr "Modification de ressources" #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find rcedit executable at \"%s\"." -msgstr "Impossible de trouver le keystore, impossible d'exporter." +msgstr "Impossible de trouver rcedit à l'emplacement \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find wine executable at \"%s\"." -msgstr "Impossible de trouver le keystore, impossible d'exporter." +msgstr "Impossible de trouver wine à l'emplacement \"%s\"." #: platform/windows/export/export.cpp #, fuzzy @@ -20371,9 +20350,8 @@ msgid "Windows executables cannot be >= 4 GiB." msgstr "Les exécutables Windows ne peuvent pas peser >= 4Gio." #: platform/windows/export/export.cpp platform/x11/export/export.cpp -#, fuzzy msgid "Failed to open executable file \"%s\"." -msgstr "Fichier exécutable invalide." +msgstr "Fichier exécutable invalide : \"%s\"." #: platform/windows/export/export.cpp platform/x11/export/export.cpp msgid "Executable file header corrupted." @@ -24222,12 +24200,11 @@ msgstr "" #: scene/gui/popup.cpp #, fuzzy msgid "Popup" -msgstr "Peupler" +msgstr "Fenêtre contextuelle" #: scene/gui/popup.cpp -#, fuzzy msgid "Exclusive" -msgstr "Inclusif" +msgstr "Exclusif" #: scene/gui/popup.cpp msgid "" @@ -24235,34 +24212,31 @@ msgid "" "functions. Making them visible for editing is fine, but they will hide upon " "running." msgstr "" -"Les pop-ups seront cachées par défaut jusqu'à ce que vous appeliez une " -"fonction popup() ou une des fonctions popup*(). Les rendre visibles pour " -"l'édition ne pose pas de problème, mais elles seront cachées lors de " -"l'exécution." +"Les fenêtres contextuelles seront cachées par défaut jusqu'à ce que vous " +"appeliez une fonction popup() ou une des fonctions popup*(). Les rendre " +"visibles pour l'édition ne pose pas de problème, mais elles seront cachées " +"lors de l'exécution." #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Hide On Item Selection" -msgstr "Centrer sur la sélection" +msgstr "Masquer lors de la sélection de l'élément" #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Hide On Checkable Item Selection" -msgstr "Suppression de la sélection de GridMap" +msgstr "Masquer lors de la sélection de l'élément cochable" #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Hide On State Item Selection" -msgstr "Supprimer la sélection" +msgstr "Cacher lors de la sélection de l'élément d'état" #: scene/gui/popup_menu.cpp +#, fuzzy msgid "Submenu Popup Delay" -msgstr "" +msgstr "Délai du pop-up du sous-menu" #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Allow Search" -msgstr "Rechercher" +msgstr "Autoriser la recherche" #: scene/gui/progress_bar.cpp msgid "Percent" @@ -24270,59 +24244,54 @@ msgstr "Pourcentage" #: scene/gui/range.cpp msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." -msgstr "Si « Exp Edit » est vrai, « Min Value » doit être supérieur à 0." +msgstr "" +"Si \"Édition Exponentielle\" est activée, \"Valeur Minimale\" doit être " +"supérieure à 0." #: scene/gui/range.cpp scene/resources/curve.cpp -#, fuzzy msgid "Min Value" -msgstr "Épingler la valeur" +msgstr "Valeur minimale" #: scene/gui/range.cpp scene/resources/curve.cpp -#, fuzzy msgid "Max Value" -msgstr "Valeur" +msgstr "Valeur maximale" #: scene/gui/range.cpp msgid "Page" msgstr "Page" #: scene/gui/range.cpp -#, fuzzy msgid "Exp Edit" -msgstr "Édition" +msgstr "Édition Exponentielle" #: scene/gui/range.cpp #, fuzzy msgid "Rounded" -msgstr "Groupé" +msgstr "Arrondir" #: scene/gui/range.cpp msgid "Allow Greater" -msgstr "" +msgstr "Autoriser supérieur" #: scene/gui/range.cpp msgid "Allow Lesser" -msgstr "" +msgstr "Autoriser inférieur" #: scene/gui/reference_rect.cpp -#, fuzzy msgid "Border Color" -msgstr "Renommer l'item de couleur" +msgstr "Couleur de la bordure" #: scene/gui/reference_rect.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Border Width" -msgstr "Pixels de bordure" +msgstr "Largeur de la bordure" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Relative Index" -msgstr "Récupérer la position" +msgstr "Position relative" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Absolute Index" -msgstr "Indentation automatique" +msgstr "Indice absolu" #: scene/gui/rich_text_effect.cpp msgid "Elapsed Time" @@ -24339,47 +24308,43 @@ msgstr "Caractère" #: scene/gui/rich_text_label.cpp msgid "BBCode" -msgstr "" +msgstr "BBCode" #: scene/gui/rich_text_label.cpp msgid "Meta Underlined" -msgstr "" +msgstr "Méta-données soulignées" #: scene/gui/rich_text_label.cpp msgid "Tab Size" msgstr "Taille de tabulation" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Fit Content Height" -msgstr "Peindre les poids de l'os" +msgstr "Ajuster à la hauteur du conteneur" #: scene/gui/rich_text_label.cpp msgid "Scroll Active" -msgstr "" +msgstr "Défilement actif" #: scene/gui/rich_text_label.cpp msgid "Scroll Following" -msgstr "" +msgstr "Suivi du défilement" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Selection Enabled" -msgstr "Sélection uniquement" +msgstr "Sélection activée" #: scene/gui/rich_text_label.cpp scene/gui/text_edit.cpp msgid "Override Selected Font Color" -msgstr "Remplacer la couleur de police sélectionnée" +msgstr "Surcharger la couleur de police sélectionnée" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Custom Effects" -msgstr "Déplacer effet de transport" +msgstr "Effets personnalisés" #: scene/gui/scroll_bar.cpp -#, fuzzy msgid "Custom Step" -msgstr "Nœud Personnalisé" +msgstr "Pas personnalisé" #: scene/gui/scroll_container.cpp msgid "" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index b634136191..21a20978a6 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -5,14 +5,15 @@ # Unlimited Creativity <marinosah1@gmail.com>, 2019. # Patik <patrikfs5@gmail.com>, 2019. # Nikola Bunjevac <nikola.bunjevac@gmail.com>, 2019, 2020. -# LeoClose <leoclose575@gmail.com>, 2020, 2021. +# LeoClose <leoclose575@gmail.com>, 2020, 2021, 2022. # Filip <fhomolka@protonmail.com>, 2022. +# Milo Ivir <mail@milotype.de>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-07-23 03:57+0000\n" -"Last-Translator: Filip <fhomolka@protonmail.com>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: Milo Ivir <mail@milotype.de>\n" "Language-Team: Croatian <https://hosted.weblate.org/projects/godot-engine/" "godot/hr/>\n" "Language: hr\n" @@ -20,7 +21,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -28,16 +29,15 @@ msgstr "Upravljački program za Tablet" #: core/bind/core_bind.cpp msgid "Clipboard" -msgstr "" +msgstr "Međuspremnik" #: core/bind/core_bind.cpp -#, fuzzy msgid "Current Screen" -msgstr "Premjesti Okvir" +msgstr "Trenutni Ekran" #: core/bind/core_bind.cpp msgid "Exit Code" -msgstr "" +msgstr "Exit Kod" #: core/bind/core_bind.cpp msgid "V-Sync Enabled" @@ -77,38 +77,31 @@ msgstr "Orijentacija zaslona" #: core/bind/core_bind.cpp core/project_settings.cpp main/main.cpp #: platform/uwp/os_uwp.cpp -#, fuzzy msgid "Window" msgstr "Prozor" #: core/bind/core_bind.cpp core/project_settings.cpp -#, fuzzy msgid "Borderless" msgstr "Bez obruba" #: core/bind/core_bind.cpp -#, fuzzy msgid "Per Pixel Transparency Enabled" msgstr "Omogućena prozirnost po pikselu" #: core/bind/core_bind.cpp core/project_settings.cpp -#, fuzzy msgid "Fullscreen" msgstr "Cijeli zaslon" #: core/bind/core_bind.cpp -#, fuzzy msgid "Maximized" msgstr "Maksimiziran" #: core/bind/core_bind.cpp -#, fuzzy msgid "Minimized" msgstr "Minimiziran" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp -#, fuzzy msgid "Resizable" msgstr "Mogućnost promjene veličine" @@ -117,7 +110,6 @@ msgstr "Mogućnost promjene veličine" #: scene/3d/physics_body.cpp scene/3d/remote_transform.cpp #: scene/gui/control.cpp scene/gui/line_edit.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Position" msgstr "Pozicija" @@ -130,38 +122,32 @@ msgstr "Pozicija" #: scene/resources/primitive_meshes.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp #: scene/resources/visual_shader.cpp servers/visual_server.cpp -#, fuzzy msgid "Size" msgstr "Veličina" #: core/bind/core_bind.cpp msgid "Endian Swap" -msgstr "" +msgstr "Promjena Endian-a" #: core/bind/core_bind.cpp -#, fuzzy msgid "Editor Hint" msgstr "Savjet Urednika" #: core/bind/core_bind.cpp -#, fuzzy msgid "Print Error Messages" msgstr "Ispis poruka o pogreškama" #: core/bind/core_bind.cpp -#, fuzzy msgid "Iterations Per Second" msgstr "Iteracije u sekundi" #: core/bind/core_bind.cpp -#, fuzzy msgid "Target FPS" msgstr "Ciljani FPS" #: core/bind/core_bind.cpp -#, fuzzy msgid "Time Scale" -msgstr "Vremenska skala" +msgstr "Skala vremena" #: core/bind/core_bind.cpp main/main.cpp msgid "Physics Jitter Fix" @@ -169,7 +155,7 @@ msgstr "" #: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Error" -msgstr "" +msgstr "Greška" #: core/bind/core_bind.cpp #, fuzzy @@ -342,7 +328,7 @@ msgstr "Neispravan unos %i (nije uspio) u izrazu" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "self se ne može koristiti jer instanca je null (nije prosljeđena)" +msgstr "self se ne može koristiti jer je instanca null (nije prosljeđena)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." @@ -1414,7 +1400,7 @@ msgstr "Okidač" #: editor/animation_track_editor.cpp scene/3d/baked_lightmap.cpp msgid "Capture" -msgstr "" +msgstr "Snimka" #: editor/animation_track_editor.cpp msgid "Nearest" @@ -24308,9 +24294,8 @@ msgid "Draw 2D Outlines" msgstr "" #: scene/main/scene_tree.cpp servers/visual_server.cpp -#, fuzzy msgid "Reflections" -msgstr "Direkcije" +msgstr "Reflekcija" #: scene/main/scene_tree.cpp msgid "Atlas Size" diff --git a/editor/translations/id.po b/editor/translations/id.po index 696799d370..ee7e21c0c0 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -40,13 +40,14 @@ # Rizky Ramadhan <rizkyterm@gmail.com>, 2022. # Primananda Kurnia <primakurnia71@gmail.com>, 2022. # FellowMustard <rachmawanng33@gmail.com>, 2022. +# Muhammad Zainal Abidin <eviepk12@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-31 18:34+0000\n" -"Last-Translator: ProgrammerIndonesia 44 <elo.jhy@gmail.com>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: Muhammad Zainal Abidin <eviepk12@gmail.com>\n" "Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/" "godot/id/>\n" "Language: id\n" @@ -54,7 +55,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -2800,7 +2801,7 @@ msgstr "Pilih" #: editor/editor_export.cpp msgid "Project export for platform:" -msgstr "" +msgstr "Proyek ekspor untuk platform:" #: editor/editor_export.cpp #, fuzzy @@ -2849,9 +2850,8 @@ msgid "Can't open file to read from path \"%s\"." msgstr "Tidak dapat membuka file untuk menulis:" #: editor/editor_export.cpp -#, fuzzy msgid "Save ZIP" -msgstr "Simpan Sebagai" +msgstr "Simpan ZIP" #: editor/editor_export.cpp msgid "" @@ -2878,7 +2878,7 @@ msgid "" msgstr "" "Platform target membutuhkan kompressi tekstur 'ETC' untuk mengembalikan " "driver ke GLES2. \n" -"Aktifkan 'Impor Lainnya' di Pengaturan Proyek, atau matikan 'Driver Fallback " +"Aktifkan 'Impor Etc' di Pengaturan Proyek, atau matikan 'Driver Fallback " "Enabled'." #: editor/editor_export.cpp @@ -2895,7 +2895,7 @@ msgid "" "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" "Platform target membutuhkan kompresi tekstur 'ETC2' atau 'PVRTC' untuk " -"GLES3. Aktifkan 'Impor Lainnya 2' atau 'Import Pvrtc' di Pengaturan Proyek." +"GLES3. Aktifkan 'Impor Etc 2' atau 'Import Pvrtc' di Pengaturan Proyek." #: editor/editor_export.cpp msgid "" @@ -2930,7 +2930,7 @@ msgstr "Operator warna." #: editor/editor_export.cpp msgid "64 Bits" -msgstr "" +msgstr "64 Bits" #: editor/editor_export.cpp msgid "Embed PCK" diff --git a/editor/translations/it.po b/editor/translations/it.po index c520b1567d..027f4609f8 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -72,13 +72,14 @@ # Gico2006 <gradaellig@protonmail.com>, 2022. # ale piccia <picciatialessio2@gmail.com>, 2022. # Simone Starace <simone.starace93@gmail.com>, 2022. +# Daniele Giunta <danielegiunta2007@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-08-30 03:11+0000\n" -"Last-Translator: Mirko <miknsop@gmail.com>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: Daniele Giunta <danielegiunta2007@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -86,7 +87,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -407,7 +408,7 @@ msgstr "Alla chiamata di '%s':" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp msgid "Seed" -msgstr "Seed" +msgstr "Seme" #: core/math/random_number_generator.cpp msgid "State" @@ -466,13 +467,12 @@ msgid "Pressed" msgstr "Premuto" #: core/os/input_event.cpp -#, fuzzy msgid "Scancode" -msgstr "Scancode" +msgstr "Codice di Scansione" #: core/os/input_event.cpp msgid "Physical Scancode" -msgstr "Scancode Fisico" +msgstr "Codice di Scansione Fisico" #: core/os/input_event.cpp #, fuzzy @@ -513,7 +513,7 @@ msgstr "Pressione" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Penna Invertita" #: core/os/input_event.cpp msgid "Relative" @@ -1353,7 +1353,6 @@ msgid "Remove this track." msgstr "Rimuovi questa traccia." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Time (s):" msgstr "Tempo (s):" @@ -1388,14 +1387,12 @@ msgid "Easing:" msgstr "Allentamento:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In-Handle:" -msgstr "Imposta Maniglia" +msgstr "In Gestione:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out-Handle:" -msgstr "Imposta Maniglia" +msgstr "Fuori Gestione:" #: editor/animation_track_editor.cpp msgid "Stream:" @@ -1539,7 +1536,6 @@ msgid "animation" msgstr "animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "AnimationPlayer can't animate itself, only other players." msgstr "AnimationPlayer non può animare se stesso, solo altri nodi." @@ -2602,7 +2598,7 @@ msgstr "File \"%s\" assente." #: editor/editor_audio_buses.cpp msgid "Layout:" -msgstr "" +msgstr "Disposizione:" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -2815,12 +2811,10 @@ msgid "Completed with warnings." msgstr "Completato con avvertimenti." #: editor/editor_export.cpp -#, fuzzy msgid "Completed successfully." msgstr "Completato con successo." #: editor/editor_export.cpp -#, fuzzy msgid "Failed." msgstr "Fallito." @@ -2837,7 +2831,6 @@ msgid "Packing" msgstr "Impacchettando" #: editor/editor_export.cpp -#, fuzzy msgid "Save PCK" msgstr "Salva PCK" @@ -2846,16 +2839,14 @@ msgid "Cannot create file \"%s\"." msgstr "impossibile creare il file \"%s\"." #: editor/editor_export.cpp -#, fuzzy msgid "Failed to export project files." -msgstr "Impossibile esportare i file del progetto" +msgstr "Esportazione dei file di progetto fallita." #: editor/editor_export.cpp msgid "Can't open file to read from path \"%s\"." msgstr "impossibile aprire file da leggere dalla path \"%s\"." #: editor/editor_export.cpp -#, fuzzy msgid "Save ZIP" msgstr "Salva ZIP" @@ -2964,7 +2955,7 @@ msgstr "ETC2" #: editor/editor_export.cpp #, fuzzy msgid "No BPTC Fallbacks" -msgstr "Nessun fallback per la BPTC" +msgstr "Nessun fallback per BPTC" #: editor/editor_export.cpp platform/android/export/export_plugin.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -2981,28 +2972,25 @@ msgstr "Modello di rilascio personalizzato non trovato." #: editor/editor_export.cpp #, fuzzy msgid "Prepare Template" -msgstr "Gestisci i modelli d'esportazione" +msgstr "Prepara Modello" #: editor/editor_export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "The given export path doesn't exist." -msgstr "Il percorso di esportazione specificato non esiste:" +msgstr "Il percorso di esportazione specificato non esiste." #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found: \"%s\"." -msgstr "File del modello non trovato:" +msgstr "File modello non trovato: \"%s\"." #: editor/editor_export.cpp -#, fuzzy msgid "Failed to copy export template." -msgstr "Template di esportazione non valido:" +msgstr "Copiatura del modello di esportazione fallita." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp #, fuzzy msgid "PCK Embedding" -msgstr "Padding" +msgstr "PCK Incorporazione" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." @@ -4094,7 +4082,7 @@ msgstr "Niente da annullare." #: editor/editor_node.cpp msgid "Undo: %s" -msgstr "Annulla" +msgstr "Annulla: %s" #: editor/editor_node.cpp msgid "Can't redo while mouse buttons are pressed." @@ -5184,7 +5172,6 @@ msgid "Size:" msgstr "Dimensione:" #: editor/editor_properties_array_dict.cpp -#, fuzzy msgid "Page:" msgstr "Pagina:" @@ -5284,9 +5271,8 @@ msgstr "" "esistente come eseguibile." #: editor/editor_run_native.cpp -#, fuzzy msgid "Project Run" -msgstr "Progetto" +msgstr "Esegui Progetto" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." @@ -5570,11 +5556,12 @@ msgstr "Uso dei tasti aggiuntivi del mouse per navigare la cronologia" #: editor/editor_settings.cpp #, fuzzy msgid "Drag And Drop Selection" -msgstr "Selezione GridMap" +msgstr "Selezione Drag And Drop" #: editor/editor_settings.cpp +#, fuzzy msgid "Stay In Script Editor On Node Selected" -msgstr "" +msgstr "Rimani nell'Editor degli Script quando un Nodo è selezionato" #: editor/editor_settings.cpp msgid "Appearance" @@ -6956,7 +6943,6 @@ msgid "Delimiter" msgstr "Delimitatore" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "ColorCorrect" msgstr "Correzione Colore" @@ -7214,9 +7200,8 @@ msgid "Generating Lightmaps" msgstr "Generando Lightmap" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Generating for Mesh:" -msgstr "Generazione della Mesh:" +msgstr "Generando per il Mesh:" #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." @@ -7248,12 +7233,17 @@ msgid "" "%s: Texture detected as used as a normal map in 3D. Enabling red-green " "texture compression to reduce memory usage (blue channel is discarded)." msgstr "" +"%s: Rilevato uso della texture come mappa Normale in 3D. Sarà abilitata la " +"compressione rosso-verde della texture per ridurre l'uso di memoria (il " +"canale blu è ignorato)." #: editor/import/resource_importer_texture.cpp msgid "" "%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap " "generation and VRAM texture compression." msgstr "" +"%s: Rilevato uso della texture in 3D. Sarà abilitato filtraggio, " +"ripetizione, generazione delle mipmap e compressione della texture in VRAM." #: editor/import/resource_importer_texture.cpp msgid "2D, Detect 3D" @@ -9999,9 +9989,8 @@ msgid "Volume" msgstr "Volume" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Emission Source:" -msgstr "Sorgente Emissione:" +msgstr "Sorgente dell' Emissione:" #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -10419,7 +10408,7 @@ msgstr "Ribalta Portale" #: editor/plugins/room_manager_editor_plugin.cpp #, fuzzy msgid "Occluder Set Transform" -msgstr "Trasformazione dell'Insieme dell'Occlusore" +msgstr "Imposta Trasformazione dell' Occlusore" #: editor/plugins/room_manager_editor_plugin.cpp msgid "Center Node" @@ -11098,13 +11087,11 @@ msgstr "Trasla" #. TRANSLATORS: Refers to changing the scale of a node in the 3D editor. #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Scaling:" -msgstr "Scalatura:" +msgstr "Scala:" #. TRANSLATORS: Refers to changing the position of a node in the 3D editor. #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Translating:" msgstr "Traslazione:" @@ -11361,7 +11348,6 @@ msgid "Use Snap" msgstr "Usa Scatto" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Converts rooms for portal culling." msgstr "Converte stanze per culling del portale." @@ -11442,7 +11428,7 @@ msgstr "Aumenta il Campo Visivo" #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Reset Field of View to Default" -msgstr "Ripristina le impostazioni predefinite" +msgstr "Ripristina il Campo Visivo alle impostazioni predefinite" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Object to Floor" @@ -11626,9 +11612,8 @@ msgid "Invalid geometry, can't replace by mesh." msgstr "Geometria non valida, impossibile sostituirla con una mesh." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to MeshInstance2D" -msgstr "Converti in Mesh2D" +msgstr "Converti in MeshInstance2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." @@ -11659,17 +11644,14 @@ msgid "Sprite" msgstr "Sprite" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Simplification:" msgstr "Semplificazione:" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Shrink (Pixels):" msgstr "Rimpicciolisci (Pixels):" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Grow (Pixels):" msgstr "Ingrandisci (Pixels):" @@ -11736,7 +11718,7 @@ msgstr "Nuova Animazione" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy msgid "Filter animations" -msgstr "Modalità di filtraggio" +msgstr "Modalità di filtraggio animazioni" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" @@ -12031,6 +12013,9 @@ msgid "" "closing this window.\n" "Close anyway?" msgstr "" +"La scheda \"Importa Oggetti\" ha alcuni elementi selezionati. Chiudendo " +"questa finestra si perderà la selezione.\n" +"Chiudere lo stesso?" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove Type" @@ -12539,7 +12524,6 @@ msgid "Palette Min Width" msgstr "Larghezza Min Paletta" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Palette Item H Separation" msgstr "Separazione Orizzontale Elementi Paletta" @@ -13003,14 +12987,13 @@ msgid "Selected Collision" msgstr "Collisione Selezionata" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way" msgstr "Collisione Selezionata Solo Da Una Parte" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "Selected Collision One Way Margin" -msgstr "Margine di Collisione BVH" +msgstr "Margine di Collisione Solo Da Una Parte Selezionato" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Selected Navigation" @@ -13048,14 +13031,12 @@ msgid "Commit" msgstr "Commit" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Staged Changes" -msgstr "Cambiamenti in Scena" +msgstr "Cambiamenti Graduali" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Unstaged Changes" -msgstr "Cambiamenti non in Scena" +msgstr "Cambiamenti non Graduali" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit:" @@ -13208,9 +13189,8 @@ msgid "Typechange" msgstr "Cambio di tipo" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Unmerged" -msgstr "Non mescolato" +msgstr "Non combinato" #: editor/plugins/version_control_editor_plugin.cpp msgid "View:" @@ -14121,12 +14101,10 @@ msgid "Runnable" msgstr "Eseguibile" #: editor/project_export.cpp -#, fuzzy msgid "Export the project for all the presets defined." msgstr "Esporta il progetto per tutti i preset definiti." #: editor/project_export.cpp -#, fuzzy msgid "All presets must have an export path defined for Export All to work." msgstr "" "Tutti i preset devono avere un percorso di esportazione definito affinché " @@ -14251,12 +14229,10 @@ msgid "More Info..." msgstr "Maggiori Informazioni..." #: editor/project_export.cpp -#, fuzzy msgid "Export PCK/Zip..." msgstr "Esporta PCK/Zip..." #: editor/project_export.cpp -#, fuzzy msgid "Export Project..." msgstr "Esporta Progetto..." @@ -14265,12 +14241,10 @@ msgid "Export All" msgstr "Esporta Tutto" #: editor/project_export.cpp -#, fuzzy msgid "Choose an export mode:" -msgstr "Si prega di scegliere una cartella vuota:" +msgstr "Scegli una modalità di esportazione:" #: editor/project_export.cpp -#, fuzzy msgid "Export All..." msgstr "Esporta Tutto..." @@ -14279,18 +14253,16 @@ msgid "ZIP File" msgstr "File ZIP" #: editor/project_export.cpp -#, fuzzy msgid "Godot Project Pack" -msgstr "Pacchetto Gioco Godot" +msgstr "Pacchetto Progetto Godot" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" msgstr "Le export templates per questa piattaforma sono mancanti:" #: editor/project_export.cpp -#, fuzzy msgid "Project Export" -msgstr "Fondatori del progetto" +msgstr "Esporta Progetto" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -15171,7 +15143,6 @@ msgid "snake_case to PascalCase" msgstr "snake_case a PascalCase" #: editor/rename_dialog.cpp -#, fuzzy msgid "Case" msgstr "Caso" @@ -15414,7 +15385,7 @@ msgstr "Abilita Nome Unico Scena" #: editor/scene_tree_dock.cpp #, fuzzy msgid "Unique names already used by another node in the scene:" -msgstr "Un altro nodo sta già usando questo nome unico nella scena." +msgstr "Nomi unici già usati da un altro nodo nella scena:" #: editor/scene_tree_dock.cpp #, fuzzy @@ -15852,7 +15823,6 @@ msgid "Attach Node Script" msgstr "Allega Script Nodo" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Remote %s:" msgstr "Remoto %s:" @@ -15934,7 +15904,7 @@ msgstr "Filtra variabili su stack" #: editor/script_editor_debugger.cpp msgid "Auto Switch To Remote Scene Tree" -msgstr "" +msgstr "Passa automaticamente all'Albero Scena Remota" #: editor/script_editor_debugger.cpp msgid "Remote Scene Tree Refresh Interval" @@ -15942,7 +15912,7 @@ msgstr "Intervallo di Refresh dello Scene Tree Remoto" #: editor/script_editor_debugger.cpp msgid "Remote Inspect Refresh Interval" -msgstr "" +msgstr "Intervallo Aggiornamento Ispettore Remoto" #: editor/script_editor_debugger.cpp msgid "Network Profiler" @@ -16040,7 +16010,7 @@ msgstr "Cambia Raggio Luce" #: editor/spatial_editor_gizmos.cpp msgid "Stream Player 3D" -msgstr "" +msgstr "Stream Player 3D" #: editor/spatial_editor_gizmos.cpp msgid "Change AudioStreamPlayer3D Emission Angle" @@ -16133,12 +16103,14 @@ msgid "Navigation Solid Disabled" msgstr "Solido di Navigazione Disabilitato" #: editor/spatial_editor_gizmos.cpp +#, fuzzy msgid "Joint Body A" -msgstr "" +msgstr "Articolazione Corpo A" #: editor/spatial_editor_gizmos.cpp +#, fuzzy msgid "Joint Body B" -msgstr "" +msgstr "Articolazione Corpo B" #: editor/spatial_editor_gizmos.cpp msgid "Room Edge" @@ -16169,13 +16141,14 @@ msgid "Set Portal Point Position" msgstr "Imposta Posizione Punto Portale" #: editor/spatial_editor_gizmos.cpp +#, fuzzy msgid "Portal Front" -msgstr "" +msgstr "Davanti del Portale" #: editor/spatial_editor_gizmos.cpp #, fuzzy msgid "Portal Back" -msgstr "Torna indietro" +msgstr "Dietro del Portale" #: editor/spatial_editor_gizmos.cpp scene/2d/light_occluder_2d.cpp #: scene/2d/tile_map.cpp @@ -16234,7 +16207,7 @@ msgstr "Server con Multithread" #: main/main.cpp msgid "RID Pool Prealloc" -msgstr "" +msgstr "Preallocazione pool RID" #: main/main.cpp msgid "Debugger stdout" @@ -16267,7 +16240,7 @@ msgstr "Logging" #: main/main.cpp msgid "File Logging" -msgstr "" +msgstr "Logging su file" #: main/main.cpp msgid "Enable File Logging" @@ -16295,7 +16268,7 @@ msgstr "Ripiega Su GLES2" #: main/main.cpp msgid "Use Nvidia Rect Flicker Workaround" -msgstr "" +msgstr "Usa stratagemma contro il flickering rettangoli su NVIDIA" #: main/main.cpp msgid "DPI" @@ -16323,7 +16296,7 @@ msgstr "Permesso" #: main/main.cpp msgid "Intended Usage" -msgstr "" +msgstr "Uso previsto" #: main/main.cpp msgid "Framebuffer Allocation" @@ -16335,7 +16308,7 @@ msgstr "Risparmio Energia" #: main/main.cpp msgid "Threads" -msgstr "" +msgstr "Threads" #: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h msgid "Thread Model" @@ -16411,7 +16384,7 @@ msgstr "Modalità Basso Utilizzo Processore" #: main/main.cpp msgid "Delta Sync After Draw" -msgstr "" +msgstr "Sincronizzazione delta dopo il disegno" #: main/main.cpp msgid "iOS" @@ -16443,9 +16416,8 @@ msgid "Shaders" msgstr "Shaders" #: main/main.cpp -#, fuzzy msgid "Debug Shader Fallbacks" -msgstr "Forza fallback dello shader" +msgstr "Forza Fallback dello Shader" #: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp #: scene/3d/world_environment.cpp scene/main/scene_tree.cpp @@ -16456,7 +16428,7 @@ msgstr "Ambiente" #: main/main.cpp #, fuzzy msgid "Default Clear Color" -msgstr "Colore Di Cancellamento Di Default" +msgstr "Colore Di Sfondo Di Default" #: main/main.cpp msgid "Boot Splash" @@ -16492,7 +16464,7 @@ msgstr "Icona Nativa Di Windows" #: main/main.cpp msgid "Buffering" -msgstr "" +msgstr "Buffering" #: main/main.cpp msgid "Agile Event Flushing" @@ -16516,7 +16488,7 @@ msgstr "Immagine Personalizzata" #: main/main.cpp msgid "Custom Image Hotspot" -msgstr "" +msgstr "Punto focale immagine personalizzato" #: main/main.cpp msgid "Tooltip Position Offset" @@ -16540,7 +16512,7 @@ msgstr "Esecuzione" #: main/main.cpp msgid "Unhandled Exception Policy" -msgstr "" +msgstr "Regola per eccezioni non gestite" #: main/main.cpp msgid "Main Loop Type" diff --git a/editor/translations/ja.po b/editor/translations/ja.po index f086111ef2..2570cb6288 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -42,13 +42,14 @@ # cacapon <takuma.tsubo@amazingengine.co.jp>, 2022. # fadhliazhari <m.fadhliazhari@gmail.com>, 2022. # Chia-Hsiang Cheng <cche0109@student.monash.edu>, 2022. +# meko <hirono.yoneyama@outlook.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-08-21 06:01+0000\n" -"Last-Translator: KokiOgawa <mupimupicandy@gmail.com>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: nitenook <admin@alterbaum.net>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" "Language: ja\n" @@ -56,7 +57,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -185,9 +186,8 @@ msgid "Time Scale" msgstr "タイムスケール" #: core/bind/core_bind.cpp main/main.cpp -#, fuzzy msgid "Physics Jitter Fix" -msgstr "物理ジッタ修正" +msgstr "物理のジッター修正" #: core/bind/core_bind.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Error" @@ -325,9 +325,8 @@ msgid "Data Array" msgstr "データ配列" #: core/io/stream_peer_ssl.cpp -#, fuzzy msgid "Blocking Handshake" -msgstr "ハンドシェイクを阻止すること" +msgstr "ハンドシェイクをブロッキング処理にする" #: core/io/udp_server.cpp msgid "Max Pending Connections" @@ -399,7 +398,7 @@ msgstr "マウスモード" #: core/os/input.cpp msgid "Use Accumulated Input" -msgstr "蓄積入力使用" +msgstr "蓄積された入力を使用" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -645,10 +644,12 @@ msgid "Always On Top" msgstr "常に最前面" #: core/project_settings.cpp +#, fuzzy msgid "Test Width" msgstr "幅テスト" #: core/project_settings.cpp +#, fuzzy msgid "Test Height" msgstr "高さテスト" @@ -743,7 +744,7 @@ msgstr "UI ページダウン" #: core/project_settings.cpp msgid "UI Home" -msgstr "ホーム" +msgstr "UI ホーム" #: core/project_settings.cpp msgid "UI End" @@ -771,9 +772,8 @@ msgid "3D" msgstr "3D" #: core/project_settings.cpp -#, fuzzy msgid "Smooth Trimesh Collision" -msgstr "スムーズ三角形メッシュコリジョン" +msgstr "三角形メッシュ コリジョンをスムーズ化" #: core/project_settings.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles2/rasterizer_scene_gles2.cpp @@ -800,7 +800,6 @@ msgstr "品質" #: core/project_settings.cpp scene/gui/file_dialog.cpp #: scene/main/scene_tree.cpp scene/resources/navigation_mesh.cpp #: servers/visual_server.cpp -#, fuzzy msgid "Filters" msgstr "フィルター" @@ -831,9 +830,8 @@ msgid "Profiler" msgstr "プロファイラー" #: core/project_settings.cpp -#, fuzzy msgid "Max Functions" -msgstr "最大関数" +msgstr "関数の上限" #: core/project_settings.cpp scene/3d/vehicle_body.cpp msgid "Compression" @@ -856,6 +854,7 @@ msgid "Compression Level" msgstr "圧縮レベル" #: core/project_settings.cpp +#, fuzzy msgid "Window Log Size" msgstr "Windowのログサイズ" @@ -1056,6 +1055,7 @@ msgid "Follow Surface" msgstr "サーフェスをフォローする" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Weight Samples" msgstr "重量サンプル" @@ -1143,7 +1143,6 @@ msgstr "アニメーション呼び出しの変更" #: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Frame" msgstr "フレーム" @@ -1171,9 +1170,8 @@ msgid "Value" msgstr "値" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Arg Count" -msgstr "引数数" +msgstr "引数の数" #: editor/animation_track_editor.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp @@ -1205,12 +1203,10 @@ msgid "Stream" msgstr "ストリーム" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start Offset" msgstr "始点オフセット" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End Offset" msgstr "終点オフセット" @@ -1225,9 +1221,8 @@ msgid "Animation" msgstr "アニメーション" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing" -msgstr "イージング(In-Out)" +msgstr "イージング" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1336,19 +1331,16 @@ msgid "Remove this track." msgstr "このトラックを除去する。" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Time (s):" -msgstr "時間 (秒): " +msgstr "時間 (秒):" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Position:" -msgstr "位置" +msgstr "位置:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Rotation:" -msgstr "回転のステップ:" +msgstr "回転:" #: editor/animation_track_editor.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -1365,14 +1357,12 @@ msgid "Type:" msgstr "型:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "(Invalid, expected type: %s)" -msgstr "無効なエクスポート テンプレート:" +msgstr "(無効, 予期されたタイプ: %s)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing:" -msgstr "イージング(In-Out)" +msgstr "イージング:" #: editor/animation_track_editor.cpp #, fuzzy @@ -1385,24 +1375,20 @@ msgid "Out-Handle:" msgstr "ハンドルを設定する" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Stream:" -msgstr "ストリーム" +msgstr "ストリーム:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start (s):" -msgstr "リスタート:" +msgstr "開始:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End (s):" -msgstr "フェードイン:" +msgstr "終了:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Clip:" -msgstr "アニメーション:" +msgstr "アニメーションクリップ:" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -1617,9 +1603,8 @@ msgid "Add Method Track Key" msgstr "メソッドトラックキーの追加" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Method not found in object:" -msgstr "オブジェクトにメソッドが見つかりません: " +msgstr "オブジェクト内にメソッドが見つかりません:" #: editor/animation_track_editor.cpp msgid "Anim Move Keys" @@ -2230,9 +2215,8 @@ msgid "Open" msgstr "開く" #: editor/dependency_editor.cpp -#, fuzzy msgid "Owners of: %s (Total: %d)" -msgstr "所有者: %s (合計: %d)" +msgstr "%s のオーナー (合計: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2343,7 +2327,6 @@ msgstr "開発リーダー" #. TRANSLATORS: This refers to a job title. #: editor/editor_about.cpp -#, fuzzy msgctxt "Job Title" msgid "Project Manager" msgstr "プロジェクトマネージャー" @@ -2587,9 +2570,8 @@ msgid "There is no '%s' file." msgstr "'%s' ファイルがありません。" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Layout:" -msgstr "レイアウト" +msgstr "レイアウト:" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -2667,7 +2649,7 @@ msgstr "既存のグローバル定数名と重複してはいけません。" #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "キーワードは自動ロード名として使用できません。" +msgstr "キーワードは自動読み込みの名前として使用できません。" #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -2788,27 +2770,23 @@ msgstr "フォルダーを作成できませんでした。" #: editor/editor_dir_dialog.cpp msgid "Choose" -msgstr "選ぶ" +msgstr "選択" #: editor/editor_export.cpp -#, fuzzy msgid "Project export for platform:" -msgstr "プラットフォーム用のプロジェクトエクスポート:" +msgstr "次のプラットフォーム向けにプロジェクトをエクスポート:" #: editor/editor_export.cpp -#, fuzzy msgid "Completed with warnings." -msgstr "ノードのパスをコピー" +msgstr "完了しましたが、警告があります。" #: editor/editor_export.cpp -#, fuzzy msgid "Completed successfully." -msgstr "パッケージのインストールに成功しました!" +msgstr "正常に完了しました。" #: editor/editor_export.cpp -#, fuzzy msgid "Failed." -msgstr "失敗:" +msgstr "失敗しました。" #: editor/editor_export.cpp msgid "Storing File:" @@ -2823,29 +2801,24 @@ msgid "Packing" msgstr "パック中" #: editor/editor_export.cpp -#, fuzzy msgid "Save PCK" -msgstr "名前を付けて保存" +msgstr "PCKを保存" #: editor/editor_export.cpp -#, fuzzy msgid "Cannot create file \"%s\"." -msgstr "フォルダーを作成できませんでした。" +msgstr "ファイル \"%s\" を作成できませんでした。" #: editor/editor_export.cpp -#, fuzzy msgid "Failed to export project files." -msgstr "プロジェクトファイルをエクスポートできませんでした" +msgstr "プロジェクトファイルをエクスポートできませんでした。" #: editor/editor_export.cpp -#, fuzzy msgid "Can't open file to read from path \"%s\"." -msgstr "書き込むファイルを開けません:" +msgstr "読み込むファイルをパス \"%s\" から開けません。" #: editor/editor_export.cpp -#, fuzzy msgid "Save ZIP" -msgstr "名前を付けて保存" +msgstr "ZIPを保存" #: editor/editor_export.cpp msgid "" @@ -2926,39 +2899,32 @@ msgid "64 Bits" msgstr "64ビット" #: editor/editor_export.cpp -#, fuzzy msgid "Embed PCK" msgstr "組み込みPCK" #: editor/editor_export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Texture Format" -msgstr "テクスチャ領域" +msgstr "テクスチャ形式" #: editor/editor_export.cpp -#, fuzzy msgid "BPTC" msgstr "BPTC" #: editor/editor_export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "S3TC" msgstr "S3TC" #: editor/editor_export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "ETC" -msgstr "TCP" +msgstr "ETC" #: editor/editor_export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "ETC2" msgstr "ETC2" #: editor/editor_export.cpp -#, fuzzy msgid "No BPTC Fallbacks" -msgstr "フォールバック" +msgstr "BPTCにフォールバックしない" #: editor/editor_export.cpp platform/android/export/export_plugin.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -2973,30 +2939,25 @@ msgid "Custom release template not found." msgstr "カスタム リリーステンプレートが見つかりません。" #: editor/editor_export.cpp -#, fuzzy msgid "Prepare Template" -msgstr "テンプレートの管理" +msgstr "テンプレートの準備" #: editor/editor_export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "The given export path doesn't exist." -msgstr "指定されたエクスポートパスが存在しません:" +msgstr "指定されたエクスポートパスが存在しません。" #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found: \"%s\"." -msgstr "テンプレートファイルが見つかりません:" +msgstr "テンプレートファイルが見つかりません: \"%s\"。" #: editor/editor_export.cpp -#, fuzzy msgid "Failed to copy export template." -msgstr "無効なエクスポート テンプレート:" +msgstr "エクスポートテンプレートのコピーに失敗しました。" #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp -#, fuzzy msgid "PCK Embedding" -msgstr "パディング" +msgstr "PCKの組み込み" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." @@ -3416,6 +3377,7 @@ msgid "ScanSources" msgstr "スキャンソース" #: editor/editor_file_system.cpp +#, fuzzy msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" @@ -4383,14 +4345,12 @@ msgid "Update Vital Only" msgstr "マテリアルの変更:" #: editor/editor_node.cpp -#, fuzzy msgid "Localize Settings" -msgstr "ローカライズ" +msgstr "ローカライズの設定" #: editor/editor_node.cpp -#, fuzzy msgid "Restore Scenes On Load" -msgstr "タイムシーク ノード" +msgstr "ロード時にシーンを復元" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Show Thumbnail On Hover" @@ -4401,23 +4361,20 @@ msgid "Inspector" msgstr "インスペクター" #: editor/editor_node.cpp -#, fuzzy msgid "Default Property Name Style" -msgstr "デフォルトのプロジェクトパス" +msgstr "デフォルトのプロパティ名のスタイル" #: editor/editor_node.cpp -#, fuzzy msgid "Default Float Step" -msgstr "デフォルトフロートステップ" +msgstr "デフォルトの小数点数のステップ" #: editor/editor_node.cpp scene/gui/tree.cpp msgid "Disable Folding" msgstr "折りたたみを無効化" #: editor/editor_node.cpp -#, fuzzy msgid "Auto Unfold Foreign Scenes" -msgstr "自動展開外来シーン" +msgstr "外部シーンの自動展開" #: editor/editor_node.cpp #, fuzzy @@ -4434,9 +4391,8 @@ msgid "Open Resources In Current Inspector" msgstr "リソースを現在のインスペクターで開く" #: editor/editor_node.cpp -#, fuzzy msgid "Resources To Open In New Inspector" -msgstr "インスペクターで開く" +msgstr "新規インスペクターで開くリソース" #: editor/editor_node.cpp msgid "Default Color Picker Mode" @@ -5096,14 +5052,12 @@ msgid "Debugger" msgstr "デバッガー" #: editor/editor_profiler.cpp -#, fuzzy msgid "Profiler Frame History Size" -msgstr "プロファイラフレーム履歴サイズ" +msgstr "プロファイラーフレームの履歴サイズ" #: editor/editor_profiler.cpp -#, fuzzy msgid "Profiler Frame Max Functions" -msgstr "プロファイラフレーム最大関数数" +msgstr "プロファイラーフレームの関数の上限" #: editor/editor_properties.cpp msgid "Edit Text:" @@ -5131,7 +5085,7 @@ msgstr "[空]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp msgid "Assign..." -msgstr "割り当て.." +msgstr "割り当て..." #: editor/editor_properties.cpp msgid "Invalid RID" @@ -5240,9 +5194,8 @@ msgid "Base Type" msgstr "基底型を変更" #: editor/editor_resource_picker.cpp -#, fuzzy msgid "Edited Resource" -msgstr "リソースを追加" +msgstr "編集したリソース" #: editor/editor_resource_picker.cpp scene/gui/line_edit.cpp #: scene/gui/slider.cpp scene/gui/spin_box.cpp @@ -5272,9 +5225,8 @@ msgstr "" "行可能にしてください。" #: editor/editor_run_native.cpp -#, fuzzy msgid "Project Run" -msgstr "プロジェクト" +msgstr "プロジェクトの実行" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." @@ -5360,7 +5312,6 @@ msgid "Separate Distraction Mode" msgstr "集中モード" #: editor/editor_settings.cpp -#, fuzzy msgid "Automatically Open Screenshots" msgstr "自動的にスクリーンショットを開く" @@ -5414,9 +5365,8 @@ msgid "Use Graph Node Headers" msgstr "グラフ ノード ヘッダーを使用する" #: editor/editor_settings.cpp -#, fuzzy msgid "Additional Spacing" -msgstr "アニメーションループ" +msgstr "追加の間隔" #: editor/editor_settings.cpp msgid "Custom Theme" @@ -5427,14 +5377,12 @@ msgid "Show Script Button" msgstr "スクリプトボタンを表示" #: editor/editor_settings.cpp -#, fuzzy msgid "Directories" -msgstr "方向" +msgstr "ディレクトリ" #: editor/editor_settings.cpp -#, fuzzy msgid "Autoscan Project Path" -msgstr "プロジェクトパス:" +msgstr "自動スキャンするプロジェクトパス" #: editor/editor_settings.cpp msgid "Default Project Path" @@ -5445,9 +5393,8 @@ msgid "On Save" msgstr "保存時" #: editor/editor_settings.cpp -#, fuzzy msgid "Compress Binary Resources" -msgstr "リソースをコピー" +msgstr "バイナリリソースの圧縮" #: editor/editor_settings.cpp #, fuzzy @@ -5463,18 +5410,16 @@ msgid "Thumbnail Size" msgstr "サムネイルのサイズ" #: editor/editor_settings.cpp -#, fuzzy msgid "Docks" -msgstr "Docks" +msgstr "ドック" #: editor/editor_settings.cpp msgid "Scene Tree" msgstr "シーンツリー" #: editor/editor_settings.cpp -#, fuzzy msgid "Start Create Dialog Fully Expanded" -msgstr "完全に展開された作成ダイアログを開始する" +msgstr "新規作成ダイアログの開始時にすべてを展開する" #: editor/editor_settings.cpp msgid "Always Show Folders" @@ -5572,14 +5517,12 @@ msgid "Mouse Extra Buttons Navigate History" msgstr "マウス追加ボタンナビゲート履歴" #: editor/editor_settings.cpp -#, fuzzy msgid "Drag And Drop Selection" -msgstr "GridMap の選択" +msgstr "選択範囲のドラッグ&ドロップ" #: editor/editor_settings.cpp -#, fuzzy msgid "Stay In Script Editor On Node Selected" -msgstr "ノード選択時にスクリプトエディタにとどまる" +msgstr "ノード選択時にスクリプトエディターにとどまる" #: editor/editor_settings.cpp msgid "Appearance" @@ -5613,7 +5556,6 @@ msgid "Code Folding" msgstr "コードの折りたたみ" #: editor/editor_settings.cpp -#, fuzzy msgid "Word Wrap" msgstr "ワードラップ" @@ -5641,7 +5583,6 @@ msgid "Show Members Overview" msgstr "メンバー概要を表示" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Files" msgstr "ファイル" @@ -5651,7 +5592,7 @@ msgstr "保存時に末尾の空白を取り除く" #: editor/editor_settings.cpp msgid "Autosave Interval Secs" -msgstr "自動保存の間隔秒数" +msgstr "自動保存する間隔の秒数" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp msgid "Restore Scripts On Load" @@ -5679,9 +5620,8 @@ msgid "Cursor" msgstr "カーソル" #: editor/editor_settings.cpp -#, fuzzy msgid "Scroll Past End Of File" -msgstr "ファイルの終わりを過ぎてスクロールする" +msgstr "ファイルの末尾を越えたスクロール" #: editor/editor_settings.cpp msgid "Block Caret" @@ -5706,34 +5646,28 @@ msgid "Completion" msgstr "完了" #: editor/editor_settings.cpp -#, fuzzy msgid "Idle Parse Delay" -msgstr "アイドル解析遅延" +msgstr "アイドル時の解析の遅延" #: editor/editor_settings.cpp -#, fuzzy msgid "Auto Brace Complete" -msgstr "自動ブレース補完" +msgstr "波括弧の自動補完" #: editor/editor_settings.cpp -#, fuzzy msgid "Code Complete Delay" -msgstr "コード補完遅延" +msgstr "コード補完の遅延" #: editor/editor_settings.cpp -#, fuzzy msgid "Put Callhint Tooltip Below Current Line" -msgstr "コールヒントツールチップを現在の行の下に配置" +msgstr "コード補完ツールチップを現在の行の下に配置" #: editor/editor_settings.cpp -#, fuzzy msgid "Callhint Tooltip Offset" -msgstr "コールヒントツールチップオフセット" +msgstr "コード補完ツールチップのオフセット" #: editor/editor_settings.cpp -#, fuzzy msgid "Complete File Paths" -msgstr "ノードのパスをコピー" +msgstr "ファイルパスの補完" #: editor/editor_settings.cpp modules/gdscript/gdscript_editor.cpp #, fuzzy @@ -5802,9 +5736,8 @@ msgstr "インスタンス化済" #: editor/editor_settings.cpp modules/gltf/gltf_node.cpp #: scene/3d/physics_body.cpp -#, fuzzy msgid "Joint" -msgstr "点" +msgstr "ジョイント" #: editor/editor_settings.cpp scene/2d/collision_shape_2d.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/touch_screen_button.cpp @@ -5821,39 +5754,32 @@ msgid "Primary Grid Steps" msgstr "グリッドのステップ:" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid Size" -msgstr "グリッドのステップ:" +msgstr "グリッドのサイズ" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid Division Level Max" -msgstr "グリッド分割レベル最大" +msgstr "グリッドの分割の最大レベル" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid Division Level Min" -msgstr "グリッド分割レベル最小" +msgstr "グリッドの分割の最小レベル" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid Division Level Bias" -msgstr "グリッド分割レベルバイアス" +msgstr "グリッドの分割レベルのバイアス" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid XZ Plane" -msgstr "GridMap ペイント" +msgstr "グリッドのXZ平面" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid XY Plane" -msgstr "GridMap ペイント" +msgstr "グリッドのXY平面" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid YZ Plane" -msgstr "GridMap ペイント" +msgstr "グリッドのYZ平面" #: editor/editor_settings.cpp msgid "Default FOV" @@ -5872,9 +5798,8 @@ msgid "Lightmap Baking Number Of CPU Threads" msgstr "ライトマップベイクのCPUスレッド数" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Scheme" -msgstr "ナビゲーションモード" +msgstr "ナビゲーションの方式" #: editor/editor_settings.cpp msgid "Invert Y Axis" @@ -6037,9 +5962,8 @@ msgid "Pan Speed" msgstr "速度:" #: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Poly Editor" -msgstr "Polygon 2D UV エディター" +msgstr "ポリゴンエディター" #: editor/editor_settings.cpp #, fuzzy @@ -6052,19 +5976,16 @@ msgid "Show Previous Outline" msgstr "前の平面" #: editor/editor_settings.cpp editor/scene_tree_dock.cpp -#, fuzzy msgid "Autorename Animation Tracks" -msgstr "アニメーションの名前を変更" +msgstr "アニメーションのトラック名を自動変更" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Create Bezier Tracks" -msgstr "デフォルトベジェトラックを作成" +msgstr "デフォルトでベジェトラックを作成" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Create Reset Tracks" -msgstr "RESETトラックを作成" +msgstr "デフォルトでRESETトラックを作成" #: editor/editor_settings.cpp #, fuzzy @@ -6086,21 +6007,18 @@ msgid "Minimap Opacity" msgstr "ミニマップの不透明度" #: editor/editor_settings.cpp -#, fuzzy msgid "Window Placement" msgstr "ウィンドウの配置" #: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp #: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp #: scene/gui/control.cpp -#, fuzzy msgid "Rect" -msgstr "Rect全面" +msgstr "矩形" #: editor/editor_settings.cpp -#, fuzzy msgid "Rect Custom Position" -msgstr "曲線のOut-Controlの位置を指定" +msgstr "矩形のカスタム位置" #: editor/editor_settings.cpp platform/android/export/export_plugin.cpp msgid "Screen" @@ -6228,9 +6146,8 @@ msgid "Line Number Color" msgstr "行番号の色" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Safe Line Number Color" -msgstr "行番号:" +msgstr "安全な行番号の色" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Caret Color" @@ -6314,9 +6231,8 @@ msgid "Flat" msgstr "フラット" #: editor/editor_spin_slider.cpp -#, fuzzy msgid "Hide Slider" -msgstr "コリジョンモード" +msgstr "スライダーを隠す" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" @@ -6994,33 +6910,28 @@ msgstr "フォルダーを作成" #: editor/import/resource_importer_bitmask.cpp #: servers/audio/effects/audio_effect_compressor.cpp -#, fuzzy msgid "Threshold" -msgstr "閾" +msgstr "しきい値" #: editor/import/resource_importer_csv_translation.cpp #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_scene.cpp #: editor/import/resource_importer_texture.cpp #: editor/import/resource_importer_wav.cpp scene/3d/gi_probe.cpp -#, fuzzy msgid "Compress" -msgstr "コンポーネント" +msgstr "圧縮" #: editor/import/resource_importer_csv_translation.cpp -#, fuzzy msgid "Delimiter" msgstr "区切り文字" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "ColorCorrect" -msgstr "Color関数。" +msgstr "ColorCorrect" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "No BPTC If RGB" -msgstr "RGB使用中の場合はBPTCを使用しない" +msgstr "RGBの場合はBPTCなしにする" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/2d/cpu_particles_2d.cpp @@ -7033,22 +6944,19 @@ msgstr "フラグ" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/animation/tween.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Repeat" msgstr "繰り返し" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp #: scene/gui/control.cpp -#, fuzzy msgid "Filter" -msgstr "フィルター:" +msgstr "フィルター" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Mipmaps" -msgstr "シグナル" +msgstr "ミップマップ" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp @@ -7062,30 +6970,26 @@ msgid "sRGB" msgstr "sRGB" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "Slices" -msgstr "自動スライス" +msgstr "スライス" #: editor/import/resource_importer_layered_texture.cpp #: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp #: scene/gui/nine_patch_rect.cpp scene/gui/scroll_container.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Horizontal" -msgstr "水平:" +msgstr "水平" #: editor/import/resource_importer_layered_texture.cpp #: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp #: scene/gui/nine_patch_rect.cpp scene/gui/scroll_container.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Vertical" -msgstr "垂直:" +msgstr "垂直" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Generate Tangents" -msgstr "ポイントを生成" +msgstr "接線を生成" #: editor/import/resource_importer_obj.cpp #, fuzzy @@ -7093,9 +6997,8 @@ msgid "Scale Mesh" msgstr "スケールモード" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Offset Mesh" -msgstr "オフセット:" +msgstr "メッシュのオフセット" #: editor/import/resource_importer_obj.cpp #: editor/import/resource_importer_scene.cpp @@ -7150,24 +7053,20 @@ msgstr "複数のシーン+マテリアルとしてインポート" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Nodes" msgstr "ノード" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Type" -msgstr "Return(戻り値)" +msgstr "ルートの型" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Name" -msgstr "リモート名" +msgstr "ルートの名前" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Scale" -msgstr "スケール" +msgstr "ルートのスケール" #: editor/import/resource_importer_scene.cpp #, fuzzy @@ -7175,19 +7074,16 @@ msgid "Custom Script" msgstr "ノードを切り取る" #: editor/import/resource_importer_scene.cpp scene/resources/texture.cpp -#, fuzzy msgid "Storage" -msgstr "ファイルの保存:" +msgstr "ストレージ" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Legacy Names" -msgstr "従来の名前を使用" +msgstr "レガシーな名前を使用" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp -#, fuzzy msgid "Materials" -msgstr "マテリアルの変更:" +msgstr "マテリアル" #: editor/import/resource_importer_scene.cpp #, fuzzy @@ -7195,7 +7091,6 @@ msgid "Keep On Reimport" msgstr "再インポート" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp -#, fuzzy msgid "Meshes" msgstr "メッシュ" @@ -7215,27 +7110,22 @@ msgid "Lightmap Texel Size" msgstr "ライトマップを焼き込む" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skins" msgstr "スキン" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Named Skins" -msgstr "スケールスナップを使用" +msgstr "名前付きスキンの使用" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "External Files" -msgstr "外部" +msgstr "外部ファイル" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Store In Subdir" msgstr "サブディレクトリに保存" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Filter Script" msgstr "スクリプトを絞り込む" @@ -7261,7 +7151,6 @@ msgstr "最適化" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp #: scene/gui/rich_text_label.cpp scene/resources/curve.cpp #: scene/resources/environment.cpp scene/resources/material.cpp -#, fuzzy msgid "Enabled" msgstr "有効" @@ -7281,14 +7170,12 @@ msgid "Max Angle" msgstr "値" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Remove Unused Tracks" -msgstr "アニメーショントラックを除去" +msgstr "未使用のトラックを除去" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Clips" -msgstr "アニメーションクリップ" +msgstr "クリップ" #: editor/import/resource_importer_scene.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/area.cpp scene/3d/cpu_particles.cpp @@ -7366,7 +7253,7 @@ msgstr "2D、3D検出" #: editor/import/resource_importer_texture.cpp #, fuzzy msgid "2D Pixel" -msgstr "凝集ピクセル" +msgstr "2Dピクセル" #: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp #, fuzzy @@ -7374,9 +7261,8 @@ msgid "Lossy Quality" msgstr "損失のある品質" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "HDR Mode" -msgstr "選択モード" +msgstr "HDRモード" #: editor/import/resource_importer_texture.cpp msgid "BPTC LDR" @@ -7386,7 +7272,6 @@ msgstr "BPTC LDR" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/mesh_instance_2d.cpp scene/2d/multimesh_instance_2d.cpp #: scene/2d/particles_2d.cpp scene/2d/sprite.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Normal Map" msgstr "法線マップ" @@ -7430,28 +7315,24 @@ msgid "Detect 3D" msgstr "3Dを検出" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "SVG" -msgstr "CSG" +msgstr "SVG" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "" "Warning, no suitable PC VRAM compression enabled in Project Settings. This " "texture will not display correctly on PC." msgstr "" -"警告、プロジェクト設定で有効な適切なPC VRAM圧縮がありません。このテクスチャ" -"は PCで正しく表示されません。" +"警告、プロジェクト設定で適切なPC VRAM圧縮が有効化されていません。このテクス" +"チャは PCで正しく表示されません。" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Atlas File" -msgstr "アウトラインのサイズ:" +msgstr "アトラスファイル" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Import Mode" -msgstr "エクスポートモード:" +msgstr "インポートモード" #: editor/import/resource_importer_texture_atlas.cpp #, fuzzy @@ -7469,7 +7350,6 @@ msgid "Force" msgstr "強制プッシュ" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "8 Bit" msgstr "8ビット" @@ -7490,32 +7370,27 @@ msgid "Max Rate Hz" msgstr "ミックス ノード" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Trim" msgstr "トリム" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Normalize" -msgstr "フォーマット" +msgstr "ノーマライズ" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Mode" -msgstr "移動モード" +msgstr "ループモード" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Begin" -msgstr "移動モード" +msgstr "ループの開始" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop End" -msgstr "移動モード" +msgstr "ループの終了" #: editor/import_defaults_editor.cpp msgid "Select Importer" @@ -7585,17 +7460,16 @@ msgid "" "Select a resource file in the filesystem or in the inspector to adjust " "import settings." msgstr "" -"ファイルシステムや Inspector にある Resource ファイルを選択してインポート設定" -"を調整してください。" +"ファイルシステムやインスペクターにあるリソースファイルを選択してインポート設" +"定を調整します。" #: editor/inspector_dock.cpp msgid "Failed to load resource." msgstr "リソースの読み込みに失敗しました。" #: editor/inspector_dock.cpp -#, fuzzy msgid "Property Name Style" -msgstr "プロジェクト名:" +msgstr "プロパティ名のスタイル" #: editor/inspector_dock.cpp scene/gui/color_picker.cpp msgid "Raw" @@ -7607,14 +7481,12 @@ msgid "Capitalized" msgstr "単語の先頭文字を大文字に" #: editor/inspector_dock.cpp -#, fuzzy msgid "Localized" -msgstr "ロケール" +msgstr "ローカライズ済" #: editor/inspector_dock.cpp -#, fuzzy msgid "Localization not available for current language." -msgstr "現地語化は現在の言語では使用できません。" +msgstr "ローカライズ化は現在の言語では使用できません。" #: editor/inspector_dock.cpp msgid "Copy Properties" @@ -8347,9 +8219,8 @@ msgid "Set the end animation. This is useful for sub-transitions." msgstr "終了アニメーションを設定する。これはサブトランジションに便利です。" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Transition:" -msgstr "トランジション: " +msgstr "トランジション:" #: editor/plugins/animation_state_machine_editor.cpp msgid "Play Mode:" @@ -8650,25 +8521,21 @@ msgid "Loading..." msgstr "読み込み中..." #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "First" msgstr "最初" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Previous" msgstr "前" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Next" msgstr "次" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Last" msgstr "最後" @@ -8718,9 +8585,8 @@ msgid "Testing" msgstr "試験的" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Failed to get repository configuration." -msgstr "リポジトリを構成できませんでした。" +msgstr "リポジトリ構成を取得できませんでした。" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" @@ -9657,9 +9523,8 @@ msgid "Swap Gradient Fill Points" msgstr "Gradient の塗りつぶしポイントを入れ替え" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp -#, fuzzy msgid "Toggle Grid Snap" -msgstr "グリッドの切り替え" +msgstr "グリッドスナップの切り替え" #: editor/plugins/item_list_editor_plugin.cpp editor/project_export.cpp #: scene/3d/label_3d.cpp scene/gui/button.cpp scene/gui/dialogs.cpp @@ -9682,9 +9547,8 @@ msgstr "ID" #: editor/plugins/item_list_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Separator" -msgstr "分離:" +msgstr "セパレーター" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" @@ -9920,7 +9784,6 @@ msgstr "" "%s" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "MeshLibrary" msgstr "メッシュライブラリ" @@ -10855,7 +10718,6 @@ msgid "List Script Names As" msgstr "スクリプト名:" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Exec Flags" msgstr "実行フラグ" @@ -11738,9 +11600,8 @@ msgid "Invalid geometry, can't replace by mesh." msgstr "ジオメトリが無効です。メッシュに置き換えることはできません。" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to MeshInstance2D" -msgstr "Mesh2Dに変換する" +msgstr "MeshInstance2Dに変換する" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." @@ -11776,14 +11637,12 @@ msgid "Simplification:" msgstr "簡略化: " #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Shrink (Pixels):" -msgstr "縮小 (ピクセル): " +msgstr "縮小 (ピクセル):" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Grow (Pixels):" -msgstr "拡大(ピクセル): " +msgstr "拡大(ピクセル):" #: editor/plugins/sprite_editor_plugin.cpp msgid "Update Preview" @@ -11846,9 +11705,8 @@ msgid "New Animation" msgstr "新規アニメーション" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Filter animations" -msgstr "メソッドを絞り込む" +msgstr "アニメーションを絞り込む" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" @@ -13043,9 +12901,8 @@ msgstr "スナッピングオプション" #: scene/gui/graph_node.cpp scene/gui/rich_text_effect.cpp #: scene/main/canvas_layer.cpp scene/resources/material.cpp #: scene/resources/particles_material.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Offset" -msgstr "オフセット:" +msgstr "オフセット" #: editor/plugins/tile_set_editor_plugin.cpp editor/rename_dialog.cpp #: scene/gui/range.cpp scene/resources/animation.cpp @@ -13072,9 +12929,8 @@ msgstr "選択" #: scene/gui/nine_patch_rect.cpp scene/gui/texture_rect.cpp #: scene/resources/material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Texture" -msgstr "テキスト" +msgstr "テクスチャ" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13094,9 +12950,8 @@ msgid "Modulate" msgstr "データの投入" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Mode" -msgstr "モード切り替え" +msgstr "タイルモード" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13104,24 +12959,20 @@ msgid "Autotile Bitmask Mode" msgstr "ビットマスクモード" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Size" -msgstr "アウトラインのサイズ:" +msgstr "サブタイルのサイズ" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Spacing" -msgstr "行間隔" +msgstr "サブタイルの間隔" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occluder Offset" -msgstr "オクルーダーポリゴンを生成" +msgstr "オクルーダーのオフセット" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Offset" -msgstr "ナビゲーションモード" +msgstr "ナビゲーションのオフセット" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -14357,51 +14208,44 @@ msgid "" msgstr "" #: editor/project_export.cpp -#, fuzzy msgid "More Info..." -msgstr "移動..." +msgstr "詳細情報..." #: editor/project_export.cpp -#, fuzzy msgid "Export PCK/Zip..." -msgstr "PCK/Zipのエクスポート" +msgstr "PCK/Zipのエクスポート..." #: editor/project_export.cpp -#, fuzzy msgid "Export Project..." -msgstr "プロジェクトのエクスポート" +msgstr "プロジェクトのエクスポート..." #: editor/project_export.cpp msgid "Export All" msgstr "すべてエクスポート" #: editor/project_export.cpp -#, fuzzy msgid "Choose an export mode:" -msgstr "空のフォルダーを選択してください。" +msgstr "エクスポートのモードを選択:" #: editor/project_export.cpp -#, fuzzy msgid "Export All..." -msgstr "すべてエクスポート" +msgstr "すべてエクスポート..." #: editor/project_export.cpp editor/project_manager.cpp msgid "ZIP File" msgstr "ZIPファイル" #: editor/project_export.cpp -#, fuzzy msgid "Godot Project Pack" -msgstr "Godotゲームパック" +msgstr "Godotプロジェクトパック" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" msgstr "このプラットフォームに対するエクスポート テンプレートが見つかりません:" #: editor/project_export.cpp -#, fuzzy msgid "Project Export" -msgstr "プロジェクト創始者" +msgstr "プロジェクトのエクスポート" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -14485,7 +14329,7 @@ msgstr "project.godot をプロジェクトパスに生成できませんでし #: editor/project_manager.cpp msgid "Error opening package file, not in ZIP format." -msgstr "パッケージファイルを開けませんでした、zip 形式ではありません。" +msgstr "パッケージファイルを開けませんでした、ZIP形式ではありません。" #: editor/project_manager.cpp msgid "The following files failed extraction from package:" @@ -14712,7 +14556,6 @@ msgstr "" #. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp -#, fuzzy msgctxt "Application" msgid "Project Manager" msgstr "プロジェクトマネージャー" @@ -15805,7 +15648,7 @@ msgstr "無効なノード名。以下の文字は使えません:" #: editor/scene_tree_editor.cpp msgid "Another node already uses this unique name in the scene." -msgstr "" +msgstr "既にシーン中の他のノードにこの固有名が使われています。" #: editor/scene_tree_editor.cpp msgid "Rename Node" @@ -15956,9 +15799,8 @@ msgid "Attach Node Script" msgstr "ノードにスクリプトをアタッチする" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Remote %s:" -msgstr "リモート " +msgstr "リモート %s:" #: editor/script_editor_debugger.cpp msgid "Bytes:" @@ -16046,7 +15888,7 @@ msgstr "リモートシーンツリーの更新間隔" #: editor/script_editor_debugger.cpp msgid "Remote Inspect Refresh Interval" -msgstr "" +msgstr "リモートインスペクトのリフレッシュ間隔" #: editor/script_editor_debugger.cpp msgid "Network Profiler" @@ -16154,7 +15996,7 @@ msgstr "AudioStreamPlayer3Dの放射角度を変更する" #: platform/osx/export/export.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Camera" -msgstr "" +msgstr "カメラ" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" @@ -16238,11 +16080,11 @@ msgstr "ナビゲーションソリッド無効化" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body A" -msgstr "" +msgstr "ジョイント ボディA" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body B" -msgstr "" +msgstr "ジョイント ボディB" #: editor/spatial_editor_gizmos.cpp msgid "Room Edge" @@ -16283,9 +16125,8 @@ msgstr "戻る" #: editor/spatial_editor_gizmos.cpp scene/2d/light_occluder_2d.cpp #: scene/2d/tile_map.cpp -#, fuzzy msgid "Occluder" -msgstr "オクルージョンモード" +msgstr "オクルーダー" #: editor/spatial_editor_gizmos.cpp msgid "Set Occluder Sphere Radius" @@ -16369,7 +16210,7 @@ msgstr "1秒あたりの最大警告数" #: main/main.cpp msgid "Flush stdout On Print" -msgstr "" +msgstr "Print時にstdoutをフラッシュ" #: main/main.cpp servers/visual_server.cpp msgid "Logging" @@ -16454,7 +16295,7 @@ msgstr "スレッドモデル" #: main/main.cpp msgid "Thread Safe BVH" -msgstr "" +msgstr "スレッドセーフなBVH" #: main/main.cpp msgid "Handheld" @@ -16473,9 +16314,8 @@ msgid "Common" msgstr "コミュニティ" #: main/main.cpp -#, fuzzy msgid "Physics FPS" -msgstr "物理フレーム %" +msgstr "物理FPS" #: main/main.cpp #, fuzzy @@ -16498,28 +16338,25 @@ msgstr "" #: main/main.cpp msgid "stdout" -msgstr "" +msgstr "stdout" #: main/main.cpp msgid "Print FPS" -msgstr "" +msgstr "FPSを表示する" #: main/main.cpp msgid "Verbose stdout" -msgstr "" +msgstr "冗長なstdout" #: main/main.cpp scene/main/scene_tree.cpp scene/resources/multimesh.cpp -#, fuzzy msgid "Physics Interpolation" -msgstr "補間モード" +msgstr "物理補間" #: main/main.cpp -#, fuzzy msgid "Enable Warnings" -msgstr "フィルタリングを有効化" +msgstr "警告を有効化" #: main/main.cpp -#, fuzzy msgid "Frame Delay Msec" msgstr "フレーム遅延 (ミリ秒)" @@ -16567,9 +16404,8 @@ msgstr "シェーダーフォールバックを強制" #: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp #: scene/3d/world_environment.cpp scene/main/scene_tree.cpp #: scene/resources/world.cpp -#, fuzzy msgid "Environment" -msgstr "環境を表示" +msgstr "環境" #: main/main.cpp msgid "Default Clear Color" @@ -16890,22 +16726,19 @@ msgstr "DTLSを使用" #: modules/fbx/editor_scene_importer_fbx.cpp msgid "FBX" -msgstr "" +msgstr "FBX" #: modules/fbx/editor_scene_importer_fbx.cpp -#, fuzzy msgid "Use FBX" -msgstr "BVHを使用" +msgstr "FBXを使用" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Config File" -msgstr "ファイルの保存:" +msgstr "構成ファイル" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Load Once" -msgstr "リソースを読み込む" +msgstr "一度だけ読み込む" #: modules/gdnative/gdnative.cpp #: modules/visual_script/visual_script_func_nodes.cpp @@ -16913,14 +16746,12 @@ msgid "Singleton" msgstr "シングルトン" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Symbol Prefix" -msgstr "接頭辞:" +msgstr "シンボルの接頭辞" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Reloadable" -msgstr "再読み込み" +msgstr "再読み込み可能" #: modules/gdnative/gdnative.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp @@ -16973,9 +16804,8 @@ msgid "Disabled GDNative Singleton" msgstr "無効なGDNativeシングルトン" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Libraries:" -msgstr "ライブラリ: " +msgstr "ライブラリ:" #: modules/gdnative/nativescript/nativescript.cpp msgid "Class Name" @@ -17016,11 +16846,11 @@ msgstr "警告をエラーとして扱う" #: modules/gdscript/gdscript.cpp msgid "Exclude Addons" -msgstr "" +msgstr "アドオンを除外" #: modules/gdscript/gdscript.cpp msgid "Autocomplete Setters And Getters" -msgstr "" +msgstr "セッターとゲッターを自動補完" #: modules/gdscript/gdscript_functions.cpp msgid "Step argument is zero!" @@ -17063,9 +16893,8 @@ msgid "Language Server" msgstr "言語サーバー" #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Enable Smart Resolve" -msgstr "解決できません" +msgstr "Smart Resolveを有効化" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Show Native Symbols In Editor" @@ -17162,18 +16991,16 @@ msgid "Indices" msgstr "すべてのデバイス" #: modules/gltf/gltf_camera.cpp -#, fuzzy msgid "FOV Size" -msgstr "サイズ:" +msgstr "FOVサイズ" #: modules/gltf/gltf_camera.cpp msgid "Zfar" -msgstr "" +msgstr "Zfar" #: modules/gltf/gltf_camera.cpp -#, fuzzy msgid "Znear" -msgstr "リニア" +msgstr "Znear" #: modules/gltf/gltf_light.cpp scene/2d/canvas_modulate.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/light_2d.cpp scene/2d/polygon_2d.cpp @@ -17225,7 +17052,7 @@ msgstr "プラットフォーム" #: modules/gltf/gltf_node.cpp scene/3d/mesh_instance.cpp msgid "Skin" -msgstr "" +msgstr "スキン" #: modules/gltf/gltf_node.cpp scene/3d/spatial.cpp #, fuzzy @@ -17238,9 +17065,8 @@ msgid "Children" msgstr "編集可能な子" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints" -msgstr "点" +msgstr "ジョイント" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp msgid "Roots" @@ -17256,9 +17082,8 @@ msgid "Godot Bone Node" msgstr "タイムシーク ノード" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Skin Root" -msgstr "新しいシーンのルート" +msgstr "スキンのルート" #: modules/gltf/gltf_skin.cpp #, fuzzy @@ -17342,15 +17167,13 @@ msgid "Scene Name" msgstr "シーンのパス:" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Root Nodes" -msgstr "ルートノード名" +msgstr "ルートノード" #: modules/gltf/gltf_state.cpp scene/2d/particles_2d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_progress.cpp -#, fuzzy msgid "Textures" -msgstr "機能" +msgstr "テクスチャ" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" @@ -17358,10 +17181,9 @@ msgstr "" #: modules/gltf/gltf_state.cpp msgid "Cameras" -msgstr "" +msgstr "カメラ" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp -#, fuzzy msgid "Lights" msgstr "ライト" @@ -17371,7 +17193,6 @@ msgid "Unique Animation Names" msgstr "新規アニメーション名:" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeletons" msgstr "スケルトン" @@ -17381,9 +17202,8 @@ msgid "Skeleton To Node" msgstr "ノードを選択" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Animations" -msgstr "アニメーション:" +msgstr "アニメーション" #: modules/gltf/gltf_texture.cpp #, fuzzy @@ -17395,9 +17215,8 @@ msgid "Mesh Library" msgstr "メッシュライブラリ" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Physics Material" -msgstr "物理フレーム %" +msgstr "物理マテリアル" #: modules/gridmap/grid_map.cpp scene/3d/visual_instance.cpp #, fuzzy @@ -17432,7 +17251,7 @@ msgstr "中央" #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp #: scene/resources/material.cpp msgid "Mask" -msgstr "" +msgstr "マスク" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp #, fuzzy @@ -17629,9 +17448,8 @@ msgstr "" #: modules/minimp3/resource_importer_mp3.cpp #: modules/stb_vorbis/audio_stream_ogg_vorbis.cpp #: modules/stb_vorbis/resource_importer_ogg_vorbis.cpp -#, fuzzy msgid "Loop Offset" -msgstr "オフセット:" +msgstr "ループのオフセット" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Eye Height" @@ -17657,11 +17475,11 @@ msgstr "" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "K1" -msgstr "" +msgstr "K1" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "K2" -msgstr "" +msgstr "K2" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -17677,19 +17495,16 @@ msgid "Auto Update Project" msgstr "名無しのプロジェクト" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Assembly Name" -msgstr "表示スケール" +msgstr "アセンブリ名" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Solution Directory" -msgstr "ディレクトリを選択" +msgstr "ソリューションのディレクトリ" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "C# Project Directory" -msgstr "ディレクトリを選択" +msgstr "C#プロジェクトのディレクトリ" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17785,11 +17600,11 @@ msgstr "ノイズのオフセット" #: modules/opensimplex/open_simplex_noise.cpp msgid "Octaves" -msgstr "" +msgstr "オクターブ" #: modules/opensimplex/open_simplex_noise.cpp msgid "Period" -msgstr "" +msgstr "周期" #: modules/opensimplex/open_simplex_noise.cpp #, fuzzy @@ -17812,7 +17627,6 @@ msgid "Names" msgstr "名前" #: modules/regex/regex.cpp -#, fuzzy msgid "Strings" msgstr "文字列" @@ -18227,7 +18041,7 @@ msgstr "メンバーを編集" #: modules/visual_script/visual_script_expression.cpp #: scene/resources/visual_shader.cpp msgid "Expression" -msgstr "" +msgstr "式" #: modules/visual_script/visual_script_flow_control.cpp msgid "Return" @@ -18245,9 +18059,8 @@ msgstr "Return(戻り値)" #: modules/visual_script/visual_script_flow_control.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Condition" -msgstr "コンディション" +msgstr "条件" #: modules/visual_script/visual_script_flow_control.cpp msgid "if (cond) is:" @@ -18447,14 +18260,12 @@ msgid "Operator" msgstr "イテレータ" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Invalid argument of type:" -msgstr ":無効な引数 引数の型: " +msgstr "無効な引数の型:" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Invalid arguments:" -msgstr ": 無効な引数: " +msgstr "無効な引数:" #: modules/visual_script/visual_script_nodes.cpp msgid "a if cond, else b" @@ -18617,18 +18428,16 @@ msgid "WaitInstanceSignal" msgstr "インスタンス" #: modules/webrtc/webrtc_data_channel.cpp -#, fuzzy msgid "Write Mode" -msgstr "優先順位モード" +msgstr "書き込みモード" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" -msgstr "" +msgstr "WebRTC" #: modules/webrtc/webrtc_data_channel.h -#, fuzzy msgid "Max Channel In Buffer (KB)" -msgstr "キャンバスのポリゴンインデックスのバッファサイズ (KB)" +msgstr "チャンネルの入力バッファの上限 (KB)" #: modules/websocket/websocket_client.cpp msgid "Verify SSL" @@ -18639,32 +18448,28 @@ msgid "Trusted SSL Certificate" msgstr "信頼済みSSL証明書" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Client" -msgstr "ネットワーク ピア" +msgstr "WebSocketクライアント" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max In Buffer (KB)" -msgstr "最大サイズ (KB)" +msgstr "入力バッファの上限 (KB)" #: modules/websocket/websocket_macros.h msgid "Max In Packets" -msgstr "" +msgstr "入力パケットの上限" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max Out Buffer (KB)" -msgstr "最大サイズ (KB)" +msgstr "出力バッファの上限 (KB)" #: modules/websocket/websocket_macros.h msgid "Max Out Packets" -msgstr "" +msgstr "出力パケットの上限" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Server" -msgstr "ネットワーク ピア" +msgstr "WebSocketサーバー" #: modules/websocket/websocket_server.cpp msgid "Bind IP" @@ -18683,9 +18488,8 @@ msgid "CA Chain" msgstr "CAチェーン" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "Handshake Timeout" -msgstr "タイムアウト。" +msgstr "ハンドシェイクのタイムアウト" #: modules/webxr/webxr_interface.cpp msgid "Session Mode" @@ -18796,9 +18600,8 @@ msgid "Use Custom Build" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Export Format" -msgstr "エクスポート先のパス" +msgstr "エクスポート形式" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18850,22 +18653,19 @@ msgstr "前のインスタンスを調べる" #: platform/android/export/export_plugin.cpp msgid "Code" -msgstr "" +msgstr "コード" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Package" -msgstr "パック中" +msgstr "パッケージ" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Unique Name" -msgstr "ノード名:" +msgstr "ユニーク名" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Signed" -msgstr "シグナル" +msgstr "署名付き" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18897,22 +18697,20 @@ msgid "XR Features" msgstr "機能" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "XR Mode" -msgstr "パンモード" +msgstr "XRモード" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Hand Tracking" -msgstr "トラッキング" +msgstr "ハンドトラッキング" #: platform/android/export/export_plugin.cpp msgid "Hand Tracking Frequency" -msgstr "" +msgstr "ハンドトラッキングの周期" #: platform/android/export/export_plugin.cpp msgid "Passthrough" -msgstr "" +msgstr "パススルー" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18950,37 +18748,32 @@ msgid "Allow" msgstr "hiDPIを許可" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Command Line" -msgstr "Command" +msgstr "コマンドライン" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Extra Args" -msgstr "追加の呼び出し引数:" +msgstr "追加の引数" #: platform/android/export/export_plugin.cpp msgid "APK Expansion" -msgstr "" +msgstr "APK拡張" #: platform/android/export/export_plugin.cpp msgid "Salt" -msgstr "" +msgstr "ソルト" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Public Key" -msgstr "SSH 公開鍵パス" +msgstr "公開鍵" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Permissions" -msgstr "放出マスク" +msgstr "権限" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Custom Permissions" -msgstr "カスタムシーンを実行" +msgstr "カスタムの権限" #: platform/android/export/export_plugin.cpp msgid "Select device from the list" @@ -19108,9 +18901,8 @@ msgstr "" "\"OpenXR\" の場合にのみ有効です。" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"." -msgstr "\"Passthrough\" は \"Xr Mode\" が \"OpenXR\" の場合にのみ有効です。" +msgstr "\"パススルー\" は \"XR Mode\" が \"OpenXR\" の場合にのみ有効です。" #: platform/android/export/export_plugin.cpp msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled." @@ -19160,20 +18952,16 @@ msgstr "" #: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Code Signing" -msgstr "DMGをコード署名中" +msgstr "コード署名" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "'apksigner' could not be found. Please check that the command is available " "in the Android SDK build-tools directory. The resulting %s is unsigned." msgstr "" -"'apksigner' が見つかりませんでした。\n" -"このコマンドが Android SDK build-tools ディレクトリにあるか確認してくださ" -"い。\n" -"%s は署名されませんでした。" +"'apksigner' が見つかりませんでした。このコマンドが Android SDK build-tools " +"ディレクトリにあるか確認してください。%s は署名されませんでした。" #: platform/android/export/export_plugin.cpp msgid "Signing debug %s..." @@ -19188,9 +18976,8 @@ msgid "Could not find keystore, unable to export." msgstr "キーストアが見つからないため、エクスポートできません。" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not start apksigner executable." -msgstr "サブプロセスを開始できませんでした!" +msgstr "apksigner実行ファイルを開始できませんでした。" #: platform/android/export/export_plugin.cpp msgid "'apksigner' returned with error #%d" @@ -19221,9 +19008,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension." msgstr "無効なファイル名です! Android APKには拡張子 *.apk が必要です。" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Unsupported export format!" -msgstr "サポートされていないエクスポートフォーマットです!\n" +msgstr "サポートされていないエクスポート形式です!" #: platform/android/export/export_plugin.cpp msgid "" @@ -19289,9 +19075,8 @@ msgstr "" "gradleのプロジェクトディレクトリを確認してください。" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Package not found: \"%s\"." -msgstr "見つからないパッケージ: %s" +msgstr "パッケージが見つかりません: \"%s\"。" #: platform/android/export/export_plugin.cpp msgid "Creating APK..." @@ -19321,9 +19106,8 @@ msgid "Adding files..." msgstr "ファイルを追加中..." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files." -msgstr "プロジェクトファイルをエクスポートできませんでした" +msgstr "プロジェクトファイルをエクスポートできませんでした。" #: platform/android/export/export_plugin.cpp msgid "Aligning APK..." @@ -19347,19 +19131,19 @@ msgstr "" #: platform/iphone/export/export.cpp msgid "iPhone 2436 X 1125" -msgstr "" +msgstr "iPhone 2436 x 1125" #: platform/iphone/export/export.cpp msgid "iPhone 2208 X 1242" -msgstr "" +msgstr "iPhone 2208 x 1242" #: platform/iphone/export/export.cpp msgid "iPad 1024 X 768" -msgstr "" +msgstr "iPad 1024 x 768" #: platform/iphone/export/export.cpp msgid "iPad 2048 X 1536" -msgstr "" +msgstr "iPad 2048 x 1536" #: platform/iphone/export/export.cpp msgid "Portrait Launch Screens" @@ -19367,35 +19151,35 @@ msgstr "" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 960" -msgstr "" +msgstr "iPhone 640 x 960" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 1136" -msgstr "" +msgstr "iPhone 640 x 1136" #: platform/iphone/export/export.cpp msgid "iPhone 750 X 1334" -msgstr "" +msgstr "iPhone 750 x 1334" #: platform/iphone/export/export.cpp msgid "iPhone 1125 X 2436" -msgstr "" +msgstr "iPhone 1125 x 2436" #: platform/iphone/export/export.cpp msgid "iPad 768 X 1024" -msgstr "" +msgstr "iPad 768 x 1024" #: platform/iphone/export/export.cpp msgid "iPad 1536 X 2048" -msgstr "" +msgstr "iPad 1536 x 2048" #: platform/iphone/export/export.cpp msgid "iPhone 1242 X 2208" -msgstr "" +msgstr "iPhone 1242 x 2208" #: platform/iphone/export/export.cpp msgid "App Store Team ID" -msgstr "" +msgstr "App Store Team ID" #: platform/iphone/export/export.cpp msgid "Provisioning Profile UUID Debug" @@ -19429,7 +19213,7 @@ msgstr "" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Info" -msgstr "" +msgstr "情報" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19501,35 +19285,35 @@ msgstr "プロパティの説明" #: platform/iphone/export/export.cpp msgid "iPhone 120 X 120" -msgstr "" +msgstr "iPhone 120 x 120" #: platform/iphone/export/export.cpp msgid "iPhone 180 X 180" -msgstr "" +msgstr "iPhone 180 x 180" #: platform/iphone/export/export.cpp msgid "iPad 76 X 76" -msgstr "" +msgstr "iPad 76 x 76" #: platform/iphone/export/export.cpp msgid "iPad 152 X 152" -msgstr "" +msgstr "iPad 152 x 152" #: platform/iphone/export/export.cpp msgid "iPad 167 X 167" -msgstr "" +msgstr "iPad 167 x 167" #: platform/iphone/export/export.cpp msgid "App Store 1024 X 1024" -msgstr "" +msgstr "App Store 1024 x 1024" #: platform/iphone/export/export.cpp msgid "Spotlight 40 X 40" -msgstr "" +msgstr "Spotlight 40 x 40" #: platform/iphone/export/export.cpp msgid "Spotlight 80 X 80" -msgstr "" +msgstr "Spotlight 80 x 80" #: platform/iphone/export/export.cpp msgid "Storyboard" @@ -19606,14 +19390,12 @@ msgid "Could not open template for export: \"%s\"." msgstr "エクスポート用のテンプレートを開けませんでした:" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Invalid export template: \"%s\"." -msgstr "無効なエクスポート テンプレート:" +msgstr "無効なエクスポートテンプレート: \"%s\"。" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not write file: \"%s\"." -msgstr "ファイルを書き込めませんでした:" +msgstr "ファイルを書き込めませんでした: \"%s\"。" #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19621,13 +19403,12 @@ msgid "Icon Creation" msgstr "マージンを設定する" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not read file: \"%s\"." -msgstr "ファイルを読み込めませんでした:" +msgstr "ファイルを読み込めませんでした: \"%s\"。" #: platform/javascript/export/export.cpp msgid "PWA" -msgstr "" +msgstr "PWA" #: platform/javascript/export/export.cpp #, fuzzy @@ -19640,21 +19421,20 @@ msgid "Export Type" msgstr "エクスポート" #: platform/javascript/export/export.cpp -#, fuzzy msgid "VRAM Texture Compression" -msgstr "VRAM圧縮" +msgstr "VRAMテクスチャ圧縮" #: platform/javascript/export/export.cpp msgid "For Desktop" -msgstr "" +msgstr "デスクトップ向け" #: platform/javascript/export/export.cpp msgid "For Mobile" -msgstr "" +msgstr "モバイル向け" #: platform/javascript/export/export.cpp msgid "HTML" -msgstr "" +msgstr "HTML" #: platform/javascript/export/export.cpp #, fuzzy @@ -19704,31 +19484,28 @@ msgid "Icon 512 X 512" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not read HTML shell: \"%s\"." -msgstr "HTMLシェルを読み込めませんでした:" +msgstr "HTMLシェルを読み込めませんでした: \"%s\"。" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not create HTTP server directory: %s." -msgstr "HTTPサーバーのディレクトリの作成に失敗:" +msgstr "HTTPサーバーのディレクトリの作成に失敗しました: %s。" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Error starting HTTP server: %d." -msgstr "HTTPサーバーの開始に失敗:" +msgstr "HTTPサーバーの開始に失敗しました: %d。" #: platform/javascript/export/export.cpp msgid "Web" -msgstr "" +msgstr "Web" #: platform/javascript/export/export.cpp msgid "HTTP Host" -msgstr "" +msgstr "HTTPホスト" #: platform/javascript/export/export.cpp msgid "HTTP Port" -msgstr "" +msgstr "HTTPポート" #: platform/javascript/export/export.cpp msgid "Use SSL" @@ -19865,9 +19642,8 @@ msgid "Removable Volumes Usage Description" msgstr "" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Codesign" -msgstr "DMGをコード署名中" +msgstr "コード署名" #: platform/osx/export/export.cpp platform/uwp/export/export.cpp #: platform/windows/export/export.cpp @@ -19881,9 +19657,8 @@ msgid "Timestamp" msgstr "時間" #: platform/osx/export/export.cpp -#, fuzzy msgid "Hardened Runtime" -msgstr "ランタイム" +msgstr "Hardened Runtime" #: platform/osx/export/export.cpp #, fuzzy @@ -19994,9 +19769,8 @@ msgid "Custom Options" msgstr "バス オプション" #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization" -msgstr "ローカライズ" +msgstr "公証" #: platform/osx/export/export.cpp msgid "Apple ID Name" @@ -20012,29 +19786,28 @@ msgid "Apple Team ID" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not open icon file \"%s\"." -msgstr "プロジェクトファイルをエクスポートできませんでした" +msgstr "アイコンファイルを開けませんでした: \"%s\"。" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start xcrun executable." -msgstr "サブプロセスを開始できませんでした!" +msgstr "xcrun実行ファイルを開始できませんでした。" #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization failed." -msgstr "ローカライズ" +msgstr "公証に失敗しました。" #: platform/osx/export/export.cpp msgid "Notarization request UUID: \"%s\"" -msgstr "" +msgstr "公証の要求UUID: \"%s\"" #: platform/osx/export/export.cpp msgid "" "The notarization process generally takes less than an hour. When the process " "is completed, you'll receive an email." msgstr "" +"公証の手続きは通常1時間以内に終了します。手続きが完了するとEメールが届きま" +"す。" #: platform/osx/export/export.cpp msgid "" @@ -20047,6 +19820,8 @@ msgid "" "Run the following command to staple the notarization ticket to the exported " "application (optional):" msgstr "" +"次のコマンドを実行して、公証のチケットをエクスポートしたアプリケーションに紐" +"付けします(オプション):" #: platform/osx/export/export.cpp msgid "Timestamping is not compatible with ad-hoc signature, and was disabled!" @@ -20114,9 +19889,8 @@ msgid "Could not find template app to export: \"%s\"." msgstr "エクスポートするテンプレートAPKが見つかりませんでした:" #: platform/osx/export/export.cpp -#, fuzzy msgid "Invalid export format." -msgstr "無効なエクスポート テンプレート:" +msgstr "無効なエクスポート形式です。" #: platform/osx/export/export.cpp msgid "" @@ -20161,10 +19935,12 @@ msgid "" "Notarization requires the app to be archived first, select the DMG or ZIP " "export format instead." msgstr "" +"公証にはまずアプリをアーカイブする必要があります。DMGまたはZIPのエクスポート" +"形式のものを選択してください。" #: platform/osx/export/export.cpp msgid "Sending archive for notarization" -msgstr "" +msgstr "公証をするためにアーカイブを送信中" #: platform/osx/export/export.cpp #, fuzzy @@ -20195,36 +19971,35 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Notarization: Notarization with an ad-hoc signature is not supported." -msgstr "" +msgstr "公証: アドホック署名による公証はサポートされていません。" #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization: Code signing is required for notarization." -msgstr "Notarization: コード署名が必要です。" +msgstr "公証: 公証にはコード署名が必要です。" #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization: Hardened runtime is required for notarization." -msgstr "Notarization: hardened runtime が必要です。" +msgstr "公証: 公証にはHardened runtimeが必要です。" #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization: Timestamp runtime is required for notarization." -msgstr "Notarization: hardened runtime が必要です。" +msgstr "公証: 公証にはTimestamp runtimeが必要です。" #: platform/osx/export/export.cpp msgid "Notarization: Apple ID name not specified." -msgstr "Notarization: Apple ID 名が指定されていません。" +msgstr "公証: Apple ID名が指定されていません。" #: platform/osx/export/export.cpp msgid "Notarization: Apple ID password not specified." -msgstr "Notarization: Apple ID パスワードが指定されていません。" +msgstr "公証: Apple ID パスワードが指定されていません。" #: platform/osx/export/export.cpp msgid "" "Warning: Notarization is disabled. The exported project will be blocked by " "Gatekeeper if it's downloaded from an unknown source." msgstr "" +"警告: 公証が無効化されています。エクスポートしたプロジェクトは、不明なソース" +"からダウンロードされた場合Gatekeeperによってブロックされます。" #: platform/osx/export/export.cpp msgid "" @@ -20248,6 +20023,9 @@ msgid "" "Warning: Notarization is not supported from this OS. The exported project " "will be blocked by Gatekeeper if it's downloaded from an unknown source." msgstr "" +"警告: このOSによる公証はサポートされていません。エクスポートしたプロジェクト" +"は、不明なソースからダウンロードされた場合Gatekeeperによってブロックされま" +"す。" #: platform/osx/export/export.cpp msgid "" @@ -20292,9 +20070,8 @@ msgid "Force Builtin Codesign" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Architecture" -msgstr "アーキテクチャエントリを追加する" +msgstr "アーキテクチャ" #: platform/uwp/export/export.cpp #, fuzzy @@ -20326,37 +20103,32 @@ msgid "Publisher GUID" msgstr "ガイドをクリアする" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Signing" -msgstr "スキニング" +msgstr "署名" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Certificate" msgstr "証明書" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Algorithm" -msgstr "デバッガー" +msgstr "アルゴリズム" #: platform/uwp/export/export.cpp msgid "Major" -msgstr "" +msgstr "メジャー" #: platform/uwp/export/export.cpp msgid "Minor" -msgstr "" +msgstr "マイナー" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Build" -msgstr "定規モード" +msgstr "ビルド" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Revision" -msgstr "バージョン" +msgstr "リビジョン" #: platform/uwp/export/export.cpp msgid "Landscape" @@ -20529,29 +20301,24 @@ msgid "Modify Resources" msgstr "リソースをコピー" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Version" -msgstr "バージョン" +msgstr "ファイルバージョン" #: platform/windows/export/export.cpp -#, fuzzy msgid "Product Version" -msgstr "無効な製品バージョン:" +msgstr "製品バージョン" #: platform/windows/export/export.cpp -#, fuzzy msgid "Company Name" -msgstr "ノード名:" +msgstr "会社名" #: platform/windows/export/export.cpp -#, fuzzy msgid "Product Name" -msgstr "プロジェクト名:" +msgstr "製品名" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Description" -msgstr "説明" +msgstr "ファイルの説明" #: platform/windows/export/export.cpp msgid "Trademarks" @@ -20674,13 +20441,12 @@ msgstr "Wine" #: platform/x11/export/export.cpp msgid "32-bit executables cannot have embedded data >= 4 GiB." -msgstr "" +msgstr "32bitの実行ファイルは4GiB以上の組み込みデータを持つことができません。" #: scene/2d/animated_sprite.cpp scene/3d/sprite_3d.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Frames" -msgstr "フレーム %" +msgstr "フレーム" #: scene/2d/animated_sprite.cpp msgid "" @@ -20711,12 +20477,12 @@ msgstr "中央" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_rect.cpp msgid "Flip H" -msgstr "" +msgstr "水平反転" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_rect.cpp msgid "Flip V" -msgstr "" +msgstr "垂直反転" #: scene/2d/area_2d.cpp scene/3d/area.cpp #, fuzzy @@ -20729,9 +20495,8 @@ msgid "Monitorable" msgstr "モニター" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Physics Overrides" -msgstr "上書き" +msgstr "物理のオーバーライド" #: scene/2d/area_2d.cpp scene/3d/area.cpp #, fuzzy @@ -20811,9 +20576,8 @@ msgstr "アニメーション" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp -#, fuzzy msgid "Bus" -msgstr "バスを追加" +msgstr "バス" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp msgid "Area Mask" @@ -20856,26 +20620,23 @@ msgstr "処理モード" #: scene/2d/camera_2d.cpp msgid "Limit" -msgstr "" +msgstr "制限" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Left" -msgstr "左上" +msgstr "左" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Right" -msgstr "ライト" +msgstr "右" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/dynamic_font.cpp scene/resources/style_box.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Bottom" -msgstr "左下" +msgstr "下" #: scene/2d/camera_2d.cpp #, fuzzy @@ -20904,12 +20665,11 @@ msgstr "スムーズステップ" #: scene/2d/camera_2d.cpp msgid "H" -msgstr "" +msgstr "水平" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "V" -msgstr "UV" +msgstr "垂直" #: scene/2d/camera_2d.cpp #, fuzzy @@ -21048,9 +20808,8 @@ msgid "" msgstr "" #: scene/2d/collision_polygon_2d.cpp -#, fuzzy msgid "Build Mode" -msgstr "定規モード" +msgstr "ビルドモード" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp #: scene/3d/collision_polygon.cpp scene/3d/collision_shape.cpp @@ -21424,7 +21183,7 @@ msgstr "" #: scene/2d/joints_2d.cpp scene/resources/animation.cpp #: scene/resources/ray_shape.cpp scene/resources/segment_shape_2d.cpp msgid "Length" -msgstr "" +msgstr "長さ" #: scene/2d/joints_2d.cpp #, fuzzy @@ -21447,9 +21206,8 @@ msgstr "" "光の形状を持つテクスチャは\"Texture\"プロパティに指定する必要があります。" #: scene/2d/light_2d.cpp scene/3d/light.cpp scene/gui/reference_rect.cpp -#, fuzzy msgid "Editor Only" -msgstr "エディター" +msgstr "エディターのみ" #: scene/2d/light_2d.cpp #, fuzzy @@ -21485,9 +21243,8 @@ msgid "Item Cull Mask" msgstr "" #: scene/2d/light_2d.cpp scene/3d/light.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Shadow" -msgstr "シェーダー" +msgstr "シャドウ" #: scene/2d/light_2d.cpp #, fuzzy @@ -21751,7 +21508,7 @@ msgstr "終りに" #: scene/2d/parallax_background.cpp msgid "Ignore Camera Zoom" -msgstr "" +msgstr "カメラのズームを無視" #: scene/2d/parallax_layer.cpp msgid "" @@ -21840,14 +21597,12 @@ msgid "Unit Offset" msgstr "グリッドのオフセット:" #: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp -#, fuzzy msgid "H Offset" -msgstr "オフセット:" +msgstr "水平オフセット" #: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp -#, fuzzy msgid "V Offset" -msgstr "オフセット:" +msgstr "垂直オフセット" #: scene/2d/path_2d.cpp scene/3d/path.cpp msgid "Cubic Interp" @@ -21858,7 +21613,6 @@ msgid "Lookahead" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/visual_instance.cpp -#, fuzzy msgid "Layers" msgstr "レイヤー" @@ -21874,9 +21628,8 @@ msgstr "初期化" #: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp #: scene/resources/physics_material.cpp -#, fuzzy msgid "Friction" -msgstr "関数" +msgstr "摩擦" #: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp #: scene/resources/physics_material.cpp @@ -21885,7 +21638,7 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Physics Material Override" -msgstr "" +msgstr "物理マテリアルのオーバーライド" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: scene/resources/world.cpp scene/resources/world_2d.cpp @@ -21905,17 +21658,15 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Mass" -msgstr "" +msgstr "質量" #: scene/2d/physics_body_2d.cpp -#, fuzzy msgid "Inertia" -msgstr "垂直:" +msgstr "慣性" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Weight" -msgstr "ライト" +msgstr "重量" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Gravity Scale" @@ -21965,14 +21716,12 @@ msgid "Torque" msgstr "トルク" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Safe Margin" -msgstr "マージンを設定する" +msgstr "セーフマージン" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Sync To Physics" -msgstr "(物理的)同期" +msgstr "物理との同期" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy @@ -22150,7 +21899,6 @@ msgstr "" "使用してください。" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Tile Set" msgstr "タイルセット" @@ -22170,9 +21918,8 @@ msgid "Half Offset" msgstr "初期化" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Tile Origin" -msgstr "原点を表示" +msgstr "タイルの原点" #: scene/2d/tile_map.cpp #, fuzzy @@ -22259,7 +22006,7 @@ msgstr "優先順位を有効化" #: scene/2d/visibility_notifier_2d.cpp msgid "Physics Process Parent" -msgstr "" +msgstr "親の物理処理" #: scene/3d/area.cpp msgid "Reverb Bus" @@ -22876,9 +22623,8 @@ msgid "Omni" msgstr "" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Mode" -msgstr "シェーダー" +msgstr "シャドウモード" #: scene/3d/light.cpp #, fuzzy @@ -23527,9 +23273,8 @@ msgid "Box Projection" msgstr "プロジェクト" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Enable Shadows" -msgstr "スナップを有効にする" +msgstr "シャドウを有効化" #: scene/3d/reflection_probe.cpp #, fuzzy @@ -23777,9 +23522,8 @@ msgid "Spatial Attachment Path" msgstr "" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Physics Enabled" -msgstr "物理フレーム %" +msgstr "物理を有効化" #: scene/3d/soft_body.cpp #, fuzzy @@ -23851,9 +23595,8 @@ msgid "Gizmo" msgstr "ギズモ" #: scene/3d/spatial_velocity_tracker.cpp -#, fuzzy msgid "Track Physics Step" -msgstr "物理フレーム %" +msgstr "物理ステップの追跡" #: scene/3d/spring_arm.cpp msgid "Spring Length" @@ -25340,9 +25083,8 @@ msgid "Pause Mode" msgstr "パンモード" #: scene/main/node.cpp -#, fuzzy msgid "Physics Interpolation Mode" -msgstr "補間モード" +msgstr "物理補間モード" #: scene/main/node.cpp #, fuzzy @@ -25622,9 +25364,8 @@ msgid "Disable Input" msgstr "アイテムを無効にする" #: scene/main/viewport.cpp servers/visual_server.cpp -#, fuzzy msgid "Shadow Atlas" -msgstr "新しいアトラス" +msgstr "シャドウアトラス" #: scene/main/viewport.cpp msgid "Quad 0" @@ -25677,14 +25418,12 @@ msgid "3D Render" msgstr "レンダリング" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Physics" -msgstr " (物理的)" +msgstr "2D物理" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Physics" -msgstr " (物理的)" +msgstr "3D物理" #: scene/register_scene_types.cpp #, fuzzy @@ -25854,14 +25593,12 @@ msgid "Font Outline Modulate" msgstr "白色調整" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow Offset X" -msgstr "グリッドのオフセット X:" +msgstr "シャドウのオフセットX" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow Offset Y" -msgstr "グリッドのオフセット Y:" +msgstr "シャドウのオフセットY" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26617,9 +26354,8 @@ msgid "Sky Contribution" msgstr "" #: scene/resources/environment.cpp -#, fuzzy msgid "Fog" -msgstr "Fog(霧)" +msgstr "フォグ" #: scene/resources/environment.cpp #, fuzzy @@ -26872,19 +26608,16 @@ msgid "Ascent" msgstr "最近:" #: scene/resources/font.cpp -#, fuzzy msgid "Distance Field" -msgstr "集中モード" +msgstr "距離フィールド" #: scene/resources/gradient.cpp -#, fuzzy msgid "Raw Data" -msgstr "Depth(深度/奥行)" +msgstr "生データ" #: scene/resources/gradient.cpp -#, fuzzy msgid "Offsets" -msgstr "オフセット:" +msgstr "オフセット" #: scene/resources/height_map_shape.cpp msgid "Map Width" @@ -26914,14 +26647,12 @@ msgid "Use Shadow To Opacity" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Unshaded" -msgstr "シェーディングなしで表示" +msgstr "シェーディングなしで" #: scene/resources/material.cpp -#, fuzzy msgid "Vertex Lighting" -msgstr "直接光" +msgstr "頂点ライティング" #: scene/resources/material.cpp #, fuzzy @@ -26938,7 +26669,7 @@ msgstr "" #: scene/resources/material.cpp msgid "Do Not Receive Shadows" -msgstr "" +msgstr "シャドウを受け取らない" #: scene/resources/material.cpp #, fuzzy @@ -26968,9 +26699,8 @@ msgid "Is sRGB" msgstr "" #: scene/resources/material.cpp servers/visual_server.cpp -#, fuzzy msgid "Parameters" -msgstr "パラメーターが変更されました:" +msgstr "パラメーター" #: scene/resources/material.cpp #, fuzzy @@ -27083,9 +26813,8 @@ msgid "Flowmap" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Ambient Occlusion" -msgstr "オクルージョン" +msgstr "アンビエントオクルージョン" #: scene/resources/material.cpp msgid "Deep Parallax" @@ -27470,7 +27199,7 @@ msgstr "アウトラインのサイズ:" #: scene/resources/sky.cpp msgid "Panorama" -msgstr "" +msgstr "パノラマ" #: scene/resources/sky.cpp #, fuzzy @@ -27483,9 +27212,8 @@ msgid "Horizon Color" msgstr "ファイルの保存:" #: scene/resources/sky.cpp -#, fuzzy msgid "Ground" -msgstr "グループ化済み" +msgstr "地面" #: scene/resources/sky.cpp #, fuzzy @@ -27493,18 +27221,16 @@ msgid "Bottom Color" msgstr "ブックマーク" #: scene/resources/sky.cpp -#, fuzzy msgid "Sun" -msgstr "実行" +msgstr "太陽" #: scene/resources/sky.cpp -#, fuzzy msgid "Latitude" -msgstr "代替" +msgstr "緯度" #: scene/resources/sky.cpp msgid "Longitude" -msgstr "" +msgstr "経度" #: scene/resources/sky.cpp msgid "Angle Min" @@ -27848,9 +27574,8 @@ msgstr "" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_panner.cpp -#, fuzzy msgid "Pan" -msgstr "平面:" +msgstr "パン" #: servers/audio/effects/audio_effect_compressor.cpp #: servers/audio/effects/audio_effect_filter.cpp @@ -27859,12 +27584,11 @@ msgstr "" #: servers/audio/effects/audio_effect_compressor.cpp msgid "Attack (µs)" -msgstr "" +msgstr "アタック (マイクロ秒)" #: servers/audio/effects/audio_effect_compressor.cpp -#, fuzzy msgid "Release (ms)" -msgstr "リリース" +msgstr "リリース (ミリ秒)" #: servers/audio/effects/audio_effect_compressor.cpp msgid "Mix" @@ -27885,14 +27609,12 @@ msgstr "" #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_phaser.cpp #: servers/audio/effects/audio_effect_reverb.cpp -#, fuzzy msgid "Feedback" -msgstr "ドキュメントのフィードバックを送る" +msgstr "フィードバック" #: servers/audio/effects/audio_effect_delay.cpp -#, fuzzy msgid "Low-pass" -msgstr "バイパス" +msgstr "ローパス" #: servers/audio/effects/audio_effect_distortion.cpp msgid "Pre Gain" @@ -27978,7 +27700,7 @@ msgstr "タイムアウト。" #: servers/audio/effects/audio_effect_stereo_enhance.cpp msgid "Surround" -msgstr "" +msgstr "サラウンド" #: servers/audio_server.cpp msgid "Enable Audio Input" @@ -28120,9 +27842,8 @@ msgid "Collision Unsafe Fraction" msgstr "コリジョンモード" #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Physics Engine" -msgstr "物理フレーム %" +msgstr "物理エンジン" #: servers/physics_server.cpp msgid "Center Of Mass" @@ -28238,9 +27959,8 @@ msgid "Quadrant 3 Subdiv" msgstr "" #: servers/visual_server.cpp -#, fuzzy msgid "Shadows" -msgstr "シェーダー" +msgstr "シャドウ" #: servers/visual_server.cpp msgid "Filter Mode" @@ -28291,7 +28011,7 @@ msgstr "" #: servers/visual_server.cpp msgid "Depth Prepass" -msgstr "" +msgstr "深度プレパス" #: servers/visual_server.cpp msgid "Disable For Vendors" @@ -28322,14 +28042,12 @@ msgid "Use Software Skinning" msgstr "ソフトウェアスキニングを使用" #: servers/visual_server.cpp -#, fuzzy msgid "Ninepatch Mode" -msgstr "補間モード" +msgstr "Ninepatchモード" #: servers/visual_server.cpp -#, fuzzy msgid "OpenGL" -msgstr "開く" +msgstr "OpenGL" #: servers/visual_server.cpp msgid "Batching Send Null" @@ -28402,7 +28120,7 @@ msgstr "フレームを貼り付け" #: servers/visual_server.cpp msgid "GLES2" -msgstr "" +msgstr "GLES2" #: servers/visual_server.cpp msgid "Compatibility" diff --git a/editor/translations/ko.po b/editor/translations/ko.po index e3edb07ce4..e1940d698c 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -38,13 +38,14 @@ # 김태우 <ogosengi3@gmail.com>, 2022. # 박민규 <80dots@gmail.com>, 2022. # 이지민 <jiminaleejung@gmail.com>, 2022. +# nulltable <un5450@naver.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-09-07 06:16+0000\n" -"Last-Translator: 이지민 <jiminaleejung@gmail.com>\n" +"PO-Revision-Date: 2022-09-23 04:16+0000\n" +"Last-Translator: nulltable <un5450@naver.com>\n" "Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/" "godot/ko/>\n" "Language: ko\n" @@ -52,7 +53,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -313,7 +314,7 @@ msgstr "스트림 피어" #: core/io/stream_peer.cpp msgid "Big Endian" -msgstr "Big Endian" +msgstr "빅 엔디안" #: core/io/stream_peer.cpp msgid "Data Array" @@ -869,7 +870,7 @@ msgstr "모듈" #: core/register_core_types.cpp msgid "TCP" -msgstr "TCP (전송 제어 프로토콜)" +msgstr "TCP" #: core/register_core_types.cpp msgid "Connect Timeout Seconds" @@ -1013,7 +1014,7 @@ msgstr "최대 렌더 요소 수" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Lights" -msgstr "최대 렌더 광원 수" +msgstr "최대 렌더 조명 수" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Reflections" @@ -1021,7 +1022,7 @@ msgstr "최대 렌더 반사 수" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Lights Per Object" -msgstr "오브젝트당 최대 광원 수" +msgstr "오브젝트당 최대 조명 수" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Subsurface Scattering" @@ -2784,7 +2785,7 @@ msgstr "패킹 중" #: editor/editor_export.cpp msgid "Save PCK" -msgstr "PCK를 저장합니다." +msgstr "PCK 저장" #: editor/editor_export.cpp msgid "Cannot create file \"%s\"." @@ -2930,12 +2931,11 @@ msgstr "Export하려고 했으나 해당 경로가 존재하지 않습니다." #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found: \"%s\"." -msgstr "템플릿 파일을 찾을 수 없습니다: \"%s\"" +msgstr "템플릿 파일을 찾을 수 없습니다: \"%s\"." #: editor/editor_export.cpp -#, fuzzy msgid "Failed to copy export template." -msgstr "잘못된 내보내기 템플릿:" +msgstr "내보내기 템플릿을 복사하지 못했습니다." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp @@ -6010,9 +6010,8 @@ msgstr "프로젝트 매니저" #. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects. #: editor/editor_settings.cpp -#, fuzzy msgid "Sorting Order" -msgstr "폴더 이름 바꾸기:" +msgstr "정렬 순서" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Symbol Color" @@ -6044,21 +6043,18 @@ msgid "Comment Color" msgstr "" #: editor/editor_settings.cpp -#, fuzzy msgid "String Color" -msgstr "저장하려는 파일:" +msgstr "문자열 색" #: editor/editor_settings.cpp platform/javascript/export/export.cpp #: platform/uwp/export/export.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Background Color" -msgstr "잘못된 배경 색상." +msgstr "배경 색" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Completion Background Color" -msgstr "잘못된 배경 색상." +msgstr "완성 배경 색" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -6083,9 +6079,8 @@ msgid "Text Color" msgstr "다음 층" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Line Number Color" -msgstr "행 번호:" +msgstr "행 번호의 색" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -6900,9 +6895,8 @@ msgstr "" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp #: scene/gui/control.cpp -#, fuzzy msgid "Filter" -msgstr "필터:" +msgstr "필터" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp @@ -6929,17 +6923,15 @@ msgstr "자동 자르기" #: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp #: scene/gui/nine_patch_rect.cpp scene/gui/scroll_container.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Horizontal" -msgstr "수평:" +msgstr "수평" #: editor/import/resource_importer_layered_texture.cpp #: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp #: scene/gui/nine_patch_rect.cpp scene/gui/scroll_container.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Vertical" -msgstr "수직:" +msgstr "수직" #: editor/import/resource_importer_obj.cpp #, fuzzy @@ -6952,9 +6944,8 @@ msgid "Scale Mesh" msgstr "스케일 모드" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Offset Mesh" -msgstr "오프셋:" +msgstr "오프셋 메시" #: editor/import/resource_importer_obj.cpp #: editor/import/resource_importer_scene.cpp @@ -6963,9 +6954,8 @@ msgid "Octahedral Compression" msgstr "표현식 설정" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Optimize Mesh Flags" -msgstr "크기: " +msgstr "메시 플래그 최적화" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" @@ -7043,9 +7033,8 @@ msgid "Use Legacy Names" msgstr "" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp -#, fuzzy msgid "Materials" -msgstr "머티리얼 바꾸기:" +msgstr "머티리얼" #: editor/import/resource_importer_scene.cpp #, fuzzy @@ -7122,14 +7111,12 @@ msgid "Enabled" msgstr "활성화" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Max Linear Error" -msgstr "최대 선형 오류:" +msgstr "최대 선형 오류" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Max Angular Error" -msgstr "최대 각도 오류:" +msgstr "최대 각도 오류" #: editor/import/resource_importer_scene.cpp #, fuzzy @@ -7149,9 +7136,8 @@ msgstr "애니메이션 클립" #: editor/import/resource_importer_scene.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/area.cpp scene/3d/cpu_particles.cpp #: scene/3d/particles.cpp scene/resources/environment.cpp -#, fuzzy msgid "Amount" -msgstr "양:" +msgstr "양" #: editor/import/resource_importer_scene.cpp #: editor/plugins/mesh_library_editor_plugin.cpp @@ -7167,9 +7153,8 @@ msgid "Generating Lightmaps" msgstr "라이트맵 생성 중" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Generating for Mesh:" -msgstr "메시 용으로 생성 중: " +msgstr "메시 용으로 생성 중:" #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." @@ -7260,14 +7245,12 @@ msgid "Invert Color" msgstr "꼭짓점" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Normal Map Invert Y" -msgstr "무작위 스케일:" +msgstr "노멀 맵 Y축 반전" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Size Limit" -msgstr "크기: " +msgstr "크기 제한" #: editor/import/resource_importer_texture.cpp msgid "Detect 3D" @@ -7285,14 +7268,12 @@ msgid "" msgstr "" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Atlas File" -msgstr "윤곽선 크기:" +msgstr "아틀라스 파일" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Import Mode" -msgstr "내보내기 모드:" +msgstr "가져오기 모드" #: editor/import/resource_importer_texture_atlas.cpp #, fuzzy @@ -8184,9 +8165,8 @@ msgid "Set the end animation. This is useful for sub-transitions." msgstr "끝 애니메이션을 설정합니다. 이것은 하위 전환에 유용합니다." #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Transition:" -msgstr "전환: " +msgstr "전환:" #: editor/plugins/animation_state_machine_editor.cpp msgid "Play Mode:" @@ -9950,9 +9930,8 @@ msgid "Volume" msgstr "볼륨" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Emission Source:" -msgstr "방출 소스: " +msgstr "방출 소스:" #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -10668,9 +10647,8 @@ msgid "Script Temperature History Size" msgstr "" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Current Script Background Color" -msgstr "잘못된 배경 색상." +msgstr "현재 스크립트 배경 색" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -12870,9 +12848,8 @@ msgstr "스냅 설정" #: scene/gui/graph_node.cpp scene/gui/rich_text_effect.cpp #: scene/main/canvas_layer.cpp scene/resources/material.cpp #: scene/resources/particles_material.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Offset" -msgstr "오프셋:" +msgstr "오프셋" #: editor/plugins/tile_set_editor_plugin.cpp editor/rename_dialog.cpp #: scene/gui/range.cpp scene/resources/animation.cpp @@ -12911,9 +12888,8 @@ msgstr "격자 오프셋:" #: editor/plugins/tile_set_editor_plugin.cpp modules/csg/csg_shape.cpp #: scene/2d/canvas_item.cpp scene/2d/particles_2d.cpp #: scene/3d/mesh_instance.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Material" -msgstr "머티리얼 바꾸기:" +msgstr "머티리얼" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/canvas_item.cpp #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/style_box.cpp @@ -13025,9 +13001,8 @@ msgid "Unstaged Changes" msgstr "셰이더 바꾸기:" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Commit:" -msgstr "커밋" +msgstr "커밋:" #: editor/plugins/version_control_editor_plugin.cpp msgid "Date:" @@ -13061,92 +13036,80 @@ msgid "Initialize" msgstr "초기화" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Remote Login" -msgstr "점 제거" +msgstr "원격 로그인" #: editor/plugins/version_control_editor_plugin.cpp msgid "Select SSH public key path" -msgstr "" +msgstr "SSH 공개키의 경로를 선택하세요" #: editor/plugins/version_control_editor_plugin.cpp msgid "Select SSH private key path" -msgstr "" +msgstr "SSH 비밀키의 경로를 선택하세요" #: editor/plugins/version_control_editor_plugin.cpp msgid "SSH Passphrase" -msgstr "SSH Passphrase" +msgstr "SSH 암호" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" msgstr "새 변경사항 감지" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Discard all changes" -msgstr "변경사항을 저장하고 닫을까요?" +msgstr "모든 변경사항 버리기" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Stage all changes" -msgstr "로컬 변경사항을 저장하는 중..." +msgstr "모든 변경사항 스테이징" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Unstage all changes" -msgstr "머티리얼 바꾸기:" +msgstr "모든 변경사항 스테이징 취소" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Commit Message" -msgstr "커밋 변경사항" +msgstr "커밋 메세지" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit Changes" msgstr "커밋 변경사항" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Commit List" -msgstr "커밋" +msgstr "커밋 목록" #: editor/plugins/version_control_editor_plugin.cpp msgid "Commit list size" -msgstr "" +msgstr "커밋 목록 크기" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Branches" -msgstr "일치함:" +msgstr "브랜치" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Create New Branch" -msgstr "새 프로젝트 만들기" +msgstr "새 브랜치 생성" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Remove Branch" -msgstr "애니메이션 트랙 제거" +msgstr "브랜치 삭제" #: editor/plugins/version_control_editor_plugin.cpp msgid "Branch Name" -msgstr "" +msgstr "브랜치 이름" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Remotes" msgstr "원격" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Create New Remote" -msgstr "새 프로젝트 만들기" +msgstr "새 원격 추가" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Remove Remote" -msgstr "항목 제거" +msgstr "원격 제거" #: editor/plugins/version_control_editor_plugin.cpp msgid "Remote Name" @@ -13158,20 +13121,19 @@ msgstr "원격 URL" #: editor/plugins/version_control_editor_plugin.cpp msgid "Fetch" -msgstr "" +msgstr "페치" #: editor/plugins/version_control_editor_plugin.cpp msgid "Pull" -msgstr "" +msgstr "풀" #: editor/plugins/version_control_editor_plugin.cpp msgid "Push" -msgstr "" +msgstr "푸시" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Force Push" -msgstr "원본 메시:" +msgstr "강제 푸시" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" @@ -13191,22 +13153,19 @@ msgstr "타입체인지" #: editor/plugins/version_control_editor_plugin.cpp msgid "Unmerged" -msgstr "" +msgstr "미병합" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "View:" -msgstr "보기" +msgstr "보기:" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Split" -msgstr "경로 가르기" +msgstr "분할" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Unified" -msgstr "수정됨" +msgstr "통합됨" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" @@ -14200,28 +14159,24 @@ msgid "More Info..." msgstr "여기로 이동..." #: editor/project_export.cpp -#, fuzzy msgid "Export PCK/Zip..." -msgstr "PCK/Zip 내보내기" +msgstr "PCK/Zip 내보내기..." #: editor/project_export.cpp -#, fuzzy msgid "Export Project..." -msgstr "프로젝트 내보내기" +msgstr "프로젝트 내보내기..." #: editor/project_export.cpp msgid "Export All" msgstr "모두 내보내기" #: editor/project_export.cpp -#, fuzzy msgid "Choose an export mode:" -msgstr "비어있는 폴더를 선택해주세요." +msgstr "내보내기 모드를 선택하세요:" #: editor/project_export.cpp -#, fuzzy msgid "Export All..." -msgstr "모두 내보내기" +msgstr "모두 내보내기..." #: editor/project_export.cpp editor/project_manager.cpp msgid "ZIP File" @@ -15332,9 +15287,8 @@ msgid "Make Local" msgstr "로컬로 만들기" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name(s)" -msgstr "노드 이름:" +msgstr "씬 고유 이름 활성화" #: editor/scene_tree_dock.cpp #, fuzzy @@ -15342,9 +15296,8 @@ msgid "Unique names already used by another node in the scene:" msgstr "이미 다른 함수/변수/시그널로 사용된 이름:" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Disable Scene Unique Name(s)" -msgstr "노드 이름:" +msgstr "씬 고유 이름 비활성화" #: editor/scene_tree_dock.cpp msgid "New Scene Root" @@ -15542,9 +15495,8 @@ msgid "Button Group" msgstr "버튼 그룹" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Disable Scene Unique Name" -msgstr "노드 이름:" +msgstr "씬 고유 이름 비활성화" #: editor/scene_tree_editor.cpp msgid "(Connecting From)" @@ -15774,9 +15726,8 @@ msgid "Attach Node Script" msgstr "노드 스크립트 붙이기" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Remote %s:" -msgstr "원격 " +msgstr "원격 %s:" #: editor/script_editor_debugger.cpp msgid "Bytes:" @@ -16010,9 +15961,8 @@ msgid "GI Probe" msgstr "GI 프로브 굽기" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Baked Indirect Light" -msgstr "간접 조명" +msgstr "구운 간접 조명" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Sphere Shape Radius" @@ -16228,9 +16178,8 @@ msgid "Driver" msgstr "" #: main/main.cpp -#, fuzzy msgid "Driver Name" -msgstr "스크립트 이름:" +msgstr "드라이버 이름" #: main/main.cpp msgid "Fallback To GLES2" @@ -16315,9 +16264,8 @@ msgid "Physics FPS" msgstr "물리 프레임 %" #: main/main.cpp -#, fuzzy msgid "Force FPS" -msgstr "원본 메시:" +msgstr "FPS 강제" #: main/main.cpp msgid "Enable Pause Aware Picking" @@ -16432,9 +16380,8 @@ msgid "Fullsize" msgstr "" #: main/main.cpp scene/resources/dynamic_font.cpp -#, fuzzy msgid "Use Filter" -msgstr "필터:" +msgstr "필터 사용" #: main/main.cpp scene/resources/style_box.cpp #, fuzzy @@ -16481,9 +16428,8 @@ msgid "Custom Image Hotspot" msgstr "" #: main/main.cpp -#, fuzzy msgid "Tooltip Position Offset" -msgstr "회전 오프셋:" +msgstr "툴팁 위치 오프셋" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp #, fuzzy @@ -16496,9 +16442,8 @@ msgid "Wait For Debugger" msgstr "디버거" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp -#, fuzzy msgid "Wait Timeout" -msgstr "시간 초과." +msgstr "대기 타임아웃" #: main/main.cpp msgid "Runtime" @@ -16612,9 +16557,8 @@ msgstr "대소문자 변환" #: scene/resources/cylinder_shape.cpp scene/resources/environment.cpp #: scene/resources/navigation_mesh.cpp scene/resources/primitive_meshes.cpp #: scene/resources/sphere_shape.cpp -#, fuzzy msgid "Radius" -msgstr "반지름:" +msgstr "반지름" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp #, fuzzy @@ -16758,9 +16702,8 @@ msgid "Use FBX" msgstr "" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Config File" -msgstr "저장하려는 파일:" +msgstr "설정 파일" #: modules/gdnative/gdnative.cpp #, fuzzy @@ -16834,19 +16777,16 @@ msgid "Disabled GDNative Singleton" msgstr "비활성화된 GDNative 싱글톤" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Libraries:" -msgstr "라이브러리: " +msgstr "라이브러리:" #: modules/gdnative/nativescript/nativescript.cpp -#, fuzzy msgid "Class Name" -msgstr "클래스 이름:" +msgstr "클래스 이름" #: modules/gdnative/nativescript/nativescript.cpp -#, fuzzy msgid "Script Class" -msgstr "스크립트 이름:" +msgstr "스크립트 클래스" #: modules/gdnative/nativescript/nativescript.cpp #, fuzzy @@ -16925,9 +16865,8 @@ msgid "Object can't provide a length." msgstr "오브젝트는 길이를 제공할 수 없습니다." #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Language Server" -msgstr "언어:" +msgstr "언어 서버" #: modules/gdscript/language_server/gdscript_language_server.cpp #, fuzzy @@ -16956,9 +16895,8 @@ msgid "Buffer View" msgstr "후면 뷰" #: modules/gltf/gltf_accessor.cpp modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Byte Offset" -msgstr "격자 오프셋:" +msgstr "바이트 오프셋" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -16971,9 +16909,8 @@ msgid "Normalized" msgstr "형식" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Count" -msgstr "양:" +msgstr "양" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp #, fuzzy @@ -17211,9 +17148,8 @@ msgid "Accessors" msgstr "" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Scene Name" -msgstr "씬 경로:" +msgstr "씬 이름" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17652,9 +17588,8 @@ msgid "Noise" msgstr "" #: modules/opensimplex/noise_texture.cpp -#, fuzzy msgid "Noise Offset" -msgstr "격자 오프셋:" +msgstr "노이즈 오프셋" #: modules/opensimplex/open_simplex_noise.cpp msgid "Octaves" @@ -17683,9 +17618,8 @@ msgid "Names" msgstr "이름" #: modules/regex/regex.cpp -#, fuzzy msgid "Strings" -msgstr "설정:" +msgstr "문자열" #: modules/upnp/upnp.cpp msgid "Discover Multicast If" @@ -17751,9 +17685,8 @@ msgstr "" "쳐주세요." #: modules/visual_script/visual_script.cpp -#, fuzzy msgid "Node returned an invalid sequence output:" -msgstr "잘못된 시퀀스 출력을 반환한 노드: " +msgstr "잘못된 시퀀스 출력을 반환한 노드:" #: modules/visual_script/visual_script.cpp msgid "Found sequence bit but not the node in the stack, report bug!" @@ -18313,9 +18246,8 @@ msgstr "배열 크기 바꾸기" #: modules/visual_script/visual_script_nodes.cpp scene/resources/material.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Operator" -msgstr "오버레이 연산자." +msgstr "연산자" #: modules/visual_script/visual_script_nodes.cpp #, fuzzy @@ -18563,9 +18495,8 @@ msgid "CA Chain" msgstr "IK 체인 지우기" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "Handshake Timeout" -msgstr "시간 초과." +msgstr "핸드쉐이크 타임아웃" #: modules/webxr/webxr_interface.cpp #, fuzzy @@ -18573,14 +18504,12 @@ msgid "Session Mode" msgstr "영역 모드" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Required Features" -msgstr "주요 기능:" +msgstr "필수적 기능" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Optional Features" -msgstr "주요 기능:" +msgstr "선택적 기능" #: modules/webxr/webxr_interface.cpp msgid "Requested Reference Space Types" @@ -18742,9 +18671,8 @@ msgid "Package" msgstr "패킹 중" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Unique Name" -msgstr "노드 이름:" +msgstr "고유 이름" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18752,9 +18680,8 @@ msgid "Signed" msgstr "시그널" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Classify As Game" -msgstr "클래스 이름:" +msgstr "게임으로 분류" #: platform/android/export/export_plugin.cpp msgid "Retain Data On Uninstall" @@ -18766,9 +18693,8 @@ msgid "Exclude From Recents" msgstr "노드 삭제" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Graphics" -msgstr "격자 오프셋:" +msgstr "그래픽" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18838,9 +18764,8 @@ msgid "Command Line" msgstr "커뮤니티" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Extra Args" -msgstr "별도의 호출 인수:" +msgstr "추가적인 인수" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -19041,14 +18966,12 @@ msgid "Code Signing" msgstr "시그널" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "'apksigner' could not be found. Please check that the command is available " "in the Android SDK build-tools directory. The resulting %s is unsigned." msgstr "" -"'apksigner'를 찾을 수 없었습니다.\n" -"명령이 Android SDK build-tools 디렉토리에서 사용 가능한지 확인해주세요.\n" -"결과 %s는 서명되지 않습니다." +"'apksigner'를 찾을 수 없습니다. 명령이 Android SDK build-tools 디렉토리에서 " +"사용 가능한지 확인해주세요. 결과물 %s는 서명되지 않았습니다." #: platform/android/export/export_plugin.cpp msgid "Signing debug %s..." @@ -19063,9 +18986,8 @@ msgid "Could not find keystore, unable to export." msgstr "keystore를 찾을 수 없어, 내보낼 수 없었습니다." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not start apksigner executable." -msgstr "하위 프로세스를 시작할 수 없습니다!" +msgstr "apksigner 실행 파일을 시작할 수 없습니다." #: platform/android/export/export_plugin.cpp msgid "'apksigner' returned with error #%d" @@ -19096,9 +19018,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension." msgstr "잘못된 파일이름입니다! Android APK는 *.apk 확장자가 필요합니다." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Unsupported export format!" -msgstr "지원되지 않는 내보내기 형식입니다!\n" +msgstr "지원되지 않는 내보내기 형식입니다!" #: platform/android/export/export_plugin.cpp msgid "" @@ -19109,27 +19030,22 @@ msgstr "" "(Project)' 메뉴에서 다시 설치해주세요." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Android build version mismatch: Template installed: %s, Godot version: %s. " "Please reinstall Android build template from 'Project' menu." msgstr "" -"Android 빌드 버전이 맞지 않음:\n" -" 설치된 템플릿: %s\n" -" Godot 버전: %s\n" -"'프로젝트' 메뉴에서 Android 빌드 템플릿을 다시 설치해주세요." +"Android 빌드 버전이 맞지 않음: 설치된 템플릿: %s, Godot 버전: %s. '프로젝트' " +"메뉴에서 Android 빌드 템플릿을 다시 설치해주세요." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Unable to overwrite res://android/build/res/*.xml files with project name." msgstr "" -"res://android/build/res/*.xml 파일을 프로젝트 이름으로 덮어쓸 수 없습니다" +"res://android/build/res/*.xml 파일을 프로젝트 이름으로 덮어쓸 수 없습니다." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "프로젝트 파일을 gradle 프로젝트로 내보낼 수 없었습니다\n" +msgstr "프로젝트 파일을 gradle 프로젝트로 내보낼 수 없습니다." #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -19140,13 +19056,12 @@ msgid "Building Android Project (gradle)" msgstr "Android 프로젝트 빌드 중 (gradle)" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Building of Android project failed, check output for the error. " "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" -"Android 프로젝트의 빌드에 실패했습니다, 출력된 오류를 확인하세요.\n" -"또는 docs.godotengine.org에서 Android 빌드 문서를 찾아보세요." +"Android 프로젝트의 빌드에 실패했습니다, 출력된 오류를 확인하세요. 또는 docs." +"godotengine.org에서 Android 빌드 문서를 찾아보세요." #: platform/android/export/export_plugin.cpp msgid "Moving output" @@ -19161,20 +19076,16 @@ msgstr "" "트 디렉토리를 확인하세요." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Package not found: \"%s\"." -msgstr "패키지를 찾을 수 없음: %s" +msgstr "패키지를 찾을 수 없음: \"%s\"." #: platform/android/export/export_plugin.cpp msgid "Creating APK..." msgstr "APK를 만드는 중..." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not find template APK to export: \"%s\"." -msgstr "" -"내보낼 템플릿 APK를 찾을 수 없음:\n" -"%s" +msgstr "내보낼 템플릿 APK를 찾을 수 없음: \"%s\"." #: platform/android/export/export_plugin.cpp #, fuzzy @@ -19193,9 +19104,8 @@ msgid "Adding files..." msgstr "파일을 추가하는 중..." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files." -msgstr "프로젝트 파일을 내보낼 수 없었습니다" +msgstr "프로젝트 파일을 내보낼 수 없습니다." #: platform/android/export/export_plugin.cpp msgid "Aligning APK..." @@ -19291,9 +19201,8 @@ msgid "Code Sign Identity Release" msgstr "" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Method Release" -msgstr "내보내기 모드:" +msgstr "내보내기 모드 출시" #: platform/iphone/export/export.cpp msgid "Targeted Device Family" @@ -19304,9 +19213,8 @@ msgid "Info" msgstr "" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Identifier" -msgstr "잘못된 식별자:" +msgstr "식별자" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19330,14 +19238,12 @@ msgid "Capabilities" msgstr "속성 붙여넣기" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Access Wi-Fi" -msgstr "성공!" +msgstr "Wi-Fi 연결" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Push Notifications" -msgstr "무작위 회전:" +msgstr "푸시 알림" #: platform/iphone/export/export.cpp #, fuzzy @@ -19474,19 +19380,16 @@ msgid "Run exported HTML in the system's default browser." msgstr "내보낸 HTML을 시스템의 기본 브라우저를 사용하여 실행합니다." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not open template for export: \"%s\"." -msgstr "내보내기 템플릿을 열 수 없음:" +msgstr "내보내기 템플릿을 열 수 없음: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Invalid export template: \"%s\"." -msgstr "잘못된 내보내기 템플릿:" +msgstr "잘못된 내보내기 템플릿: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not write file: \"%s\"." -msgstr "파일에 쓸 수 없음:" +msgstr "파일에 쓸 수 없음: \"%s\"." #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19494,18 +19397,16 @@ msgid "Icon Creation" msgstr "여백 설정" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not read file: \"%s\"." -msgstr "파일을 읽을 수 없음:" +msgstr "파일을 읽을 수 없음: \"%s\"." #: platform/javascript/export/export.cpp msgid "PWA" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Variant" -msgstr "간격:" +msgstr "변종" #: platform/javascript/export/export.cpp #, fuzzy @@ -19577,19 +19478,16 @@ msgid "Icon 512 X 512" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not read HTML shell: \"%s\"." -msgstr "HTML shell을 읽을 수 없음:" +msgstr "HTML shell을 읽을 수 없음: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not create HTTP server directory: %s." -msgstr "HTTP 서버 디렉토리를 만들 수 없음:" +msgstr "HTTP 서버 디렉토리를 만들 수 없음: %s." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Error starting HTTP server: %d." -msgstr "HTTP 서버를 시작하는 중 오류:" +msgstr "HTTP 서버를 시작하는 중 오류: %d." #: platform/javascript/export/export.cpp msgid "Web" @@ -19693,9 +19591,8 @@ msgid "Unknown object type." msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "App Category" -msgstr "카테고리:" +msgstr "앱 카테고리" #: platform/osx/export/export.cpp msgid "High Res" @@ -19888,14 +19785,12 @@ msgid "Apple Team ID" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not open icon file \"%s\"." -msgstr "프로젝트 파일을 내보낼 수 없었습니다" +msgstr "아이콘 파일 \"%s\"를 열 수 없습니다." #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start xcrun executable." -msgstr "하위 프로세스를 시작할 수 없습니다!" +msgstr "xcrun 실행 파일을 시작하지 못했습니다." #: platform/osx/export/export.cpp #, fuzzy @@ -19953,9 +19848,8 @@ msgid "No identity found." msgstr "아이콘을 찾을 수 없습니다." #: platform/osx/export/export.cpp -#, fuzzy msgid "Cannot sign file %s." -msgstr "파일 저장 중 오류: %s" +msgstr "파일 %s를 서명할 수 없습니다." #: platform/osx/export/export.cpp msgid "Relative symlinks are not supported, exported \"%s\" might be broken!" @@ -20374,9 +20268,8 @@ msgid "Debug Algorithm" msgstr "디버거" #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to rename temporary file \"%s\"." -msgstr "임시 파일을 제거할 수 없음:" +msgstr "임시 파일 \"%s\"의 이름을 바꾸지 못했습니다." #: platform/windows/export/export.cpp msgid "Identity Type" @@ -20402,19 +20295,16 @@ msgid "File Version" msgstr "버전" #: platform/windows/export/export.cpp -#, fuzzy msgid "Product Version" -msgstr "잘못된 제품 GUID." +msgstr "제품 버전" #: platform/windows/export/export.cpp -#, fuzzy msgid "Company Name" -msgstr "노드 이름:" +msgstr "회사 이름" #: platform/windows/export/export.cpp -#, fuzzy msgid "Product Name" -msgstr "프로젝트 이름:" +msgstr "제품 이름" #: platform/windows/export/export.cpp #, fuzzy @@ -20426,9 +20316,8 @@ msgid "Trademarks" msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Resources Modification" -msgstr "무작위 회전:" +msgstr "리소스 변경" #: platform/windows/export/export.cpp #, fuzzy @@ -20463,9 +20352,8 @@ msgid "Could not find osslsigncode executable at \"%s\"." msgstr "keystore를 찾을 수 없어, 내보낼 수 없었습니다." #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid identity type." -msgstr "잘못된 식별자:" +msgstr "잘못된 식별자 타입입니다." #: platform/windows/export/export.cpp #, fuzzy @@ -20485,9 +20373,8 @@ msgid "Signtool failed to sign executable: %s." msgstr "잘못된 확장자." #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to remove temporary file \"%s\"." -msgstr "임시 파일을 제거할 수 없음:" +msgstr "임시 파일 \"%s\"를 제거하지 못했습니다." #: platform/windows/export/export.cpp msgid "" @@ -20496,19 +20383,16 @@ msgid "" msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid icon path:" -msgstr "잘못된 경로." +msgstr "잘못된 아이콘 경로:" #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid file version:" -msgstr "잘못된 확장자." +msgstr "잘못된 파일 버전:" #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid product version:" -msgstr "잘못된 제품 GUID." +msgstr "잘못된 제품 버전:" #: platform/windows/export/export.cpp msgid "Windows executables cannot be >= 4 GiB." @@ -20674,9 +20558,8 @@ msgstr "" #: scene/3d/light.cpp scene/3d/reflection_probe.cpp #: scene/3d/visibility_notifier.cpp scene/3d/visual_instance.cpp #: scene/resources/material.cpp -#, fuzzy msgid "Max Distance" -msgstr "거리 선택:" +msgstr "최대 거리" #: scene/2d/audio_stream_player_2d.cpp scene/3d/light.cpp #, fuzzy @@ -20710,9 +20593,8 @@ msgstr "회전 단계:" #: scene/2d/camera_2d.cpp scene/2d/listener_2d.cpp scene/3d/camera.cpp #: scene/3d/listener.cpp scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Current" -msgstr "현재:" +msgstr "현재" #: scene/2d/camera_2d.cpp scene/gui/graph_edit.cpp #, fuzzy @@ -21009,9 +20891,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Randomness" -msgstr "임의 재시작 (초):" +msgstr "무작위성" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21502,9 +21383,8 @@ msgid "Target Desired Distance" msgstr "" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Path Max Distance" -msgstr "거리 선택:" +msgstr "경로 최대 거리" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp #, fuzzy @@ -21530,9 +21410,8 @@ msgid "Time Horizon" msgstr "수평으로 뒤집기" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Max Speed" -msgstr "속도:" +msgstr "최대 속도" #: scene/2d/navigation_agent_2d.cpp msgid "" @@ -21574,9 +21453,8 @@ msgstr "진행" #: scene/2d/node_2d.cpp scene/2d/polygon_2d.cpp scene/3d/spatial.cpp #: scene/main/canvas_layer.cpp -#, fuzzy msgid "Rotation Degrees" -msgstr "%s도로 회전." +msgstr "회전 각도" #: scene/2d/node_2d.cpp scene/3d/spatial.cpp #, fuzzy @@ -21584,14 +21462,12 @@ msgid "Global Rotation" msgstr "상수" #: scene/2d/node_2d.cpp -#, fuzzy msgid "Global Rotation Degrees" -msgstr "%s도로 회전." +msgstr "전역 회전 각도" #: scene/2d/node_2d.cpp -#, fuzzy msgid "Global Scale" -msgstr "무작위 스케일:" +msgstr "전역 스케일" #: scene/2d/node_2d.cpp scene/3d/spatial.cpp #, fuzzy @@ -21609,9 +21485,8 @@ msgid "Scroll" msgstr "" #: scene/2d/parallax_background.cpp -#, fuzzy msgid "Base Offset" -msgstr "오프셋:" +msgstr "기본 오프셋" #: scene/2d/parallax_background.cpp #, fuzzy @@ -21705,19 +21580,16 @@ msgid "PathFollow2D only works when set as a child of a Path2D node." msgstr "PathFollow2D는 Path2D 노드의 자식 노드로 있을 때만 작동합니다." #: scene/2d/path_2d.cpp scene/3d/path.cpp -#, fuzzy msgid "Unit Offset" -msgstr "격자 오프셋:" +msgstr "단위 오프셋" #: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp -#, fuzzy msgid "H Offset" -msgstr "오프셋:" +msgstr "가로 오프셋" #: scene/2d/path_2d.cpp scene/3d/camera.cpp scene/3d/path.cpp -#, fuzzy msgid "V Offset" -msgstr "오프셋:" +msgstr "세로 오프셋" #: scene/2d/path_2d.cpp scene/3d/path.cpp msgid "Cubic Interp" @@ -21778,9 +21650,8 @@ msgid "Mass" msgstr "" #: scene/2d/physics_body_2d.cpp -#, fuzzy msgid "Inertia" -msgstr "수직:" +msgstr "관성" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy @@ -21817,9 +21688,8 @@ msgid "Sleeping" msgstr "스마트 스냅" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Can Sleep" -msgstr "속도:" +msgstr "슬립 가능" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Damp" @@ -21843,9 +21713,8 @@ msgid "Safe Margin" msgstr "여백 설정" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Sync To Physics" -msgstr " (물리)" +msgstr "물리에 연동" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy @@ -21865,9 +21734,8 @@ msgid "Normal" msgstr "형식" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Remainder" -msgstr "렌더러:" +msgstr "나머지" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy @@ -21917,14 +21785,12 @@ msgid "Invert" msgstr "" #: scene/2d/polygon_2d.cpp -#, fuzzy msgid "Vertex Colors" -msgstr "꼭짓점" +msgstr "꼭짓점 색" #: scene/2d/polygon_2d.cpp -#, fuzzy msgid "Internal Vertex Count" -msgstr "내부 꼭짓점 만들기" +msgstr "내부 꼭짓점 개수" #: scene/2d/position_2d.cpp #, fuzzy @@ -22184,9 +22050,8 @@ msgid "ARVROrigin requires an ARVRCamera child node." msgstr "ARVROrigin은 자식으로 ARVRCamera 노드가 필요합니다." #: scene/3d/arvr_nodes.cpp servers/arvr_server.cpp -#, fuzzy msgid "World Scale" -msgstr "무작위 스케일:" +msgstr "세계 크기" #: scene/3d/audio_stream_player_3d.cpp #, fuzzy @@ -22215,9 +22080,8 @@ msgid "Emission Angle" msgstr "방출 색상" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Degrees" -msgstr "%s도로 회전." +msgstr "각도" #: scene/3d/audio_stream_player_3d.cpp #, fuzzy @@ -22236,9 +22100,8 @@ msgstr "" #: scene/3d/audio_stream_player_3d.cpp #: servers/audio/effects/audio_effect_filter.cpp -#, fuzzy msgid "dB" -msgstr "B" +msgstr "dB" #: scene/3d/audio_stream_player_3d.cpp #, fuzzy @@ -22299,9 +22162,8 @@ msgid "Bounce Indirect Energy" msgstr "" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Use Denoiser" -msgstr "필터:" +msgstr "노이즈 감소 사용" #: scene/3d/baked_lightmap.cpp scene/resources/texture.cpp msgid "Use HDR" @@ -22328,9 +22190,8 @@ msgid "Generate" msgstr "일반" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Max Size" -msgstr "크기:" +msgstr "최대 크기" #: scene/3d/baked_lightmap.cpp #, fuzzy @@ -25901,9 +25762,8 @@ msgid "Title Height" msgstr "테스트" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Close Highlight" -msgstr "직접 조명" +msgstr "강조 닫기" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26162,9 +26022,8 @@ msgid "Menu" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Menu Highlight" -msgstr "직접 조명" +msgstr "메뉴 강조" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26779,9 +26638,8 @@ msgid "Unshaded" msgstr "셰이더 없음 표시" #: scene/resources/material.cpp -#, fuzzy msgid "Vertex Lighting" -msgstr "직접 조명" +msgstr "꼭짓점 조명" #: scene/resources/material.cpp #, fuzzy @@ -26815,9 +26673,8 @@ msgid "Albedo Tex MSDF" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Vertex Color" -msgstr "꼭짓점" +msgstr "꼭짓점 색" #: scene/resources/material.cpp msgid "Use As Albedo" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 9410069ae4..2b09ed5abc 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -65,7 +65,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-08-30 03:11+0000\n" +"PO-Revision-Date: 2022-09-23 04:16+0000\n" "Last-Translator: Nnn <irri2020@outlook.com>\n" "Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/" "nl/>\n" @@ -74,7 +74,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -249,9 +249,8 @@ msgstr "" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Function" -msgstr "Functies" +msgstr "Functie" #: core/image.cpp core/packed_data_container.cpp scene/2d/polygon_2d.cpp #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp @@ -263,14 +262,12 @@ msgstr "" #: modules/gdscript/language_server/gdscript_language_server.cpp #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: scene/gui/file_dialog.cpp -#, fuzzy msgid "Network" -msgstr "Netwerk Profiler" +msgstr "Netwerk" #: core/io/file_access_network.cpp -#, fuzzy msgid "Remote FS" -msgstr "Remote " +msgstr "Remote" #: core/io/file_access_network.cpp msgid "Page Size" @@ -293,14 +290,12 @@ msgid "Read Chunk Size" msgstr "" #: core/io/marshalls.cpp -#, fuzzy msgid "Object ID" -msgstr "Objecten Getekend" +msgstr "Object ID" #: core/io/multiplayer_api.cpp core/io/packet_peer.cpp -#, fuzzy msgid "Allow Object Decoding" -msgstr "\"Onion Skinning\" Inschakelen" +msgstr "Object Decoding Toestaan" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp msgid "Refuse New Network Connections" @@ -317,9 +312,8 @@ msgid "Root Node" msgstr "Wortelknoopnaam" #: core/io/networked_multiplayer_peer.cpp -#, fuzzy msgid "Refuse New Connections" -msgstr "Verbinden" +msgstr "Nieuwe Verbindingen Weigeren" #: core/io/networked_multiplayer_peer.cpp #, fuzzy @@ -411,7 +405,6 @@ msgid "Seed" msgstr "" #: core/math/random_number_generator.cpp -#, fuzzy msgid "State" msgstr "Status" @@ -424,9 +417,8 @@ msgid "Max Size (KB)" msgstr "" #: core/os/input.cpp -#, fuzzy msgid "Mouse Mode" -msgstr "Verplaatsingsmodus" +msgstr "Muismodus" #: core/os/input.cpp #, fuzzy @@ -457,21 +449,18 @@ msgid "Meta" msgstr "" #: core/os/input_event.cpp -#, fuzzy msgid "Command" -msgstr "Gemeenschap" +msgstr "Commando" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr "Physics Frame %" +msgstr "Fysiek" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Pressed" -msgstr "Voorinstellingen" +msgstr "Gedrukt" #: core/os/input_event.cpp msgid "Scancode" @@ -490,24 +479,20 @@ msgid "Echo" msgstr "" #: core/os/input_event.cpp scene/gui/base_button.cpp -#, fuzzy msgid "Button Mask" -msgstr "Button (Knop)" +msgstr "Knop Masker" #: core/os/input_event.cpp scene/2d/node_2d.cpp scene/gui/control.cpp -#, fuzzy msgid "Global Position" -msgstr "Constante" +msgstr "Globale Positie" #: core/os/input_event.cpp -#, fuzzy msgid "Factor" -msgstr "Vector" +msgstr "Factor" #: core/os/input_event.cpp -#, fuzzy msgid "Button Index" -msgstr "Muis Knop Index:" +msgstr "Knop Index" #: core/os/input_event.cpp msgid "Doubleclick" @@ -518,26 +503,23 @@ msgid "Tilt" msgstr "" #: core/os/input_event.cpp -#, fuzzy msgid "Pressure" -msgstr "Voorinstellingen" +msgstr "Druk" #: core/os/input_event.cpp msgid "Pen Inverted" msgstr "" #: core/os/input_event.cpp -#, fuzzy msgid "Relative" -msgstr "Relatief kleven" +msgstr "Relatief" #: core/os/input_event.cpp scene/2d/camera_2d.cpp scene/2d/cpu_particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/interpolated_camera.cpp #: scene/animation/animation_player.cpp scene/resources/environment.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed" -msgstr "Snelheid:" +msgstr "Snelheid" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: scene/3d/sprite_3d.cpp @@ -545,14 +527,12 @@ msgid "Axis" msgstr "As" #: core/os/input_event.cpp -#, fuzzy msgid "Axis Value" -msgstr "Waarde vastzetten" +msgstr "As Waarde" #: core/os/input_event.cpp modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Index" -msgstr "Index:" +msgstr "Index" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: modules/visual_script/visual_script_nodes.cpp @@ -570,14 +550,12 @@ msgid "Delta" msgstr "" #: core/os/input_event.cpp -#, fuzzy msgid "Channel" -msgstr "Wijzig" +msgstr "Kanaal" #: core/os/input_event.cpp main/main.cpp -#, fuzzy msgid "Message" -msgstr "Commit veranderingen" +msgstr "Bericht" #: core/os/input_event.cpp #, fuzzy @@ -587,18 +565,16 @@ msgstr "Pitch" #: core/os/input_event.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/physics_body_2d.cpp scene/3d/cpu_particles.cpp #: scene/3d/physics_body.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity" -msgstr "Initialiseren" +msgstr "Versnelling" #: core/os/input_event.cpp msgid "Instrument" msgstr "" #: core/os/input_event.cpp -#, fuzzy msgid "Controller Number" -msgstr "Regelnummer:" +msgstr "Controller Nummer" #: core/os/input_event.cpp msgid "Controller Value" @@ -607,14 +583,12 @@ msgstr "" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Application" -msgstr "Actie" +msgstr "Applicatie" #: core/project_settings.cpp main/main.cpp -#, fuzzy msgid "Config" -msgstr "Kleven instellen" +msgstr "Configuratie" #: core/project_settings.cpp #, fuzzy @@ -653,14 +627,12 @@ msgid "Main Scene" msgstr "Startscène" #: core/project_settings.cpp -#, fuzzy msgid "Disable stdout" -msgstr "Autotile uitschakelen" +msgstr "Stdout Uitschakelen" #: core/project_settings.cpp -#, fuzzy msgid "Disable stderr" -msgstr "Item Uitschakelen" +msgstr "Stderr Uitschakelen" #: core/project_settings.cpp msgid "Use Hidden Project Data Directory" @@ -677,9 +649,8 @@ msgstr "" #: core/project_settings.cpp main/main.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #: platform/uwp/os_uwp.cpp -#, fuzzy msgid "Display" -msgstr "Alles tonen" +msgstr "Tonen" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp @@ -693,23 +664,20 @@ msgstr "" #: scene/resources/capsule_shape_2d.cpp scene/resources/cylinder_shape.cpp #: scene/resources/font.cpp scene/resources/navigation_mesh.cpp #: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp -#, fuzzy msgid "Height" -msgstr "Licht" +msgstr "Hoogte" #: core/project_settings.cpp msgid "Always On Top" msgstr "" #: core/project_settings.cpp -#, fuzzy msgid "Test Width" -msgstr "Linkerbreedte" +msgstr "Test Breedte" #: core/project_settings.cpp -#, fuzzy msgid "Test Height" -msgstr "Testen" +msgstr "Test Hoogte" #: core/project_settings.cpp editor/animation_track_editor.cpp #: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp @@ -752,58 +720,49 @@ msgid "Version Control Autoload On Startup" msgstr "Versiebeheersysteem" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Plugin Name" -msgstr "Versiebeheer" +msgstr "Versiebeheer Controle Plugin Naam" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp -#, fuzzy msgid "Input" -msgstr "Voeg invoer toe" +msgstr "Invoer" #: core/project_settings.cpp msgid "UI Accept" msgstr "" #: core/project_settings.cpp -#, fuzzy msgid "UI Select" -msgstr "Selecteer" +msgstr "UI Selecteer" #: core/project_settings.cpp -#, fuzzy msgid "UI Cancel" -msgstr "Annuleer" +msgstr "UI Annuleer" #: core/project_settings.cpp -#, fuzzy msgid "UI Focus Next" -msgstr "Focus Pad" +msgstr "UI Focus Volgende" #: core/project_settings.cpp -#, fuzzy msgid "UI Focus Prev" -msgstr "Focus Pad" +msgstr "UI Focus Vorige" #: core/project_settings.cpp -#, fuzzy msgid "UI Left" -msgstr "Linksboven" +msgstr "UI Links" #: core/project_settings.cpp -#, fuzzy msgid "UI Right" -msgstr "Rechtsboves" +msgstr "UI Rechts" #: core/project_settings.cpp msgid "UI Up" msgstr "" #: core/project_settings.cpp -#, fuzzy msgid "UI Down" -msgstr "Omlaag" +msgstr "UI Omlaag" #: core/project_settings.cpp #, fuzzy diff --git a/editor/translations/pt.po b/editor/translations/pt.po index 271dcc1e8b..3052fff9bb 100644 --- a/editor/translations/pt.po +++ b/editor/translations/pt.po @@ -28,13 +28,14 @@ # Zé Beato Página Oficial <zebeato@gmail.com>, 2022. # Rafael Testa <rafael1testa@gmail.com>, 2022. # Baiterson <baiter160@gmail.com>, 2022. +# Tuily <brizolla.tuily@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-08-25 13:04+0000\n" -"Last-Translator: Baiterson <baiter160@gmail.com>\n" +"PO-Revision-Date: 2022-09-19 05:22+0000\n" +"Last-Translator: Tuily <brizolla.tuily@gmail.com>\n" "Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/" "godot/pt/>\n" "Language: pt\n" @@ -42,7 +43,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -5662,9 +5663,8 @@ msgid "Pick Distance" msgstr "Escolher Distância" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Preview Size" -msgstr "Pré-visualização" +msgstr "Tamanho de Pré-visualização" #: editor/editor_settings.cpp msgid "Primary Grid Color" diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 4541da85ee..30ad718462 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -151,13 +151,15 @@ # Avery <jarreed0@gmail.com>, 2022. # TheJC <the-green-green.0rvdk@simplelogin.fr>, 2022. # Mauricio Mazur <mauricio.mazur12@gmail.com>, 2022. +# ! Zyll <emanueljunior756@gmail.com>, 2022. +# Kirrby <kirrby.gaming@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2022-09-05 11:17+0000\n" -"Last-Translator: TheJC <the-green-green.0rvdk@simplelogin.fr>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: Kirrby <kirrby.gaming@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -165,7 +167,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -1128,7 +1130,7 @@ msgstr "Máximo de luzes renderizáveis" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Reflections" -msgstr "Máximo de Reflexos renderizáveis" +msgstr "Max. Reflexões Renderizaveis" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Lights Per Object" @@ -3383,7 +3385,7 @@ msgstr "Mostrar Arquivos Ocultos" #: editor/editor_file_dialog.cpp msgid "Disable Overwrite Warning" -msgstr "Desativar Aviso de Substituição" +msgstr "Desativar aviso de substituição" #: editor/editor_file_dialog.cpp msgid "Go Back" @@ -3486,7 +3488,7 @@ msgstr "(Re)Importando Assets" #: editor/editor_file_system.cpp msgid "Reimport Missing Imported Files" -msgstr "Reimportar Arquivos Importados Ausentes" +msgstr "Reimportar arquivos importados perdidos" #: editor/editor_help.cpp scene/2d/camera_2d.cpp scene/gui/control.cpp #: scene/gui/nine_patch_rect.cpp scene/resources/dynamic_font.cpp @@ -3597,7 +3599,7 @@ msgstr "Ajuda" #: editor/editor_help.cpp msgid "Sort Functions Alphabetically" -msgstr "Classificar Funções em Ordem Alfabética" +msgstr "Ordenar funções alfabéticamente" #: editor/editor_help_search.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp @@ -4402,7 +4404,7 @@ msgstr "Redimensionar se Houver Muitas Guias" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Minimum Width" -msgstr "Largura Mínima" +msgstr "Largura mínima" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Output" @@ -4410,7 +4412,7 @@ msgstr "Saída" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Always Clear Output On Play" -msgstr "Sempre limpar saída ao jogar" +msgstr "Sempre Limpar Output no modo Play" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Always Open Output On Play" @@ -15375,19 +15377,16 @@ msgid "Make Local" msgstr "Tornar Local" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name(s)" -msgstr "Habilitar Nome Único de Cena" +msgstr "Habilitar Nome(s) Único(s) de Cena" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Unique names already used by another node in the scene:" -msgstr "Outro nó já está usando este nome único na cena atual." +msgstr "Nomes únicos já estão sendo usados por outro nó na cena:" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Disable Scene Unique Name(s)" -msgstr "Desabilitar Nome Único de Cena" +msgstr "Desabilitar Nome(s) Único(s) de Cena" #: editor/scene_tree_dock.cpp msgid "New Scene Root" @@ -17483,14 +17482,12 @@ msgid "Assembly Name" msgstr "Nome de Exibição" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Solution Directory" -msgstr "Escolha um Diretório" +msgstr "Diretório da Solução" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "C# Project Directory" -msgstr "Escolha um Diretório" +msgstr "Diretório do Projeto C#" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17572,8 +17569,9 @@ msgid "As Normal Map" msgstr "Como Mapa Normal" #: modules/opensimplex/noise_texture.cpp +#, fuzzy msgid "Bump Strength" -msgstr "" +msgstr "Força da colisão" #: modules/opensimplex/noise_texture.cpp msgid "Noise" @@ -18454,12 +18452,14 @@ msgid "Optional Features" msgstr "Funcionalidades Opcionais" #: modules/webxr/webxr_interface.cpp +#, fuzzy msgid "Requested Reference Space Types" -msgstr "" +msgstr "Tipos de Espaço de Referência Solicitados" #: modules/webxr/webxr_interface.cpp +#, fuzzy msgid "Reference Space Type" -msgstr "" +msgstr "Tipo de Espaço de Referência" #: modules/webxr/webxr_interface.cpp msgid "Visibility State" @@ -18493,8 +18493,9 @@ msgid "Debug Keystore Pass" msgstr "" #: platform/android/export/export.cpp +#, fuzzy msgid "Force System User" -msgstr "" +msgstr "Forçar Usuário do Sistema" #: platform/android/export/export.cpp msgid "Shutdown ADB On Exit" @@ -19090,8 +19091,9 @@ msgid "The character '%s' is not allowed in Identifier." msgstr "O caractere '%s' não é permitido no identificador." #: platform/iphone/export/export.cpp +#, fuzzy msgid "Landscape Launch Screens" -msgstr "" +msgstr "Telas de Inicialização de Paisagem" #: platform/iphone/export/export.cpp msgid "iPhone 2436 X 1125" @@ -19299,9 +19301,8 @@ msgid "Custom BG Color" msgstr "Cor Personalizada de Fundo" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Icons" -msgstr "Exportar Ícone" +msgstr "Exportar Ícones" #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp @@ -19520,8 +19521,9 @@ msgid "Invalid executable file." msgstr "Arquivo executável inválido." #: platform/osx/export/codesign.cpp +#, fuzzy msgid "Can't resize signature load command." -msgstr "" +msgstr "Não é possível redimensionar o comando de carregamento da assinatura." #: platform/osx/export/codesign.cpp msgid "Failed to create fat binary." @@ -20124,6 +20126,8 @@ msgid "" "Godot's Mono version does not support the UWP platform. Use the standard " "build (no C# support) if you wish to target UWP." msgstr "" +"A versão Mono do Godot não suporta a plataforma UWP. Use a build padrão (sem " +"suporte a C#) se deseja exportar para UWP." #: platform/uwp/export/export.cpp msgid "Invalid package short name." diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 0dc49c7dba..e01815b513 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -18,13 +18,14 @@ # FlooferLand <yunaflarf@gmail.com>, 2021, 2022. # N3mEee <n3mebusiness@gmail.com>, 2021. # Psynt <nichita@cadvegra.com>, 2022. +# Ilie Adrian Avramescu <himark1977@protonmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-05-15 09:38+0000\n" -"Last-Translator: Psynt <nichita@cadvegra.com>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: Ilie Adrian Avramescu <himark1977@protonmail.com>\n" "Language-Team: Romanian <https://hosted.weblate.org/projects/godot-engine/" "godot/ro/>\n" "Language: ro\n" @@ -33,11 +34,11 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2;\n" -"X-Generator: Weblate 4.13-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" -msgstr "" +msgstr "Driver de tableta" #: core/bind/core_bind.cpp msgid "Clipboard" @@ -61,7 +62,7 @@ msgstr "V-Sync Prin Compozitor" #: core/bind/core_bind.cpp main/main.cpp msgid "Delta Smoothing" -msgstr "" +msgstr "Netezirea Delta" #: core/bind/core_bind.cpp #, fuzzy @@ -70,11 +71,11 @@ msgstr "Mod Mutare" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" -msgstr "" +msgstr "Timp de utilizare scăzut al procesorului (μsec)" #: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp msgid "Keep Screen On" -msgstr "" +msgstr "Păstrați ecranul pornit" #: core/bind/core_bind.cpp msgid "Min Window Size" @@ -116,7 +117,7 @@ msgstr "Minimizat" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp msgid "Resizable" -msgstr "" +msgstr "Redimensionabil" #: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp #: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp @@ -148,7 +149,7 @@ msgstr "Indiciu Editor" #: core/bind/core_bind.cpp msgid "Print Error Messages" -msgstr "" +msgstr "Imprimare mesaje de eroare" #: core/bind/core_bind.cpp msgid "Iterations Per Second" @@ -159,9 +160,8 @@ msgid "Target FPS" msgstr "Frecvență Țintă" #: core/bind/core_bind.cpp -#, fuzzy msgid "Time Scale" -msgstr "Nod DimensiuneTimp" +msgstr "Scară de timp" #: core/bind/core_bind.cpp main/main.cpp #, fuzzy @@ -173,22 +173,20 @@ msgid "Error" msgstr "Eroare" #: core/bind/core_bind.cpp -#, fuzzy msgid "Error String" -msgstr "Eroare La Salvarea" +msgstr "Eroare string" #: core/bind/core_bind.cpp msgid "Error Line" msgstr "Linia Erorii" #: core/bind/core_bind.cpp -#, fuzzy msgid "Result" -msgstr "Căutați în Ajutor" +msgstr "Rezultat" #: core/command_queue_mt.cpp core/message_queue.cpp main/main.cpp msgid "Memory" -msgstr "" +msgstr "Memorie" #: core/command_queue_mt.cpp core/message_queue.cpp #: core/register_core_types.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp @@ -208,7 +206,7 @@ msgstr "Trage: Rotire" #: core/command_queue_mt.cpp msgid "Multithreading Queue Size (KB)" -msgstr "" +msgstr "Mărimea cozii de așteptare pentru mai multe fire (KB)" #: core/func_ref.cpp modules/visual_script/visual_script_builtin_funcs.cpp #: modules/visual_script/visual_script_func_nodes.cpp @@ -220,7 +218,7 @@ msgstr "Funcție" #: core/image.cpp core/packed_data_container.cpp scene/2d/polygon_2d.cpp #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Data" -msgstr "" +msgstr "Date" #: core/io/file_access_network.cpp core/register_core_types.cpp #: editor/editor_file_dialog.cpp editor/editor_settings.cpp main/main.cpp @@ -242,11 +240,11 @@ msgstr "Marime Pagina" #: core/io/file_access_network.cpp msgid "Page Read Ahead" -msgstr "" +msgstr "Pagina Citește înainte" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" -msgstr "" +msgstr "Mod de blocare Activat" #: core/io/http_client.cpp msgid "Connection" @@ -300,7 +298,7 @@ msgstr "" #: core/io/packet_peer.cpp msgid "Stream Peer" -msgstr "" +msgstr "Fluxul Peer" #: core/io/stream_peer.cpp msgid "Big Endian" @@ -312,7 +310,7 @@ msgstr "" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" -msgstr "" +msgstr "Blocare Handshake" #: core/io/udp_server.cpp #, fuzzy @@ -367,7 +365,7 @@ msgstr "În apelarea lui '%s':" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp msgid "Seed" -msgstr "" +msgstr "Semințe" #: core/math/random_number_generator.cpp #, fuzzy @@ -376,7 +374,7 @@ msgstr "Mod Rotație" #: core/message_queue.cpp msgid "Message Queue" -msgstr "" +msgstr "Coada de mesaje" #: core/message_queue.cpp msgid "Max Size (KB)" @@ -411,7 +409,7 @@ msgstr "Control" #: core/os/input_event.cpp msgid "Meta" -msgstr "" +msgstr "Meta" #: core/os/input_event.cpp #, fuzzy @@ -444,7 +442,7 @@ msgstr "Unicode" #: core/os/input_event.cpp msgid "Echo" -msgstr "" +msgstr "Ecou" #: core/os/input_event.cpp scene/gui/base_button.cpp #, fuzzy @@ -478,7 +476,7 @@ msgstr "Presiune" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Stilou inversat" #: core/os/input_event.cpp msgid "Relative" @@ -552,7 +550,7 @@ msgstr "Linia Numărul:" #: core/os/input_event.cpp msgid "Controller Value" -msgstr "" +msgstr "Valoarea controlerului" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp @@ -679,7 +677,7 @@ msgstr "Editor" #: core/project_settings.cpp msgid "Main Run Args" -msgstr "" +msgstr "Argumente principale ale rulării" #: core/project_settings.cpp #, fuzzy @@ -688,7 +686,7 @@ msgstr "Calea Scenei:" #: core/project_settings.cpp msgid "Search In File Extensions" -msgstr "" +msgstr "Căutare în extensii de fișiere" #: core/project_settings.cpp msgid "Script Templates Search Path" @@ -721,7 +719,7 @@ msgstr "Selectează" #: core/project_settings.cpp msgid "UI Cancel" -msgstr "" +msgstr "Anulare interfață utilizator" #: core/project_settings.cpp #, fuzzy @@ -754,7 +752,7 @@ msgstr "Descarcă" #: core/project_settings.cpp msgid "UI Page Up" -msgstr "" +msgstr "Pagina UI în sus" #: core/project_settings.cpp msgid "UI Page Down" @@ -762,11 +760,11 @@ msgstr "" #: core/project_settings.cpp msgid "UI Home" -msgstr "" +msgstr "UI Acasă" #: core/project_settings.cpp msgid "UI End" -msgstr "" +msgstr "Sfârșitul interfeței de utilizator" #: core/project_settings.cpp main/main.cpp modules/bullet/register_types.cpp #: modules/bullet/space_bullet.cpp scene/2d/physics_body_2d.cpp @@ -815,7 +813,7 @@ msgstr "" #: scene/resources/multimesh.cpp servers/visual/visual_server_scene.cpp #: servers/visual_server.cpp msgid "Quality" -msgstr "" +msgstr "Calitate" #: core/project_settings.cpp scene/gui/file_dialog.cpp #: scene/main/scene_tree.cpp scene/resources/navigation_mesh.cpp @@ -826,7 +824,7 @@ msgstr "Filtre:" #: core/project_settings.cpp scene/main/viewport.cpp msgid "Sharpen Intensity" -msgstr "" +msgstr "Intensitate Sharpen" #: core/project_settings.cpp editor/editor_export.cpp editor/editor_node.cpp #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp @@ -849,7 +847,7 @@ msgstr "Setări:" #: core/project_settings.cpp editor/script_editor_debugger.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp msgid "Profiler" -msgstr "" +msgstr "Profiler" #: core/project_settings.cpp #, fuzzy @@ -871,35 +869,35 @@ msgstr "" #: core/project_settings.cpp msgid "Long Distance Matching" -msgstr "" +msgstr "Potrivire la distanță" #: core/project_settings.cpp msgid "Compression Level" -msgstr "" +msgstr "Nivelul de compresie" #: core/project_settings.cpp msgid "Window Log Size" -msgstr "" +msgstr "Dimensiunea jurnalului de fereastră" #: core/project_settings.cpp msgid "Zlib" -msgstr "" +msgstr "Zlib" #: core/project_settings.cpp msgid "Gzip" -msgstr "" +msgstr "Gzip" #: core/project_settings.cpp platform/android/export/export.cpp msgid "Android" -msgstr "" +msgstr "Android" #: core/project_settings.cpp msgid "Modules" -msgstr "" +msgstr "Module" #: core/register_core_types.cpp msgid "TCP" -msgstr "" +msgstr "TCP" #: core/register_core_types.cpp #, fuzzy @@ -908,7 +906,7 @@ msgstr "Conectați la Nod:" #: core/register_core_types.cpp msgid "Packet Peer Stream" -msgstr "" +msgstr "Pachet Peer Stream" #: core/register_core_types.cpp msgid "Max Buffer (Power of 2)" @@ -957,7 +955,7 @@ msgstr "Se Testează" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "" +msgstr "Fallback" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -1015,7 +1013,7 @@ msgstr "" #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/visual_server.cpp msgid "2D" -msgstr "" +msgstr "2D" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -1032,7 +1030,7 @@ msgstr "Utilizează Pixel Snap" #: drivers/gles2/rasterizer_scene_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Immediate Buffer Size (KB)" -msgstr "" +msgstr "Dimensiunea imediată a bufferului (KB)" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp @@ -1043,7 +1041,7 @@ msgstr "Procesează Lightmaps" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Use Bicubic Sampling" -msgstr "" +msgstr "Utilizarea eșantionării bicubice" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Elements" @@ -16758,7 +16756,7 @@ msgstr "" #: main/main.cpp msgid "iOS" -msgstr "" +msgstr "iOS" #: main/main.cpp msgid "Hide Home Indicator" @@ -19934,7 +19932,7 @@ msgstr "Eroare la scrierea TextFile:" #: platform/javascript/export/export.cpp msgid "Web" -msgstr "" +msgstr "Web" #: platform/javascript/export/export.cpp msgid "HTTP Host" @@ -20861,9 +20859,8 @@ msgid "Executable \"pck\" section not found." msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Windows" -msgstr "Fereastră Nouă" +msgstr "Windows" #: platform/windows/export/export.cpp msgid "Rcedit" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index b79923abf1..0432de4da5 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -124,13 +124,15 @@ # Gulpy <yak.aryslan.1999@gmail.com>, 2022. # Sergey Karmanov <ppoocpel8888@gmail.com>, 2022. # Дмитрий <Dimega@inbox.ru>, 2022. +# Vladimir Kirillovskiy <vladimir.kirillovskiy@gmail.com>, 2022. +# Evgeniy Khramov <thejenjagamertjg@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-09-01 15:11+0000\n" -"Last-Translator: Дмитрий <Dimega@inbox.ru>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: Evgeniy Khramov <thejenjagamertjg@gmail.com>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" "Language: ru\n" @@ -139,7 +141,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -1263,12 +1265,10 @@ msgid "Type" msgstr "Тип" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" msgstr "Задать обработчик" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" msgstr "Задать обработчик" @@ -14207,14 +14207,12 @@ msgid "More Info..." msgstr "Подробнее..." #: editor/project_export.cpp -#, fuzzy msgid "Export PCK/Zip..." -msgstr "Экспортировать PCK/Zip" +msgstr "Экспортировать PCK/Zip..." #: editor/project_export.cpp -#, fuzzy msgid "Export Project..." -msgstr "Экспортировать проект" +msgstr "Экспортировать проект..." #: editor/project_export.cpp msgid "Export All" @@ -14226,7 +14224,7 @@ msgstr "Пожалуйста, выберите режим экспорта:" #: editor/project_export.cpp msgid "Export All..." -msgstr "Экспортировать всё" +msgstr "Экспортировать всё..." #: editor/project_export.cpp editor/project_manager.cpp msgid "ZIP File" @@ -14242,9 +14240,8 @@ msgid "Export templates for this platform are missing:" msgstr "Шаблоны экспорта для этой платформы отсутствуют:" #: editor/project_export.cpp -#, fuzzy msgid "Project Export" -msgstr "Основатели проекта" +msgstr "Экспорт проекта" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -15364,9 +15361,8 @@ msgid "Enable Scene Unique Name(s)" msgstr "Добавить уникальное имя сцене" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Unique names already used by another node in the scene:" -msgstr "Данное уникальное имя уже использовано у другого узла в сцене." +msgstr "Данное уникальное имя уже использовано у другого узла в сцене:" #: editor/scene_tree_dock.cpp #, fuzzy @@ -17195,19 +17191,16 @@ msgid "Octant Size" msgstr "Размер октанта" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center X" -msgstr "По центру" +msgstr "По центру X" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Y" -msgstr "По центру" +msgstr "По центру Y" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Z" -msgstr "По центру" +msgstr "По центру Z" #: modules/gridmap/grid_map.cpp scene/2d/collision_object_2d.cpp #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp @@ -17224,9 +17217,8 @@ msgstr "Навигация" #: scene/2d/navigation_agent_2d.cpp scene/2d/navigation_polygon.cpp #: scene/2d/tile_map.cpp scene/3d/navigation.cpp scene/3d/navigation_agent.cpp #: scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Navigation Layers" -msgstr "Чувствительность навигации" +msgstr "Слои навигации" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Plane" @@ -17466,9 +17458,8 @@ msgid "Solution Directory" msgstr "Выбрать каталог" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "C# Project Directory" -msgstr "Выбрать каталог" +msgstr "Каталог C# проекта" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17624,9 +17615,8 @@ msgid "IGD Our Addr" msgstr "IGD Наш Адр" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "IGD Status" -msgstr "Статус" +msgstr "IGD Статус" #: modules/visual_script/visual_script.cpp msgid "" @@ -18441,9 +18431,8 @@ msgid "Visibility State" msgstr "Видимость" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Bounds Geometry" -msgstr "Повторить" +msgstr "Геометрия границ" #: modules/webxr/webxr_interface.cpp msgid "XR Standard Mapping" @@ -18545,14 +18534,12 @@ msgid "Keystore" msgstr "Хранилище ключей" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Debug User" -msgstr "Отладчик" +msgstr "Пользователь отладчика" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Debug Password" -msgstr "Пароль" +msgstr "Пароль отладчика" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18589,18 +18576,16 @@ msgid "Signed" msgstr "Подписано" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Classify As Game" -msgstr "Имя класса" +msgstr "Классифицировать как игру" #: platform/android/export/export_plugin.cpp msgid "Retain Data On Uninstall" -msgstr "" +msgstr "Сохранить данные при удалении программы" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Exclude From Recents" -msgstr "Удалить узлы" +msgstr "Исключить из недавнего" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18660,9 +18645,8 @@ msgid "Support Xlarge" msgstr "Поддержка" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "User Data Backup" -msgstr "Пользовательский интерфейс" +msgstr "Резервное копирование пользовательских данных" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18670,32 +18654,28 @@ msgid "Allow" msgstr "Разрешено" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Command Line" -msgstr "Command" +msgstr "Командная строка" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp msgid "Extra Args" msgstr "Дополнительные аргументы" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "APK Expansion" -msgstr "Выражение" +msgstr "APK расширение" #: platform/android/export/export_plugin.cpp msgid "Salt" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Public Key" -msgstr "Путь к открытому ключу SSH" +msgstr "Открытый ключ" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Permissions" -msgstr "Маска излучения" +msgstr "Разрешения" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18857,12 +18837,16 @@ msgstr "" #: platform/android/export/export_plugin.cpp msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid." msgstr "" +"\"Min SDK\" должно быть валидным целым числом, полученное \"%s\" - не " +"валидно." #: platform/android/export/export_plugin.cpp msgid "" "\"Min SDK\" cannot be lower than %d, which is the version needed by the " "Godot library." msgstr "" +"\"Min SDK\" не может быть меньше чем %d - это версия требуемая Godot " +"библиотекой." #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18876,12 +18860,16 @@ msgstr "" msgid "" "\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid." msgstr "" +"\"Target SDK\" должно быть валидным целым числом, полученное \"%s\" - не " +"валидно." #: platform/android/export/export_plugin.cpp msgid "" "\"Target SDK\" %d is higher than the default version %d. This may work, but " "wasn't tested and may be unstable." msgstr "" +"\"Target SDK\" %d выше чем версия по умолчанию %d. Это может сработать, но " +"не тестировано и может быть не стабильным." #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18890,9 +18878,8 @@ msgstr "Версия «Target Sdk» должна быть больше или р #: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Code Signing" -msgstr "Подпись кода DMG" +msgstr "Подпись кода" #: platform/android/export/export_plugin.cpp msgid "" @@ -18969,7 +18956,8 @@ msgstr "" #: platform/android/export/export_plugin.cpp msgid "" "Unable to overwrite res://android/build/res/*.xml files with project name." -msgstr "Невозможно перезаписать res://android/build/res/*.xml с именем проекта" +msgstr "" +"Невозможно перезаписать res://android/build/res/*.xml с именем проекта." #: platform/android/export/export_plugin.cpp msgid "Could not export project files to gradle project." @@ -19144,9 +19132,8 @@ msgid "Identifier" msgstr "Индетификатор" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Signature" -msgstr "Сигнал" +msgstr "Подпись" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19155,14 +19142,12 @@ msgstr "Старшая версия" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Copyright" -msgstr "Справа вверху" +msgstr "Авторские права" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Capabilities" -msgstr "Капитализировать свойства" +msgstr "Возможности" #: platform/iphone/export/export.cpp msgid "Access Wi-Fi" @@ -19173,37 +19158,32 @@ msgid "Push Notifications" msgstr "Всплывающее уведомление" #: platform/iphone/export/export.cpp -#, fuzzy msgid "User Data" -msgstr "Пользовательский интерфейс" +msgstr "Пользовательские данные" #: platform/iphone/export/export.cpp msgid "Accessible From Files App" -msgstr "" +msgstr "Доступно из приложения Files" #: platform/iphone/export/export.cpp msgid "Accessible From iTunes Sharing" -msgstr "" +msgstr "Доступно из iTunes Sharing" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Privacy" -msgstr "Закрытый ключ" +msgstr "Конфиденциальность" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Camera Usage Description" -msgstr "Описание" +msgstr "Описание использования камеры" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Microphone Usage Description" -msgstr "Описания свойств" +msgstr "Описание использования микрофона" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Photolibrary Usage Description" -msgstr "Описания свойств" +msgstr "Описание использования фото-библиотеки" #: platform/iphone/export/export.cpp msgid "iPhone 120 X 120" @@ -19246,40 +19226,33 @@ msgid "Use Launch Screen Storyboard" msgstr "" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Image Scale Mode" -msgstr "Режим масштабирования" +msgstr "Режим масштабирования изображения" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom Image @2x" -msgstr "Пользовательское изображение" +msgstr "Пользовательское изображение @2x" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom Image @3x" -msgstr "Пользовательское изображение" +msgstr "Пользовательское изображение @3x" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Use Custom BG Color" -msgstr "Пользовательский цвет" +msgstr "Использовать пользовательский цвет фона" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom BG Color" -msgstr "Пользовательский цвет" +msgstr "Пользовательский цвет фона" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Icons" -msgstr "Развернуть все" +msgstr "Экспортировать иконки" #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp -#, fuzzy msgid "Prepare Templates" -msgstr "Управление шаблонами" +msgstr "Подготовить шаблоны" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19319,9 +19292,8 @@ msgid "Could not write file: \"%s\"." msgstr "Не удалось записать файл: \"%s\"." #: platform/javascript/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Icon Creation" -msgstr "Задать отступ" +msgstr "Создание иконки" #: platform/javascript/export/export.cpp msgid "Could not read file: \"%s\"." @@ -19337,14 +19309,12 @@ msgid "Variant" msgstr "Вариация оттенка" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Export Type" -msgstr "Экспорт" +msgstr "Тип экспорта" #: platform/javascript/export/export.cpp -#, fuzzy msgid "VRAM Texture Compression" -msgstr "Выражение" +msgstr "VRAM компрессия текстуры" #: platform/javascript/export/export.cpp msgid "For Desktop" @@ -19359,9 +19329,8 @@ msgid "HTML" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Export Icon" -msgstr "Развернуть все" +msgstr "Экспортировать иконку" #: platform/javascript/export/export.cpp #, fuzzy @@ -19374,36 +19343,35 @@ msgstr "" #: platform/javascript/export/export.cpp msgid "Canvas Resize Policy" -msgstr "" +msgstr "Политика изменения размера холста" #: platform/javascript/export/export.cpp msgid "Focus Canvas On Start" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Experimental Virtual Keyboard" -msgstr "Фильтр сигналов" +msgstr "Экспериментальная виртуальная клавиатура" #: platform/javascript/export/export.cpp msgid "Progressive Web App" -msgstr "" +msgstr "Прогрессивное веб-приложение" #: platform/javascript/export/export.cpp msgid "Offline Page" -msgstr "" +msgstr "Офлайн-страница" #: platform/javascript/export/export.cpp msgid "Icon 144 X 144" -msgstr "" +msgstr "Иконка 144 X 144" #: platform/javascript/export/export.cpp msgid "Icon 180 X 180" -msgstr "" +msgstr "Иконка 180 X 180" #: platform/javascript/export/export.cpp msgid "Icon 512 X 512" -msgstr "" +msgstr "Иконка 512 X 512" #: platform/javascript/export/export.cpp msgid "Could not read HTML shell: \"%s\"." @@ -19414,9 +19382,8 @@ msgid "Could not create HTTP server directory: %s." msgstr "Не удалось создать каталог HTTP-сервера: %s." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Error starting HTTP server: %d." -msgstr "Ошибка запуска HTTP-сервера:" +msgstr "Ошибка запуска HTTP-сервера: %d." #: platform/javascript/export/export.cpp msgid "Web" @@ -19525,31 +19492,27 @@ msgstr "Описание" #: platform/osx/export/export.cpp msgid "Address Book Usage Description" -msgstr "" +msgstr "Описание использования адресной книги" #: platform/osx/export/export.cpp -#, fuzzy msgid "Calendar Usage Description" -msgstr "Описание" +msgstr "Описание использования календаря" #: platform/osx/export/export.cpp -#, fuzzy msgid "Photos Library Usage Description" -msgstr "Описания свойств" +msgstr "Описание использования Фото библиотеки" #: platform/osx/export/export.cpp -#, fuzzy msgid "Desktop Folder Usage Description" -msgstr "Описания методов" +msgstr "Описание использования папки рабочего стола" #: platform/osx/export/export.cpp -#, fuzzy msgid "Documents Folder Usage Description" -msgstr "Описания методов" +msgstr "Описание использования папки Документов" #: platform/osx/export/export.cpp msgid "Downloads Folder Usage Description" -msgstr "" +msgstr "Описание использования папки загрузок" #: platform/osx/export/export.cpp msgid "Network Volumes Usage Description" @@ -19591,49 +19554,44 @@ msgid "Entitlements" msgstr "Гизмо" #: platform/osx/export/export.cpp -#, fuzzy msgid "Custom File" -msgstr "Пользовательский шрифт" +msgstr "Пользовательский файл" #: platform/osx/export/export.cpp msgid "Allow JIT Code Execution" -msgstr "" +msgstr "Разрешить выполнение JIT-кода" #: platform/osx/export/export.cpp msgid "Allow Unsigned Executable Memory" -msgstr "" +msgstr "Разрешить неподписанную исполняемую память" #: platform/osx/export/export.cpp msgid "Allow Dyld Environment Variables" -msgstr "" +msgstr "Разрешить переменные среды Dyld" #: platform/osx/export/export.cpp -#, fuzzy msgid "Disable Library Validation" -msgstr "Заблокированная кнопка" +msgstr "Отключить валидацию библиотеки" #: platform/osx/export/export.cpp -#, fuzzy msgid "Audio Input" -msgstr "Добавить вход" +msgstr "Аудио вход" #: platform/osx/export/export.cpp msgid "Address Book" -msgstr "" +msgstr "Адресная книга" #: platform/osx/export/export.cpp msgid "Calendars" -msgstr "" +msgstr "Календари" #: platform/osx/export/export.cpp -#, fuzzy msgid "Photos Library" -msgstr "Экспортировать библиотеку" +msgstr "Библиотека фотографий" #: platform/osx/export/export.cpp -#, fuzzy msgid "Apple Events" -msgstr "Добавить событие" +msgstr "Apple события" #: platform/osx/export/export.cpp #, fuzzy @@ -19642,51 +19600,43 @@ msgstr "Отладка" #: platform/osx/export/export.cpp msgid "App Sandbox" -msgstr "" +msgstr "Приложение \"песочница\"" #: platform/osx/export/export.cpp -#, fuzzy msgid "Network Server" -msgstr "Сетевой узел" +msgstr "Сетевой сервер" #: platform/osx/export/export.cpp -#, fuzzy msgid "Network Client" -msgstr "Сетевой узел" +msgstr "Сетевой клиент" #: platform/osx/export/export.cpp -#, fuzzy msgid "Device USB" -msgstr "Устройство" +msgstr "Устройство USB" #: platform/osx/export/export.cpp msgid "Device Bluetooth" -msgstr "" +msgstr "Устройство Bluetooth" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Downloads" -msgstr "Загрузка" +msgstr "Файлы загрузок" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Pictures" -msgstr "Возможности" +msgstr "Файлы картинок" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Music" -msgstr "Файлы" +msgstr "Файлы музыки" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Movies" -msgstr "Фильтр тайлов" +msgstr "Файлы фильмов" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Custom Options" -msgstr "Параметры шины" +msgstr "Пользовательские параметры" #: platform/osx/export/export.cpp #, fuzzy @@ -19698,27 +19648,24 @@ msgid "Apple ID Name" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Apple ID Password" -msgstr "Пароль" +msgstr "Пароль Apple ID" #: platform/osx/export/export.cpp msgid "Apple Team ID" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not open icon file \"%s\"." -msgstr "Не удалось экспортировать файлы проекта" +msgstr "Не получилось открыть файлы иконок \"%s\"." #: platform/osx/export/export.cpp msgid "Could not start xcrun executable." msgstr "Не удаётся запустить исполняемый файл xcrun." #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization failed." -msgstr "Локализация" +msgstr "Нотаризация не удалась." #: platform/osx/export/export.cpp msgid "Notarization request UUID: \"%s\"" @@ -19774,15 +19721,16 @@ msgid "" "Could not start codesign executable, make sure Xcode command line tools are " "installed." msgstr "" +"Не удалось запустить исполняемый файл codesign, убедитесь, что инструменты " +"командной строки Xcode установлены." #: platform/osx/export/export.cpp platform/windows/export/export.cpp msgid "No identity found." msgstr "Identity не найдена." #: platform/osx/export/export.cpp -#, fuzzy msgid "Cannot sign file %s." -msgstr "Ошибка при сохранении файла: %s" +msgstr "Не удалось подписать файл %s." #: platform/osx/export/export.cpp #, fuzzy @@ -19802,25 +19750,23 @@ msgstr "Не удаётся запустить исполняемый файл h #: platform/osx/export/export.cpp msgid "`hdiutil create` failed - file exists." -msgstr "" +msgstr "Не удалось выполнить `hdiutil create` - файл уже существует." #: platform/osx/export/export.cpp msgid "`hdiutil create` failed." -msgstr "" +msgstr "Не удалось выполнить `hdiutil create`." #: platform/osx/export/export.cpp msgid "Creating app bundle" msgstr "Создание пакета приложения" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not find template app to export: \"%s\"." -msgstr "Не удалось найти шаблон приложения для экспорта:" +msgstr "Не удалось найти шаблон приложения для экспорта: \"%s\"." #: platform/osx/export/export.cpp -#, fuzzy msgid "Invalid export format." -msgstr "Неверный шаблон экспорта:" +msgstr "Неверный формат экспорта." #: platform/osx/export/export.cpp msgid "" @@ -19880,9 +19826,8 @@ msgid "Sending archive for notarization" msgstr "Отправка архива для подтверждения" #: platform/osx/export/export.cpp -#, fuzzy msgid "ZIP Creation" -msgstr "Проекция" +msgstr "Создание ZIP" #: platform/osx/export/export.cpp msgid "Could not open file to read from path \"%s\"." @@ -20028,9 +19973,8 @@ msgid "Force Builtin Codesign" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Architecture" -msgstr "Добавить поле архитектуры" +msgstr "Архитектура" #: platform/uwp/export/export.cpp #, fuzzy @@ -20043,7 +19987,7 @@ msgstr "Короткое имя" #: platform/uwp/export/export.cpp msgid "Publisher" -msgstr "" +msgstr "Издатель" #: platform/uwp/export/export.cpp msgid "Publisher Display Name" @@ -20054,9 +19998,8 @@ msgid "Product GUID" msgstr "GUID Продукта" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Publisher GUID" -msgstr "Очистить направляющие" +msgstr "Издатель GUID" #: platform/uwp/export/export.cpp #, fuzzy @@ -20064,14 +20007,12 @@ msgid "Signing" msgstr "Сигнал" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Certificate" -msgstr "Сертификаты" +msgstr "Сертификат" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Algorithm" -msgstr "Отладчик" +msgstr "Алгоритм" #: platform/uwp/export/export.cpp msgid "Major" @@ -20082,9 +20023,8 @@ msgid "Minor" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Build" -msgstr "Режим измерения" +msgstr "Сборка" #: platform/uwp/export/export.cpp #, fuzzy @@ -20096,9 +20036,8 @@ msgid "Landscape" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Portrait" -msgstr "Порт" +msgstr "Портрет" #: platform/uwp/export/export.cpp msgid "Landscape Flipped" @@ -20115,23 +20054,23 @@ msgstr "Режим масштабирования" #: platform/uwp/export/export.cpp msgid "Square 44 X 44 Logo" -msgstr "" +msgstr "Квадратный логотип 44 X 44" #: platform/uwp/export/export.cpp msgid "Square 71 X 71 Logo" -msgstr "" +msgstr "Квадратный логотип 71 X 71" #: platform/uwp/export/export.cpp msgid "Square 150 X 150 Logo" -msgstr "" +msgstr "Квадратный логотип 150 X 150" #: platform/uwp/export/export.cpp msgid "Square 310 X 310 Logo" -msgstr "" +msgstr "Квадратный логотип 310 X 310" #: platform/uwp/export/export.cpp msgid "Wide 310 X 150 Logo" -msgstr "" +msgstr "Широкий логотип 310 X 150" #: platform/uwp/export/export.cpp #, fuzzy @@ -20139,13 +20078,12 @@ msgid "Splash Screen" msgstr "Рисовать экран" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Tiles" -msgstr "Файлы" +msgstr "Тайлы" #: platform/uwp/export/export.cpp msgid "Show Name On Square 150 X 150" -msgstr "" +msgstr "Показать имя на квадрате 150 X 150" #: platform/uwp/export/export.cpp msgid "Show Name On Wide 310 X 150" @@ -20218,23 +20156,20 @@ msgid "UWP" msgstr "UWP" #: platform/uwp/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Signtool" -msgstr "Сигнал" +msgstr "Инструмент подписи" #: platform/uwp/export/export.cpp msgid "Debug Certificate" msgstr "Сертификат отладки" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Debug Algorithm" -msgstr "Отладчик" +msgstr "Алгоритм отладчика" #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to rename temporary file \"%s\"." -msgstr "Невозможно удалить временный файл:" +msgstr "Невозможно удалить временный файл \"%s\"." #: platform/windows/export/export.cpp msgid "Identity Type" @@ -20250,41 +20185,36 @@ msgid "Digest Algorithm" msgstr "Отладчик" #: platform/windows/export/export.cpp -#, fuzzy msgid "Modify Resources" -msgstr "Копировать параметры" +msgstr "Изменить ресурсы" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Version" -msgstr "Версия" +msgstr "Версия файла" #: platform/windows/export/export.cpp msgid "Product Version" msgstr "Версия продукта" #: platform/windows/export/export.cpp -#, fuzzy msgid "Company Name" -msgstr "Имя кости" +msgstr "Имя компании" #: platform/windows/export/export.cpp msgid "Product Name" msgstr "Название продукта" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Description" -msgstr "Описание" +msgstr "Описание файла" #: platform/windows/export/export.cpp msgid "Trademarks" -msgstr "" +msgstr "Торговые марки" #: platform/windows/export/export.cpp -#, fuzzy msgid "Resources Modification" -msgstr "Всплывающее уведомление" +msgstr "Изменение ресурсов" #: platform/windows/export/export.cpp #, fuzzy @@ -20307,9 +20237,8 @@ msgstr "" "Windows > Rcedit) для изменения значка или информационных данных приложения." #: platform/windows/export/export.cpp -#, fuzzy msgid "rcedit failed to modify executable: %s." -msgstr "Недопустимый исполняемый файл." +msgstr "rcedit не смог изменить исполняемый файл: %s." #: platform/windows/export/export.cpp #, fuzzy @@ -20322,14 +20251,12 @@ msgid "Could not find osslsigncode executable at \"%s\"." msgstr "Не удалось найти хранилище ключей, невозможно экспортировать." #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid identity type." -msgstr "Неверный идентификатор:" +msgstr "Неверный идентификатор." #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid timestamp server." -msgstr "Недопустимое имя." +msgstr "Неверный сервер метки времени." #: platform/windows/export/export.cpp #, fuzzy @@ -20342,14 +20269,12 @@ msgstr "" "Windows > Rcedit) для изменения значка или информационных данных приложения." #: platform/windows/export/export.cpp -#, fuzzy msgid "Signtool failed to sign executable: %s." -msgstr "Недопустимый исполняемый файл." +msgstr "Signtool не смог подписать исполняемый файл: %s." #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to remove temporary file \"%s\"." -msgstr "Невозможно удалить временный файл:" +msgstr "Невозможно удалить временный файл \"%s\"." #: platform/windows/export/export.cpp msgid "" @@ -20376,9 +20301,8 @@ msgid "Windows executables cannot be >= 4 GiB." msgstr "" #: platform/windows/export/export.cpp platform/x11/export/export.cpp -#, fuzzy msgid "Failed to open executable file \"%s\"." -msgstr "Недопустимый исполняемый файл." +msgstr "Не удалось открыть исполняемый файл \"%s\"." #: platform/windows/export/export.cpp platform/x11/export/export.cpp msgid "Executable file header corrupted." @@ -20447,39 +20371,32 @@ msgid "Flip V" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Monitoring" -msgstr "Параметр" +msgstr "Наблюдение" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Monitorable" -msgstr "Параметр" +msgstr "Наблюдаемый" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Physics Overrides" -msgstr "Переопределить" +msgstr "Переопределение физики" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Space Override" -msgstr "Переопределить" +msgstr "Переопределение пространства" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Point" -msgstr "Генерировать точки" +msgstr "Точка гравитации" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Distance Scale" -msgstr "Ждать сигнал объекта" +msgstr "Масштаб гравитационной дистанции" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Vec" -msgstr "Превью по умолчанию" +msgstr "Вектор Гравитации" #: scene/2d/area_2d.cpp scene/2d/cpu_particles_2d.cpp scene/3d/area.cpp #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp @@ -20496,9 +20413,8 @@ msgid "Angular Damp" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Audio Bus" -msgstr "Добавить аудио шину" +msgstr "Аудио шина" #: scene/2d/area_2d.cpp scene/3d/area.cpp #, fuzzy @@ -20507,9 +20423,8 @@ msgstr "Переопределить" #: scene/2d/audio_stream_player_2d.cpp scene/audio/audio_stream_player.cpp #: scene/gui/video_player.cpp servers/audio/effects/audio_effect_amplify.cpp -#, fuzzy msgid "Volume dB" -msgstr "Объём" +msgstr "Громкость dB" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp @@ -20520,9 +20435,8 @@ msgstr "Масштабировать" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp -#, fuzzy msgid "Autoplay" -msgstr "Переключить автовоспроизведение" +msgstr "Автовоспроизведение" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp @@ -20537,9 +20451,8 @@ msgid "Max Distance" msgstr "Максимальное расстояние" #: scene/2d/audio_stream_player_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Attenuation" -msgstr "Анимация" +msgstr "Затухание" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp @@ -20559,9 +20472,8 @@ msgid "Anchor Mode" msgstr "Режим якорей" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Rotating" -msgstr "Вращающийся" +msgstr "Вращение" #: scene/2d/camera_2d.cpp scene/2d/listener_2d.cpp scene/3d/camera.cpp #: scene/3d/listener.cpp scene/animation/animation_blend_tree.cpp @@ -20574,9 +20486,8 @@ msgid "Zoom" msgstr "Приблизить" #: scene/2d/camera_2d.cpp scene/main/canvas_layer.cpp -#, fuzzy msgid "Custom Viewport" -msgstr "1 Окно" +msgstr "Пользовательское окно просмотра" #: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp @@ -20591,22 +20502,19 @@ msgstr "Лимит" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Left" -msgstr "UI Влево" +msgstr "Лево" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Right" -msgstr "Свет" +msgstr "Право" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/dynamic_font.cpp scene/resources/style_box.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Bottom" -msgstr "Слева внизу" +msgstr "Внизу" #: scene/2d/camera_2d.cpp #, fuzzy @@ -20663,9 +20571,8 @@ msgstr "Задать отступ" #: scene/2d/canvas_item.cpp scene/resources/environment.cpp #: scene/resources/material.cpp -#, fuzzy msgid "Blend Mode" -msgstr "Blend2 узел" +msgstr "Режим смешивания" #: scene/2d/canvas_item.cpp #, fuzzy @@ -20673,9 +20580,8 @@ msgid "Light Mode" msgstr "Справа по всей высоте" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Particles Animation" -msgstr "Частицы" +msgstr "Анимация частиц" #: scene/2d/canvas_item.cpp msgid "Particles Anim H Frames" @@ -20686,9 +20592,8 @@ msgid "Particles Anim V Frames" msgstr "" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Particles Anim Loop" -msgstr "Частицы" +msgstr "Цикл анимации частиц" #: scene/2d/canvas_item.cpp scene/3d/spatial.cpp msgid "Visibility" @@ -20709,9 +20614,8 @@ msgid "Show Behind Parent" msgstr "" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Show On Top" -msgstr "Отображать центр" +msgstr "Отображать поверх" #: scene/2d/canvas_item.cpp scene/2d/light_occluder_2d.cpp #: scene/2d/tile_map.cpp @@ -20776,9 +20680,8 @@ msgid "" msgstr "" #: scene/2d/collision_polygon_2d.cpp -#, fuzzy msgid "Build Mode" -msgstr "Режим измерения" +msgstr "Режим сборки" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp #: scene/3d/collision_polygon.cpp scene/3d/collision_shape.cpp @@ -20792,9 +20695,8 @@ msgid "One Way Collision" msgstr "Одностороннее столкновение" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp -#, fuzzy msgid "One Way Collision Margin" -msgstr "Создать полигон столкновений" +msgstr "Отступ одностороннего полигона столкновений" #: scene/2d/collision_shape_2d.cpp msgid "" @@ -20869,9 +20771,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Fixed FPS" -msgstr "Показывать FPS" +msgstr "Фиксированный FPS" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -20885,9 +20786,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Local Coords" -msgstr "Локальные проекты" +msgstr "Локальные координаты" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -20910,15 +20810,13 @@ msgid "Rect Extents" msgstr "Гизмо" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp -#, fuzzy msgid "Normals" -msgstr "Формат" +msgstr "Нормали" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Align Y" -msgstr "Оператор присваивания" +msgstr "Выравнивать по Y" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -20938,9 +20836,8 @@ msgstr "Начальная скорость" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity Random" -msgstr "Скорость" +msgstr "Случайная скорость" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp @@ -20950,9 +20847,8 @@ msgstr "Угловая скорость" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity Curve" -msgstr "Скорость" +msgstr "Кривая скорости" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -20966,20 +20862,18 @@ msgstr "Линейное ускорение" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Accel" -msgstr "Доступ" +msgstr "Ускорение" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp msgid "Accel Random" -msgstr "" +msgstr "Случайное ускорение" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Accel Curve" -msgstr "Разделить кривую" +msgstr "Кривая ускорения" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21006,9 +20900,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Damping Curve" -msgstr "Разделить кривую" +msgstr "Кривая затухания" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/light.cpp #: scene/resources/particles_material.cpp @@ -21022,23 +20915,20 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Angle Curve" -msgstr "Сомкнуть кривую" +msgstr "Кривая угла" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp -#, fuzzy msgid "Scale Amount" -msgstr "Количество солнц" +msgstr "Масштаб" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp msgid "Scale Amount Random" msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp -#, fuzzy msgid "Scale Amount Curve" -msgstr "Масштабировать от курсора" +msgstr "Кривая масштаба" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21058,45 +20948,38 @@ msgstr "Вариация оттенка" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Variation" -msgstr "Вариация оттенка" +msgstr "Вариация" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Variation Random" -msgstr "Вариация оттенка" +msgstr "Случайная вариация" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Variation Curve" -msgstr "Вариация оттенка" +msgstr "Кривая вариации" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed Random" -msgstr "Масштаб скорости" +msgstr "Случайная скорость" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed Curve" -msgstr "Разделить кривую" +msgstr "Кривая скорости" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Offset Random" -msgstr "Смещение" +msgstr "Случайное смещение" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Offset Curve" -msgstr "Сомкнуть кривую" +msgstr "Кривая смещения" #: scene/2d/joints_2d.cpp msgid "Node A and Node B must be PhysicsBody2Ds" @@ -21122,14 +21005,12 @@ msgstr "" "Узел А и Узел B должны быть различными экземплярами класса PhysicsBody2D" #: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Node A" -msgstr "Узел" +msgstr "Узел А" #: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Node B" -msgstr "Узел" +msgstr "Узел B" #: scene/2d/joints_2d.cpp scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/light.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp @@ -21138,9 +21019,8 @@ msgid "Bias" msgstr "" #: scene/2d/joints_2d.cpp -#, fuzzy msgid "Disable Collision" -msgstr "Заблокированная кнопка" +msgstr "Отключить столкновения" #: scene/2d/joints_2d.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Softness" @@ -21152,9 +21032,8 @@ msgid "Length" msgstr "Длина" #: scene/2d/joints_2d.cpp -#, fuzzy msgid "Initial Offset" -msgstr "Инициализировать" +msgstr "Начальное смещение" #: scene/2d/joints_2d.cpp scene/3d/vehicle_body.cpp msgid "Rest Length" @@ -21176,9 +21055,8 @@ msgid "Editor Only" msgstr "Редактор" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Texture Scale" -msgstr "Область текстуры" +msgstr "Масштаб текстуры" #: scene/2d/light_2d.cpp scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/light.cpp scene/resources/environment.cpp @@ -21195,14 +21073,12 @@ msgid "Z Max" msgstr "" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Layer Min" -msgstr "Изменить размер камеры" +msgstr "Слой Min" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Layer Max" -msgstr "Слой" +msgstr "Слой Max" #: scene/2d/light_2d.cpp msgid "Item Cull Mask" @@ -21217,14 +21093,12 @@ msgid "Buffer Size" msgstr "Размер буфера" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Gradient Length" -msgstr "Градиент отредактирован" +msgstr "Длина градиента" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Filter Smooth" -msgstr "Фильтр методов" +msgstr "Фильтровать сглаживание" #: scene/2d/light_occluder_2d.cpp msgid "Closed" @@ -21346,14 +21220,12 @@ msgid "Path Max Distance" msgstr "Максимальное расстояние пути" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Avoidance" -msgstr "Дополнительно" +msgstr "Уклонение" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Avoidance Enabled" -msgstr "Включить" +msgstr "Включить уклонение" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Neighbor Dist" @@ -21568,14 +21440,12 @@ msgid "Layers" msgstr "Слои" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Constant Linear Velocity" -msgstr "Инициализировать" +msgstr "Постоянная линейная скорость" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Constant Angular Velocity" -msgstr "Инициализировать" +msgstr "Постоянная угловая скорость" #: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp #: scene/resources/physics_material.cpp @@ -21712,26 +21582,22 @@ msgstr "ID коллайдера" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider RID" -msgstr "Неверный RID" +msgstr "Коллайдер RID" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider Shape" -msgstr "Режим столкновения" +msgstr "Форма коллайдера" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Collider Shape Index" -msgstr "Режим столкновения" +msgstr "Индекс формы коллайдера" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider Velocity" -msgstr "Вид с орбиты вправо" +msgstr "Скорость коллайдера" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Collider Metadata" @@ -21742,14 +21608,12 @@ msgid "Invert" msgstr "" #: scene/2d/polygon_2d.cpp -#, fuzzy msgid "Vertex Colors" -msgstr "Вершины" +msgstr "Цвета вершин" #: scene/2d/polygon_2d.cpp -#, fuzzy msgid "Internal Vertex Count" -msgstr "Создать внутреннюю вершину" +msgstr "Внутренний счет вершин" #: scene/2d/position_2d.cpp #, fuzzy @@ -21761,9 +21625,8 @@ msgid "Exclude Parent" msgstr "" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp -#, fuzzy msgid "Cast To" -msgstr "Создать Шейдерный узел" +msgstr "Отбрасывать на" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp msgid "Collide With" @@ -21784,14 +21647,12 @@ msgstr "" "Node2D." #: scene/2d/remote_transform_2d.cpp scene/3d/remote_transform.cpp -#, fuzzy msgid "Remote Path" -msgstr "Удалить точку" +msgstr "Удаленный путь" #: scene/2d/remote_transform_2d.cpp scene/3d/remote_transform.cpp -#, fuzzy msgid "Use Global Coordinates" -msgstr "Следующая координата" +msgstr "Использовать глобальные координаты" #: scene/2d/skeleton_2d.cpp scene/3d/skeleton.cpp #, fuzzy @@ -21799,9 +21660,8 @@ msgid "Rest" msgstr "Перезапустить" #: scene/2d/skeleton_2d.cpp -#, fuzzy msgid "Default Length" -msgstr "Тема по умолчанию" +msgstr "Длина по умолчанию" #: scene/2d/skeleton_2d.cpp msgid "This Bone2D chain should end at a Skeleton2D node." @@ -21852,9 +21712,8 @@ msgid "Tile Set" msgstr "Набор тайлов" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Quadrant Size" -msgstr "Изменить размер камеры" +msgstr "Размер квадранта" #: scene/2d/tile_map.cpp #, fuzzy @@ -21877,14 +21736,12 @@ msgid "Y Sort" msgstr "Сортировать" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Show Collision" -msgstr "Столкновение" +msgstr "Показывать столкновение" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Compatibility Mode" -msgstr "Режим приоритета" +msgstr "Режим совместимости" #: scene/2d/tile_map.cpp msgid "Centered Textures" @@ -21895,9 +21752,8 @@ msgid "Cell Clip UV" msgstr "" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Use Parent" -msgstr "Режим столкновения" +msgstr "Использовать родитель" #: scene/2d/tile_map.cpp msgid "Use Kinematic" @@ -21909,9 +21765,8 @@ msgid "Shape Centered" msgstr "Привязка к центру узла" #: scene/2d/touch_screen_button.cpp -#, fuzzy msgid "Shape Visible" -msgstr "Переключить видимость" +msgstr "Видимость формы" #: scene/2d/touch_screen_button.cpp msgid "Passby Press" @@ -21930,29 +21785,24 @@ msgstr "" "является его прямым родителем." #: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp -#, fuzzy msgid "Pause Animations" -msgstr "Вставить анимацию" +msgstr "Приостановить анимации" #: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp -#, fuzzy msgid "Freeze Bodies" -msgstr "Тела" +msgstr "Заморозить тела" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Pause Particles" -msgstr "Частицы" +msgstr "Приостановить частицы" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Pause Animated Sprites" -msgstr "Вставить анимацию" +msgstr "Приостановить анимационные спрайты" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Process Parent" -msgstr "Включить приоритет" +msgstr "Родитель процесса" #: scene/2d/visibility_notifier_2d.cpp msgid "Physics Process Parent" @@ -21992,9 +21842,8 @@ msgstr "" "будет привязан к фактическому контроллеру." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "Anchor ID" -msgstr "Только якоря" +msgstr "ID якоря" #: scene/3d/arvr_nodes.cpp msgid "ARVRAnchor must have an ARVROrigin node as its parent." @@ -22018,9 +21867,8 @@ msgid "World Scale" msgstr "Мировой масштаб" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Attenuation Model" -msgstr "Animation узел" +msgstr "Модель затухания" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit dB" @@ -22039,9 +21887,8 @@ msgid "Out Of Range Mode" msgstr "Режим Вне Зоны Действия" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Emission Angle" -msgstr "Цвета излучения" +msgstr "Угол излучения" #: scene/3d/audio_stream_player_3d.cpp msgid "Degrees" @@ -22176,18 +22023,16 @@ msgid "Min Light" msgstr "Минимальный Свет" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -#, fuzzy msgid "Propagation" -msgstr "Навигация" +msgstr "Распространение" #: scene/3d/baked_lightmap.cpp msgid "Image Path" msgstr "Путь к изображению" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Light Data" -msgstr "С данными" +msgstr "Данные света" #: scene/3d/bone_attachment.cpp scene/3d/physics_body.cpp msgid "Bone Name" @@ -22337,28 +22182,24 @@ msgid "Ring Axis" msgstr "Ось Кольца" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Rotate Y" -msgstr "Повернуть" +msgstr "Повернуть по Y" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Disable Z" -msgstr "Отключить 3D" +msgstr "Отключить Z" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp msgid "Flatness" msgstr "Плоскостность" #: scene/3d/cull_instance.cpp servers/visual_server.cpp -#, fuzzy msgid "Portals" -msgstr "Перевернуть порталы" +msgstr "Порталы" #: scene/3d/cull_instance.cpp -#, fuzzy msgid "Portal Mode" -msgstr "Режим приоритета" +msgstr "Режим портала" #: scene/3d/cull_instance.cpp msgid "Include In Bound" @@ -22404,9 +22245,8 @@ msgid "Subdiv" msgstr "" #: scene/3d/gi_probe.cpp -#, fuzzy msgid "Dynamic Range" -msgstr "Динамическая библиотека" +msgstr "Динамический диапазон" #: scene/3d/gi_probe.cpp scene/3d/light.cpp msgid "Normal Bias" @@ -22414,23 +22254,20 @@ msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Pixel Size" -msgstr "Попиксельная привязка" +msgstr "Размер пикселя" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Billboard" msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Shaded" -msgstr "Шейдер" +msgstr "Затененный" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Double Sided" -msgstr "Двойной щелчок" +msgstr "Двухсторонний" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/material.cpp msgid "No Depth Test" @@ -22454,9 +22291,8 @@ msgid "Render Priority" msgstr "Приоритет рендеринга" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Outline Render Priority" -msgstr "Приоритет рендеринга" +msgstr "Выделить приоритет рендеринга" #: scene/3d/label_3d.cpp #, fuzzy @@ -22469,14 +22305,12 @@ msgid "Font" msgstr "Шрифт" #: scene/3d/label_3d.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Horizontal Alignment" -msgstr "Горизонтальная включена" +msgstr "Горизонтальное выравнивание" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Vertical Alignment" -msgstr "Выравнивание" +msgstr "Вертикальное выравнивание" #: scene/3d/label_3d.cpp scene/gui/dialogs.cpp scene/gui/label.cpp msgid "Autowrap" @@ -22488,25 +22322,21 @@ msgid "Indirect Energy" msgstr "Цвета излучения" #: scene/3d/light.cpp -#, fuzzy msgid "Negative" -msgstr "GDNative" +msgstr "Негатив" #: scene/3d/light.cpp scene/resources/material.cpp #: scene/resources/visual_shader.cpp -#, fuzzy msgid "Specular" -msgstr "Режим измерения" +msgstr "" #: scene/3d/light.cpp -#, fuzzy msgid "Bake Mode" -msgstr "Режим битовой маски" +msgstr "Режим запекания" #: scene/3d/light.cpp -#, fuzzy msgid "Contact" -msgstr "Контраст" +msgstr "Контакт" #: scene/3d/light.cpp #, fuzzy @@ -22514,24 +22344,20 @@ msgid "Reverse Cull Face" msgstr "Сбросить громкость шины" #: scene/3d/light.cpp servers/visual_server.cpp -#, fuzzy msgid "Directional Shadow" -msgstr "Направления" +msgstr "Направленные тени" #: scene/3d/light.cpp -#, fuzzy msgid "Split 1" -msgstr "Раздельный" +msgstr "Раздельный 1" #: scene/3d/light.cpp -#, fuzzy msgid "Split 2" -msgstr "Раздельный" +msgstr "Раздельный 2" #: scene/3d/light.cpp -#, fuzzy msgid "Split 3" -msgstr "Раздельный" +msgstr "Раздельный 3" #: scene/3d/light.cpp #, fuzzy @@ -22544,23 +22370,20 @@ msgid "Bias Split Scale" msgstr "Базовый масштаб" #: scene/3d/light.cpp -#, fuzzy msgid "Depth Range" -msgstr "Глубина" +msgstr "Диапазон глубины" #: scene/3d/light.cpp msgid "Omni" msgstr "" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Mode" -msgstr "Шейдер" +msgstr "Режим тени" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Detail" -msgstr "Показать по умолчанию" +msgstr "Детали тени" #: scene/3d/light.cpp msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." @@ -22571,9 +22394,8 @@ msgid "Spot" msgstr "" #: scene/3d/light.cpp -#, fuzzy msgid "Angle Attenuation" -msgstr "Анимация" +msgstr "Угол угасания" #: scene/3d/mesh_instance.cpp msgid "Software Skinning" @@ -22592,23 +22414,20 @@ msgid "" msgstr "" #: scene/3d/navigation.cpp scene/resources/curve.cpp -#, fuzzy msgid "Up Vector" -msgstr "Вектор" +msgstr "Вектор вверх" #: scene/3d/navigation.cpp -#, fuzzy msgid "Cell Height" -msgstr "Тестируемые" +msgstr "Высота клетки" #: scene/3d/navigation_agent.cpp msgid "Agent Height Offset" msgstr "" #: scene/3d/navigation_agent.cpp -#, fuzzy msgid "Ignore Y" -msgstr "[Игнорировать]" +msgstr "Игнорировать Y" #: scene/3d/navigation_agent.cpp #, fuzzy @@ -22677,9 +22496,8 @@ msgstr "" "Mode установлено в «Particle Billboard»." #: scene/3d/particles.cpp -#, fuzzy msgid "Visibility AABB" -msgstr "Переключить видимость" +msgstr "Видимость AABB" #: scene/3d/particles.cpp #, fuzzy @@ -22719,59 +22537,48 @@ msgstr "" "Измените размер дочерней формы коллизии." #: scene/3d/physics_body.cpp -#, fuzzy msgid "Axis Lock" -msgstr "Ось" +msgstr "Заблокировать ось" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear X" -msgstr "Линейный" +msgstr "Линейный X" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Y" -msgstr "Линейный" +msgstr "Линейный Y" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Z" -msgstr "Линейный" +msgstr "Линейный Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular X" -msgstr "Угловая скорость" +msgstr "Угловая скорость X" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Y" -msgstr "Угловая скорость" +msgstr "Угловая скорость Y" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Z" -msgstr "Угловая скорость" +msgstr "Угловая скорость Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion X" -msgstr "Движение" +msgstr "Движение X" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion Y" -msgstr "Движение" +msgstr "Движение Y" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion Z" -msgstr "Движение" +msgstr "Движение Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Joint Constraints" -msgstr "Константы" +msgstr "Ограничения соединений" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Impulse Clamp" @@ -22798,24 +22605,20 @@ msgid "Angular Limit Enabled" msgstr "Фильтр сигналов" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Upper" -msgstr "Линейный" +msgstr "Верхний лимит угловой скорости" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Lower" -msgstr "Угловая скорость" +msgstr "Нижний лимит угловой скорости" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Bias" -msgstr "Линейный" +msgstr "Смещение лимита угловой скорости" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Softness" -msgstr "Угловая скорость" +msgstr "Мягкость лимита угловой скорости" #: scene/3d/physics_body.cpp #, fuzzy @@ -22823,14 +22626,12 @@ msgid "Angular Limit Relaxation" msgstr "Угловая скорость" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Upper" -msgstr "Линейный" +msgstr "Линейный лимит верхний" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Lower" -msgstr "Линейный" +msgstr "Линейный лимит нижний" #: scene/3d/physics_body.cpp #, fuzzy @@ -22979,14 +22780,12 @@ msgid "Angular Limit" msgstr "Угловой Предел" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper" -msgstr "ВЕРХНИЙ РЕГИСТР" +msgstr "Верхний" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower" -msgstr "нижний регистр" +msgstr "Нижний" #: scene/3d/physics_joint.cpp msgid "Motor" @@ -23003,14 +22802,12 @@ msgid "Max Impulse" msgstr "Макс скорость" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit" -msgstr "Линейный" +msgstr "Линейный лимит" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper Distance" -msgstr "Расстояние образца" +msgstr "Верхняя дистанция" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23023,29 +22820,24 @@ msgid "Restitution" msgstr "Описание" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motion" -msgstr "Инициализировать" +msgstr "Линейное движение" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Ortho" -msgstr "Задний ортогональный" +msgstr "Линейный ортогональный" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper Angle" -msgstr "ВЕРХНИЙ РЕГИСТР" +msgstr "Верхний Угол" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower Angle" -msgstr "нижний регистр" +msgstr "Нижний угол" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Angular Motion" -msgstr "Угловая скорость" +msgstr "Угловое движение" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23053,19 +22845,16 @@ msgid "Angular Ortho" msgstr "Угловая прямость" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit X" -msgstr "Линейный" +msgstr "Линейный лимит X" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor X" -msgstr "Инициализировать" +msgstr "Линейный мотор X" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Force Limit" -msgstr "Рисовать лимиты" +msgstr "Форсировать лимиты" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23090,14 +22879,12 @@ msgid "Angular Spring X" msgstr "X Угловой Пружины" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit Y" -msgstr "Линейный" +msgstr "Линейный лимит Y" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor Y" -msgstr "Инициализировать" +msgstr "Линейный мотор Y" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23118,14 +22905,12 @@ msgid "Angular Spring Y" msgstr "Y Угловой Пружины" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit Z" -msgstr "Линейный" +msgstr "Линейный лимит Z" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor Z" -msgstr "Инициализировать" +msgstr "Линейный мотор Z" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23170,14 +22955,12 @@ msgid "Linked Room" msgstr "Связанная комната" #: scene/3d/portal.cpp -#, fuzzy msgid "Use Default Margin" -msgstr "По умолчанию" +msgstr "Использовать отступы по умолчанию" #: scene/3d/proximity_group.cpp -#, fuzzy msgid "Group Name" -msgstr "Сгруппирован" +msgstr "Имя группы" #: scene/3d/proximity_group.cpp msgid "Dispatch Mode" @@ -23188,18 +22971,16 @@ msgid "Grid Radius" msgstr "Радиус сетки" #: scene/3d/ray_cast.cpp -#, fuzzy msgid "Debug Shape" -msgstr "Отладчик" +msgstr "Форма отладчика" #: scene/3d/ray_cast.cpp scene/resources/style_box.cpp msgid "Thickness" msgstr "" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp -#, fuzzy msgid "Update Mode" -msgstr "Режим вращения" +msgstr "Режим обновления" #: scene/3d/reflection_probe.cpp #, fuzzy @@ -23212,14 +22993,12 @@ msgid "Box Projection" msgstr "Проект" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Enable Shadows" -msgstr "Включить привязку" +msgstr "Включить тени" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Color" -msgstr "Выбрать цвет" +msgstr "Ambient цвет" #: scene/3d/reflection_probe.cpp #, fuzzy @@ -23227,9 +23006,8 @@ msgid "Ambient Energy" msgstr "Цвета излучения" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Contrib" -msgstr "Отступ вправо" +msgstr "Ambient влияние" #: scene/3d/remote_transform.cpp msgid "" @@ -23273,9 +23051,8 @@ msgid "Bound" msgstr "Граница" #: scene/3d/room_group.cpp -#, fuzzy msgid "Roomgroup Priority" -msgstr "Приоритет" +msgstr "Roomgroup приоритет" #: scene/3d/room_group.cpp msgid "The RoomManager should not be placed inside a RoomGroup." @@ -23309,28 +23086,24 @@ msgstr "Главная" #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp #: scene/animation/animation_tree_player.cpp #: servers/audio/effects/audio_effect_delay.cpp -#, fuzzy msgid "Active" -msgstr "Действие" +msgstr "Активный" #: scene/3d/room_manager.cpp msgid "Roomlist" msgstr "Список комнат" #: scene/3d/room_manager.cpp servers/visual_server.cpp -#, fuzzy msgid "PVS" -msgstr "FPS" +msgstr "" #: scene/3d/room_manager.cpp -#, fuzzy msgid "PVS Mode" -msgstr "Режим осмотра" +msgstr "PVS режим" #: scene/3d/room_manager.cpp -#, fuzzy msgid "PVS Filename" -msgstr "ZIP-файл" +msgstr "PVS имя файла" #: scene/3d/room_manager.cpp servers/visual_server.cpp msgid "Gameplay" @@ -23342,42 +23115,36 @@ msgid "Gameplay Monitor" msgstr "Геймплей" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Use Secondary PVS" -msgstr "Использовать привязку масштабирования" +msgstr "Использовать вторичный PVS" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Merge Meshes" -msgstr "Меши" +msgstr "Соединить меши" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Show Margins" -msgstr "Отображать центр" +msgstr "Показать отступы" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Debug Sprawl" -msgstr "Отладка" +msgstr "Отладка Sprawl" #: scene/3d/room_manager.cpp msgid "Overlap Warning Threshold" msgstr "" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Preview Camera" -msgstr "Размер превью" +msgstr "Камера предпросмотра" #: scene/3d/room_manager.cpp msgid "Portal Depth Limit" msgstr "" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Default Portal Margin" -msgstr "Отступ портала" +msgstr "Отступ портала по умолчанию" #: scene/3d/room_manager.cpp #, fuzzy @@ -23435,43 +23202,36 @@ msgstr "" "Убедитесь, что все комнаты содержат геометрию или границы заданы вручную." #: scene/3d/skeleton.cpp scene/resources/skin.cpp -#, fuzzy msgid "Pose" -msgstr "Копировать позу" +msgstr "Поза" #: scene/3d/skeleton.cpp -#, fuzzy msgid "Bound Children" -msgstr "Дети" +msgstr "Связать детей" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Pinned Points" -msgstr "Закреплено %s" +msgstr "Закрепленные точки" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Attachments" -msgstr "Гизмо" +msgstr "Приложения" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Point Index" -msgstr "Получить индекс" +msgstr "Индекс точки" #: scene/3d/soft_body.cpp msgid "Spatial Attachment Path" msgstr "" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Physics Enabled" -msgstr "Кадр физики %" +msgstr "Физика включена" #: scene/3d/soft_body.cpp -#, fuzzy msgid "Parent Collision Ignore" -msgstr "Создать полигон столкновений" +msgstr "Игнорировать родительские столкновения" #: scene/3d/soft_body.cpp msgid "Simulation Precision" @@ -23552,9 +23312,8 @@ msgid "Opacity" msgstr "" #: scene/3d/sprite_3d.cpp scene/resources/material.cpp -#, fuzzy msgid "Transparent" -msgstr "Транспонировать" +msgstr "Прозрачный" #: scene/3d/sprite_3d.cpp msgid "" @@ -23578,9 +23337,8 @@ msgid "Per-Wheel Motion" msgstr "Колёсико вниз" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Engine Force" -msgstr "Онлайн документация" +msgstr "Сила движка" #: scene/3d/vehicle_body.cpp msgid "Brake" @@ -23617,28 +23375,24 @@ msgid "Friction Slip" msgstr "Функция" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Suspension" -msgstr "Выражение" +msgstr "Подвеска" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Max Force" -msgstr "Ошибка" +msgstr "Макс Сила" #: scene/3d/visibility_notifier.cpp msgid "AABB" msgstr "" #: scene/3d/visual_instance.cpp scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Geometry" -msgstr "Повторить" +msgstr "Геометрия" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Material Override" -msgstr "Переопределить" +msgstr "Переопределить материалы" #: scene/3d/visual_instance.cpp #, fuzzy @@ -23646,9 +23400,8 @@ msgid "Material Overlay" msgstr "Наложение материала" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Cast Shadow" -msgstr "Создать Шейдерный узел" +msgstr "Отбрасывать тень" #: scene/3d/visual_instance.cpp #, fuzzy @@ -23666,9 +23419,8 @@ msgid "Generate Lightmap" msgstr "Создание карт освещения" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Lightmap Scale" -msgstr "Запекание LightMap" +msgstr "Масштаб карты освещения" #: scene/3d/visual_instance.cpp msgid "LOD" @@ -23719,9 +23471,8 @@ msgid "Animation not found: '%s'" msgstr "Анимация не найдена: %s" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Mix Mode" -msgstr "Mix узел" +msgstr "Mix режим" #: scene/animation/animation_blend_tree.cpp msgid "Fadein Time" @@ -23742,24 +23493,20 @@ msgid "Autorestart" msgstr "Автоперезапуск" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Delay" -msgstr "Задержка (мс)" +msgstr "Задержка" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Random Delay" -msgstr "Случайная задержка автоперезапуска" +msgstr "Случайная задержка" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Add Amount" -msgstr "Количество" +msgstr "Добавить количество" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Blend Amount" -msgstr "Количество солнц" +msgstr "Количество смешивания" #: scene/animation/animation_blend_tree.cpp #, fuzzy @@ -23773,19 +23520,16 @@ msgstr "Добавить входной порт" #: scene/animation/animation_blend_tree.cpp #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Xfade Time" -msgstr "Время затухания" +msgstr "Время Xfade" #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Switch Mode" -msgstr "Множественный выбор" +msgstr "Режим переключения" #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Auto Advance" -msgstr "Автоматическая установка" +msgstr "Автоматическое продвижение" #: scene/animation/animation_node_state_machine.cpp #, fuzzy @@ -23797,28 +23541,24 @@ msgid "Anim Apply Reset" msgstr "Анимация - Применить сброс" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Current Animation" -msgstr "Задать анимацию" +msgstr "Текущая анимация" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Assigned Animation" -msgstr "Добавить анимацию" +msgstr "Привязанная анимация" #: scene/animation/animation_player.cpp msgid "Reset On Save" msgstr "" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Current Animation Length" -msgstr "Изменить длину анимации" +msgstr "Длина текущей анимации" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Current Animation Position" -msgstr "Добавить точку анимации" +msgstr "Позиция текущей анимации" #: scene/animation/animation_player.cpp #, fuzzy @@ -23826,9 +23566,8 @@ msgid "Playback Options" msgstr "Параметры воспроизведения" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Default Blend Time" -msgstr "Тема по умолчанию" +msgstr "Время смешения по умолчанию" #: scene/animation/animation_player.cpp msgid "Method Call Mode" @@ -23867,32 +23606,28 @@ msgid "Tree Root" msgstr "Корень дерева" #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Anim Player" -msgstr "Закрепить анимацию игрока" +msgstr "Анимация игрока" #: scene/animation/animation_tree.cpp msgid "Root Motion" msgstr "" #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Track" -msgstr "Добавить трек" +msgstr "Дорожка" #: scene/animation/animation_tree_player.cpp msgid "This node has been deprecated. Use AnimationTree instead." msgstr "Этот узел был удален. Вместо этого используйте AnimationTree." #: scene/animation/animation_tree_player.cpp -#, fuzzy msgid "Playback" -msgstr "Запустить" +msgstr "Воспроизведение" #: scene/animation/animation_tree_player.cpp -#, fuzzy msgid "Master Player" -msgstr "Вставить параметры" +msgstr "Главный Игрок" #: scene/animation/animation_tree_player.cpp #, fuzzy @@ -23900,29 +23635,24 @@ msgid "Base Path" msgstr "Путь экспорта" #: scene/animation/root_motion_view.cpp -#, fuzzy msgid "Animation Path" -msgstr "Анимация" +msgstr "Путь анимации" #: scene/animation/root_motion_view.cpp -#, fuzzy msgid "Zero Y" -msgstr "Ноль" +msgstr "Ноль Y" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Root Bone" -msgstr "Имя корневого узла" +msgstr "Корневая кость" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Tip Bone" -msgstr "Кости" +msgstr "Конечная кость" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Interpolation" -msgstr "Режим интерполяции" +msgstr "Интерполяция" #: scene/animation/skeleton_ik.cpp #, fuzzy @@ -23938,40 +23668,34 @@ msgid "Magnet" msgstr "Магнит" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Target Node" -msgstr "Переподчинить узел" +msgstr "Целевой узел" #: scene/animation/skeleton_ik.cpp -#, fuzzy msgid "Max Iterations" -msgstr "Сделать функцию" +msgstr "Макс повторений" #: scene/animation/tween.cpp msgid "Playback Process Mode" msgstr "" #: scene/animation/tween.cpp -#, fuzzy msgid "Playback Speed" -msgstr "Запустить сцену" +msgstr "Скорость воспроизведения" #: scene/audio/audio_stream_player.cpp -#, fuzzy msgid "Mix Target" -msgstr "Цель" +msgstr "Смешанная цель" #: scene/gui/aspect_ratio_container.cpp scene/gui/range.cpp #: servers/audio/effects/audio_effect_compressor.cpp -#, fuzzy msgid "Ratio" -msgstr "Сохранять пропорции" +msgstr "Пропорции" #: scene/gui/aspect_ratio_container.cpp scene/gui/texture_button.cpp #: scene/gui/texture_rect.cpp -#, fuzzy msgid "Stretch Mode" -msgstr "Режим выделения" +msgstr "Режим растяжения" #: scene/gui/aspect_ratio_container.cpp scene/gui/box_container.cpp msgid "Alignment" @@ -23983,9 +23707,8 @@ msgid "Shortcut In Tooltip" msgstr "Отображать центр" #: scene/gui/base_button.cpp -#, fuzzy msgid "Action Mode" -msgstr "Режим иконки" +msgstr "Режим действия" #: scene/gui/base_button.cpp msgid "Enabled Focus Mode" @@ -24018,9 +23741,8 @@ msgid "Icon Align" msgstr "" #: scene/gui/button.cpp -#, fuzzy msgid "Expand Icon" -msgstr "Развернуть все" +msgstr "Расширить иконку" #: scene/gui/center_container.cpp #, fuzzy @@ -24043,24 +23765,20 @@ msgid "Edit Alpha" msgstr "Редактировать полигон" #: scene/gui/color_picker.cpp -#, fuzzy msgid "HSV Mode" -msgstr "Режим выделения" +msgstr "HSV режим" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Raw Mode" -msgstr "Режим осмотра" +msgstr "Режим Raw" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Deferred Mode" -msgstr "Отложенное" +msgstr "Отложенный режим" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Presets Enabled" -msgstr "Предустановки" +msgstr "Пресеты включены" #: scene/gui/color_picker.cpp msgid "Presets Visible" @@ -24108,14 +23826,12 @@ msgstr "" "положение «Stop» или «Pass»." #: scene/gui/control.cpp -#, fuzzy msgid "Anchor" -msgstr "Только якоря" +msgstr "Якорь" #: scene/gui/control.cpp -#, fuzzy msgid "Grow Direction" -msgstr "Направления" +msgstr "Направление роста" #: scene/gui/control.cpp scene/resources/navigation_mesh.cpp msgid "Min Size" @@ -24136,14 +23852,12 @@ msgid "Hint" msgstr "" #: scene/gui/control.cpp -#, fuzzy msgid "Tooltip" -msgstr "Инструменты" +msgstr "Подсказка" #: scene/gui/control.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Focus" -msgstr "Переместить фокус на строку пути" +msgstr "Фокус" #: scene/gui/control.cpp msgid "Neighbour Left" @@ -24158,9 +23872,8 @@ msgid "Neighbour Right" msgstr "" #: scene/gui/control.cpp -#, fuzzy msgid "Neighbour Bottom" -msgstr "Внизу посередине" +msgstr "Сосед снизу" #: scene/gui/control.cpp msgid "Next" @@ -24187,9 +23900,8 @@ msgid "Size Flags" msgstr "Флаги размера" #: scene/gui/control.cpp -#, fuzzy msgid "Stretch Ratio" -msgstr "Режим выделения" +msgstr "Коэффициент растяжения" #: scene/gui/control.cpp #, fuzzy @@ -24239,19 +23951,16 @@ msgid "Snap Distance" msgstr "Расстояние привязки" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Min" -msgstr "Приблизить" +msgstr "Приблизить Min" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Max" -msgstr "Приблизить" +msgstr "Приблизить Max" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Step" -msgstr "Отдалить" +msgstr "Приблизить шаг" #: scene/gui/graph_edit.cpp #, fuzzy @@ -24274,9 +23983,8 @@ msgstr "Показать кости" #: scene/gui/graph_node.cpp scene/gui/option_button.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Selected" -msgstr "Выделение" +msgstr "Выделено" #: scene/gui/graph_node.cpp scene/resources/default_theme/default_theme.cpp msgid "Comment" @@ -24300,23 +24008,20 @@ msgid "Incremental Search Max Interval Msec" msgstr "" #: scene/gui/item_list.cpp scene/gui/tree.cpp -#, fuzzy msgid "Allow Reselect" -msgstr "Применить сброс" +msgstr "Разрешить перевыбор" #: scene/gui/item_list.cpp scene/gui/tree.cpp -#, fuzzy msgid "Allow RMB Select" -msgstr "Заполнить выбранное" +msgstr "Разрешить выбор ПКМ" #: scene/gui/item_list.cpp msgid "Max Text Lines" msgstr "" #: scene/gui/item_list.cpp -#, fuzzy msgid "Auto Height" -msgstr "Тестируемые" +msgstr "Авто высота" #: scene/gui/item_list.cpp msgid "Max Columns" @@ -24339,18 +24044,16 @@ msgid "Fixed Icon Size" msgstr "Фиксированный размер иконки" #: scene/gui/label.cpp -#, fuzzy msgid "V Align" -msgstr "Оператор присваивания" +msgstr "Вертикальное выравнивание" #: scene/gui/label.cpp scene/gui/rich_text_label.cpp msgid "Visible Characters" msgstr "Видимые символы" #: scene/gui/label.cpp scene/gui/rich_text_label.cpp -#, fuzzy msgid "Percent Visible" -msgstr "Переключить видимость" +msgstr "Процент видимости" #: scene/gui/label.cpp msgid "Lines Skipped" @@ -24378,34 +24081,28 @@ msgid "Expand To Text Length" msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Context Menu Enabled" -msgstr "Контекстная справка" +msgstr "Включить контекстное меню" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Virtual Keyboard Enabled" -msgstr "Фильтр сигналов" +msgstr "Включить виртуальную клавиатуру" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Clear Button Enabled" -msgstr "Фильтр сигналов" +msgstr "Включить кнопку очистки" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Shortcut Keys Enabled" -msgstr "Горячие клавиши" +msgstr "Включить горячие клавиши" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Middle Mouse Paste Enabled" -msgstr "Фильтр сигналов" +msgstr "Включить вставку средней кнопкой мыши" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Selecting Enabled" -msgstr "Только выделенное" +msgstr "Включить выделение" #: scene/gui/line_edit.cpp scene/gui/rich_text_label.cpp #: scene/gui/text_edit.cpp @@ -24413,14 +24110,12 @@ msgid "Deselect On Focus Loss Enabled" msgstr "" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Right Icon" -msgstr "Правая кнопка мыши" +msgstr "Правая иконка" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Placeholder" -msgstr "Загрузить как заполнитель" +msgstr "Заполнитель" #: scene/gui/line_edit.cpp msgid "Alpha" @@ -24443,9 +24138,8 @@ msgid "Underline" msgstr "" #: scene/gui/menu_button.cpp -#, fuzzy msgid "Switch On Hover" -msgstr "Множественный выбор" +msgstr "Переключить при наведении" #: scene/gui/nine_patch_rect.cpp scene/resources/style_box.cpp #, fuzzy @@ -24453,9 +24147,8 @@ msgid "Draw Center" msgstr "По центру" #: scene/gui/nine_patch_rect.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Region Rect" -msgstr "Задать регион" +msgstr "Прямоугольный регион" #: scene/gui/nine_patch_rect.cpp #, fuzzy @@ -24479,9 +24172,8 @@ msgstr "" "работать как Stretch." #: scene/gui/popup.cpp -#, fuzzy msgid "Popup" -msgstr "Заполнить" +msgstr "Всплывающее окно" #: scene/gui/popup.cpp #, fuzzy @@ -24499,9 +24191,8 @@ msgstr "" "но они будут скрыты при запуске." #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Hide On Item Selection" -msgstr "Центрировать выбранное" +msgstr "Спрятать при выделении предмета" #: scene/gui/popup_menu.cpp #, fuzzy @@ -24518,9 +24209,8 @@ msgid "Submenu Popup Delay" msgstr "" #: scene/gui/popup_menu.cpp -#, fuzzy msgid "Allow Search" -msgstr "Поиск" +msgstr "Разрешить поиск" #: scene/gui/progress_bar.cpp msgid "Percent" @@ -24548,9 +24238,8 @@ msgid "Exp Edit" msgstr "Редактировать" #: scene/gui/range.cpp -#, fuzzy msgid "Rounded" -msgstr "Сгруппирован" +msgstr "Округлённый" #: scene/gui/range.cpp msgid "Allow Greater" @@ -24569,14 +24258,12 @@ msgid "Border Width" msgstr "Ширина границы" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Relative Index" -msgstr "Получить индекс" +msgstr "Относительный индекс" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Absolute Index" -msgstr "Автоотступ" +msgstr "Абсолютный индекс" #: scene/gui/rich_text_effect.cpp #, fuzzy @@ -24584,9 +24271,8 @@ msgid "Elapsed Time" msgstr "Прошедшее время" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Env" -msgstr "Конец" +msgstr "Среда" #: scene/gui/rich_text_effect.cpp msgid "Character" @@ -24605,9 +24291,8 @@ msgid "Tab Size" msgstr "Размер табов" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Fit Content Height" -msgstr "Изменить вес костей" +msgstr "Вместить по высоте контента" #: scene/gui/rich_text_label.cpp msgid "Scroll Active" @@ -24618,9 +24303,8 @@ msgid "Scroll Following" msgstr "" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Selection Enabled" -msgstr "Только выделенное" +msgstr "Включить выделение" #: scene/gui/rich_text_label.cpp scene/gui/text_edit.cpp #, fuzzy @@ -24628,14 +24312,12 @@ msgid "Override Selected Font Color" msgstr "Переопределить выбранный цвет шрифта" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Custom Effects" -msgstr "Передвинуть эффект шины" +msgstr "Пользовательские эффекты" #: scene/gui/scroll_bar.cpp -#, fuzzy msgid "Custom Step" -msgstr "Пользовательский узел" +msgstr "Пользовательский шаг" #: scene/gui/scroll_container.cpp msgid "" @@ -24671,9 +24353,8 @@ msgid "Scrollable" msgstr "" #: scene/gui/slider.cpp -#, fuzzy msgid "Tick Count" -msgstr "Выбрать цвет" +msgstr "Счетчик галочек" #: scene/gui/slider.cpp #, fuzzy @@ -24694,9 +24375,8 @@ msgid "Split Offset" msgstr "Смещение разделения" #: scene/gui/split_container.cpp scene/gui/tree.cpp -#, fuzzy msgid "Collapsed" -msgstr "Свернуть все" +msgstr "Свернуто" #: scene/gui/split_container.cpp #, fuzzy @@ -24782,9 +24462,8 @@ msgid "Draw" msgstr "Рисовать" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Block Mode" -msgstr "Разблокировать узел" +msgstr "Режим блокировки" #: scene/gui/text_edit.cpp msgid "Moving By Right Click" @@ -24803,9 +24482,8 @@ msgid "Hover" msgstr "" #: scene/gui/texture_button.cpp -#, fuzzy msgid "Focused" -msgstr "Переместить фокус на строку пути" +msgstr "Сфокусировано" #: scene/gui/texture_button.cpp #, fuzzy @@ -24814,9 +24492,8 @@ msgstr "Режим столкновения" #: scene/gui/texture_button.cpp scene/gui/texture_rect.cpp #: scene/gui/video_player.cpp -#, fuzzy msgid "Expand" -msgstr "Развернуть все" +msgstr "Развернуть" #: scene/gui/texture_progress.cpp msgid "Under" @@ -24828,9 +24505,8 @@ msgid "Over" msgstr "Перезаписать" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Progress" -msgstr "Свойства темы" +msgstr "Прогресс" #: scene/gui/texture_progress.cpp msgid "Progress Offset" @@ -24849,9 +24525,8 @@ msgid "Radial Fill" msgstr "" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Initial Angle" -msgstr "Инициализировать" +msgstr "Начальный угол" #: scene/gui/texture_progress.cpp #, fuzzy @@ -24868,24 +24543,20 @@ msgid "Nine Patch Stretch" msgstr "Режим интерполяции" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Stretch Margin Left" -msgstr "Задать отступ" +msgstr "Растянуть отступ лево" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Stretch Margin Top" -msgstr "Задать отступ" +msgstr "Растянуть отступ вверх" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Stretch Margin Right" -msgstr "Задать отступ" +msgstr "Растянуть отступ право" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Stretch Margin Bottom" -msgstr "Режим выделения" +msgstr "Растянуть отступ низ" #: scene/gui/tree.cpp msgid "Custom Minimum Height" @@ -24896,9 +24567,8 @@ msgid "(Other)" msgstr "(Другие)" #: scene/gui/tree.cpp -#, fuzzy msgid "Column Titles Visible" -msgstr "Переключить видимость" +msgstr "Видимость заголовков столбцов" #: scene/gui/tree.cpp #, fuzzy @@ -24922,9 +24592,8 @@ msgid "Paused" msgstr "Остановлен" #: scene/gui/video_player.cpp -#, fuzzy msgid "Buffering Msec" -msgstr "Буферизация" +msgstr "Буферизация Msec" #: scene/gui/video_player.cpp #, fuzzy @@ -24932,9 +24601,8 @@ msgid "Stream Position" msgstr "Установить позицию входа кривой" #: scene/gui/viewport_container.cpp -#, fuzzy msgid "Stretch Shrink" -msgstr "Извлечь" +msgstr "Растянуть сжать" #: scene/main/canvas_layer.cpp #, fuzzy @@ -24946,9 +24614,8 @@ msgid "Download File" msgstr "Загрузить файл" #: scene/main/http_request.cpp -#, fuzzy msgid "Download Chunk Size" -msgstr "Загрузка" +msgstr "Размер куска скачивания" #: scene/main/http_request.cpp msgid "Body Size Limit" @@ -24978,38 +24645,32 @@ msgid "Name Casing" msgstr "" #: scene/main/node.cpp -#, fuzzy msgid "Editor Description" -msgstr "Описание" +msgstr "Редактировать описание" #: scene/main/node.cpp -#, fuzzy msgid "Pause Mode" -msgstr "Режим осмотра" +msgstr "Режим паузы" #: scene/main/node.cpp -#, fuzzy msgid "Physics Interpolation Mode" -msgstr "физическая интерполяции" +msgstr "Режим физической интерполяции" #: scene/main/node.cpp -#, fuzzy msgid "Display Folded" -msgstr "Режим без теней" +msgstr "Показать сложённым" #: scene/main/node.cpp -#, fuzzy msgid "Filename" -msgstr "Переименовать" +msgstr "Имя файла" #: scene/main/node.cpp msgid "Owner" msgstr "Владелец" #: scene/main/node.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Multiplayer" -msgstr "Умножить %s" +msgstr "Мультиплеер" #: scene/main/node.cpp #, fuzzy @@ -25022,9 +24683,8 @@ msgid "Process Priority" msgstr "Включить приоритет" #: scene/main/scene_tree.cpp scene/main/timer.cpp -#, fuzzy msgid "Time Left" -msgstr "Слева вверху" +msgstr "Осталось времени" #: scene/main/scene_tree.cpp #, fuzzy @@ -25032,18 +24692,16 @@ msgid "Debug Collisions Hint" msgstr "Режим столкновения" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Debug Navigation Hint" -msgstr "Режим навигации" +msgstr "Подсказка режима навигации" #: scene/main/scene_tree.cpp msgid "Use Font Oversampling" msgstr "" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Edited Scene Root" -msgstr "Новый корень сцены" +msgstr "Редактировать корень сцены" #: scene/main/scene_tree.cpp msgid "Root" @@ -25064,9 +24722,8 @@ msgid "Shape Color" msgstr "" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Contact Color" -msgstr "Выбрать цвет" +msgstr "Цвет контакта" #: scene/main/scene_tree.cpp msgid "Geometry Color" @@ -25082,9 +24739,8 @@ msgid "Max Contacts Displayed" msgstr "" #: scene/main/scene_tree.cpp scene/resources/shape_2d.cpp -#, fuzzy msgid "Draw 2D Outlines" -msgstr "Создать контур" +msgstr "Создать 2D контур" #: scene/main/scene_tree.cpp servers/visual_server.cpp msgid "Reflections" @@ -25119,9 +24775,8 @@ msgid "Use 32 BPC Depth" msgstr "" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Default Environment" -msgstr "Окружение" +msgstr "Окружение по умолчанию" #: scene/main/scene_tree.cpp msgid "" @@ -25154,9 +24809,8 @@ msgid "Autostart" msgstr "Автозапуск" #: scene/main/viewport.cpp -#, fuzzy msgid "Viewport Path" -msgstr "Путь экспорта" +msgstr "Путь окна предпросмотра" #: scene/main/viewport.cpp msgid "" @@ -25197,14 +24851,12 @@ msgid "World 2D" msgstr "Мир 2D" #: scene/main/viewport.cpp -#, fuzzy msgid "Transparent BG" -msgstr "Транспонировать" +msgstr "Прозрачный фон" #: scene/main/viewport.cpp -#, fuzzy msgid "Handle Input Locally" -msgstr "Изменить входное значение" +msgstr "Обрабатывать ввод локально" #: scene/main/viewport.cpp msgid "FXAA" @@ -25229,9 +24881,8 @@ msgid "Render Direct To Screen" msgstr "" #: scene/main/viewport.cpp -#, fuzzy msgid "Debug Draw" -msgstr "Отладка" +msgstr "Отладка рисовки" #: scene/main/viewport.cpp #, fuzzy @@ -25243,9 +24894,8 @@ msgid "V Flip" msgstr "" #: scene/main/viewport.cpp -#, fuzzy msgid "Clear Mode" -msgstr "Режим измерения" +msgstr "Режим очистки" #: scene/main/viewport.cpp msgid "Enable 2D" @@ -25284,58 +24934,48 @@ msgid "Quad 3" msgstr "" #: scene/main/viewport.cpp -#, fuzzy msgid "Canvas Transform" -msgstr "Очистить преобразование" +msgstr "Преобразование полотна" #: scene/main/viewport.cpp -#, fuzzy msgid "Global Canvas Transform" -msgstr "Сохранить глобальные преобразования" +msgstr "Глобальное преобразование полотна" #: scene/main/viewport.cpp msgid "Tooltip Delay (sec)" msgstr "" #: scene/register_scene_types.cpp -#, fuzzy msgid "Swap OK Cancel" -msgstr "UI Отменить" +msgstr "Поменять местами OK Cancel" #: scene/register_scene_types.cpp -#, fuzzy msgid "Layer Names" -msgstr "Имя переменной" +msgstr "Имена слоя" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Render" -msgstr "Рендеринг" +msgstr "2D Рендеринг" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Render" -msgstr "Рендеринг" +msgstr "3D Рендеринг" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Physics" -msgstr "Физика" +msgstr "2D Физика" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Physics" -msgstr "Физика" +msgstr "3D Физика" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Navigation" -msgstr "Навигация" +msgstr "2D Навигация" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Navigation" -msgstr "Навигация" +msgstr "3D Навигация" #: scene/register_scene_types.cpp msgid "Use hiDPI" @@ -25364,9 +25004,8 @@ msgid "Segments" msgstr "Сегменты" #: scene/resources/curve.cpp -#, fuzzy msgid "Bake Resolution" -msgstr "Половинное разрешение" +msgstr "Запечь разрешение" #: scene/resources/curve.cpp msgid "Bake Interval" @@ -25377,34 +25016,28 @@ msgid "Panel" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color" -msgstr "Цвет комментария" +msgstr "Цвет шрифта" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Pressed" -msgstr "Цвет кости 1" +msgstr "Цвет нажатого шрифта" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Hover" -msgstr "Цвет кости 1" +msgstr "Цвет наведенного шрифта" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Focus" -msgstr "Следовать за фокусом" +msgstr "Цвет шрифта в фокусе" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Disabled" -msgstr "Отключить обрезку" +msgstr "Цвет отключенного шрифта" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "H Separation" -msgstr "H Разделение" +msgstr "Горизонтальное разделение" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25482,9 +25115,8 @@ msgid "Off Disabled" msgstr "Отключённый" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Shadow" -msgstr "Цвет кости 1" +msgstr "Цвет тени шрифта" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25502,43 +25134,36 @@ msgid "Shadow Offset Y" msgstr "Отступ тени по Y" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow As Outline" -msgstr "Показывать предыдущий контур" +msgstr "Тень как контур" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Color Selected" -msgstr "Разблокировать выделенное" +msgstr "Цвет шрифта выделенного" #: scene/resources/default_theme/default_theme.cpp msgid "Font Color Uneditable" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Cursor Color" -msgstr "Пользовательский цвет" +msgstr "Цвет курсора" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Clear Button Color" -msgstr "Фильтр сигналов" +msgstr "Цвет кнопки Очистить" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Clear Button Color Pressed" -msgstr "Фильтр сигналов" +msgstr "Цвет нажатой кнопки Очистить" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Minimum Spaces" -msgstr "Главная сцена" +msgstr "Минимальные расстояния" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "BG" -msgstr "Б" +msgstr "Задний фон" #: scene/resources/default_theme/default_theme.cpp msgid "FG" @@ -25552,9 +25177,8 @@ msgstr "Вкладка 1" #: scene/resources/default_theme/default_theme.cpp #: scene/resources/dynamic_font.cpp scene/resources/world.cpp #: scene/resources/world_2d.cpp -#, fuzzy msgid "Space" -msgstr "Главная сцена" +msgstr "Пространство" #: scene/resources/default_theme/default_theme.cpp msgid "Folded" @@ -25630,9 +25254,8 @@ msgid "Decrement Pressed" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Slider" -msgstr "Коллайдер" +msgstr "Слайдер" #: scene/resources/default_theme/default_theme.cpp msgid "Grabber Area" @@ -25661,19 +25284,16 @@ msgid "Scaleborder Size" msgstr "Размер границы" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Title Font" -msgstr "Размер шрифта заголовков справки" +msgstr "Шрифт заголовка" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Title Color" -msgstr "Цвет текста" +msgstr "Цвет заголовка" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Title Height" -msgstr "Тестовая высота" +msgstr "Высота заголовка" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25691,9 +25311,8 @@ msgid "Close V Offset" msgstr "Смещение шума" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Parent Folder" -msgstr "Создать папку" +msgstr "Родительская папка" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25716,9 +25335,8 @@ msgid "Labeled Separator Right" msgstr "Именованный разделитель" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Font Separator" -msgstr "Разделитель цветов шрифта" +msgstr "Разделитель шрифта" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25740,14 +25358,12 @@ msgid "Selected Frame" msgstr "Выбрать кадры" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Default Frame" -msgstr "Z Far по умолчанию" +msgstr "Кадр по умолчанию" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Default Focus" -msgstr "Шрифт по умолчанию" +msgstr "Фокус по умолчанию" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25755,9 +25371,8 @@ msgid "Comment Focus" msgstr "Комментарий" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Breakpoint" -msgstr "Точки останова" +msgstr "Точка остановки" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25775,9 +25390,8 @@ msgid "Resizer Color" msgstr "Использовать цвет" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Title Offset" -msgstr "Смещение байтов" +msgstr "Смещение заголовка" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25804,9 +25418,8 @@ msgid "Cursor Unfocused" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Button Pressed" -msgstr "Нажато" +msgstr "Нажатая кнопка" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25824,19 +25437,16 @@ msgid "Title Button Hover" msgstr "Кнопка-переключатель" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Custom Button" -msgstr "Пользовательский шрифт" +msgstr "Пользовательская кнопка" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Custom Button Pressed" -msgstr "Параметры шины" +msgstr "Пользовательская кнопка нажата" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Custom Button Hover" -msgstr "Пользовательский цвет" +msgstr "Пользовательская кнопка наведена" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25878,14 +25488,12 @@ msgid "Custom Button Font Highlight" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Item Margin" -msgstr "Задать отступ" +msgstr "Отступ предмета" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Button Margin" -msgstr "Маска кнопок" +msgstr "Отступ кнопки" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25898,19 +25506,16 @@ msgid "Draw Guides" msgstr "Отображение направляющих" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Scroll Border" -msgstr "Вертикальная прокрутка" +msgstr "Граница прокрутки" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Scroll Speed" -msgstr "Скорость вертикальной прокрутки" +msgstr "Скорость прокрутки" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Icon Margin" -msgstr "Задать отступ" +msgstr "Отступ иконки" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25970,9 +25575,8 @@ msgid "Label V Align BG" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Large" -msgstr "Цель" +msgstr "Крупный" #: scene/resources/default_theme/default_theme.cpp msgid "Folder" @@ -26024,9 +25628,8 @@ msgid "Add Preset" msgstr "Загрузить пресет" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Color Hue" -msgstr "Тема редактора" +msgstr "Оттенок цвета" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26054,28 +25657,24 @@ msgid "Preset BG Icon" msgstr "Пресет" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Normal Font" -msgstr "Передняя часть портала" +msgstr "Обычный шрифт" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Bold Font" -msgstr "Шрифт кода" +msgstr "Жирный шрифт" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Italics Font" -msgstr "Основной шрифт" +msgstr "Курсивный шрифт" #: scene/resources/default_theme/default_theme.cpp msgid "Bold Italics Font" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Mono Font" -msgstr "Основной шрифт" +msgstr "Моноширинный шрифт" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26088,29 +25687,24 @@ msgid "Table V Separation" msgstr "Разделение таблицы V" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Margin Left" -msgstr "Задать отступ" +msgstr "Отступ слева" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Margin Top" -msgstr "Отступ" +msgstr "Отступ сверху" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Margin Right" -msgstr "Отступ вправо" +msgstr "Отступ справа" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Margin Bottom" -msgstr "Режим выделения" +msgstr "Отступ снизу" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Autohide" -msgstr "Автоматически" +msgstr "Скрывать автоматически" #: scene/resources/default_theme/default_theme.cpp msgid "Minus" @@ -26131,9 +25725,8 @@ msgid "Grid Major" msgstr "Сеточная карта" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Selection Fill" -msgstr "Только выделенное" +msgstr "Заполнение выделенного" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26183,9 +25776,8 @@ msgid "Outline Size" msgstr "Размер контура" #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Outline Color" -msgstr "Функция" +msgstr "Цвет контура" #: scene/resources/dynamic_font.cpp #, fuzzy @@ -26215,9 +25807,8 @@ msgid "Sky" msgstr "Небо" #: scene/resources/environment.cpp -#, fuzzy msgid "Sky Custom FOV" -msgstr "Пользовательский узел" +msgstr "Пользовательский угол обзора неба" #: scene/resources/environment.cpp msgid "Sky Orientation" @@ -26262,24 +25853,20 @@ msgid "Sun Amount" msgstr "Количество солнц" #: scene/resources/environment.cpp -#, fuzzy msgid "Depth Enabled" -msgstr "Глубина" +msgstr "Глубина включена" #: scene/resources/environment.cpp -#, fuzzy msgid "Depth Begin" -msgstr "Глубина" +msgstr "Глубина начало" #: scene/resources/environment.cpp -#, fuzzy msgid "Depth End" -msgstr "Глубина" +msgstr "Глубина конец" #: scene/resources/environment.cpp -#, fuzzy msgid "Depth Curve" -msgstr "Разделить кривую" +msgstr "Кривая глубины" #: scene/resources/environment.cpp #, fuzzy @@ -26292,9 +25879,8 @@ msgid "Transmit Curve" msgstr "Разделить кривую" #: scene/resources/environment.cpp -#, fuzzy msgid "Height Enabled" -msgstr "Фильтр сигналов" +msgstr "Высота включена" #: scene/resources/environment.cpp msgid "Height Min" @@ -26305,9 +25891,8 @@ msgid "Height Max" msgstr "Макс высота" #: scene/resources/environment.cpp -#, fuzzy msgid "Height Curve" -msgstr "Разделить кривую" +msgstr "Кривая высоты" #: scene/resources/environment.cpp #, fuzzy @@ -26341,9 +25926,8 @@ msgid "SS Reflections" msgstr "Масштабировать выбранное" #: scene/resources/environment.cpp -#, fuzzy msgid "Max Steps" -msgstr "Шаг" +msgstr "Макс шагов" #: scene/resources/environment.cpp #, fuzzy @@ -26431,9 +26015,8 @@ msgstr "" #: scene/resources/environment.cpp #: servers/audio/effects/audio_effect_chorus.cpp -#, fuzzy msgid "3" -msgstr "3D" +msgstr "3" #: scene/resources/environment.cpp #: servers/audio/effects/audio_effect_chorus.cpp @@ -26465,9 +26048,8 @@ msgid "HDR Luminance Cap" msgstr "" #: scene/resources/environment.cpp -#, fuzzy msgid "HDR Scale" -msgstr "Масштабировать" +msgstr "HDR маcштаб" #: scene/resources/environment.cpp msgid "Bicubic Upscale" @@ -26478,9 +26060,8 @@ msgid "Adjustments" msgstr "Adjustments (настройки)" #: scene/resources/environment.cpp -#, fuzzy msgid "Brightness" -msgstr "Свет" +msgstr "Яркость" #: scene/resources/environment.cpp #, fuzzy @@ -26502,9 +26083,8 @@ msgid "Distance Field" msgstr "Режим без отвлечения" #: scene/resources/gradient.cpp -#, fuzzy msgid "Raw Data" -msgstr "Данные карты" +msgstr "Необработанные данные" #: scene/resources/gradient.cpp #, fuzzy @@ -26562,9 +26142,8 @@ msgid "Do Not Receive Shadows" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Disable Ambient Light" -msgstr "Отступ вправо" +msgstr "Отключить окружающие освещение" #: scene/resources/material.cpp #, fuzzy @@ -26576,9 +26155,8 @@ msgid "Albedo Tex MSDF" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Vertex Color" -msgstr "Вершины" +msgstr "Цвет вершин" #: scene/resources/material.cpp msgid "Use As Albedo" @@ -26593,9 +26171,8 @@ msgid "Parameters" msgstr "Параметры" #: scene/resources/material.cpp -#, fuzzy msgid "Diffuse Mode" -msgstr "Режим осмотра" +msgstr "Режим смешения" #: scene/resources/material.cpp #, fuzzy @@ -26639,9 +26216,8 @@ msgid "Use Alpha Scissor" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Particles Anim" -msgstr "Частицы" +msgstr "Анимация частиц" #: scene/resources/material.cpp #, fuzzy @@ -26667,9 +26243,8 @@ msgid "Texture Channel" msgstr "Область текстуры" #: scene/resources/material.cpp -#, fuzzy msgid "Emission" -msgstr "Маска излучения" +msgstr "Излучение" #: scene/resources/material.cpp msgid "On UV2" @@ -26744,14 +26319,12 @@ msgid "Detail" msgstr "Деталь" #: scene/resources/material.cpp -#, fuzzy msgid "UV Layer" -msgstr "Слой" +msgstr "UV Слой" #: scene/resources/material.cpp -#, fuzzy msgid "UV1" -msgstr "UV" +msgstr "UV1" #: scene/resources/material.cpp msgid "Triplanar" @@ -26762,9 +26335,8 @@ msgid "Triplanar Sharpness" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "UV2" -msgstr "UV" +msgstr "UV2" #: scene/resources/material.cpp #, fuzzy @@ -26776,9 +26348,8 @@ msgid "Distance Fade" msgstr "" #: scene/resources/material.cpp -#, fuzzy msgid "Async Mode" -msgstr "Режим осмотра" +msgstr "Асинхронный режим" #: scene/resources/mesh.cpp #, fuzzy @@ -26790,14 +26361,12 @@ msgid "Custom AABB" msgstr "" #: scene/resources/mesh_library.cpp -#, fuzzy msgid "Mesh Transform" -msgstr "Преобразование" +msgstr "Преобразование меша" #: scene/resources/mesh_library.cpp -#, fuzzy msgid "NavMesh Transform" -msgstr "Очистить преобразование" +msgstr "NavMesh преобразование" #: scene/resources/multimesh.cpp #, fuzzy @@ -26823,9 +26392,8 @@ msgid "Visible Instance Count" msgstr "" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Sampling" -msgstr "Масштаб:" +msgstr "Семплирование" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -26846,9 +26414,8 @@ msgid "Source Group Name" msgstr "Название группы-источника" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Cells" -msgstr "Ячейка" +msgstr "Ячейки" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -26864,33 +26431,28 @@ msgid "Max Slope" msgstr "" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Regions" -msgstr "Регион" +msgstr "Регионы" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Merge Size" -msgstr "Слияние из Сцены" +msgstr "Размер слияния" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Edges" -msgstr "Край" +msgstr "Края" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Max Error" -msgstr "Ошибка" +msgstr "Max Ошибка" #: scene/resources/navigation_mesh.cpp msgid "Verts Per Poly" msgstr "" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Details" -msgstr "Деталь" +msgstr "Детали" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -26915,14 +26477,12 @@ msgid "Walkable Low Height Spans" msgstr "" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Baking AABB" -msgstr "Генерация AABB" +msgstr "Запекание AABB" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Baking AABB Offset" -msgstr "Базовое смещение" +msgstr "Смещение запекания AABB" #: scene/resources/occluder_shape.cpp msgid "Spheres" @@ -26933,9 +26493,8 @@ msgid "OccluderShapeSphere Set Spheres" msgstr "OccluderShapeSphere Задать сферы" #: scene/resources/occluder_shape_polygon.cpp -#, fuzzy msgid "Polygon Points" -msgstr "Полигоны" +msgstr "Точки полигонов" #: scene/resources/occluder_shape_polygon.cpp #, fuzzy @@ -26951,19 +26510,16 @@ msgid "Trail" msgstr "След" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Divisor" -msgstr "Разделить %s" +msgstr "Разделитель" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Size Modifier" -msgstr "Модификатор скорости свободного вида" +msgstr "Модификатор скорости" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Color Modifier" -msgstr "Модификатор замедления свободного вида" +msgstr "Модификатор цвета" #: scene/resources/particles_material.cpp #, fuzzy @@ -26987,9 +26543,8 @@ msgid "Scale Random" msgstr "Случайный Масштаб" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Scale Curve" -msgstr "Сомкнуть кривую" +msgstr "Кривая масштаба" #: scene/resources/physics_material.cpp msgid "Rough" @@ -27030,23 +26585,20 @@ msgid "Top Radius" msgstr "Верхний радиус" #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Bottom Radius" -msgstr "Справа внизу" +msgstr "Нижний радиус" #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Left To Right" -msgstr "Справа вверху" +msgstr "Слева на право" #: scene/resources/primitive_meshes.cpp msgid "Is Hemisphere" msgstr "" #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Curve Step" -msgstr "Кривая" +msgstr "Шаг кривой" #: scene/resources/ray_shape.cpp scene/resources/segment_shape_2d.cpp msgid "Slips On Slope" @@ -27071,9 +26623,8 @@ msgid "Bind" msgstr "Привязка" #: scene/resources/skin.cpp -#, fuzzy msgid "Bone" -msgstr "Кости" +msgstr "Кость" #: scene/resources/sky.cpp #, fuzzy @@ -27135,9 +26686,8 @@ msgid "Skew" msgstr "" #: scene/resources/style_box.cpp -#, fuzzy msgid "Corner Radius" -msgstr "Изменение внутреннего радиуса полукруга" +msgstr "Радиус угла" #: scene/resources/style_box.cpp msgid "Corner Detail" @@ -27156,9 +26706,8 @@ msgid "Grow End" msgstr "" #: scene/resources/texture.cpp -#, fuzzy msgid "Load Path" -msgstr "Загрузить пресет" +msgstr "Загрузить путь" #: scene/resources/texture.cpp msgid "Base Texture" @@ -27169,9 +26718,8 @@ msgid "Image Size" msgstr "Размер изображения" #: scene/resources/texture.cpp -#, fuzzy msgid "Side" -msgstr "Стороны" +msgstr "Сторона" #: scene/resources/texture.cpp #, fuzzy @@ -27184,24 +26732,20 @@ msgid "Back" msgstr "Назад" #: scene/resources/texture.cpp -#, fuzzy msgid "Storage Mode" -msgstr "Режим масштабирования" +msgstr "Режим хранения" #: scene/resources/texture.cpp -#, fuzzy msgid "Lossy Storage Quality" -msgstr "Захват" +msgstr "Качество сжатого хранилища" #: scene/resources/texture.cpp -#, fuzzy msgid "From" -msgstr "Заполнить от" +msgstr "От" #: scene/resources/texture.cpp -#, fuzzy msgid "To" -msgstr "Верх" +msgstr "До" #: scene/resources/texture.cpp #, fuzzy @@ -27248,14 +26792,12 @@ msgid "Diffuse" msgstr "Режим осмотра" #: scene/resources/visual_shader.cpp -#, fuzzy msgid "Async" -msgstr "Режим осмотра" +msgstr "Асинхронный" #: scene/resources/visual_shader.cpp -#, fuzzy msgid "Modes" -msgstr "Режим" +msgstr "Режимы" #: scene/resources/visual_shader.cpp msgid "Input Name" @@ -27317,9 +26859,8 @@ msgid "Scenario" msgstr "Сцена" #: scene/resources/world.cpp scene/resources/world_2d.cpp -#, fuzzy msgid "Navigation Map" -msgstr "Навигация" +msgstr "Карта навигации" #: scene/resources/world.cpp scene/resources/world_2d.cpp msgid "Direct Space State" @@ -27344,14 +26885,12 @@ msgid "Default Map Up" msgstr "Шаг по умолчанию плавающих чисел" #: scene/resources/world.cpp scene/resources/world_2d.cpp -#, fuzzy msgid "Default Cell Size" -msgstr "Размер ячейки" +msgstr "Размер ячейки по умолчанию" #: scene/resources/world.cpp scene/resources/world_2d.cpp -#, fuzzy msgid "Default Cell Height" -msgstr "Тестируемые" +msgstr "Высота клетки по умолчанию" #: scene/resources/world.cpp scene/resources/world_2d.cpp #, fuzzy @@ -27427,9 +26966,8 @@ msgid "Rate Hz" msgstr "" #: servers/audio/effects/audio_effect_chorus.cpp -#, fuzzy msgid "Depth (ms)" -msgstr "Глубина" +msgstr "Глубина (мс)" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp @@ -27453,9 +26991,8 @@ msgid "Attack (µs)" msgstr "" #: servers/audio/effects/audio_effect_compressor.cpp -#, fuzzy msgid "Release (ms)" -msgstr "Релиз" +msgstr "Релиз (мс)" #: servers/audio/effects/audio_effect_compressor.cpp msgid "Mix" @@ -27476,9 +27013,8 @@ msgstr "" #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_phaser.cpp #: servers/audio/effects/audio_effect_reverb.cpp -#, fuzzy msgid "Feedback" -msgstr "Отправить отзыв о документации" +msgstr "Отзыв" #: servers/audio/effects/audio_effect_delay.cpp #, fuzzy @@ -27706,9 +27242,8 @@ msgid "Collision Unsafe Fraction" msgstr "Режим столкновения" #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Physics Engine" -msgstr "Кадр физики %" +msgstr "Физический движек" #: servers/physics_server.cpp msgid "Center Of Mass" @@ -27758,23 +27293,20 @@ msgid "Spatial Partitioning" msgstr "Пространственное разбиение" #: servers/visual_server.cpp -#, fuzzy msgid "Render Loop Enabled" -msgstr "Фильтр сигналов" +msgstr "Включить цикл рендера" #: servers/visual_server.cpp msgid "VRAM Compression" msgstr "Сжатие VRAM" #: servers/visual_server.cpp -#, fuzzy msgid "Import BPTC" -msgstr "Импорт" +msgstr "Импорт BPTC" #: servers/visual_server.cpp -#, fuzzy msgid "Import S3TC" -msgstr "Импорт" +msgstr "Импорт S3TC" #: servers/visual_server.cpp msgid "Import ETC" @@ -27785,9 +27317,8 @@ msgid "Import ETC2" msgstr "Импортировать ETC2" #: servers/visual_server.cpp -#, fuzzy msgid "Import PVRTC" -msgstr "Импортировать тему" +msgstr "Импорт PVRTC" #: servers/visual_server.cpp msgid "Lossless Compression" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index e115c4d368..8cbf35a18b 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -84,13 +84,14 @@ # Volkan Gezer <volkangezer@gmail.com>, 2022. # bsr <bsndrn16@gmail.com>, 2022. # Ramazan SANCAR <ramazansancar4545@gmail.com>, 2022. +# Burak Orcun OZKABLAN <borcunozkablan@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-08-30 03:11+0000\n" -"Last-Translator: Ramazan SANCAR <ramazansancar4545@gmail.com>\n" +"PO-Revision-Date: 2022-09-11 22:22+0000\n" +"Last-Translator: Burak Orcun OZKABLAN <borcunozkablan@gmail.com>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\n" @@ -263,9 +264,8 @@ msgid "Limits" msgstr "Limitler" #: core/command_queue_mt.cpp -#, fuzzy msgid "Command Queue" -msgstr "Komut Sırası" +msgstr "Komut Kuyruğu" #: core/command_queue_mt.cpp msgid "Multithreading Queue Size (KB)" @@ -1153,9 +1153,8 @@ msgid "Anim Duplicate Keys" msgstr "Animasyon Anahtarları Çoğalt" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Delete Keys" -msgstr "Animasyon Anahtarları Sil" +msgstr "Animasyon Silme Tuşları" #: editor/animation_track_editor.cpp #, fuzzy diff --git a/editor/translations/uk.po b/editor/translations/uk.po index fe0bc96c04..07cfe5b6b1 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -24,13 +24,14 @@ # Гліб Соколов <ramithes@i.ua>, 2022. # Max Donchenko <maxx.donchenko@gmail.com>, 2022. # Artem <artem@molotov.work>, 2022. +# Teashrock <kajitsu22@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-08-25 13:04+0000\n" -"Last-Translator: Artem <artem@molotov.work>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: Teashrock <kajitsu22@gmail.com>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" "Language: uk\n" @@ -39,7 +40,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -466,7 +467,6 @@ msgid "Pressure" msgstr "Тиск" #: core/os/input_event.cpp -#, fuzzy msgid "Pen Inverted" msgstr "Перо перевернуте" @@ -5498,10 +5498,9 @@ msgstr "Додаткові кнопки миші для навігації жу #: editor/editor_settings.cpp #, fuzzy msgid "Drag And Drop Selection" -msgstr "Перетягніть виділення" +msgstr "Перетягніть виділене" #: editor/editor_settings.cpp -#, fuzzy msgid "Stay In Script Editor On Node Selected" msgstr "Залишитися в редакторі скриптів на вибраному вузлі" @@ -6377,7 +6376,7 @@ msgstr "Поточна версія:" #: editor/export_template_manager.cpp msgid "Export templates are missing. Download them or install from a file." msgstr "" -"Не вистачає шаблонів експортування. Отримайте їх або встановіть з файла." +"Не вистачає шаблонів експортування. Отримайте їх або встановіть із файлу." #: editor/export_template_manager.cpp msgid "Export templates are installed and ready to be used." @@ -14159,7 +14158,7 @@ msgstr "Експортування проєкту" #: editor/project_export.cpp msgid "Manage Export Templates" -msgstr "Управління шаблонами експорту" +msgstr "Керування шаблонами експорту" #: editor/project_export.cpp msgid "Export With Debug" @@ -15189,7 +15188,7 @@ msgstr "Вилучити вузол «%s»?" msgid "" "Saving the branch as a scene requires having a scene open in the editor." msgstr "" -"Щоб можна було зберегти гілку як сцену, сцену має бути відкрито у редакторі." +"Щоб можна було зберегти гілку як сцену, сцена має бути відкрита у редакторі." #: editor/scene_tree_dock.cpp msgid "" @@ -15276,9 +15275,8 @@ msgid "Enable Scene Unique Name(s)" msgstr "Увімкнути унікальну назву сцени" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Unique names already used by another node in the scene:" -msgstr "Цю унікальну назву у сцені вже використано іншим вузлом." +msgstr "Цю унікальну назву у сцені вже використано іншим вузлом:" #: editor/scene_tree_dock.cpp #, fuzzy @@ -16966,7 +16964,6 @@ msgid "Joints Original" msgstr "Початок з'єднання" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Inverse Binds" msgstr "Зворотні зв'язки" @@ -18771,10 +18768,8 @@ msgid "" "'apksigner' could not be found. Please check that the command is available " "in the Android SDK build-tools directory. The resulting %s is unsigned." msgstr "" -"Не вдалося знайти «apksigner».\n" -"Будь ласка, перевірте, чи є програма доступною у каталозі build-tools набору " -"засобів для розробки Android.\n" -"Отриманий у результаті %s не підписано." +"Не вдалося знайти «apksigner». Будь ласка, перевірте, чи є команда доступною " +"у каталозі build-tools Android SDK. Отриманий результат %s не підписано." #: platform/android/export/export_plugin.cpp msgid "Signing debug %s..." @@ -18791,7 +18786,7 @@ msgstr "Не вдалося знайти сховище ключів. Немож #: platform/android/export/export_plugin.cpp #, fuzzy msgid "Could not start apksigner executable." -msgstr "Не вдалося запустити підпроцес!" +msgstr "Не вдалося запустити виконуваний файл apksigner." #: platform/android/export/export_plugin.cpp msgid "'apksigner' returned with error #%d" @@ -18825,9 +18820,8 @@ msgstr "" "Некоректна назва файла! Пакунок Android APK повинен мати суфікс назви *.apk." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Unsupported export format!" -msgstr "Непідтримуваний формат експортування!\n" +msgstr "Непідтримуваний формат експортування!" #: platform/android/export/export_plugin.cpp msgid "" @@ -18839,28 +18833,24 @@ msgstr "" "допомогою меню «Проєкт»." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Android build version mismatch: Template installed: %s, Godot version: %s. " "Please reinstall Android build template from 'Project' menu." msgstr "" -"Невідповідність версія для збирання для Android:\n" -" Встановлений шаблон: %s\n" -" Версія Godot: %s\n" -"Будь ласка, повторно встановіть шаблон для збирання для Android за допомогою " -"меню «Проєкт»." +"Невідповідність версія для збирання під Android: Встановлений шаблон: %s, " +"Версія Godot: %s. Будь ласка, повторно встановіть шаблон для збирання під " +"Android за допомогою меню «Проєкт»." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Unable to overwrite res://android/build/res/*.xml files with project name." msgstr "" -"Не вдалося перезаписати файли res://android/build/res/*.xml із назвою проєкту" +"Не вдалося перезаписати файли res://android/build/res/*.xml із назвою " +"проєкту." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "Не вдалося експортувати файли проєкту до проєкту gradle\n" +msgstr "Не вдалося експортувати файли проєкту до проєкту gradle." #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -18871,15 +18861,13 @@ msgid "Building Android Project (gradle)" msgstr "Збирання проєкту Android (gradle)" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Building of Android project failed, check output for the error. " "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" -"Не вдалося виконати збирання проєкту Android. Ознайомтеся із виведеними " -"даними, щоб визначити причину помилки.\n" -"Крім того, можете відвідати docs.godotengine.org і ознайомитися із " -"документацією щодо збирання для Android." +"Не вдалося виконати збирання проєкту для Android. Ознайомтеся із виведеними " +"даними, щоб визначити причину помилки. Крім того, можете відвідати docs." +"godotengine.org і ознайомитися із документацією щодо збирання для Android." #: platform/android/export/export_plugin.cpp msgid "Moving output" @@ -18894,29 +18882,24 @@ msgstr "" "дані можна знайти у каталозі проєкту gradle." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Package not found: \"%s\"." -msgstr "Пакунок не знайдено: %s" +msgstr "Пакунок не знайдено: \"%s\"." #: platform/android/export/export_plugin.cpp msgid "Creating APK..." msgstr "Створення APK…" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not find template APK to export: \"%s\"." -msgstr "" -"Не вдалося знайти шаблон APK для експортування:\n" -"%s" +msgstr "Не вдалося знайти шаблон APK для експортування: %s." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Missing libraries in the export template for the selected architectures: %s. " "Please build a template with all required libraries, or uncheck the missing " "architectures in the export preset." msgstr "" -"Не вистачає бібліотек у шаблоні експортування для вибраних архітектур: %s.\n" +"Не вистачає бібліотек у шаблоні експортування для вибраних архітектур: %s. " "Будь ласка, створіть шаблон з усіма необхідними бібліотеками або зніміть " "позначку з архітектур із пропущеними бібліотеками у стилі експортування." @@ -18925,9 +18908,8 @@ msgid "Adding files..." msgstr "Додавання файлів…" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files." -msgstr "Не вдалося експортувати файли проєкту" +msgstr "Не вдалося експортувати файли проєкту." #: platform/android/export/export_plugin.cpp msgid "Aligning APK..." @@ -19199,19 +19181,16 @@ msgid "Run exported HTML in the system's default browser." msgstr "Виконати експортований HTML у браузері за умовчанням системи." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not open template for export: \"%s\"." -msgstr "Не вдалося відкрити шаблон для експорту:" +msgstr "Не вдалося відкрити шаблон для експорту: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Invalid export template: \"%s\"." -msgstr "Неправильний шаблон експорту:" +msgstr "Неправильний шаблон експорту: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not write file: \"%s\"." -msgstr "Не вдалося записати файл:" +msgstr "Не вдалося записати файл: \"%s\"." #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19219,9 +19198,8 @@ msgid "Icon Creation" msgstr "Поле піктограми" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not read file: \"%s\"." -msgstr "Не вдалося прочитати файл:" +msgstr "Не вдалося прочитати файл: \"%s\"." #: platform/javascript/export/export.cpp msgid "PWA" @@ -19296,19 +19274,17 @@ msgid "Icon 512 X 512" msgstr "Піктограма 512⨯12" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not read HTML shell: \"%s\"." -msgstr "Не вдалося прочитати оболонку HTML:" +msgstr "Не вдалося прочитати оболонку HTML: \"%s\"." #: platform/javascript/export/export.cpp #, fuzzy msgid "Could not create HTTP server directory: %s." -msgstr "Не вдалося створити каталог на сервері HTTP:" +msgstr "Не вдалося створити каталог для сервера HTTP: %s." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Error starting HTTP server: %d." -msgstr "Помилка під час спроби запуску сервера HTTP:" +msgstr "Помилка під час спроби запуску сервера HTTP: %d." #: platform/javascript/export/export.cpp msgid "Web" @@ -19574,17 +19550,17 @@ msgstr "" #: platform/osx/export/export.cpp #, fuzzy msgid "Could not open icon file \"%s\"." -msgstr "Не вдалося експортувати файли проєкту" +msgstr "Не вдалося відкрити файл іконки \"%s\"." #: platform/osx/export/export.cpp #, fuzzy msgid "Could not start xcrun executable." -msgstr "Не вдалося запустити підпроцес!" +msgstr "Не вдалося запустити виконуваний файл xcrun." #: platform/osx/export/export.cpp #, fuzzy msgid "Notarization failed." -msgstr "Засвідчення" +msgstr "Нотаріальне засвідчення не відбулося." #: platform/osx/export/export.cpp msgid "Notarization request UUID: \"%s\"" @@ -19649,9 +19625,8 @@ msgid "No identity found." msgstr "Не знайдено профілю." #: platform/osx/export/export.cpp -#, fuzzy msgid "Cannot sign file %s." -msgstr "Помилка під час збереження файла: %s" +msgstr "Не вдається підписати файл %s." #: platform/osx/export/export.cpp #, fuzzy @@ -19668,7 +19643,7 @@ msgstr "Напрямок" #: platform/osx/export/export.cpp #, fuzzy msgid "Could not start hdiutil executable." -msgstr "Не вдалося запустити підпроцес!" +msgstr "Не вдалося запустити виконуваний файл hdiutil." #: platform/osx/export/export.cpp msgid "`hdiutil create` failed - file exists." @@ -19683,14 +19658,12 @@ msgid "Creating app bundle" msgstr "Створюємо комплект програми" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not find template app to export: \"%s\"." -msgstr "Не вдалося знайти програму-шаблон для експортування:" +msgstr "Не вдалося знайти шаблон програми для експортування: \"%s\"." #: platform/osx/export/export.cpp -#, fuzzy msgid "Invalid export format." -msgstr "Неправильний шаблон експорту:" +msgstr "Неправильний формат експорту." #: platform/osx/export/export.cpp msgid "" @@ -19757,7 +19730,7 @@ msgstr "Проєкція" #: platform/osx/export/export.cpp #, fuzzy msgid "Could not open file to read from path \"%s\"." -msgstr "Не вдалося експортувати файли проєкту до проєкту gradle\n" +msgstr "Не вдалося відкрити файл для читання з шляху \"%s\"." #: platform/osx/export/export.cpp msgid "Invalid bundle identifier:" @@ -20102,9 +20075,8 @@ msgid "Debug Algorithm" msgstr "Алгоритм діагностики" #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to rename temporary file \"%s\"." -msgstr "Не вдалося вилучити тимчасовий файл:" +msgstr "Не вдалося перейменувати тимчасовий файл \"%s\"." #: platform/windows/export/export.cpp msgid "Identity Type" @@ -20190,7 +20162,7 @@ msgstr "Не вдалося знайти сховище ключів. Немож #: platform/windows/export/export.cpp #, fuzzy msgid "Invalid identity type." -msgstr "Тип профілю" +msgstr "Невірний тип профілю." #: platform/windows/export/export.cpp #, fuzzy @@ -20214,9 +20186,8 @@ msgid "Signtool failed to sign executable: %s." msgstr "Некоректний виконуваний файл." #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to remove temporary file \"%s\"." -msgstr "Не вдалося вилучити тимчасовий файл:" +msgstr "Не вдалося вилучити тимчасовий файл \"%s\"." #: platform/windows/export/export.cpp msgid "" @@ -26126,7 +26097,7 @@ msgstr "" #: scene/resources/navigation_mesh.cpp #, fuzzy msgid "Sampling" -msgstr "Масштаб:" +msgstr "Масштаб" #: scene/resources/navigation_mesh.cpp #, fuzzy diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index 86a37e167f..1aeaea7087 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -89,7 +89,7 @@ msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2022-08-25 13:04+0000\n" +"PO-Revision-Date: 2022-09-22 15:26+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" @@ -98,7 +98,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -15022,17 +15022,14 @@ msgid "Make Local" msgstr "转为本地" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name(s)" msgstr "启用场景唯一名称" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Unique names already used by another node in the scene:" -msgstr "该场景中已有使用该唯一名称的节点。" +msgstr "唯一名称已被该场景中的其他节点使用:" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Disable Scene Unique Name(s)" msgstr "禁用场景唯一名称" @@ -17086,19 +17083,16 @@ msgid "Auto Update Project" msgstr "自动更新项目" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Assembly Name" -msgstr "显示名称" +msgstr "程序集名称" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "Solution Directory" -msgstr "选择目录" +msgstr "解决方案目录" #: modules/mono/godotsharp_dirs.cpp -#, fuzzy msgid "C# Project Directory" -msgstr "选择目录" +msgstr "C# 项目目录" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -18801,7 +18795,6 @@ msgid "Custom BG Color" msgstr "自定义背景色" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Icons" msgstr "导出图标" @@ -19593,6 +19586,8 @@ msgid "" "Godot's Mono version does not support the UWP platform. Use the standard " "build (no C# support) if you wish to target UWP." msgstr "" +"Godot 的 Mono 版本不支持 UWP 平台。如果想要以 UWP 为目标,请使用标准构建(不" +"支持 C#)。" #: platform/uwp/export/export.cpp msgid "Invalid package short name." @@ -20647,7 +20642,7 @@ msgid "" "instead." msgstr "" "“Navigation2D”节点和“Navigation2D.get_simple_path()”已废弃,会在将来的版本中" -"移除。请用“Navigation2DServer.map_get_path()”替代。" +"移除。 请用“Navigation2DServer.map_get_path()”替代。" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Pathfinding" @@ -21788,7 +21783,7 @@ msgid "" "instead." msgstr "" "“Navigation”节点和“Navigation.get_simple_path()”已废弃,会在将来的版本中移" -"除。请用“NavigationServer.map_get_path()”替代。" +"除。 请用“NavigationServer.map_get_path()”替代。" #: scene/3d/navigation.cpp scene/resources/curve.cpp msgid "Up Vector" @@ -24227,7 +24222,7 @@ msgstr "自定义" #: scene/register_scene_types.cpp msgid "Custom Font" -msgstr "自定字体" +msgstr "自定义字体" #: scene/resources/audio_stream_sample.cpp #: servers/audio/effects/audio_stream_generator.cpp servers/audio_server.cpp diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index 994c49156e..4cd08539e4 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -37,13 +37,14 @@ # marktwtn <marktwtn@gmail.com>, 2022. # Shi-Xun Hong <jimmy3421@gmail.com>, 2022. # Hugel <qihu@nfschina.com>, 2022. +# nitenook <admin@alterbaum.net>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-09-07 06:16+0000\n" -"Last-Translator: Chia-Hsiang Cheng <cche0109@student.monash.edu>\n" +"PO-Revision-Date: 2022-09-27 21:37+0000\n" +"Last-Translator: nitenook <admin@alterbaum.net>\n" "Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hant/>\n" "Language: zh_TW\n" @@ -51,7 +52,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -10679,6 +10680,7 @@ msgid "Create Rest Pose from Bones" msgstr "自骨骼建立靜止姿勢" #: editor/plugins/skeleton_2d_editor_plugin.cpp +#, fuzzy msgid "Skeleton2D" msgstr "Sekeleton2D" |