Selaa lähdekoodia

PopupMenu upgrade: Hide on item selection (#7306)

* Added the option to set hide on item selection. Usable in GDScript and from within the source code when you want to specify popup menus you don't want to close immediately when selecting an item

* Renamed getter from get_ to is_, fixed parent/child behavior, renamed bool variable to match most code and added ADD_PROPERTYNO to save some memory
Ivan P. Skodje 8 vuotta sitten
vanhempi
commit
da950cd0f2
4 muutettua tiedostoa jossa 50 lisäystä ja 4 poistoa
  1. 14 0
      doc/base/classes.xml
  2. 32 4
      scene/gui/popup_menu.cpp
  3. 3 0
      scene/gui/popup_menu.h
  4. 1 0
      tools/editor/editor_node.cpp

+ 14 - 0
doc/base/classes.xml

@@ -30931,6 +30931,13 @@
 				Clear the popup menu, in effect removing all items.
 				Clear the popup menu, in effect removing all items.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="is_hide_on_item_selection">
+			<return type="bool">
+			</return>
+			<description>
+				Returns a boolean that indicates whether or not the PopupMenu will hide on item selection.
+			</description>
+		</method>
 		<method name="get_item_ID" qualifiers="const">
 		<method name="get_item_ID" qualifiers="const">
 			<return type="int">
 			<return type="int">
 			</return>
 			</return>
@@ -31050,6 +31057,13 @@
 				Removes the item at index "idx" from the menu. Note that the indexes of items after the removed item are going to be shifted by one.
 				Removes the item at index "idx" from the menu. Note that the indexes of items after the removed item are going to be shifted by one.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="set_hide_on_item_selection">
+			<argument index="0" name="enable" type="bool">
+			</argument>
+			<description>
+				Sets whether or not the PopupMenu will hide on item selection.
+			</description>
+		</method>
 		<method name="set_item_ID">
 		<method name="set_item_ID">
 			<argument index="0" name="idx" type="int">
 			<argument index="0" name="idx" type="int">
 			</argument>
 			</argument>

+ 32 - 4
scene/gui/popup_menu.cpp

@@ -899,11 +899,24 @@ void PopupMenu::activate_item(int p_item) {
 	Node *next = get_parent();
 	Node *next = get_parent();
 	PopupMenu *pop = next->cast_to<PopupMenu>();
 	PopupMenu *pop = next->cast_to<PopupMenu>();
 	while (pop) {
 	while (pop) {
-		pop->hide();
-		next = next->get_parent();
-		pop = next->cast_to<PopupMenu>();
+		// We close all parents that are chained together, 
+		// with hide_on_item_selection enabled
+		if(hide_on_item_selection && pop->is_hide_on_item_selection()) {
+			pop->hide();
+			next = next->get_parent();
+			pop = next->cast_to<PopupMenu>();
+		}
+		else {
+			// Break out of loop when the next parent has 
+			// hide_on_item_selection disabled
+			break;
+		}
+	}
+	// Hides popup by default; unless otherwise specified 
+	// by using set_hide_on_item_selection
+	if (hide_on_item_selection) {
+		hide();
 	}
 	}
-	hide();
 
 
 }
 }
 
 
@@ -1019,6 +1032,16 @@ void PopupMenu::_set_items(const Array& p_items){
 
 
 }
 }
 
 
