|
@@ -35,9 +35,9 @@
|
|
|
#include "core/input/input.h"
|
|
|
#include "core/os/keyboard.h"
|
|
|
#include "core/os/os.h"
|
|
|
-#include "core/string/print_string.h"
|
|
|
-#include "core/string/translation.h"
|
|
|
#include "scene/gui/menu_bar.h"
|
|
|
+#include "scene/gui/panel_container.h"
|
|
|
+#include "scene/resources/style_box_flat.h"
|
|
|
#include "scene/theme/theme_db.h"
|
|
|
|
|
|
HashMap<NativeMenu::SystemMenus, PopupMenu *> PopupMenu::system_menus;
|
|
@@ -223,6 +223,9 @@ Size2 PopupMenu::_get_item_icon_size(int p_idx) const {
|
|
|
Size2 PopupMenu::_get_contents_minimum_size() const {
|
|
|
Size2 minsize = theme_cache.panel_style->get_minimum_size();
|
|
|
minsize.width += scroll_container->get_v_scroll_bar()->get_size().width;
|
|
|
+ // Take shadows into account.
|
|
|
+ minsize.width += panel->get_offset(SIDE_LEFT) - panel->get_offset(SIDE_RIGHT);
|
|
|
+ minsize.height += panel->get_offset(SIDE_TOP) - panel->get_offset(SIDE_BOTTOM);
|
|
|
|
|
|
float max_w = 0.0;
|
|
|
float icon_w = 0.0;
|
|
@@ -313,17 +316,31 @@ int PopupMenu::_get_items_total_height() const {
|
|
|
}
|
|
|
|
|
|
int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
|
|
|
+ // Make the item area exclude shadows and the vertical margins and scrollbar.
|
|
|
+ Rect2 item_clickable_area = panel->get_global_rect();
|
|
|
+ if (scroll_container->get_v_scroll_bar()->is_visible_in_tree()) {
|
|
|
+ const int scroll_width = scroll_container->get_v_scroll_bar()->get_size().width;
|
|
|
+ if (is_layout_rtl()) {
|
|
|
+ item_clickable_area.position.x += scroll_width;
|
|
|
+ item_clickable_area.size.width -= scroll_width;
|
|
|
+ }
|
|
|
+ item_clickable_area.size.width -= scroll_width;
|
|
|
+ }
|
|
|
float win_scale = get_content_scale_factor();
|
|
|
- if (p_over.x < 0 || p_over.x >= get_size().width * win_scale || p_over.y < theme_cache.panel_style->get_margin(Side::SIDE_TOP) * win_scale) {
|
|
|
+ item_clickable_area.position.y = (item_clickable_area.position.y + theme_cache.panel_style->get_margin(SIDE_TOP)) * win_scale;
|
|
|
+ item_clickable_area.size.y -= theme_cache.panel_style->get_margin(SIDE_TOP) + theme_cache.panel_style->get_margin(SIDE_BOTTOM);
|
|
|
+ item_clickable_area.size *= win_scale;
|
|
|
+
|
|
|
+ if (p_over.x < item_clickable_area.position.x || p_over.x >= item_clickable_area.position.x + item_clickable_area.size.width ||
|
|
|
+ p_over.y < item_clickable_area.position.y || p_over.y >= item_clickable_area.position.y + item_clickable_area.size.height) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- Point2 ofs = Point2(0, theme_cache.v_separation * 0.5) * win_scale;
|
|
|
-
|
|
|
+ float ofs = item_clickable_area.position.y + theme_cache.v_separation * 0.5;
|
|
|
for (int i = 0; i < items.size(); i++) {
|
|
|
- ofs.y += i > 0 ? (float)theme_cache.v_separation * win_scale : (float)theme_cache.v_separation * win_scale * 0.5;
|
|
|
- ofs.y += _get_item_height(i) * win_scale;
|
|
|
- if (p_over.y - control->get_position().y * win_scale < ofs.y) {
|
|
|
+ ofs += i > 0 ? (float)theme_cache.v_separation * win_scale : (float)theme_cache.v_separation * win_scale * 0.5;
|
|
|
+ ofs += _get_item_height(i) * win_scale;
|
|
|
+ if (p_over.y - control->get_position().y * win_scale < ofs) {
|
|
|
return i;
|
|
|
}
|
|
|
}
|
|
@@ -332,35 +349,43 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
|
|
|
}
|
|
|
|
|
|
void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) {
|
|
|
- Popup *submenu_popup = items[p_over].submenu;
|
|
|
+ PopupMenu *submenu_popup = items[p_over].submenu;
|
|
|
if (submenu_popup->is_visible()) {
|
|
|
return; // Already visible.
|
|
|
}
|
|
|
|
|
|
- Point2 this_pos = get_position();
|
|
|
+ const float win_scale = get_content_scale_factor();
|
|
|
+
|
|
|
+ const Point2 panel_ofs_start = Point2(panel->get_offset(SIDE_LEFT), panel->get_offset(SIDE_TOP)) * win_scale;
|
|
|
+ const Point2 panel_ofs_end = Point2(panel->get_offset(SIDE_RIGHT), panel->get_offset(SIDE_BOTTOM)).abs() * win_scale;
|
|
|
+
|
|
|
+ const Point2 this_pos = get_position() + Point2(0, panel_ofs_start.y + theme_cache.panel_style->get_margin(SIDE_TOP) * win_scale);
|
|
|
Rect2 this_rect(this_pos, get_size());
|
|
|
|
|
|
- float scroll_offset = control->get_position().y;
|
|
|
- float scaled_ofs_cache = items[p_over]._ofs_cache * get_content_scale_factor();
|
|
|
- float scaled_height_cache = items[p_over]._height_cache * get_content_scale_factor();
|
|
|
+ const float scroll_offset = control->get_position().y;
|
|
|
+ const float scaled_ofs_cache = items[p_over]._ofs_cache * win_scale;
|
|
|
+ const float scaled_height_cache = items[p_over]._height_cache * win_scale;
|
|
|
|
|
|
submenu_popup->reset_size(); // Shrink the popup size to its contents.
|
|
|
- Size2 submenu_size = submenu_popup->get_size();
|
|
|
+ const Size2 submenu_size = submenu_popup->get_size();
|
|
|
|
|
|
- Point2 submenu_pos;
|
|
|
- if (control->is_layout_rtl()) {
|
|
|
- submenu_pos = this_pos + Point2(-submenu_size.width, scaled_ofs_cache + scroll_offset - theme_cache.v_separation / 2);
|
|
|
- } else {
|
|
|
- submenu_pos = this_pos + Point2(this_rect.size.width, scaled_ofs_cache + scroll_offset - theme_cache.v_separation / 2);
|
|
|
- }
|
|
|
+ // Calculate the submenu's position.
|
|
|
+ Point2 submenu_pos(0, -submenu_popup->get_theme_stylebox(SceneStringName(panel))->get_margin(SIDE_TOP) * submenu_popup->get_content_scale_factor());
|
|
|
+ Rect2i screen_rect = is_embedded() ? Rect2i(get_embedder()->get_visible_rect()) : get_parent_rect();
|
|
|
+ if (is_layout_rtl()) {
|
|
|
+ submenu_pos += this_pos + Point2(-submenu_size.width + panel_ofs_end.x, scaled_ofs_cache + scroll_offset - theme_cache.v_separation / 2);
|
|
|
+ if (submenu_pos.x < screen_rect.position.x) {
|
|
|
+ submenu_pos.x = this_pos.x + this_rect.size.width - panel_ofs_start.x;
|
|
|
+ }
|
|
|
|
|
|
- // Fix pos if going outside parent rect.
|
|
|
- if (submenu_pos.x < get_parent_rect().position.x) {
|
|
|
- submenu_pos.x = this_pos.x + submenu_size.width;
|
|
|
- }
|
|
|
+ this_rect.position.x += panel_ofs_end.x;
|
|
|
+ } else {
|
|
|
+ submenu_pos += this_pos + Point2(this_rect.size.width - panel_ofs_end.x, scaled_ofs_cache + scroll_offset - theme_cache.v_separation / 2);
|
|
|
+ if (submenu_pos.x + submenu_size.width > screen_rect.position.x + screen_rect.size.width) {
|
|
|
+ submenu_pos.x = this_pos.x - submenu_size.width + panel_ofs_start.x;
|
|
|
+ }
|
|
|
|
|
|
- if (submenu_pos.x + submenu_size.width > get_parent_rect().position.x + get_parent_rect().size.width) {
|
|
|
- submenu_pos.x = this_pos.x - submenu_size.width;
|
|
|
+ this_rect.position.x += panel_ofs_start.x;
|
|
|
}
|
|
|
|
|
|
submenu_popup->set_position(submenu_pos);
|
|
@@ -387,9 +412,7 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) {
|
|
|
|
|
|
// Set autohide areas.
|
|
|
|
|
|
- Rect2 safe_area = this_rect;
|
|
|
- safe_area.position.y += scaled_ofs_cache + scroll_offset + theme_cache.panel_style->get_offset().height - theme_cache.v_separation / 2;
|
|
|
- safe_area.size.y = scaled_height_cache + theme_cache.v_separation;
|
|
|
+ const Rect2 safe_area(get_position(), get_size());
|
|
|
Viewport *vp = submenu_popup->get_embedder();
|
|
|
if (vp) {
|
|
|
vp->subwindow_set_popup_safe_rect(submenu_popup, safe_area);
|
|
@@ -397,16 +420,18 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) {
|
|
|
DisplayServer::get_singleton()->window_set_popup_safe_rect(submenu_popup->get_window_id(), safe_area);
|
|
|
}
|
|
|
|
|
|
- // Make the position of the parent popup relative to submenu popup.
|
|
|
- this_rect.position = this_rect.position - submenu_pum->get_position();
|
|
|
+ this_rect.position -= submenu_pum->get_position(); // Make the position of the parent popup relative to submenu popup.
|
|
|
+ this_rect.size.width -= panel_ofs_start.x + panel_ofs_end.x;
|
|
|
+ this_rect.size.height -= panel_ofs_end.y + (theme_cache.panel_style->get_margin(SIDE_TOP) + theme_cache.panel_style->get_margin(SIDE_BOTTOM)) * win_scale;
|
|
|
|
|
|
// Autohide area above the submenu item.
|
|
|
submenu_pum->clear_autohide_areas();
|
|
|
- submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y, this_rect.size.x, scaled_ofs_cache + scroll_offset + theme_cache.panel_style->get_offset().height - theme_cache.v_separation / 2));
|
|
|
+ submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y - theme_cache.panel_style->get_margin(SIDE_TOP) * win_scale,
|
|
|
+ this_rect.size.x, scaled_ofs_cache + scroll_offset + theme_cache.panel_style->get_margin(SIDE_TOP) * win_scale - theme_cache.v_separation / 2));
|
|
|
|
|
|
// If there is an area below the submenu item, add an autohide area there.
|
|
|
if (scaled_ofs_cache + scaled_height_cache + scroll_offset <= control->get_size().height) {
|
|
|
- int from = scaled_ofs_cache + scaled_height_cache + scroll_offset + theme_cache.v_separation / 2 + theme_cache.panel_style->get_offset().height;
|
|
|
+ const int from = scaled_ofs_cache + scaled_height_cache + scroll_offset + theme_cache.v_separation / 2;
|
|
|
submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y + from, this_rect.size.x, this_rect.size.y - from));
|
|
|
}
|
|
|
}
|
|
@@ -446,7 +471,7 @@ void PopupMenu::_input_from_window(const Ref<InputEvent> &p_event) {
|
|
|
if (p_event.is_valid()) {
|
|
|
_input_from_window_internal(p_event);
|
|
|
} else {
|
|
|
- WARN_PRINT_ONCE("PopupMenu has received an invalid InputEvent. Consider filtering invalid events out.");
|
|
|
+ WARN_PRINT_ONCE("PopupMenu has received an invalid InputEvent. Consider filtering out invalid events.");
|
|
|
}
|
|
|
Popup::_input_from_window(p_event);
|
|
|
}
|
|
@@ -570,15 +595,19 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Make an area which does not include v scrollbar, so that items are not activated when dragging scrollbar.
|
|
|
- Rect2 item_clickable_area = scroll_container->get_rect();
|
|
|
+ // Make the item area exclude shadows and the vertical margins and scrollbar.
|
|
|
+ Rect2 item_clickable_area = panel->get_global_rect();
|
|
|
if (scroll_container->get_v_scroll_bar()->is_visible_in_tree()) {
|
|
|
+ int scroll_width = scroll_container->get_v_scroll_bar()->get_size().width;
|
|
|
if (is_layout_rtl()) {
|
|
|
- item_clickable_area.position.x += scroll_container->get_v_scroll_bar()->get_size().width;
|
|
|
+ item_clickable_area.position.x += scroll_width;
|
|
|
+ item_clickable_area.size.width -= scroll_width;
|
|
|
}
|
|
|
- item_clickable_area.size.width -= scroll_container->get_v_scroll_bar()->get_size().width;
|
|
|
+ item_clickable_area.size.width -= scroll_width;
|
|
|
}
|
|
|
- item_clickable_area.size = item_clickable_area.size * get_content_scale_factor();
|
|
|
+ item_clickable_area.position.y = (item_clickable_area.position.y + theme_cache.panel_style->get_margin(SIDE_TOP)) * get_content_scale_factor();
|
|
|
+ item_clickable_area.size.y -= theme_cache.panel_style->get_margin(SIDE_TOP) + theme_cache.panel_style->get_margin(SIDE_BOTTOM);
|
|
|
+ item_clickable_area.size *= get_content_scale_factor();
|
|
|
|
|
|
Ref<InputEventMouseButton> b = p_event;
|
|
|
|
|
@@ -592,9 +621,16 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) {
|
|
|
during_grabbed_click = false;
|
|
|
is_scrolling = is_layout_rtl() ? b->get_position().x < item_clickable_area.position.x : b->get_position().x > item_clickable_area.size.width;
|
|
|
|
|
|
+ // Hide it if the shadows have been clicked.
|
|
|
+ if (get_flag(FLAG_POPUP) && !panel->get_global_rect().has_point(b->get_position())) {
|
|
|
+ _close_pressed();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
if (!item_clickable_area.has_point(b->get_position())) {
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
_mouse_over_update(b->get_position());
|
|
|
} else {
|
|
|
if (is_scrolling) {
|
|
@@ -608,6 +644,7 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) {
|
|
|
if (!item_clickable_area.has_point(b->get_position())) {
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
// Disable clicks under a time threshold to avoid selection right when opening the popup.
|
|
|
if (was_during_grabbed_click && OS::get_singleton()->get_ticks_msec() - popup_time_msec < 400) {
|
|
|
return;
|
|
@@ -643,7 +680,7 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) {
|
|
|
activated_by_keyboard = false;
|
|
|
|
|
|
for (const Rect2 &E : autohide_areas) {
|
|
|
- if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E.has_point(m->get_position())) {
|
|
|
+ if (!scroll_container->get_global_rect().has_point(m->get_position()) && E.has_point(m->get_position())) {
|
|
|
// The mouse left the safe area, prepare to close.
|
|
|
_close_pressed();
|
|
|
return;
|
|
@@ -655,7 +692,7 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) {
|
|
|
minimum_lifetime_timer->stop();
|
|
|
}
|
|
|
|
|
|
- if (!item_clickable_area.has_point(m->get_position())) {
|
|
|
+ if (mouse_over == -1 && !item_clickable_area.has_point(m->get_position())) {
|
|
|
return;
|
|
|
}
|
|
|
_mouse_over_update(m->get_position());
|
|
@@ -971,6 +1008,57 @@ void PopupMenu::_menu_changed() {
|
|
|
emit_signal(SNAME("menu_changed"));
|
|
|
}
|
|
|
|
|
|
+void PopupMenu::_update_shadow_offsets() const {
|
|
|
+ if (!DisplayServer::get_singleton()->is_window_transparency_available() && !is_embedded()) {
|
|
|
+ panel->set_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Ref<StyleBoxFlat> sb = theme_cache.panel_style;
|
|
|
+ if (sb.is_null()) {
|
|
|
+ panel->set_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const int shadow_size = sb->get_shadow_size();
|
|
|
+ if (shadow_size == 0) {
|
|
|
+ panel->set_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Offset the background panel so it leaves space inside the window for the shadows to be drawn.
|
|
|
+ const Point2 shadow_offset = sb->get_shadow_offset();
|
|
|
+ if (is_layout_rtl()) {
|
|
|
+ panel->set_offset(SIDE_LEFT, shadow_size + shadow_offset.x);
|
|
|
+ panel->set_offset(SIDE_RIGHT, -shadow_size + shadow_offset.x);
|
|
|
+ } else {
|
|
|
+ panel->set_offset(SIDE_LEFT, shadow_size - shadow_offset.x);
|
|
|
+ panel->set_offset(SIDE_RIGHT, -shadow_size - shadow_offset.x);
|
|
|
+ }
|
|
|
+ panel->set_offset(SIDE_TOP, shadow_size - shadow_offset.y);
|
|
|
+ panel->set_offset(SIDE_BOTTOM, -shadow_size - shadow_offset.y);
|
|
|
+}
|
|
|
+
|
|
|
+Rect2i PopupMenu::_popup_adjust_rect() const {
|
|
|
+ Rect2i current = Popup::_popup_adjust_rect();
|
|
|
+ if (current == Rect2i()) {
|
|
|
+ return current;
|
|
|
+ }
|
|
|
+
|
|
|
+ pre_popup_rect = current;
|
|
|
+
|
|
|
+ _update_shadow_offsets();
|
|
|
+
|
|
|
+ if (is_layout_rtl()) {
|
|
|
+ current.position -= Vector2(ABS(panel->get_offset(SIDE_RIGHT)), panel->get_offset(SIDE_TOP)) * get_content_scale_factor();
|
|
|
+ } else {
|
|
|
+ current.position -= Vector2(panel->get_offset(SIDE_LEFT), panel->get_offset(SIDE_TOP)) * get_content_scale_factor();
|
|
|
+ }
|
|
|
+ current.size += Vector2(panel->get_offset(SIDE_LEFT) - panel->get_offset(SIDE_RIGHT), panel->get_offset(SIDE_TOP) - panel->get_offset(SIDE_BOTTOM)) * get_content_scale_factor();
|
|
|
+
|
|
|
+ return current;
|
|
|
+}
|
|
|
+
|
|
|
void PopupMenu::add_child_notify(Node *p_child) {
|
|
|
Window::add_child_notify(p_child);
|
|
|
|
|
@@ -1018,6 +1106,13 @@ void PopupMenu::_notification(int p_what) {
|
|
|
if (system_menu_id != NativeMenu::INVALID_MENU_ID) {
|
|
|
bind_global_menu();
|
|
|
}
|
|
|
+
|
|
|
+ if (!Engine::get_singleton()->is_editor_hint() && !DisplayServer::get_singleton()->is_window_transparency_available() && !is_embedded()) {
|
|
|
+ Ref<StyleBoxFlat> sb = theme_cache.panel_style;
|
|
|
+ if (sb.is_valid() && (sb->get_shadow_size() > 0 || sb->get_corner_radius(CORNER_TOP_LEFT) > 0 || sb->get_corner_radius(CORNER_TOP_RIGHT) > 0 || sb->get_corner_radius(CORNER_BOTTOM_LEFT) > 0 || sb->get_corner_radius(CORNER_BOTTOM_RIGHT) > 0)) {
|
|
|
+ WARN_PRINT_ONCE("The current theme styles PopupMenu to have shadows and/or rounded corners, but those won't display correctly if 'display/window/per_pixel_transparency/allowed' isn't enabled in the Project Settings, nor if it isn't supported.");
|
|
|
+ }
|
|
|
+ }
|
|
|
} break;
|
|
|
|
|
|
case NOTIFICATION_EXIT_TREE: {
|
|
@@ -1026,12 +1121,16 @@ void PopupMenu::_notification(int p_what) {
|
|
|
}
|
|
|
} break;
|
|
|
|
|
|
+ case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
|
|
case NOTIFICATION_THEME_CHANGED: {
|
|
|
- scroll_container->add_theme_style_override(SceneStringName(panel), theme_cache.panel_style);
|
|
|
+ panel->add_theme_style_override(SceneStringName(panel), theme_cache.panel_style);
|
|
|
+
|
|
|
+ if (is_visible()) {
|
|
|
+ _update_shadow_offsets();
|
|
|
+ }
|
|
|
|
|
|
[[fallthrough]];
|
|
|
}
|
|
|
- case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
|
|
case NOTIFICATION_TRANSLATION_CHANGED: {
|
|
|
NativeMenu *nmenu = NativeMenu::get_singleton();
|
|
|
bool is_global = global_menu.is_valid();
|
|
@@ -1064,6 +1163,17 @@ void PopupMenu::_notification(int p_what) {
|
|
|
}
|
|
|
} break;
|
|
|
|
|
|
+ case NOTIFICATION_WM_SIZE_CHANGED: {
|
|
|
+ if (is_visible()) {
|
|
|
+ const Vector2i offsets = Vector2i(panel->get_offset(SIDE_LEFT) - panel->get_offset(SIDE_RIGHT), panel->get_offset(SIDE_TOP) - panel->get_offset(SIDE_BOTTOM));
|
|
|
+ // Check if the size actually changed.
|
|
|
+ if (pre_popup_rect.size + offsets != get_size()) {
|
|
|
+ // Play safe, and stick with the new size.
|
|
|
+ pre_popup_rect = Rect2i();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } break;
|
|
|
+
|
|
|
case NOTIFICATION_POST_POPUP: {
|
|
|
popup_time_msec = OS::get_singleton()->get_ticks_msec();
|
|
|
initial_button_mask = Input::get_singleton()->get_mouse_button_mask();
|
|
@@ -1176,10 +1286,25 @@ void PopupMenu::_notification(int p_what) {
|
|
|
}
|
|
|
|
|
|
set_process_internal(false);
|
|
|
+
|
|
|
+ // Remove the extra space used by the shadows, so they can be ignored when the popup is hidden.
|
|
|
+ panel->set_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 0);
|
|
|
+
|
|
|
+ if (pre_popup_rect != Rect2i()) {
|
|
|
+ set_position(pre_popup_rect.position);
|
|
|
+ set_size(pre_popup_rect.size);
|
|
|
+
|
|
|
+ pre_popup_rect = Rect2i();
|
|
|
+ }
|
|
|
} else {
|
|
|
if (!is_embedded()) {
|
|
|
set_process_internal(true);
|
|
|
}
|
|
|
+
|
|
|
+ // The popup was made visible directly (without `popup_*()`), so just update the offsets without touching the rect.
|
|
|
+ if (pre_popup_rect == Rect2i()) {
|
|
|
+ _update_shadow_offsets();
|
|
|
+ }
|
|
|
}
|
|
|
} break;
|
|
|
}
|
|
@@ -2868,11 +2993,17 @@ void PopupMenu::set_visible(bool p_visible) {
|
|
|
}
|
|
|
|
|
|
PopupMenu::PopupMenu() {
|
|
|
+ set_flag(FLAG_TRANSPARENT, true);
|
|
|
+
|
|
|
+ // The panel used to draw the panel style.
|
|
|
+ panel = memnew(PanelContainer);
|
|
|
+ panel->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
|
|
|
+ add_child(panel, false, INTERNAL_MODE_FRONT);
|
|
|
+
|
|
|
// Scroll Container
|
|
|
scroll_container = memnew(ScrollContainer);
|
|
|
scroll_container->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
|
|
|
- scroll_container->set_clip_contents(true);
|
|
|
- add_child(scroll_container, false, INTERNAL_MODE_FRONT);
|
|
|
+ panel->add_child(scroll_container, false, INTERNAL_MODE_FRONT);
|
|
|
|
|
|
// The control which will display the items
|
|
|
control = memnew(Control);
|