Browse Source

Merge pull request #66711 from rsubtil/port_popup_menu_rework

[3.x] PopupMenu rework and enhancements
Rémi Verschelde 2 years ago
parent
commit
dd7f517407
3 changed files with 346 additions and 314 deletions
  1. 3 0
      doc/classes/PopupMenu.xml
  2. 318 313
      scene/gui/popup_menu.cpp
  3. 25 1
      scene/gui/popup_menu.h

+ 3 - 0
doc/classes/PopupMenu.xml

@@ -478,6 +478,9 @@
 		<member name="hide_on_state_item_selection" type="bool" setter="set_hide_on_state_item_selection" getter="is_hide_on_state_item_selection" default="false">
 		<member name="hide_on_state_item_selection" type="bool" setter="set_hide_on_state_item_selection" getter="is_hide_on_state_item_selection" default="false">
 			If [code]true[/code], hides the [PopupMenu] when a state item is selected.
 			If [code]true[/code], hides the [PopupMenu] when a state item is selected.
 		</member>
 		</member>
+		<member name="max_height" type="float" setter="set_max_height" getter="get_max_height" default="0.0">
+			If non-zero, the [code]PopupMenu[/code] will be resized vertically to that maximum value, showing a scrollbar if the content doesn't fit.
+		</member>
 		<member name="submenu_popup_delay" type="float" setter="set_submenu_popup_delay" getter="get_submenu_popup_delay" default="0.3">
 		<member name="submenu_popup_delay" type="float" setter="set_submenu_popup_delay" getter="get_submenu_popup_delay" default="0.3">
 			Sets the delay time in seconds for the submenu item to popup on mouse hovering. If the popup menu is added as a child of another (acting as a submenu), it will inherit the delay time of the parent menu item.
 			Sets the delay time in seconds for the submenu item to popup on mouse hovering. If the popup menu is added as a child of another (acting as a submenu), it will inherit the delay time of the parent menu item.
 		</member>
 		</member>

File diff suppressed because it is too large
+ 318 - 313
scene/gui/popup_menu.cpp


+ 25 - 1
scene/gui/popup_menu.h

@@ -31,7 +31,10 @@
 #ifndef POPUP_MENU_H
 #ifndef POPUP_MENU_H
 #define POPUP_MENU_H
 #define POPUP_MENU_H
 
 
+#include "scene/gui/margin_container.h"
 #include "scene/gui/popup.h"
 #include "scene/gui/popup.h"
+#include "scene/gui/scroll_container.h"
+#include "scene/gui/shortcut.h"
 
 
 class PopupMenu : public Popup {
 class PopupMenu : public Popup {
 	GDCLASS(PopupMenu, Popup);
 	GDCLASS(PopupMenu, Popup);
@@ -56,11 +59,17 @@ class PopupMenu : public Popup {
 		String tooltip;
 		String tooltip;
 		uint32_t accel;
 		uint32_t accel;
 		int _ofs_cache;
 		int _ofs_cache;
+		int _height_cache;
 		int h_ofs;
 		int h_ofs;
 		Ref<ShortCut> shortcut;
 		Ref<ShortCut> shortcut;
 		bool shortcut_is_global;
 		bool shortcut_is_global;
 		bool shortcut_is_disabled;
 		bool shortcut_is_disabled;
 
 
+		// Returns (0,0) if icon is null.
+		Size2 get_icon_size() const {
+			return icon.is_null() ? Size2() : icon->get_size();
+		}
+
 		Item() {
 		Item() {
 			checked = false;
 			checked = false;
 			checkable_type = CHECKABLE_TYPE_NONE;
 			checkable_type = CHECKABLE_TYPE_NONE;
@@ -70,6 +79,7 @@ class PopupMenu : public Popup {
 			accel = 0;
 			accel = 0;
 			disabled = false;
 			disabled = false;
 			_ofs_cache = 0;
 			_ofs_cache = 0;
+			_height_cache = 0;
 			h_ofs = 0;
 			h_ofs = 0;
 			shortcut_is_global = false;
 			shortcut_is_global = false;
 			shortcut_is_disabled = false;
 			shortcut_is_disabled = false;
@@ -89,7 +99,10 @@ class PopupMenu : public Popup {
 	String _get_accel_text(int p_item) const;
 	String _get_accel_text(int p_item) const;
 	int _get_mouse_over(const Point2 &p_over) const;
 	int _get_mouse_over(const Point2 &p_over) const;
 	virtual Size2 get_minimum_size() const;
 	virtual Size2 get_minimum_size() const;
-	void _scroll(float p_factor, const Point2 &p_over);
+
+	int _get_items_total_height() const;
+	void _scroll_to_item(int p_item);
+
 	void _gui_input(const Ref<InputEvent> &p_event);
 	void _gui_input(const Ref<InputEvent> &p_event);
 	void _activate_submenu(int over, bool p_by_keyboard = false);
 	void _activate_submenu(int over, bool p_by_keyboard = false);
 	void _submenu_timeout();
 	void _submenu_timeout();
@@ -113,6 +126,14 @@ class PopupMenu : public Popup {
 	uint64_t search_time_msec;
 	uint64_t search_time_msec;
 	String search_string;
 	String search_string;
 
 
+	MarginContainer *margin_container;
+	ScrollContainer *scroll_container;
+	Control *control;
+	real_t max_height;
+
+	void _draw_items();
+	void _draw_background();
+
 protected:
 protected:
 	virtual bool has_point(const Point2 &p_point) const;
 	virtual bool has_point(const Point2 &p_point) const;
 
 
@@ -215,6 +236,9 @@ public:
 	void set_allow_search(bool p_allow);
 	void set_allow_search(bool p_allow);
 	bool get_allow_search() const;
 	bool get_allow_search() const;
 
 
+	void set_max_height(real_t p_max_height);
+	real_t get_max_height() const;
+
 	virtual void popup(const Rect2 &p_bounds = Rect2());
 	virtual void popup(const Rect2 &p_bounds = Rect2());
 
 
 	void set_hide_on_window_lose_focus(bool p_enabled);
 	void set_hide_on_window_lose_focus(bool p_enabled);

Some files were not shown because too many files changed in this diff