+// Hide on item selection determines whether or not the popup will close after item selection
+void PopupMenu::set_hide_on_item_selection(bool p_enabled) {
+
+	hide_on_item_selection=p_enabled;
+}
+
+bool PopupMenu::is_hide_on_item_selection() {
+
+	return hide_on_item_selection;
+}
 
 
 String PopupMenu::get_tooltip(const Point2& p_pos) const {
 String PopupMenu::get_tooltip(const Point2& p_pos) const {
 
 
@@ -1107,9 +1130,13 @@ void PopupMenu::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_set_items"),&PopupMenu::_set_items);
 	ObjectTypeDB::bind_method(_MD("_set_items"),&PopupMenu::_set_items);
 	ObjectTypeDB::bind_method(_MD("_get_items"),&PopupMenu::_get_items);
 	ObjectTypeDB::bind_method(_MD("_get_items"),&PopupMenu::_get_items);
 
 
+	ObjectTypeDB::bind_method(_MD("set_hide_on_item_selection","enable"),&PopupMenu::set_hide_on_item_selection);
+	ObjectTypeDB::bind_method(_MD("is_hide_on_item_selection"),&PopupMenu::is_hide_on_item_selection);
+
 	ObjectTypeDB::bind_method(_MD("_submenu_timeout"),&PopupMenu::_submenu_timeout);
 	ObjectTypeDB::bind_method(_MD("_submenu_timeout"),&PopupMenu::_submenu_timeout);
 
 
 	ADD_PROPERTY( PropertyInfo(Variant::ARRAY,"items",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR), _SCS("_set_items"),_SCS("_get_items") );
 	ADD_PROPERTY( PropertyInfo(Variant::ARRAY,"items",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR), _SCS("_set_items"),_SCS("_get_items") );
+	ADD_PROPERTYNO( PropertyInfo(Variant::BOOL, "hide_on_item_selection" ), _SCS("set_hide_on_item_selection"), _SCS("is_hide_on_item_selection") );
 
 
 	ADD_SIGNAL( MethodInfo("item_pressed", PropertyInfo( Variant::INT,"ID") ) );
 	ADD_SIGNAL( MethodInfo("item_pressed", PropertyInfo( Variant::INT,"ID") ) );
 
 
@@ -1128,6 +1155,7 @@ PopupMenu::PopupMenu() {
 
 
 	set_focus_mode(FOCUS_ALL);
 	set_focus_mode(FOCUS_ALL);
 	set_as_toplevel(true);
 	set_as_toplevel(true);
+	set_hide_on_item_selection(true);
 
 
 	submenu_timer = memnew( Timer );
 	submenu_timer = memnew( Timer );
 	submenu_timer->set_wait_time(0.3);
 	submenu_timer->set_wait_time(0.3);

+ 3 - 0
scene/gui/popup_menu.h

@@ -74,6 +74,7 @@ class PopupMenu : public Popup {
 	void _submenu_timeout();
 	void _submenu_timeout();
 
 
 	bool invalidated_click;
 	bool invalidated_click;
+	bool hide_on_item_selection;
 	Vector2 moved;
 	Vector2 moved;
 
 
 	Array _get_items() const;
 	Array _get_items() const;
@@ -153,6 +154,8 @@ public:
 	void clear_autohide_areas();
 	void clear_autohide_areas();
 
 
 	void set_invalidate_click_until_motion();
 	void set_invalidate_click_until_motion();
+	void set_hide_on_item_selection(bool p_enabled);
+	bool is_hide_on_item_selection();
 
 
 	PopupMenu();
 	PopupMenu();
 	~PopupMenu();
 	~PopupMenu();

+ 1 - 0
tools/editor/editor_node.cpp

@@ -5957,6 +5957,7 @@ EditorNode::EditorNode() {
 	debug_button->set_tooltip(TTR("Debug options"));
 	debug_button->set_tooltip(TTR("Debug options"));
 
 
 	p=debug_button->get_popup();
 	p=debug_button->get_popup();
+	p->set_hide_on_item_selection(false);
 	p->add_check_item(TTR("Deploy with Remote Debug"),RUN_DEPLOY_REMOTE_DEBUG);
 	p->add_check_item(TTR("Deploy with Remote Debug"),RUN_DEPLOY_REMOTE_DEBUG);
 	p->set_item_tooltip(p->get_item_count()-1,TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
 	p->set_item_tooltip(p->get_item_count()-1,TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
 	p->add_check_item(TTR("Small Deploy with Network FS"),RUN_FILE_SERVER);
 	p->add_check_item(TTR("Small Deploy with Network FS"),RUN_FILE_SERVER);