Преглед на файлове

Make various improvements to OptionButton

- Allow OptionButton selection to be set to -1 to signify no selection, both via API and in the editor.
- Reset OptionButton selection to -1 when the selected item has been removed.
- Fully convert PopupMenu to a zero-based ID system, which improves an inconsistency in generated IDs when making new items in the editor.

(cherry picked from commit 3b146c5eaa06d9f6827c651802b9fb2a9a1e013d)
Sergey Pershenkov преди 3 години
родител
ревизия
431c032d8c
променени са 3 файла, в които са добавени 33 реда и са изтрити 16 реда
  1. 2 1
      doc/classes/OptionButton.xml
  2. 28 12
      scene/gui/option_button.cpp
  3. 3 3
      scene/gui/popup_menu.cpp

+ 2 - 1
doc/classes/OptionButton.xml

@@ -97,7 +97,7 @@
 		<method name="get_selected_id" qualifiers="const">
 		<method name="get_selected_id" qualifiers="const">
 			<return type="int" />
 			<return type="int" />
 			<description>
 			<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>
 			</description>
 		</method>
 		</method>
 		<method name="get_selected_metadata" qualifiers="const">
 		<method name="get_selected_metadata" qualifiers="const">
@@ -125,6 +125,7 @@
 			<argument index="0" name="idx" type="int" />
 			<argument index="0" name="idx" type="int" />
 			<description>
 			<description>
 				Selects an item by index and makes it the current item. This will work even if the item is disabled.
 				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>
 			</description>
 		</method>
 		</method>
 		<method name="set_item_disabled">
 		<method name="set_item_disabled">

+ 28 - 12
scene/gui/option_button.cpp

@@ -32,6 +32,8 @@
 #include "core/os/input.h"
 #include "core/os/input.h"
 #include "core/print_string.h"
 #include "core/print_string.h"
 
 
+static const int NONE_SELECTED = -1;
+
 Size2 OptionButton::get_minimum_size() const {
 Size2 OptionButton::get_minimum_size() const {
 	Size2 minsize = Button::get_minimum_size();
 	Size2 minsize = Button::get_minimum_size();
 
 
@@ -173,6 +175,10 @@ Ref<Texture> OptionButton::get_item_icon(int p_idx) const {
 }
 }
 
 
 int OptionButton::get_item_id(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);
 	return popup->get_item_id(p_idx);
 }
 }
 
 
@@ -203,26 +209,33 @@ void OptionButton::add_separator() {
 void OptionButton::clear() {
 void OptionButton::clear() {
 	popup->clear();
 	popup->clear();
 	set_text("");
 	set_text("");
-	current = -1;
+	current = NONE_SELECTED;
 }
 }
 
 
 void OptionButton::_select(int p_which, bool p_emit) {
 void OptionButton::_select(int p_which, bool p_emit) {
-	if (p_which < 0) {
-		return;
-	}
 	if (p_which == current) {
 	if (p_which == current) {
 		return;
 		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());
+
+		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));
+		current = p_which;
+		set_text(popup->get_item_text(current));
+		set_icon(popup->get_item_icon(current));
+	}
 
 
 	if (is_inside_tree() && p_emit) {
 	if (is_inside_tree() && p_emit) {
 		emit_signal("item_selected", current);
 		emit_signal("item_selected", current);
@@ -230,7 +243,7 @@ void OptionButton::_select(int p_which, bool p_emit) {
 }
 }
 
 
 void OptionButton::_select_int(int p_which) {
 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;
 		return;
 	}
 	}
 	_select(p_which, false);
 	_select(p_which, false);
@@ -261,6 +274,9 @@ Variant OptionButton::get_selected_metadata() const {
 
 
 void OptionButton::remove_item(int p_idx) {
 void OptionButton::remove_item(int p_idx) {
 	popup->remove_item(p_idx);
 	popup->remove_item(p_idx);
+	if (current == p_idx) {
+		_select(NONE_SELECTED);
+	}
 }
 }
 
 
 PopupMenu *OptionButton::get_popup() const {
 PopupMenu *OptionButton::get_popup() const {

+ 3 - 3
scene/gui/popup_menu.cpp

@@ -666,7 +666,7 @@ void PopupMenu::_notification(int p_what) {
 #define ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel) \
 #define ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel) \
 	item.text = p_label;                              \
 	item.text = p_label;                              \
 	item.xl_text = tr(p_label);                       \
 	item.xl_text = tr(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;
 	item.accel = p_accel;
 
 
 void PopupMenu::add_item(const String &p_label, int p_id, uint32_t p_accel) {
 void PopupMenu::add_item(const String &p_label, int p_id, uint32_t p_accel) {
@@ -739,7 +739,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
 	_ref_shortcut(p_shortcut);                                                         \
 	_ref_shortcut(p_shortcut);                                                         \
 	item.text = p_shortcut->get_name();                                                \
 	item.text = p_shortcut->get_name();                                                \
 	item.xl_text = tr(item.text);                                                      \
 	item.xl_text = tr(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 = p_shortcut;                                                        \
 	item.shortcut_is_global = p_global;
 	item.shortcut_is_global = p_global;
 
 
@@ -802,7 +802,7 @@ void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu,
 	Item item;
 	Item item;
 	item.text = p_label;
 	item.text = p_label;
 	item.xl_text = tr(p_label);
 	item.xl_text = tr(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;
 	item.submenu = p_submenu;
 	items.push_back(item);
 	items.push_back(item);
 	update();
 	update();