Merge pull request #16947 from Faless/ui_actions
GUI elements ui_action usage, improvements
This commit is contained in:
commit
c531262190
11 changed files with 413 additions and 420 deletions
|
@ -282,6 +282,16 @@ void InputMap::load_default() {
|
||||||
key->set_scancode(KEY_PAGEDOWN);
|
key->set_scancode(KEY_PAGEDOWN);
|
||||||
action_add_event("ui_page_down", key);
|
action_add_event("ui_page_down", key);
|
||||||
|
|
||||||
|
add_action("ui_home");
|
||||||
|
key.instance();
|
||||||
|
key->set_scancode(KEY_HOME);
|
||||||
|
action_add_event("ui_home", key);
|
||||||
|
|
||||||
|
add_action("ui_end");
|
||||||
|
key.instance();
|
||||||
|
key->set_scancode(KEY_END);
|
||||||
|
action_add_event("ui_end", key);
|
||||||
|
|
||||||
//set("display/window/handheld/orientation", "landscape");
|
//set("display/window/handheld/orientation", "landscape");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1030,6 +1030,20 @@ ProjectSettings::ProjectSettings() {
|
||||||
GLOBAL_DEF("input/ui_page_down", va);
|
GLOBAL_DEF("input/ui_page_down", va);
|
||||||
input_presets.push_back("input/ui_page_down");
|
input_presets.push_back("input/ui_page_down");
|
||||||
|
|
||||||
|
va = Array();
|
||||||
|
key.instance();
|
||||||
|
key->set_scancode(KEY_HOME);
|
||||||
|
va.push_back(key);
|
||||||
|
GLOBAL_DEF("input/ui_home", va);
|
||||||
|
input_presets.push_back("input/ui_home");
|
||||||
|
|
||||||
|
va = Array();
|
||||||
|
key.instance();
|
||||||
|
key->set_scancode(KEY_END);
|
||||||
|
va.push_back(key);
|
||||||
|
GLOBAL_DEF("input/ui_end", va);
|
||||||
|
input_presets.push_back("input/ui_end");
|
||||||
|
|
||||||
//GLOBAL_DEF("display/window/handheld/orientation", "landscape");
|
//GLOBAL_DEF("display/window/handheld/orientation", "landscape");
|
||||||
|
|
||||||
custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
|
custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
|
||||||
|
|
|
@ -373,12 +373,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
||||||
case KEY_UP: {
|
case KEY_UP: {
|
||||||
|
|
||||||
shift_selection_check_pre(k->get_shift());
|
shift_selection_check_pre(k->get_shift());
|
||||||
|
if (get_cursor_position() == 0) handled = false;
|
||||||
set_cursor_position(0);
|
set_cursor_position(0);
|
||||||
shift_selection_check_post(k->get_shift());
|
shift_selection_check_post(k->get_shift());
|
||||||
} break;
|
} break;
|
||||||
case KEY_DOWN: {
|
case KEY_DOWN: {
|
||||||
|
|
||||||
shift_selection_check_pre(k->get_shift());
|
shift_selection_check_pre(k->get_shift());
|
||||||
|
if (get_cursor_position() == text.length()) handled = false;
|
||||||
set_cursor_position(text.length());
|
set_cursor_position(text.length());
|
||||||
shift_selection_check_post(k->get_shift());
|
shift_selection_check_post(k->get_shift());
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -75,6 +75,10 @@ void OptionButton::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OptionButton::_focused(int p_which) {
|
||||||
|
emit_signal("item_focused", p_which);
|
||||||
|
}
|
||||||
|
|
||||||
void OptionButton::_selected(int p_which) {
|
void OptionButton::_selected(int p_which) {
|
||||||
|
|
||||||
int selid = -1;
|
int selid = -1;
|
||||||
|
@ -290,6 +294,7 @@ void OptionButton::get_translatable_strings(List<String> *p_strings) const {
|
||||||
void OptionButton::_bind_methods() {
|
void OptionButton::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_selected"), &OptionButton::_selected);
|
ClassDB::bind_method(D_METHOD("_selected"), &OptionButton::_selected);
|
||||||
|
ClassDB::bind_method(D_METHOD("_focused"), &OptionButton::_focused);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("add_item", "label", "id"), &OptionButton::add_item, DEFVAL(-1));
|
ClassDB::bind_method(D_METHOD("add_item", "label", "id"), &OptionButton::add_item, DEFVAL(-1));
|
||||||
ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id"), &OptionButton::add_icon_item);
|
ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id"), &OptionButton::add_icon_item);
|
||||||
|
@ -322,6 +327,7 @@ void OptionButton::_bind_methods() {
|
||||||
// "selected" property must come after "items", otherwise GH-10213 occurs
|
// "selected" property must come after "items", otherwise GH-10213 occurs
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected");
|
||||||
ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "ID")));
|
ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "ID")));
|
||||||
|
ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "ID")));
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionButton::OptionButton() {
|
OptionButton::OptionButton() {
|
||||||
|
@ -336,6 +342,7 @@ OptionButton::OptionButton() {
|
||||||
popup->set_as_toplevel(true);
|
popup->set_as_toplevel(true);
|
||||||
popup->set_pass_on_modal_close_click(false);
|
popup->set_pass_on_modal_close_click(false);
|
||||||
popup->connect("id_pressed", this, "_selected");
|
popup->connect("id_pressed", this, "_selected");
|
||||||
|
popup->connect("id_focused", this, "_focused");
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionButton::~OptionButton() {
|
OptionButton::~OptionButton() {
|
||||||
|
|
|
@ -43,6 +43,7 @@ class OptionButton : public Button {
|
||||||
PopupMenu *popup;
|
PopupMenu *popup;
|
||||||
int current;
|
int current;
|
||||||
|
|
||||||
|
void _focused(int p_which);
|
||||||
void _selected(int p_which);
|
void _selected(int p_which);
|
||||||
void _select(int p_which, bool p_emit = false);
|
void _select(int p_which, bool p_emit = false);
|
||||||
void _select_int(int p_which);
|
void _select_int(int p_which);
|
||||||
|
|
|
@ -211,86 +211,69 @@ void PopupMenu::_scroll(float p_factor, const Point2 &p_over) {
|
||||||
|
|
||||||
void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
|
void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
Ref<InputEventKey> k = p_event;
|
if (p_event->is_action("ui_down") && p_event->is_pressed()) {
|
||||||
|
|
||||||
if (k.is_valid()) {
|
int search_from = mouse_over + 1;
|
||||||
|
if (search_from >= items.size())
|
||||||
|
search_from = 0;
|
||||||
|
|
||||||
if (!k->is_pressed())
|
for (int i = search_from; i < items.size(); i++) {
|
||||||
return;
|
|
||||||
|
|
||||||
switch (k->get_scancode()) {
|
if (i < 0 || i >= items.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
case KEY_DOWN: {
|
if (!items[i].separator && !items[i].disabled) {
|
||||||
|
|
||||||
int search_from = mouse_over + 1;
|
mouse_over = i;
|
||||||
if (search_from >= items.size())
|
emit_signal("id_focused", i);
|
||||||
search_from = 0;
|
update();
|
||||||
|
accept_event();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (p_event->is_action("ui_up") && p_event->is_pressed()) {
|
||||||
|
|
||||||
for (int i = search_from; i < items.size(); i++) {
|
int search_from = mouse_over - 1;
|
||||||
|
if (search_from < 0)
|
||||||
|
search_from = items.size() - 1;
|
||||||
|
|
||||||
if (i < 0 || i >= items.size())
|
for (int i = search_from; i >= 0; i--) {
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!items[i].separator && !items[i].disabled) {
|
if (i < 0 || i >= items.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
mouse_over = i;
|
if (!items[i].separator && !items[i].disabled) {
|
||||||
update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case KEY_UP: {
|
|
||||||
|
|
||||||
int search_from = mouse_over - 1;
|
mouse_over = i;
|
||||||
if (search_from < 0)
|
emit_signal("id_focused", i);
|
||||||
search_from = items.size() - 1;
|
update();
|
||||||
|
accept_event();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (p_event->is_action("ui_left") && p_event->is_pressed()) {
|
||||||
|
|
||||||
for (int i = search_from; i >= 0; i--) {
|
Node *n = get_parent();
|
||||||
|
if (n && Object::cast_to<PopupMenu>(n)) {
|
||||||
|
hide();
|
||||||
|
accept_event();
|
||||||
|
}
|
||||||
|
} else if (p_event->is_action("ui_right") && p_event->is_pressed()) {
|
||||||
|
|
||||||
if (i < 0 || i >= items.size())
|
if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over) {
|
||||||
continue;
|
_activate_submenu(mouse_over);
|
||||||
|
accept_event();
|
||||||
|
}
|
||||||
|
} else if (p_event->is_action("ui_accept") && p_event->is_pressed()) {
|
||||||
|
|
||||||
if (!items[i].separator && !items[i].disabled) {
|
if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {
|
||||||
|
|
||||||
mouse_over = i;
|
if (items[mouse_over].submenu != "" && submenu_over != mouse_over) {
|
||||||
update();
|
_activate_submenu(mouse_over);
|
||||||
break;
|
} else {
|
||||||
}
|
activate_item(mouse_over);
|
||||||
}
|
}
|
||||||
} break;
|
accept_event();
|
||||||
|
|
||||||
case KEY_LEFT: {
|
|
||||||
|
|
||||||
Node *n = get_parent();
|
|
||||||
if (!n)
|
|
||||||
break;
|
|
||||||
|
|
||||||
PopupMenu *pm = Object::cast_to<PopupMenu>(n);
|
|
||||||
if (!pm)
|
|
||||||
break;
|
|
||||||
|
|
||||||
hide();
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case KEY_RIGHT: {
|
|
||||||
|
|
||||||
if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over)
|
|
||||||
_activate_submenu(mouse_over);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case KEY_ENTER:
|
|
||||||
case KEY_KP_ENTER: {
|
|
||||||
|
|
||||||
if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {
|
|
||||||
|
|
||||||
if (items[mouse_over].submenu != "" && submenu_over != mouse_over) {
|
|
||||||
_activate_submenu(mouse_over);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
activate_item(mouse_over);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1229,6 +1212,7 @@ void PopupMenu::_bind_methods() {
|
||||||
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "hide_on_state_item_selection"), "set_hide_on_state_item_selection", "is_hide_on_state_item_selection");
|
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "hide_on_state_item_selection"), "set_hide_on_state_item_selection", "is_hide_on_state_item_selection");
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("id_pressed", PropertyInfo(Variant::INT, "ID")));
|
ADD_SIGNAL(MethodInfo("id_pressed", PropertyInfo(Variant::INT, "ID")));
|
||||||
|
ADD_SIGNAL(MethodInfo("id_focused", PropertyInfo(Variant::INT, "ID")));
|
||||||
ADD_SIGNAL(MethodInfo("index_pressed", PropertyInfo(Variant::INT, "index")));
|
ADD_SIGNAL(MethodInfo("index_pressed", PropertyInfo(Variant::INT, "index")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,54 +199,40 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<InputEventKey> k = p_event;
|
if (p_event->is_pressed()) {
|
||||||
|
|
||||||
if (k.is_valid()) {
|
if (p_event->is_action("ui_left")) {
|
||||||
|
|
||||||
if (!k->is_pressed())
|
if (orientation != HORIZONTAL)
|
||||||
return;
|
return;
|
||||||
|
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
|
||||||
|
|
||||||
switch (k->get_scancode()) {
|
} else if (p_event->is_action("ui_right")) {
|
||||||
|
|
||||||
case KEY_LEFT: {
|
if (orientation != HORIZONTAL)
|
||||||
|
return;
|
||||||
|
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
|
||||||
|
|
||||||
if (orientation != HORIZONTAL)
|
} else if (p_event->is_action("ui_up")) {
|
||||||
return;
|
|
||||||
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
|
|
||||||
|
|
||||||
} break;
|
if (orientation != VERTICAL)
|
||||||
case KEY_RIGHT: {
|
return;
|
||||||
|
|
||||||
if (orientation != HORIZONTAL)
|
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
|
||||||
return;
|
|
||||||
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
|
|
||||||
|
|
||||||
} break;
|
} else if (p_event->is_action("ui_down")) {
|
||||||
case KEY_UP: {
|
|
||||||
|
|
||||||
if (orientation != VERTICAL)
|
if (orientation != VERTICAL)
|
||||||
return;
|
return;
|
||||||
|
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
|
||||||
|
|
||||||
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
|
} else if (p_event->is_action("ui_home")) {
|
||||||
|
|
||||||
} break;
|
set_value(get_min());
|
||||||
case KEY_DOWN: {
|
|
||||||
|
|
||||||
if (orientation != VERTICAL)
|
} else if (p_event->is_action("ui_end")) {
|
||||||
return;
|
|
||||||
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
|
|
||||||
|
|
||||||
} break;
|
set_value(get_max());
|
||||||
case KEY_HOME: {
|
|
||||||
|
|
||||||
set_value(get_min());
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case KEY_END: {
|
|
||||||
|
|
||||||
set_value(get_max());
|
|
||||||
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,28 +118,14 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
|
||||||
return;
|
return;
|
||||||
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
|
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
|
||||||
accept_event();
|
accept_event();
|
||||||
|
} else if (p_event->is_action("ui_home") && p_event->is_pressed()) {
|
||||||
|
|
||||||
} else {
|
set_value(get_min());
|
||||||
|
accept_event();
|
||||||
|
} else if (p_event->is_action("ui_end") && p_event->is_pressed()) {
|
||||||
|
|
||||||
Ref<InputEventKey> k = p_event;
|
set_value(get_max());
|
||||||
|
accept_event();
|
||||||
if (!k.is_valid() || !k->is_pressed())
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (k->get_scancode()) {
|
|
||||||
|
|
||||||
case KEY_HOME: {
|
|
||||||
|
|
||||||
set_value(get_min());
|
|
||||||
accept_event();
|
|
||||||
} break;
|
|
||||||
case KEY_END: {
|
|
||||||
|
|
||||||
set_value(get_max());
|
|
||||||
accept_event();
|
|
||||||
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2061,11 +2061,298 @@ void Tree::popup_select(int p_option) {
|
||||||
item_edited(popup_edited_item_col, popup_edited_item);
|
item_edited(popup_edited_item_col, popup_edited_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tree::_go_left() {
|
||||||
|
if (selected_col == 0) {
|
||||||
|
if (selected_item->get_children() != NULL && !selected_item->is_collapsed()) {
|
||||||
|
selected_item->set_collapsed(true);
|
||||||
|
} else {
|
||||||
|
if (columns.size() == 1) { // goto parent with one column
|
||||||
|
TreeItem *parent = selected_item->get_parent();
|
||||||
|
if (selected_item != get_root() && parent && parent->is_selectable(selected_col) && !(hide_root && parent == get_root())) {
|
||||||
|
select_single_item(parent, get_root(), selected_col);
|
||||||
|
}
|
||||||
|
} else if (selected_item->get_prev_visible()) {
|
||||||
|
selected_col = columns.size() - 1;
|
||||||
|
_go_up(); // go to upper column if possible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (select_mode == SELECT_MULTI) {
|
||||||
|
selected_col--;
|
||||||
|
emit_signal("cell_selected");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
selected_item->select(selected_col - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
accept_event();
|
||||||
|
ensure_cursor_is_visible();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tree::_go_right() {
|
||||||
|
if (selected_col == (columns.size() - 1)) {
|
||||||
|
if (selected_item->get_children() != NULL && selected_item->is_collapsed()) {
|
||||||
|
selected_item->set_collapsed(false);
|
||||||
|
} else if (selected_item->get_next_visible()) {
|
||||||
|
selected_item->select(0);
|
||||||
|
_go_down();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (select_mode == SELECT_MULTI) {
|
||||||
|
selected_col++;
|
||||||
|
emit_signal("cell_selected");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
selected_item->select(selected_col + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
ensure_cursor_is_visible();
|
||||||
|
accept_event();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tree::_go_up() {
|
||||||
|
TreeItem *prev = NULL;
|
||||||
|
if (!selected_item) {
|
||||||
|
prev = get_last_item();
|
||||||
|
selected_col = 0;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
prev = selected_item->get_prev_visible();
|
||||||
|
if (last_keypress != 0) {
|
||||||
|
//incr search next
|
||||||
|
int col;
|
||||||
|
prev = _search_item_text(prev, incr_search, &col, true, true);
|
||||||
|
if (!prev) {
|
||||||
|
accept_event();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (select_mode == SELECT_MULTI) {
|
||||||
|
|
||||||
|
if (!prev)
|
||||||
|
return;
|
||||||
|
selected_item = prev;
|
||||||
|
emit_signal("cell_selected");
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
int col = selected_col < 0 ? 0 : selected_col;
|
||||||
|
while (prev && !prev->cells[col].selectable)
|
||||||
|
prev = prev->get_prev_visible();
|
||||||
|
if (!prev)
|
||||||
|
return; // do nothing..
|
||||||
|
prev->select(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_cursor_is_visible();
|
||||||
|
accept_event();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tree::_go_down() {
|
||||||
|
TreeItem *next = NULL;
|
||||||
|
if (!selected_item) {
|
||||||
|
|
||||||
|
next = hide_root ? root->get_next_visible() : root;
|
||||||
|
selected_item = 0;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
next = selected_item->get_next_visible();
|
||||||
|
|
||||||
|
if (last_keypress != 0) {
|
||||||
|
//incr search next
|
||||||
|
int col;
|
||||||
|
next = _search_item_text(next, incr_search, &col, true);
|
||||||
|
if (!next) {
|
||||||
|
accept_event();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (select_mode == SELECT_MULTI) {
|
||||||
|
|
||||||
|
if (!next) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selected_item = next;
|
||||||
|
emit_signal("cell_selected");
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
int col = selected_col < 0 ? 0 : selected_col;
|
||||||
|
|
||||||
|
while (next && !next->cells[col].selectable)
|
||||||
|
next = next->get_next_visible();
|
||||||
|
if (!next) {
|
||||||
|
return; // do nothing..
|
||||||
|
}
|
||||||
|
next->select(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_cursor_is_visible();
|
||||||
|
accept_event();
|
||||||
|
}
|
||||||
|
|
||||||
void Tree::_gui_input(Ref<InputEvent> p_event) {
|
void Tree::_gui_input(Ref<InputEvent> p_event) {
|
||||||
|
|
||||||
Ref<InputEventKey> k = p_event;
|
Ref<InputEventKey> k = p_event;
|
||||||
|
|
||||||
if (k.is_valid()) {
|
if (p_event->is_action("ui_right") && p_event->is_pressed()) {
|
||||||
|
|
||||||
|
if (!cursor_can_exit_tree) accept_event();
|
||||||
|
|
||||||
|
if (!selected_item || select_mode == SELECT_ROW || selected_col > (columns.size() - 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (k.is_valid() && k->get_alt()) {
|
||||||
|
selected_item->set_collapsed(false);
|
||||||
|
TreeItem *next = selected_item->get_children();
|
||||||
|
while (next && next != selected_item->next) {
|
||||||
|
next->set_collapsed(false);
|
||||||
|
next = next->get_next_visible();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_go_right();
|
||||||
|
}
|
||||||
|
} else if (p_event->is_action("ui_left") && p_event->is_pressed()) {
|
||||||
|
|
||||||
|
if (!cursor_can_exit_tree) accept_event();
|
||||||
|
|
||||||
|
if (!selected_item || select_mode == SELECT_ROW || selected_col < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k.is_valid() && k->get_alt()) {
|
||||||
|
selected_item->set_collapsed(true);
|
||||||
|
TreeItem *next = selected_item->get_children();
|
||||||
|
while (next && next != selected_item->next) {
|
||||||
|
next->set_collapsed(true);
|
||||||
|
next = next->get_next_visible();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_go_left();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (p_event->is_action("ui_up") && p_event->is_pressed()) {
|
||||||
|
|
||||||
|
if (!cursor_can_exit_tree) accept_event();
|
||||||
|
|
||||||
|
_go_up();
|
||||||
|
|
||||||
|
} else if (p_event->is_action("ui_down") && p_event->is_pressed()) {
|
||||||
|
|
||||||
|
if (!cursor_can_exit_tree) accept_event();
|
||||||
|
|
||||||
|
_go_down();
|
||||||
|
|
||||||
|
} else if (p_event->is_action("ui_page_down") && p_event->is_pressed()) {
|
||||||
|
|
||||||
|
if (!cursor_can_exit_tree) accept_event();
|
||||||
|
|
||||||
|
TreeItem *next = NULL;
|
||||||
|
if (!selected_item)
|
||||||
|
return;
|
||||||
|
next = selected_item;
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
|
||||||
|
TreeItem *_n = next->get_next_visible();
|
||||||
|
if (_n) {
|
||||||
|
next = _n;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next == selected_item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (select_mode == SELECT_MULTI) {
|
||||||
|
|
||||||
|
selected_item = next;
|
||||||
|
emit_signal("cell_selected");
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while (next && !next->cells[selected_col].selectable)
|
||||||
|
next = next->get_next_visible();
|
||||||
|
if (!next) {
|
||||||
|
return; // do nothing..
|
||||||
|
}
|
||||||
|
next->select(selected_col);
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_cursor_is_visible();
|
||||||
|
} else if (p_event->is_action("ui_page_up") && p_event->is_pressed()) {
|
||||||
|
|
||||||
|
if (!cursor_can_exit_tree) accept_event();
|
||||||
|
|
||||||
|
TreeItem *prev = NULL;
|
||||||
|
if (!selected_item)
|
||||||
|
return;
|
||||||
|
prev = selected_item;
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
|
||||||
|
TreeItem *_n = prev->get_prev_visible();
|
||||||
|
if (_n) {
|
||||||
|
prev = _n;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (prev == selected_item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (select_mode == SELECT_MULTI) {
|
||||||
|
|
||||||
|
selected_item = prev;
|
||||||
|
emit_signal("cell_selected");
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while (prev && !prev->cells[selected_col].selectable)
|
||||||
|
prev = prev->get_prev_visible();
|
||||||
|
if (!prev) {
|
||||||
|
return; // do nothing..
|
||||||
|
}
|
||||||
|
prev->select(selected_col);
|
||||||
|
}
|
||||||
|
ensure_cursor_is_visible();
|
||||||
|
} else if (p_event->is_action("ui_accept") && p_event->is_pressed()) {
|
||||||
|
|
||||||
|
if (selected_item) {
|
||||||
|
//bring up editor if possible
|
||||||
|
if (!edit_selected()) {
|
||||||
|
emit_signal("item_activated");
|
||||||
|
incr_search.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accept_event();
|
||||||
|
} else if (p_event->is_action("ui_select") && p_event->is_pressed()) {
|
||||||
|
|
||||||
|
if (select_mode == SELECT_MULTI) {
|
||||||
|
if (!selected_item)
|
||||||
|
return;
|
||||||
|
if (selected_item->is_selected(selected_col)) {
|
||||||
|
selected_item->deselect(selected_col);
|
||||||
|
emit_signal("multi_selected", selected_item, selected_col, false);
|
||||||
|
} else if (selected_item->is_selectable(selected_col)) {
|
||||||
|
selected_item->select(selected_col);
|
||||||
|
emit_signal("multi_selected", selected_item, selected_col, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accept_event();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k.is_valid()) { // Incremental search
|
||||||
|
|
||||||
if (!k->is_pressed())
|
if (!k->is_pressed())
|
||||||
return;
|
return;
|
||||||
|
@ -2077,306 +2364,15 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
|
||||||
if (hide_root && !root->get_next_visible())
|
if (hide_root && !root->get_next_visible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (k->get_scancode()) {
|
if (k->get_unicode() > 0) {
|
||||||
#define EXIT_BREAK \
|
|
||||||
{ \
|
|
||||||
if (!cursor_can_exit_tree) accept_event(); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
case KEY_RIGHT: {
|
|
||||||
bool dobreak = true;
|
|
||||||
|
|
||||||
//TreeItem *next = NULL;
|
_do_incr_search(String::chr(k->get_unicode()));
|
||||||
if (!selected_item)
|
accept_event();
|
||||||
break;
|
|
||||||
if (select_mode == SELECT_ROW) {
|
|
||||||
EXIT_BREAK;
|
|
||||||
}
|
|
||||||
if (selected_col > (columns.size() - 1)) {
|
|
||||||
EXIT_BREAK;
|
|
||||||
}
|
|
||||||
if (k->get_alt()) {
|
|
||||||
selected_item->set_collapsed(false);
|
|
||||||
TreeItem *next = selected_item->get_children();
|
|
||||||
while (next && next != selected_item->next) {
|
|
||||||
next->set_collapsed(false);
|
|
||||||
next = next->get_next_visible();
|
|
||||||
}
|
|
||||||
} else if (selected_col == (columns.size() - 1)) {
|
|
||||||
if (selected_item->get_children() != NULL && selected_item->is_collapsed()) {
|
|
||||||
selected_item->set_collapsed(false);
|
|
||||||
} else {
|
|
||||||
selected_col = 0;
|
|
||||||
dobreak = false; // fall through to key_down
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (select_mode == SELECT_MULTI) {
|
|
||||||
selected_col++;
|
|
||||||
emit_signal("cell_selected");
|
|
||||||
} else {
|
|
||||||
|
|
||||||
selected_item->select(selected_col + 1);
|
return;
|
||||||
}
|
} else {
|
||||||
}
|
if (k->get_scancode() != KEY_SHIFT)
|
||||||
update();
|
last_keypress = 0;
|
||||||
ensure_cursor_is_visible();
|
|
||||||
accept_event();
|
|
||||||
if (dobreak) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case KEY_DOWN: {
|
|
||||||
|
|
||||||
TreeItem *next = NULL;
|
|
||||||
if (!selected_item) {
|
|
||||||
|
|
||||||
next = hide_root ? root->get_next_visible() : root;
|
|
||||||
selected_item = 0;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
next = selected_item->get_next_visible();
|
|
||||||
|
|
||||||
//if (diff < uint64_t(GLOBAL_DEF("gui/incr_search_max_interval_msec",2000))) {
|
|
||||||
if (last_keypress != 0) {
|
|
||||||
//incr search next
|
|
||||||
int col;
|
|
||||||
next = _search_item_text(next, incr_search, &col, true);
|
|
||||||
if (!next) {
|
|
||||||
accept_event();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_mode == SELECT_MULTI) {
|
|
||||||
|
|
||||||
if (!next)
|
|
||||||
EXIT_BREAK;
|
|
||||||
|
|
||||||
selected_item = next;
|
|
||||||
emit_signal("cell_selected");
|
|
||||||
update();
|
|
||||||
} else {
|
|
||||||
|
|
||||||
int col = selected_col < 0 ? 0 : selected_col;
|
|
||||||
|
|
||||||
while (next && !next->cells[col].selectable)
|
|
||||||
next = next->get_next_visible();
|
|
||||||
if (!next)
|
|
||||||
EXIT_BREAK; // do nothing..
|
|
||||||
next->select(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_cursor_is_visible();
|
|
||||||
accept_event();
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case KEY_LEFT: {
|
|
||||||
bool dobreak = true;
|
|
||||||
|
|
||||||
//TreeItem *next = NULL;
|
|
||||||
if (!selected_item)
|
|
||||||
break;
|
|
||||||
if (select_mode == SELECT_ROW) {
|
|
||||||
EXIT_BREAK;
|
|
||||||
}
|
|
||||||
if (selected_col < 0) {
|
|
||||||
EXIT_BREAK;
|
|
||||||
}
|
|
||||||
if (k->get_alt()) {
|
|
||||||
selected_item->set_collapsed(true);
|
|
||||||
TreeItem *next = selected_item->get_children();
|
|
||||||
while (next && next != selected_item->next) {
|
|
||||||
next->set_collapsed(true);
|
|
||||||
next = next->get_next_visible();
|
|
||||||
}
|
|
||||||
} else if (selected_col == 0) {
|
|
||||||
if (selected_item->get_children() != NULL && !selected_item->is_collapsed()) {
|
|
||||||
selected_item->set_collapsed(true);
|
|
||||||
} else {
|
|
||||||
if (columns.size() == 1) { // goto parent with one column
|
|
||||||
TreeItem *parent = selected_item->get_parent();
|
|
||||||
if (selected_item != get_root() && parent && parent->is_selectable(selected_col) && !(hide_root && parent == get_root())) {
|
|
||||||
select_single_item(parent, get_root(), selected_col);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
selected_col = columns.size() - 1;
|
|
||||||
dobreak = false; // fall through to key_up
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (select_mode == SELECT_MULTI) {
|
|
||||||
selected_col--;
|
|
||||||
emit_signal("cell_selected");
|
|
||||||
} else {
|
|
||||||
|
|
||||||
selected_item->select(selected_col - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
update();
|
|
||||||
accept_event();
|
|
||||||
ensure_cursor_is_visible();
|
|
||||||
|
|
||||||
if (dobreak) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case KEY_UP: {
|
|
||||||
|
|
||||||
TreeItem *prev = NULL;
|
|
||||||
if (!selected_item) {
|
|
||||||
prev = get_last_item();
|
|
||||||
selected_col = 0;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
prev = selected_item->get_prev_visible();
|
|
||||||
if (last_keypress != 0) {
|
|
||||||
//incr search next
|
|
||||||
int col;
|
|
||||||
prev = _search_item_text(prev, incr_search, &col, true, true);
|
|
||||||
if (!prev) {
|
|
||||||
accept_event();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_mode == SELECT_MULTI) {
|
|
||||||
|
|
||||||
if (!prev)
|
|
||||||
break;
|
|
||||||
selected_item = prev;
|
|
||||||
emit_signal("cell_selected");
|
|
||||||
update();
|
|
||||||
} else {
|
|
||||||
|
|
||||||
int col = selected_col < 0 ? 0 : selected_col;
|
|
||||||
while (prev && !prev->cells[col].selectable)
|
|
||||||
prev = prev->get_prev_visible();
|
|
||||||
if (!prev)
|
|
||||||
break; // do nothing..
|
|
||||||
prev->select(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_cursor_is_visible();
|
|
||||||
accept_event();
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case KEY_PAGEDOWN: {
|
|
||||||
|
|
||||||
TreeItem *next = NULL;
|
|
||||||
if (!selected_item)
|
|
||||||
break;
|
|
||||||
next = selected_item;
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
|
|
||||||
TreeItem *_n = next->get_next_visible();
|
|
||||||
if (_n) {
|
|
||||||
next = _n;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (next == selected_item)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (select_mode == SELECT_MULTI) {
|
|
||||||
|
|
||||||
selected_item = next;
|
|
||||||
emit_signal("cell_selected");
|
|
||||||
update();
|
|
||||||
} else {
|
|
||||||
|
|
||||||
while (next && !next->cells[selected_col].selectable)
|
|
||||||
next = next->get_next_visible();
|
|
||||||
if (!next)
|
|
||||||
EXIT_BREAK; // do nothing..
|
|
||||||
next->select(selected_col);
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_cursor_is_visible();
|
|
||||||
} break;
|
|
||||||
case KEY_PAGEUP: {
|
|
||||||
|
|
||||||
TreeItem *prev = NULL;
|
|
||||||
if (!selected_item)
|
|
||||||
break;
|
|
||||||
prev = selected_item;
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
|
|
||||||
TreeItem *_n = prev->get_prev_visible();
|
|
||||||
if (_n) {
|
|
||||||
prev = _n;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (prev == selected_item)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (select_mode == SELECT_MULTI) {
|
|
||||||
|
|
||||||
selected_item = prev;
|
|
||||||
emit_signal("cell_selected");
|
|
||||||
update();
|
|
||||||
} else {
|
|
||||||
|
|
||||||
while (prev && !prev->cells[selected_col].selectable)
|
|
||||||
prev = prev->get_prev_visible();
|
|
||||||
if (!prev)
|
|
||||||
EXIT_BREAK; // do nothing..
|
|
||||||
prev->select(selected_col);
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_cursor_is_visible();
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case KEY_F2:
|
|
||||||
case KEY_ENTER:
|
|
||||||
case KEY_KP_ENTER: {
|
|
||||||
|
|
||||||
if (selected_item) {
|
|
||||||
//bring up editor if possible
|
|
||||||
if (!edit_selected()) {
|
|
||||||
emit_signal("item_activated");
|
|
||||||
incr_search.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
accept_event();
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case KEY_SPACE: {
|
|
||||||
if (select_mode == SELECT_MULTI) {
|
|
||||||
if (!selected_item)
|
|
||||||
break;
|
|
||||||
if (selected_item->is_selected(selected_col)) {
|
|
||||||
selected_item->deselect(selected_col);
|
|
||||||
emit_signal("multi_selected", selected_item, selected_col, false);
|
|
||||||
} else if (selected_item->is_selectable(selected_col)) {
|
|
||||||
selected_item->select(selected_col);
|
|
||||||
emit_signal("multi_selected", selected_item, selected_col, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
accept_event();
|
|
||||||
|
|
||||||
} break;
|
|
||||||
default: {
|
|
||||||
|
|
||||||
if (k->get_unicode() > 0) {
|
|
||||||
|
|
||||||
_do_incr_search(String::chr(k->get_unicode()));
|
|
||||||
accept_event();
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (k->get_scancode() != KEY_SHIFT)
|
|
||||||
last_keypress = 0;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -507,6 +507,10 @@ private:
|
||||||
ValueEvaluator *evaluator;
|
ValueEvaluator *evaluator;
|
||||||
|
|
||||||
int _count_selected_items(TreeItem *p_from) const;
|
int _count_selected_items(TreeItem *p_from) const;
|
||||||
|
void _go_left();
|
||||||
|
void _go_right();
|
||||||
|
void _go_down();
|
||||||
|
void _go_up();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
|
@ -2028,6 +2028,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
||||||
top->notification(Control::NOTIFICATION_MODAL_CLOSE);
|
top->notification(Control::NOTIFICATION_MODAL_CLOSE);
|
||||||
top->_modal_stack_remove();
|
top->_modal_stack_remove();
|
||||||
top->hide();
|
top->hide();
|
||||||
|
// Close modal, set input as handled
|
||||||
|
get_tree()->set_input_as_handled();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue