فهرست منبع

Merge pull request #57330 from eikobear/master

Rémi Verschelde 3 سال پیش
والد
کامیت
ffa566c770
3فایلهای تغییر یافته به همراه35 افزوده شده و 22 حذف شده
  1. 2 1
      doc/classes/OptionButton.xml
  2. 30 18
      scene/gui/option_button.cpp
  3. 3 3
      scene/gui/popup_menu.cpp

+ 2 - 1
doc/classes/OptionButton.xml

@@ -84,7 +84,7 @@
 		<method name="get_selected_id" qualifiers="const">
 			<return type="int" />
 			<description>
-				Returns the ID of the selected item, or [code]0[/code] if no item is selected.
+				Returns the ID of the selected item, or [code]-1[/code] if no item is selected.
 			</description>
 		</method>
 		<method name="get_selected_metadata" qualifiers="const">
@@ -112,6 +112,7 @@
 			<argument index="0" name="idx" type="int" />
 			<description>
 				Selects an item by index and makes it the current item. This will work even if the item is disabled.
+				Passing [code]-1[/code] as the index deselects any currently selected item.
 			</description>
 		</method>
 		<method name="set_item_disabled">

+ 30 - 18
scene/gui/option_button.cpp

@@ -32,6 +32,8 @@
 
 #include "core/string/print_string.h"
 
+static const int NONE_SELECTED = -1;
+
 Size2 OptionButton::get_minimum_size() const {
 	Size2 minsize = Button::get_minimum_size();
 
@@ -119,7 +121,7 @@ bool OptionButton::_set(const StringName &p_name, const Variant &p_value) {
 		int idx = components[1].get_slice("_", 1).to_int();
 		if (idx == current) {
 			// Force refreshing currently displayed item.
-			current = -1;
+			current = NONE_SELECTED;
 			_select(idx, false);
 		}
 
@@ -154,7 +156,7 @@ void OptionButton::_get_property_list(List<PropertyInfo> *p_list) const {
 		pi.usage &= ~(!popup->is_item_checked(i) ? PROPERTY_USAGE_STORAGE : 0);
 		p_list->push_back(pi);
 
-		pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "1,10,1,or_greater");
+		pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "0,10,1,or_greater");
 		p_list->push_back(pi);
 
 		pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/disabled", i));
@@ -234,6 +236,10 @@ Ref<Texture2D> OptionButton::get_item_icon(int p_idx) const {
 }
 
 int OptionButton::get_item_id(int p_idx) const {
+	if (p_idx == NONE_SELECTED) {
+		return NONE_SELECTED;
+	}
+
 	return popup->get_item_id(p_idx);
 }
 
@@ -266,26 +272,33 @@ void OptionButton::add_separator() {
 void OptionButton::clear() {
 	popup->clear();
 	set_text("");
-	current = -1;
+	current = NONE_SELECTED;
 }
 
 void OptionButton::_select(int p_which, bool p_emit) {
-	if (p_which < 0) {
-		return;
-	}
 	if (p_which == current) {
 		return;
 	}
 
-	ERR_FAIL_INDEX(p_which, popup->get_item_count());
+	if (p_which == NONE_SELECTED) {
+		for (int i = 0; i < popup->get_item_count(); i++) {
+			popup->set_item_checked(i, false);
+		}
 
-	for (int i = 0; i < popup->get_item_count(); i++) {
-		popup->set_item_checked(i, i == p_which);
-	}
+		current = NONE_SELECTED;
+		set_text("");
+		set_icon(NULL);
+	} else {
+		ERR_FAIL_INDEX(p_which, popup->get_item_count());
 
-	current = p_which;
-	set_text(popup->get_item_text(current));
-	set_icon(popup->get_item_icon(current));
+		for (int i = 0; i < popup->get_item_count(); i++) {
+			popup->set_item_checked(i, i == p_which);
+		}
+
+		current = p_which;
+		set_text(popup->get_item_text(current));
+		set_icon(popup->get_item_icon(current));
+	}
 
 	if (is_inside_tree() && p_emit) {
 		emit_signal(SNAME("item_selected"), current);
@@ -293,7 +306,7 @@ void OptionButton::_select(int p_which, bool p_emit) {
 }
 
 void OptionButton::_select_int(int p_which) {
-	if (p_which < 0 || p_which >= popup->get_item_count()) {
+	if (p_which < NONE_SELECTED || p_which >= popup->get_item_count()) {
 		return;
 	}
 	_select(p_which, false);
@@ -308,10 +321,6 @@ int OptionButton::get_selected() const {
 }
 
 int OptionButton::get_selected_id() const {
-	int idx = get_selected();
-	if (idx < 0) {
-		return 0;
-	}
 	return get_item_id(current);
 }
 
@@ -325,6 +334,9 @@ Variant OptionButton::get_selected_metadata() const {
 
 void OptionButton::remove_item(int p_idx) {
 	popup->remove_item(p_idx);
+	if (current == p_idx) {
+		_select(NONE_SELECTED);
+	}
 }
 
 PopupMenu *OptionButton::get_popup() const {

+ 3 - 3
scene/gui/popup_menu.cpp

@@ -810,7 +810,7 @@ void PopupMenu::_notification(int p_what) {
 #define ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel) \
 	item.text = p_label;                              \
 	item.xl_text = atr(p_label);                      \
-	item.id = p_id == -1 ? items.size() : p_id;       \
+	item.id = p_id == -1 ? items.size() - 1 : p_id;   \
 	item.accel = p_accel;
 
 void PopupMenu::add_item(const String &p_label, int p_id, Key p_accel) {
@@ -892,7 +892,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
 	_ref_shortcut(p_shortcut);                                                         \
 	item.text = p_shortcut->get_name();                                                \
 	item.xl_text = atr(item.text);                                                     \
-	item.id = p_id == -1 ? items.size() : p_id;                                        \
+	item.id = p_id == -1 ? items.size() - 1 : p_id;                                    \
 	item.shortcut = p_shortcut;                                                        \
 	item.shortcut_is_global = p_global;
 
@@ -961,7 +961,7 @@ void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu,
 	Item item;
 	item.text = p_label;
 	item.xl_text = atr(p_label);
-	item.id = p_id == -1 ? items.size() : p_id;
+	item.id = p_id == -1 ? items.size() - 1 : p_id;
 	item.submenu = p_submenu;
 	items.push_back(item);
 	_shape_item(items.size() - 1);