diff options
25 files changed, 163 insertions, 59 deletions
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 48fa009300..06bd64577b 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -7,6 +7,7 @@ This control provides a selectable list of items that may be in a single (or multiple columns) with option of text, icons, or both text and icon. Tooltips are supported and may be different for every item in the list. Selectable items in the list may be selected or deselected and multiple selection may be enabled. Selection with right mouse button may also be enabled to allow use of popup context menus. Items may also be "activated" by double-clicking them or by pressing [kbd]Enter[/kbd]. Item text only supports single-line strings, newline characters (e.g. [code]\n[/code]) in the string won't produce a newline. Text wrapping is enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to fully fit its content by default. You need to set [member fixed_column_width] greater than zero to wrap the text. + All [code]set_*[/code] methods allow negative item index, which makes the item accessed from the last one. </description> <tutorials> </tutorials> diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index b64c392357..4bcfc3c726 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -7,6 +7,7 @@ [PopupMenu] is a modal window used to display a list of options. They are popular in toolbars or context menus. The size of a [PopupMenu] can be limited by using [member Window.max_size]. If the height of the list of items is larger than the maximum height of the [PopupMenu], a [ScrollContainer] within the popup will allow the user to scroll the contents. If no maximum size is set, or if it is set to 0, the [PopupMenu] height will be limited by its parent rect. + All [code]set_*[/code] methods allow negative item index, which makes the item accessed from the last one. </description> <tutorials> </tutorials> diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index e1198026b6..cd79238844 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -925,7 +925,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { String name = E.operator String().replace("AudioEffect", ""); effect_options->add_item(name); - effect_options->set_item_metadata(effect_options->get_item_count() - 1, E); + effect_options->set_item_metadata(-1, E); } bus_options = memnew(MenuButton); diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 0fef4597be..a45792022c 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -214,7 +214,7 @@ void EditorFileDialog::update_dir() { if (dir_access->get_current_dir().is_network_share_path()) { _update_drives(false); drives->add_item(RTR("Network")); - drives->set_item_disabled(drives->get_item_count() - 1, true); + drives->set_item_disabled(-1, true); drives->select(drives->get_item_count() - 1); } else { drives->select(dir_access->get_current_drive()); @@ -314,8 +314,8 @@ void EditorFileDialog::_post_popup() { recentd.remove_at(i--); } else { recent->add_item(name, folder); - recent->set_item_metadata(recent->get_item_count() - 1, recentd[i]); - recent->set_item_icon_modulate(recent->get_item_count() - 1, folder_color); + recent->set_item_metadata(-1, recentd[i]); + recent->set_item_icon_modulate(-1, folder_color); } } EditorSettings::get_singleton()->set_recent_dirs(recentd); @@ -800,9 +800,9 @@ void EditorFileDialog::update_file_list() { item_list->add_item(dir_name); if (display_mode == DISPLAY_THUMBNAILS) { - item_list->set_item_icon(item_list->get_item_count() - 1, folder_thumbnail); + item_list->set_item_icon(-1, folder_thumbnail); } else { - item_list->set_item_icon(item_list->get_item_count() - 1, folder); + item_list->set_item_icon(-1, folder); } Dictionary d; @@ -810,8 +810,8 @@ void EditorFileDialog::update_file_list() { d["path"] = cdir.plus_file(dir_name); d["dir"] = true; - item_list->set_item_metadata(item_list->get_item_count() - 1, d); - item_list->set_item_icon_modulate(item_list->get_item_count() - 1, folder_color); + item_list->set_item_metadata(-1, d); + item_list->set_item_icon_modulate(-1, folder_color); dirs.pop_front(); } @@ -858,10 +858,10 @@ void EditorFileDialog::update_file_list() { if (get_icon_func) { Ref<Texture2D> icon = get_icon_func(cdir.plus_file(files.front()->get())); if (display_mode == DISPLAY_THUMBNAILS) { - item_list->set_item_icon(item_list->get_item_count() - 1, file_thumbnail); - item_list->set_item_tag_icon(item_list->get_item_count() - 1, icon); + item_list->set_item_icon(-1, file_thumbnail); + item_list->set_item_tag_icon(-1, icon); } else { - item_list->set_item_icon(item_list->get_item_count() - 1, icon); + item_list->set_item_icon(-1, icon); } } @@ -870,7 +870,7 @@ void EditorFileDialog::update_file_list() { d["dir"] = false; String fullpath = cdir.plus_file(files.front()->get()); d["path"] = fullpath; - item_list->set_item_metadata(item_list->get_item_count() - 1, d); + item_list->set_item_metadata(-1, d); if (display_mode == DISPLAY_THUMBNAILS && previews_enabled) { EditorResourcePreview::get_singleton()->queue_resource_preview(fullpath, this, "_thumbnail_result", fullpath); @@ -1321,8 +1321,8 @@ void EditorFileDialog::_update_favorites() { continue; // We don't handle favorite files here. } - favorites->set_item_metadata(favorites->get_item_count() - 1, favorited[i]); - favorites->set_item_icon_modulate(favorites->get_item_count() - 1, folder_color); + favorites->set_item_metadata(-1, favorited[i]); + favorites->set_item_icon_modulate(-1, folder_color); if (setthis) { favorite->set_pressed(true); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 17b219f8dc..c508856638 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -6516,7 +6516,7 @@ EditorNode::EditorNode() { ED_SHORTCUT_OVERRIDE("editor/take_screenshot", "macos", KeyModifierMask::CMD | Key::F12); p->add_shortcut(ED_GET_SHORTCUT("editor/take_screenshot"), EDITOR_SCREENSHOT); - p->set_item_tooltip(p->get_item_count() - 1, TTR("Screenshots are stored in the Editor Data/Settings Folder.")); + p->set_item_tooltip(-1, TTR("Screenshots are stored in the Editor Data/Settings Folder.")); ED_SHORTCUT_AND_COMMAND("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KeyModifierMask::SHIFT | Key::F11); ED_SHORTCUT_OVERRIDE("editor/fullscreen_mode", "macos", KeyModifierMask::CMD | KeyModifierMask::CTRL | Key::F); diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 85d304ec5d..77f135bb63 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -83,7 +83,7 @@ void EditorRunNative::_notification(int p_what) { mb->set_tooltip(eep->get_options_tooltip()); for (int i = 0; i < dc; i++) { mb->get_popup()->add_icon_item(eep->get_option_icon(i), eep->get_option_label(i)); - mb->get_popup()->set_item_tooltip(mb->get_popup()->get_item_count() - 1, eep->get_option_tooltip(i)); + mb->get_popup()->set_item_tooltip(-1, eep->get_option_tooltip(i)); } } } diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index b2c216297e..d9539784ac 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -779,14 +779,14 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { icon = folder_icon; if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { files->add_item(text, icon, true); - files->set_item_metadata(files->get_item_count() - 1, favorite); + files->set_item_metadata(-1, favorite); } } else if (favorite.ends_with("/")) { text = favorite.substr(0, favorite.length() - 1).get_file(); icon = folder_icon; if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { files->add_item(text, icon, true); - files->set_item_metadata(files->get_item_count() - 1, favorite); + files->set_item_metadata(-1, favorite); } } else { int index; @@ -840,9 +840,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { bd += "/"; } - files->set_item_metadata(files->get_item_count() - 1, bd); - files->set_item_selectable(files->get_item_count() - 1, false); - files->set_item_icon_modulate(files->get_item_count() - 1, folder_color); + files->set_item_metadata(-1, bd); + files->set_item_selectable(-1, false); + files->set_item_icon_modulate(-1, folder_color); } bool reversed = file_sort == FILE_SORT_NAME_REVERSE; @@ -852,8 +852,8 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { String dname = efd->get_subdir(i)->get_name(); files->add_item(dname, folder_icon, true); - files->set_item_metadata(files->get_item_count() - 1, directory.plus_file(dname) + "/"); - files->set_item_icon_modulate(files->get_item_count() - 1, folder_color); + files->set_item_metadata(-1, directory.plus_file(dname) + "/"); + files->set_item_icon_modulate(-1, folder_color); if (cselection.has(dname)) { files->select(files->get_item_count() - 1, false); diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index 72cc33048c..9f1daac69f 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -128,7 +128,7 @@ void ImportDock::set_edit_path(const String &p_path) { for (const Pair<String, String> &E : importer_names) { import_as->add_item(E.first); - import_as->set_item_metadata(import_as->get_item_count() - 1, E.second); + import_as->set_item_metadata(-1, E.second); if (E.second == importer_name) { import_as->select(import_as->get_item_count() - 1); } @@ -149,7 +149,7 @@ void ImportDock::set_edit_path(const String &p_path) { void ImportDock::_add_keep_import_option(const String &p_importer_name) { import_as->add_separator(); import_as->add_item(TTR("Keep File (No Import)")); - import_as->set_item_metadata(import_as->get_item_count() - 1, "keep"); + import_as->set_item_metadata(-1, "keep"); if (p_importer_name == "keep") { import_as->select(import_as->get_item_count() - 1); } @@ -286,7 +286,7 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { for (const Pair<String, String> &E : importer_names) { import_as->add_item(E.first); - import_as->set_item_metadata(import_as->get_item_count() - 1, E.second); + import_as->set_item_metadata(-1, E.second); if (E.second == params->importer->get_importer_name()) { import_as->select(import_as->get_item_count() - 1); } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index f983492f7f..ab8e2ca54a 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1670,11 +1670,11 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug onion_skinning->set_tooltip(TTR("Onion Skinning Options")); onion_skinning->get_popup()->add_separator(TTR("Directions")); onion_skinning->get_popup()->add_check_item(TTR("Past"), ONION_SKINNING_PAST); - onion_skinning->get_popup()->set_item_checked(onion_skinning->get_popup()->get_item_count() - 1, true); + onion_skinning->get_popup()->set_item_checked(-1, true); onion_skinning->get_popup()->add_check_item(TTR("Future"), ONION_SKINNING_FUTURE); onion_skinning->get_popup()->add_separator(TTR("Depth")); onion_skinning->get_popup()->add_radio_check_item(TTR("1 step"), ONION_SKINNING_1_STEP); - onion_skinning->get_popup()->set_item_checked(onion_skinning->get_popup()->get_item_count() - 1, true); + onion_skinning->get_popup()->set_item_checked(-1, true); onion_skinning->get_popup()->add_radio_check_item(TTR("2 steps"), ONION_SKINNING_2_STEPS); onion_skinning->get_popup()->add_radio_check_item(TTR("3 steps"), ONION_SKINNING_3_STEPS); onion_skinning->get_popup()->add_separator(); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 50f253b167..fd9b665b20 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -1145,7 +1145,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const String name = cat["name"]; int id = cat["id"]; categories->add_item(name); - categories->set_item_metadata(categories->get_item_count() - 1, id); + categories->set_item_metadata(-1, id); category_map[cat["id"]] = name; } } diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 501becac57..c8d5aa3fdc 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -63,30 +63,24 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(MenuButton *p_debug_menu) { PopupMenu *p = debug_menu->get_popup(); p->set_hide_on_checkable_item_selection(false); p->add_check_shortcut(ED_SHORTCUT("editor/deploy_with_remote_debug", TTR("Deploy with Remote Debug")), RUN_DEPLOY_REMOTE_DEBUG); - p->set_item_tooltip( - p->get_item_count() - 1, + p->set_item_tooltip(-1, TTR("When this option is enabled, using one-click deploy will make the executable attempt to connect to this computer's IP so the running project can be debugged.\nThis option is intended to be used for remote debugging (typically with a mobile device).\nYou don't need to enable it to use the GDScript debugger locally.")); p->add_check_shortcut(ED_SHORTCUT("editor/small_deploy_with_network_fs", TTR("Small Deploy with Network Filesystem")), RUN_FILE_SERVER); - p->set_item_tooltip( - p->get_item_count() - 1, + p->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.")); p->add_separator(); p->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISONS); - p->set_item_tooltip( - p->get_item_count() - 1, + p->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.")); p->add_check_shortcut(ED_SHORTCUT("editor/visible_navigation", TTR("Visible Navigation")), RUN_DEBUG_NAVIGATION); - p->set_item_tooltip( - p->get_item_count() - 1, + p->set_item_tooltip(-1, TTR("When this option is enabled, navigation meshes and polygons will be visible in the running project.")); p->add_separator(); p->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Synchronize Scene Changes")), RUN_LIVE_DEBUG); - p->set_item_tooltip( - p->get_item_count() - 1, + p->set_item_tooltip(-1, TTR("When this option is enabled, any changes made to the scene in the editor will be replicated in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled.")); p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Synchronize Script Changes")), RUN_RELOAD_SCRIPTS); - p->set_item_tooltip( - p->get_item_count() - 1, + p->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.")); // Multi-instance, start/stop diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 64540ac157..8f285cb7f9 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -447,16 +447,16 @@ MeshInstance3DEditor::MeshInstance3DEditor() { options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MeshInstance3D"), SNAME("EditorIcons"))); options->get_popup()->add_item(TTR("Create Trimesh Static Body"), MENU_OPTION_CREATE_STATIC_TRIMESH_BODY); - options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a StaticBody3D and assigns a polygon-based collision shape to it automatically.\nThis is the most accurate (but slowest) option for collision detection.")); + options->get_popup()->set_item_tooltip(-1, TTR("Creates a StaticBody3D and assigns a polygon-based collision shape to it automatically.\nThis is the most accurate (but slowest) option for collision detection.")); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Trimesh Collision Sibling"), MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE); - options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is the most accurate (but slowest) option for collision detection.")); + options->get_popup()->set_item_tooltip(-1, TTR("Creates a polygon-based collision shape.\nThis is the most accurate (but slowest) option for collision detection.")); options->get_popup()->add_item(TTR("Create Single Convex Collision Sibling"), MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE); - options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a single convex collision shape.\nThis is the fastest (but least accurate) option for collision detection.")); + options->get_popup()->set_item_tooltip(-1, TTR("Creates a single convex collision shape.\nThis is the fastest (but least accurate) option for collision detection.")); options->get_popup()->add_item(TTR("Create Simplified Convex Collision Sibling"), MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE); - options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a simplified convex collision shape.\nThis is similar to single collision shape, but can result in a simpler geometry in some cases, at the cost of accuracy.")); + options->get_popup()->set_item_tooltip(-1, TTR("Creates a simplified convex collision shape.\nThis is similar to single collision shape, but can result in a simpler geometry in some cases, at the cost of accuracy.")); options->get_popup()->add_item(TTR("Create Multiple Convex Collision Siblings"), MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES); - options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between a single convex collision and a polygon-based collision.")); + options->get_popup()->set_item_tooltip(-1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between a single convex collision and a polygon-based collision.")); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Navigation Mesh"), MENU_OPTION_CREATE_NAVMESH); options->get_popup()->add_separator(); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index d506a1f3ab..2da5978fab 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1881,7 +1881,7 @@ void ScriptEditor::_update_members_overview() { String name = functions[i].get_slice(":", 0); if (filter.is_empty() || filter.is_subsequence_ofn(name)) { members_overview->add_item(name); - members_overview->set_item_metadata(members_overview->get_item_count() - 1, functions[i].get_slice(":", 1).to_int() - 1); + members_overview->set_item_metadata(-1, functions[i].get_slice(":", 1).to_int() - 1); } } @@ -2139,7 +2139,7 @@ void ScriptEditor::_update_script_names() { for (int i = 0; i < sedata_filtered.size(); i++) { script_list->add_item(sedata_filtered[i].name, sedata_filtered[i].icon); if (sedata_filtered[i].tool) { - script_list->set_item_icon_modulate(script_list->get_item_count() - 1, tool_color); + script_list->set_item_icon_modulate(-1, tool_color); } int index = script_list->get_item_count() - 1; diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 10b6129864..30ca1c605f 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -579,7 +579,7 @@ void ScriptTextEditor::_update_bookmark_list() { } bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - `" + line + "`"); - bookmarks_menu->set_item_metadata(bookmarks_menu->get_item_count() - 1, bookmark_list[i]); + bookmarks_menu->set_item_metadata(-1, bookmark_list[i]); } } @@ -731,7 +731,7 @@ void ScriptTextEditor::_update_breakpoint_list() { } breakpoints_menu->add_item(String::num((int)breakpoint_list[i] + 1) + " - `" + line + "`"); - breakpoints_menu->set_item_metadata(breakpoints_menu->get_item_count() - 1, breakpoint_list[i]); + breakpoints_menu->set_item_metadata(-1, breakpoint_list[i]); } } diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 382138a995..02f11bb82f 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -647,7 +647,7 @@ void ShaderEditor::_update_bookmark_list() { } bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\""); - bookmarks_menu->set_item_metadata(bookmarks_menu->get_item_count() - 1, bookmark_list[i]); + bookmarks_menu->set_item_metadata(-1, bookmark_list[i]); } } diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index c8db16d3be..4a63080747 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -847,7 +847,7 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) { at = at->get_atlas(); } - tree->set_item_tooltip(tree->get_item_count() - 1, tooltip); + tree->set_item_tooltip(-1, tooltip); } if (sel == i) { tree->select(tree->get_item_count() - 1); diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 940f269803..34f3ec73c0 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -179,7 +179,7 @@ void TextEditor::_update_bookmark_list() { } bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\""); - bookmarks_menu->set_item_metadata(bookmarks_menu->get_item_count() - 1, bookmark_list[i]); + bookmarks_menu->set_item_metadata(-1, bookmark_list[i]); } } diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp index 0f8c8c616c..086588f5a5 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.cpp +++ b/editor/plugins/tiles/atlas_merging_dialog.cpp @@ -241,7 +241,7 @@ void AtlasMergingDialog::update_tile_set(Ref<TileSet> p_tile_set) { if (texture.is_valid()) { String item_text = vformat("%s (id:%d)", texture->get_path().get_file(), source_id); atlas_merging_atlases_list->add_item(item_text, texture); - atlas_merging_atlases_list->set_item_metadata(atlas_merging_atlases_list->get_item_count() - 1, source_id); + atlas_merging_atlases_list->set_item_metadata(-1, source_id); } } } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 4a0fc0b29f..8d8c65f2c4 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -188,7 +188,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { } sources_list->add_item(item_text, texture); - sources_list->set_item_metadata(sources_list->get_item_count() - 1, source_id); + sources_list->set_item_metadata(-1, source_id); } if (sources_list->get_item_count() > 0) { diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index 49e589c9ef..8b0b184f54 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -182,7 +182,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { } sources_list->add_item(item_text, texture); - sources_list->set_item_metadata(sources_list->get_item_count() - 1, source_id); + sources_list->set_item_metadata(-1, source_id); } // Set again the current selected item if needed. diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 571b87a0aa..27f6854140 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2551,7 +2551,7 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_ menu_properties->clear(); for (const String &p : valid_properties) { menu_properties->add_item(capitalize ? p.capitalize() : p); - menu_properties->set_item_metadata(menu_properties->get_item_count() - 1, p); + menu_properties->set_item_metadata(-1, p); } menu_properties->reset_size(); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 055b30dae2..1e6286bc9c 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -641,7 +641,7 @@ void ScriptCreateDialog::_update_template_menu() { if (!templates_found.is_empty()) { if (!separator) { template_menu->add_separator(); - template_menu->set_item_text(template_menu->get_item_count() - 1, display_name); + template_menu->set_item_text(-1, display_name); separator = true; } for (ScriptLanguage::ScriptTemplate &t : templates_found) { diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 678229683f..75bed61042 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -176,7 +176,7 @@ void FileDialog::update_dir() { if (dir_access->get_current_dir().is_network_share_path()) { _update_drives(false); drives->add_item(RTR("Network")); - drives->set_item_disabled(drives->get_item_count() - 1, true); + drives->set_item_disabled(-1, true); drives->select(drives->get_item_count() - 1); } else { drives->select(dir_access->get_current_drive()); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index e83524b06c..8c0f696a9f 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -83,6 +83,9 @@ int ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) { } void ItemList::set_item_text(int p_idx, const String &p_text) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].text = p_text; @@ -97,6 +100,9 @@ String ItemList::get_item_text(int p_idx) const { } void ItemList::set_item_text_direction(int p_idx, Control::TextDirection p_text_direction) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3); if (items[p_idx].text_direction != p_text_direction) { @@ -119,6 +125,9 @@ void ItemList::clear_item_opentype_features(int p_idx) { } void ItemList::set_item_opentype_feature(int p_idx, const String &p_name, int p_value) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); int32_t tag = TS->name_to_tag(p_name); if (!items[p_idx].opentype_features.has(tag) || (int)items[p_idx].opentype_features[tag] != p_value) { @@ -138,6 +147,9 @@ int ItemList::get_item_opentype_feature(int p_idx, const String &p_name) const { } void ItemList::set_item_language(int p_idx, const String &p_language) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); if (items[p_idx].language != p_language) { items.write[p_idx].language = p_language; @@ -152,6 +164,9 @@ String ItemList::get_item_language(int p_idx) const { } void ItemList::set_item_tooltip_enabled(int p_idx, const bool p_enabled) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].tooltip_enabled = p_enabled; } @@ -162,6 +177,9 @@ bool ItemList::is_item_tooltip_enabled(int p_idx) const { } void ItemList::set_item_tooltip(int p_idx, const String &p_tooltip) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].tooltip = p_tooltip; @@ -175,6 +193,9 @@ String ItemList::get_item_tooltip(int p_idx) const { } void ItemList::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].icon = p_icon; @@ -189,6 +210,9 @@ Ref<Texture2D> ItemList::get_item_icon(int p_idx) const { } void ItemList::set_item_icon_transposed(int p_idx, const bool p_transposed) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].icon_transposed = p_transposed; @@ -203,6 +227,9 @@ bool ItemList::is_item_icon_transposed(int p_idx) const { } void ItemList::set_item_icon_region(int p_idx, const Rect2 &p_region) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].icon_region = p_region; @@ -217,6 +244,9 @@ Rect2 ItemList::get_item_icon_region(int p_idx) const { } void ItemList::set_item_icon_modulate(int p_idx, const Color &p_modulate) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].icon_modulate = p_modulate; @@ -230,6 +260,9 @@ Color ItemList::get_item_icon_modulate(int p_idx) const { } void ItemList::set_item_custom_bg_color(int p_idx, const Color &p_custom_bg_color) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].custom_bg = p_custom_bg_color; @@ -243,6 +276,9 @@ Color ItemList::get_item_custom_bg_color(int p_idx) const { } void ItemList::set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].custom_fg = p_custom_fg_color; @@ -256,6 +292,9 @@ Color ItemList::get_item_custom_fg_color(int p_idx) const { } void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture2D> &p_tag_icon) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].tag_icon = p_tag_icon; @@ -270,6 +309,9 @@ Ref<Texture2D> ItemList::get_item_tag_icon(int p_idx) const { } void ItemList::set_item_selectable(int p_idx, bool p_selectable) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].selectable = p_selectable; @@ -281,6 +323,9 @@ bool ItemList::is_item_selectable(int p_idx) const { } void ItemList::set_item_disabled(int p_idx, bool p_disabled) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].disabled = p_disabled; @@ -293,6 +338,9 @@ bool ItemList::is_item_disabled(int p_idx) const { } void ItemList::set_item_metadata(int p_idx, const Variant &p_metadata) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].metadata = p_metadata; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 840c3d5c31..4220066b20 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -999,6 +999,9 @@ void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu, /* Methods to modify existing items. */ void PopupMenu::set_item_text(int p_idx, const String &p_text) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].text = p_text; items.write[p_idx].xl_text = atr(p_text); @@ -1009,6 +1012,9 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) { } void PopupMenu::set_item_text_direction(int p_item, Control::TextDirection p_text_direction) { + if (p_item < 0) { + p_item += get_item_count(); + } ERR_FAIL_INDEX(p_item, items.size()); ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3); if (items[p_item].text_direction != p_text_direction) { @@ -1019,6 +1025,9 @@ void PopupMenu::set_item_text_direction(int p_item, Control::TextDirection p_tex } void PopupMenu::clear_item_opentype_features(int p_item) { + if (p_item < 0) { + p_item += get_item_count(); + } ERR_FAIL_INDEX(p_item, items.size()); items.write[p_item].opentype_features.clear(); items.write[p_item].dirty = true; @@ -1026,6 +1035,9 @@ void PopupMenu::clear_item_opentype_features(int p_item) { } void PopupMenu::set_item_opentype_feature(int p_item, const String &p_name, int p_value) { + if (p_item < 0) { + p_item += get_item_count(); + } ERR_FAIL_INDEX(p_item, items.size()); int32_t tag = TS->name_to_tag(p_name); if (!items[p_item].opentype_features.has(tag) || (int)items[p_item].opentype_features[tag] != p_value) { @@ -1036,6 +1048,9 @@ void PopupMenu::set_item_opentype_feature(int p_item, const String &p_name, int } void PopupMenu::set_item_language(int p_item, const String &p_language) { + if (p_item < 0) { + p_item += get_item_count(); + } ERR_FAIL_INDEX(p_item, items.size()); if (items[p_item].language != p_language) { items.write[p_item].language = p_language; @@ -1045,6 +1060,9 @@ void PopupMenu::set_item_language(int p_item, const String &p_language) { } void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].icon = p_icon; @@ -1053,6 +1071,9 @@ void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) { } void PopupMenu::set_item_checked(int p_idx, bool p_checked) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].checked = p_checked; @@ -1062,6 +1083,9 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) { } void PopupMenu::set_item_id(int p_idx, int p_id) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].id = p_id; @@ -1070,6 +1094,9 @@ void PopupMenu::set_item_id(int p_idx, int p_id) { } void PopupMenu::set_item_accelerator(int p_idx, Key p_accel) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].accel = p_accel; items.write[p_idx].dirty = true; @@ -1079,6 +1106,9 @@ void PopupMenu::set_item_accelerator(int p_idx, Key p_accel) { } void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].metadata = p_meta; control->update(); @@ -1086,6 +1116,9 @@ void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) { } void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].disabled = p_disabled; control->update(); @@ -1093,6 +1126,9 @@ void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) { } void PopupMenu::set_item_submenu(int p_idx, const String &p_submenu) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].submenu = p_submenu; control->update(); @@ -1201,6 +1237,9 @@ int PopupMenu::get_item_state(int p_idx) const { } void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].separator = p_separator; control->update(); @@ -1212,24 +1251,36 @@ bool PopupMenu::is_item_separator(int p_idx) const { } void PopupMenu::set_item_as_checkable(int p_idx, bool p_checkable) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].checkable_type = p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE; control->update(); } void PopupMenu::set_item_as_radio_checkable(int p_idx, bool p_radio_checkable) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].checkable_type = p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE; control->update(); } void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].tooltip = p_tooltip; control->update(); } void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); if (items[p_idx].shortcut.is_valid()) { _unref_shortcut(items[p_idx].shortcut); @@ -1246,6 +1297,9 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bo } void PopupMenu::set_item_h_offset(int p_idx, int p_offset) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].h_ofs = p_offset; control->update(); @@ -1253,12 +1307,18 @@ void PopupMenu::set_item_h_offset(int p_idx, int p_offset) { } void PopupMenu::set_item_multistate(int p_idx, int p_state) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].state = p_state; control->update(); } void PopupMenu::set_item_shortcut_disabled(int p_idx, bool p_disabled) { + if (p_idx < 0) { + p_idx += get_item_count(); + } ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].shortcut_is_disabled = p_disabled; control->update(); |