summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2020-03-19 23:32:09 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-03-26 15:49:44 +0100
commitb3080bc2f4d7bc5c15b3a0ff7b67690c4677577e (patch)
tree0487e2d739133015048b1e0dd1fd9abaf7bbb18a /scene/gui
parent09ba290364aaa5b54528e82144ec0a40e10b497b (diff)
Popups have also been converted to windows
Controls using the old modal API have been replaced to use popups.
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/color_picker.cpp33
-rw-r--r--scene/gui/control.cpp5
-rw-r--r--scene/gui/menu_button.cpp1
-rw-r--r--scene/gui/popup.cpp35
-rw-r--r--scene/gui/popup.h4
-rw-r--r--scene/gui/popup_menu.cpp64
-rw-r--r--scene/gui/popup_menu.h2
-rw-r--r--scene/gui/tree.cpp63
-rw-r--r--scene/gui/tree.h8
9 files changed, 166 insertions, 49 deletions
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 948e46b649..2ec9bb2292 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -247,6 +247,9 @@ void ColorPicker::_update_color(bool p_update_sliders) {
}
void ColorPicker::_update_presets() {
+ return;
+ //presets should be shown using buttons or something else, this method is not a good idea
+
presets_per_row = 10;
Size2 size = bt_add_preset->get_size();
Size2 preset_size = Size2(MIN(size.width * presets.size(), presets_per_row * size.width), size.height * (Math::ceil((float)presets.size() / presets_per_row)));
@@ -884,8 +887,32 @@ void ColorPickerButton::_modal_closed() {
void ColorPickerButton::pressed() {
_update_picker();
- popup->set_position(get_screen_position() - picker->get_combined_minimum_size() * get_global_transform().get_scale());
- //popup->set_scale(get_global_transform().get_scale());
+
+ popup->set_as_minsize();
+
+ Rect2i usable_rect = popup->get_usable_parent_rect();
+ //let's try different positions to see which one we can use
+
+ Rect2i cp_rect(Point2i(), popup->get_size());
+ for (int i = 0; i < 4; i++) {
+ if (i > 1) {
+ cp_rect.position.y = get_screen_position().y - cp_rect.size.y;
+ } else {
+ cp_rect.position.y = get_screen_position().y + get_size().height;
+ }
+
+ if (i & 1) {
+ cp_rect.position.x = get_screen_position().x;
+ } else {
+
+ cp_rect.position.x = get_screen_position().x - MAX(0, (cp_rect.size.x - get_size().x));
+ }
+
+ if (usable_rect.encloses(cp_rect)) {
+ break;
+ }
+ }
+ popup->set_position(cp_rect.position);
popup->popup();
picker->set_focus_on_line_edit();
}
@@ -961,7 +988,9 @@ PopupPanel *ColorPickerButton::get_popup() {
void ColorPickerButton::_update_picker() {
if (!picker) {
popup = memnew(PopupPanel);
+ popup->set_wrap_controls(true);
picker = memnew(ColorPicker);
+ picker->set_anchors_and_margins_preset(PRESET_WIDE);
popup->add_child(picker);
add_child(popup);
picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed));
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index bfaace69d7..14bca0e2c8 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -625,7 +625,7 @@ void Control::_notification(int p_notification) {
get_viewport()->_gui_hid_control(this);
//remove key focus
- //remove modalness
+
} else {
data.minimum_size_valid = false;
_size_changed();
@@ -2117,9 +2117,6 @@ void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_o
Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr;
- if (c && c != p_owner && c->data.theme.is_valid()) // has a theme, this can't be propagated
- return;
-
if (w && w != p_owner_window && w->theme.is_valid()) // has a theme, this can't be propagated
return;
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index 61441ff958..ba1f651b5c 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -63,6 +63,7 @@ void MenuButton::pressed() {
popup->set_size(Size2(size.width, 0));
popup->set_parent_rect(Rect2(Point2(gp - popup->get_position()), get_size()));
+ popup->take_mouse_focus();
popup->popup();
}
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 4ed87ff42f..77843262e1 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -42,6 +42,7 @@ void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
}
void Popup::_parent_focused() {
+
_close_pressed();
}
void Popup::_notification(int p_what) {
@@ -72,6 +73,7 @@ void Popup::_notification(int p_what) {
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
_close_pressed();
+
} break;
}
}
@@ -101,6 +103,35 @@ void Popup::_bind_methods() {
ADD_SIGNAL(MethodInfo("popup_hide"));
}
+Rect2i Popup::_popup_adjust_rect() const {
+ ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
+ Rect2i parent = get_usable_parent_rect();
+
+ if (parent == Rect2i()) {
+ return Rect2i();
+ }
+
+ Rect2i current(get_position(), get_size());
+
+ if (current.position.x + current.size.x > parent.position.x + parent.size.x) {
+ current.position.x = parent.position.x + parent.size.x - current.size.x;
+ }
+
+ if (current.position.x < parent.position.x) {
+ current.position.x = parent.position.x;
+ }
+
+ if (current.position.y + current.size.y > parent.position.y + parent.size.y) {
+ current.position.y = parent.position.y + parent.size.y - current.size.y;
+ }
+
+ if (current.position.y < parent.position.y) {
+ current.position.y = parent.position.y;
+ }
+
+ return current;
+}
+
Popup::Popup() {
parent_visible = nullptr;
@@ -166,7 +197,9 @@ void PopupPanel::_update_child_rects() {
void PopupPanel::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_ENTER_TREE) {
+ if (p_what == NOTIFICATION_THEME_CHANGED) {
+ panel->add_theme_style_override("panel", get_theme_stylebox("panel", "PopupPanel"));
+ } else if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_ENTER_TREE) {
panel->add_theme_style_override("panel", get_theme_stylebox("panel", "PopupPanel"));
_update_child_rects();
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 20b355bc18..6cd2b4028f 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -41,9 +41,11 @@ class Popup : public Window {
void _input_from_window(const Ref<InputEvent> &p_event);
void _parent_focused();
- void _close_pressed();
protected:
+ void _close_pressed();
+ virtual Rect2i _popup_adjust_rect() const;
+
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index e325f2661a..c096dc94cb 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -185,6 +185,9 @@ void PopupMenu::_activate_submenu(int over) {
void PopupMenu::_submenu_timeout() {
+ //if (!has_focus()) {
+ // return; //do not activate if not has focus
+ //}
if (mouse_over == submenu_over)
_activate_submenu(mouse_over);
@@ -196,17 +199,24 @@ void PopupMenu::_scroll(float p_factor, const Point2 &p_over) {
int vseparation = get_theme_constant("vseparation");
Ref<Font> font = get_theme_font("font");
- float dy = (vseparation + font->get_height()) * 3 * p_factor;
+ Rect2 visible_rect = get_usable_parent_rect();
+
+ int dy = (vseparation + font->get_height()) * 3 * p_factor;
if (dy > 0) {
const float global_top = get_position().y;
- const float limit = global_top < 0 ? -global_top : 0;
+ const float limit = global_top < visible_rect.position.y ? visible_rect.position.y - global_top : 0;
dy = MIN(dy, limit);
} else if (dy < 0) {
const float global_bottom = get_position().y + get_size().y;
- const float viewport_height = get_parent_rect().size.y;
+ const float viewport_height = visible_rect.position.y + visible_rect.size.y;
const float limit = global_bottom > viewport_height ? global_bottom - viewport_height : 0;
dy = -MIN(-dy, limit);
}
+
+ if (dy == 0) {
+ return;
+ }
+
set_position(get_position() + Vector2(0, dy));
Ref<InputEventMouseMotion> ie;
@@ -295,15 +305,11 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
case BUTTON_WHEEL_DOWN: {
- if (get_position().y + get_size().y > get_parent_rect().size.y) {
- _scroll(-b->get_factor(), b->get_position());
- }
+ _scroll(-b->get_factor(), b->get_position());
} break;
case BUTTON_WHEEL_UP: {
- if (get_position().y < 0) {
- _scroll(b->get_factor(), b->get_position());
- }
+ _scroll(b->get_factor(), b->get_position());
} break;
default: {
// Allow activating item by releasing the LMB or any that was down when the popup appeared
@@ -355,7 +361,8 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) {
if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E->get().has_point(m->get_position())) {
- call_deferred("hide");
+
+ _close_pressed();
return;
}
}
@@ -382,9 +389,7 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventPanGesture> pan_gesture = p_event;
if (pan_gesture.is_valid()) {
- if (get_position().y + get_size().y > get_parent_rect().size.y || get_position().y < 0) {
- _scroll(-pan_gesture->get_delta().y, pan_gesture->get_position());
- }
+ _scroll(-pan_gesture->get_delta().y, pan_gesture->get_position());
}
Ref<InputEventKey> k = p_event;
@@ -578,7 +583,7 @@ void PopupMenu::_notification(int p_what) {
} break;
case NOTIFICATION_WM_MOUSE_ENTER: {
- grab_focus();
+ //grab_focus();
} break;
case NOTIFICATION_WM_MOUSE_EXIT: {
@@ -595,6 +600,21 @@ void PopupMenu::_notification(int p_what) {
case NOTIFICATION_WM_SIZE_CHANGED: {
} break;
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ //only used when using operating system windows
+ if (get_window_id() != DisplayServer::INVALID_WINDOW_ID && autohide_areas.size()) {
+ Point2 mouse_pos = DisplayServer::get_singleton()->mouse_get_position();
+ mouse_pos -= get_position();
+
+ for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) {
+
+ if (!Rect2(Point2(), get_size()).has_point(mouse_pos) && E->get().has_point(mouse_pos)) {
+ _close_pressed();
+ return;
+ }
+ }
+ }
+ } break;
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible()) {
@@ -617,6 +637,12 @@ void PopupMenu::_notification(int p_what) {
pm->hide();
}
+
+ set_process_internal(false);
+ } else {
+ if (get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
+ set_process_internal(true);
+ }
}
} break;
}
@@ -1366,6 +1392,14 @@ void PopupMenu::clear_autohide_areas() {
autohide_areas.clear();
}
+void PopupMenu::take_mouse_focus() {
+ ERR_FAIL_COND(!is_inside_tree());
+
+ if (get_parent()) {
+ get_parent()->get_viewport()->pass_mouse_focus_to(this, control);
+ }
+}
+
void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &PopupMenu::_gui_input);
@@ -1473,7 +1507,7 @@ PopupMenu::PopupMenu() {
add_child(control);
control->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- control->connect("gui_input", callable_mp(this, &PopupMenu::_gui_input));
+ connect("window_input", callable_mp(this, &PopupMenu::_gui_input));
control->connect("draw", callable_mp(this, &PopupMenu::_draw));
mouse_over = -1;
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 511c630ad2..2eef1f009d 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -215,6 +215,8 @@ public:
virtual void popup(const Rect2 &p_bounds = Rect2());
+ void take_mouse_focus();
+
PopupMenu();
~PopupMenu();
};
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 38ae1f36bc..653ac74164 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -38,6 +38,8 @@
#include "core/project_settings.h"
#include "scene/main/window.h"
+#include "box_container.h"
+
#ifdef TOOLS_ENABLED
#include "editor/editor_scale.h"
#endif
@@ -2056,13 +2058,12 @@ void Tree::_text_editor_modal_close() {
if (value_editor->has_point(value_editor->get_local_mouse_position()))
return;
- text_editor_enter(text_editor->get_text());
+ _text_editor_enter(text_editor->get_text());
}
-void Tree::text_editor_enter(String p_text) {
+void Tree::_text_editor_enter(String p_text) {
- text_editor->hide();
- value_editor->hide();
+ popup_editor->hide();
if (!popup_edited_item)
return;
@@ -2806,22 +2807,22 @@ bool Tree::edit_selected() {
} else if (c.mode == TreeItem::CELL_MODE_STRING || c.mode == TreeItem::CELL_MODE_RANGE) {
+ Rect2 popup_rect;
+
Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2);
- Point2i textedpos = get_global_position() + rect.position - ofs;
+
+ Point2i textedpos = get_screen_position() + rect.position - ofs;
cache.text_editor_position = textedpos;
- text_editor->set_position(textedpos);
- text_editor->set_size(rect.size);
+ popup_rect.position = textedpos;
+ popup_rect.size = rect.size;
text_editor->clear();
text_editor->set_text(c.mode == TreeItem::CELL_MODE_STRING ? c.text : String::num(c.val, Math::range_step_decimals(c.step)));
text_editor->select_all();
if (c.mode == TreeItem::CELL_MODE_RANGE) {
- value_editor->set_position(textedpos + Point2i(0, text_editor->get_size().height));
- value_editor->set_size(Size2(rect.size.width, 1));
-#ifndef _MSC_VER
-#warning show modal no longer works, need to replace by a popup
-#endif
+ popup_rect.size.y += value_editor->get_minimum_size().height;
+
value_editor->show();
updating_value_editor = true;
value_editor->set_min(c.min);
@@ -2830,12 +2831,17 @@ bool Tree::edit_selected() {
value_editor->set_value(c.val);
value_editor->set_exp_ratio(c.expr);
updating_value_editor = false;
+ } else {
+ value_editor->hide();
}
-#ifndef _MSC_VER
-#warning show modal no longer works, need to replace by a popup
-#endif
- text_editor->show();
+
+ popup_editor->set_position(popup_rect.position);
+ popup_editor->set_size(popup_rect.size);
+ popup_editor->popup();
+ popup_editor->child_controls_changed();
+
text_editor->grab_focus();
+
return true;
}
@@ -4026,13 +4032,22 @@ Tree::Tree() {
popup_menu->hide();
add_child(popup_menu);
// popup_menu->set_as_toplevel(true);
+
+ popup_editor = memnew(PopupPanel);
+ popup_editor->set_wrap_controls(true);
+ add_child(popup_editor);
+ popup_editor_vb = memnew(VBoxContainer);
+ popup_editor->add_child(popup_editor_vb);
+ popup_editor_vb->add_theme_constant_override("separation", 0);
+ popup_editor_vb->set_anchors_and_margins_preset(PRESET_WIDE);
text_editor = memnew(LineEdit);
- add_child(text_editor);
- text_editor->set_as_toplevel(true);
- text_editor->hide();
+ popup_editor_vb->add_child(text_editor);
+ text_editor->set_v_size_flags(SIZE_EXPAND_FILL);
+ text_editor->set_h_size_flags(SIZE_EXPAND_FILL);
value_editor = memnew(HSlider);
- add_child(value_editor);
- value_editor->set_as_toplevel(true);
+ value_editor->set_v_size_flags(SIZE_EXPAND_FILL);
+ value_editor->set_h_size_flags(SIZE_EXPAND_FILL);
+ popup_editor_vb->add_child(value_editor);
value_editor->hide();
h_scroll = memnew(HScrollBar);
@@ -4047,13 +4062,11 @@ Tree::Tree() {
h_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved));
v_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved));
- text_editor->connect("text_entered", callable_mp(this, &Tree::text_editor_enter));
- text_editor->connect("modal_closed", callable_mp(this, &Tree::_text_editor_modal_close));
+ text_editor->connect("text_entered", callable_mp(this, &Tree::_text_editor_enter));
+ popup_editor->connect("popup_hide", callable_mp(this, &Tree::_text_editor_modal_close));
popup_menu->connect("id_pressed", callable_mp(this, &Tree::popup_select));
value_editor->connect("value_changed", callable_mp(this, &Tree::value_editor_changed));
- value_editor->set_as_toplevel(true);
- text_editor->set_as_toplevel(true);
set_notify_transform(true);
updating_value_editor = false;
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index b179c5bcba..becbe76598 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -290,6 +290,8 @@ public:
VARIANT_ENUM_CAST(TreeItem::TreeCellMode);
VARIANT_ENUM_CAST(TreeItem::TextAlign);
+class VBoxContainer;
+
class Tree : public Control {
GDCLASS(Tree, Control);
@@ -359,6 +361,10 @@ private:
};
bool show_column_titles;
+
+ VBoxContainer *popup_editor_vb;
+
+ PopupPanel *popup_editor;
LineEdit *text_editor;
HSlider *value_editor;
bool updating_value_editor;
@@ -379,7 +385,7 @@ private:
int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item);
void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = NULL, bool *r_in_range = NULL, bool p_force_deselect = false);
int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod);
- void text_editor_enter(String p_text);
+ void _text_editor_enter(String p_text);
void _text_editor_modal_close();
void value_editor_changed(double p_value);