mirror of
https://github.com/godotengine/godot.git
synced 2025-12-08 06:09:55 +00:00
Tree multiselect with shift up & down arrow keys
This commit is contained in:
parent
e37c6261ea
commit
eb973015d6
2 changed files with 61 additions and 4 deletions
|
|
@ -3557,6 +3557,47 @@ void Tree::_go_up() {
|
|||
accept_event();
|
||||
}
|
||||
|
||||
void Tree::_shift_select_range(TreeItem *new_item) {
|
||||
if (!new_item) {
|
||||
new_item = selected_item;
|
||||
}
|
||||
int s_col = selected_col;
|
||||
bool in_range = false;
|
||||
TreeItem *item = root;
|
||||
|
||||
if (!shift_anchor) {
|
||||
shift_anchor = selected_item;
|
||||
}
|
||||
|
||||
while (item) {
|
||||
bool at_range_edge = item == shift_anchor || item == new_item;
|
||||
if (at_range_edge) {
|
||||
in_range = !in_range;
|
||||
}
|
||||
if (new_item == shift_anchor) {
|
||||
in_range = false;
|
||||
}
|
||||
if (item->is_visible_in_tree()) {
|
||||
if (in_range || at_range_edge) {
|
||||
if (!item->is_selected(selected_col) && item->is_selectable(selected_col)) {
|
||||
item->select(selected_col);
|
||||
emit_signal(SNAME("multi_selected"), item, selected_col, true);
|
||||
}
|
||||
} else if (item->is_selected(selected_col)) {
|
||||
item->deselect(selected_col);
|
||||
emit_signal(SNAME("multi_selected"), item, selected_col, false);
|
||||
}
|
||||
}
|
||||
item = item->get_next_in_tree(false);
|
||||
}
|
||||
|
||||
selected_item = new_item;
|
||||
selected_col = s_col;
|
||||
ensure_cursor_is_visible();
|
||||
queue_redraw();
|
||||
accept_event();
|
||||
}
|
||||
|
||||
void Tree::_go_down() {
|
||||
TreeItem *next = nullptr;
|
||||
if (!selected_item) {
|
||||
|
|
@ -3646,6 +3687,10 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
|
|||
|
||||
Ref<InputEventKey> k = p_event;
|
||||
|
||||
if (k.is_valid() && k->get_keycode() == Key::SHIFT && !k->is_pressed()) {
|
||||
shift_anchor = nullptr;
|
||||
}
|
||||
|
||||
bool is_command = k.is_valid() && k->is_command_or_control_pressed();
|
||||
if (p_event->is_action(cache.rtl ? "ui_left" : "ui_right") && p_event->is_pressed()) {
|
||||
if (!cursor_can_exit_tree) {
|
||||
|
|
@ -3687,15 +3732,25 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
|
|||
if (!cursor_can_exit_tree) {
|
||||
accept_event();
|
||||
}
|
||||
|
||||
_go_up();
|
||||
// Shift Up Selection.
|
||||
if (k.is_valid() && k->is_shift_pressed() && selected_item && select_mode == SELECT_MULTI) {
|
||||
TreeItem *new_item = selected_item->get_prev_visible(false);
|
||||
_shift_select_range(new_item);
|
||||
} else {
|
||||
_go_up();
|
||||
}
|
||||
|
||||
} else if (p_event->is_action("ui_down") && p_event->is_pressed() && !is_command) {
|
||||
if (!cursor_can_exit_tree) {
|
||||
accept_event();
|
||||
}
|
||||
|
||||
_go_down();
|
||||
// Shift Down Selection.
|
||||
if (k.is_valid() && k->is_shift_pressed() && selected_item && select_mode == SELECT_MULTI) {
|
||||
TreeItem *new_item = selected_item->get_next_visible(false);
|
||||
_shift_select_range(new_item);
|
||||
} else {
|
||||
_go_down();
|
||||
}
|
||||
} else if (p_event->is_action("ui_menu") && p_event->is_pressed()) {
|
||||
if (allow_rmb_select && selected_item) {
|
||||
emit_signal(SNAME("item_mouse_selected"), get_item_rect(selected_item).position, MouseButton::RIGHT);
|
||||
|
|
|
|||
|
|
@ -464,6 +464,7 @@ private:
|
|||
TreeItem *popup_edited_item = nullptr;
|
||||
TreeItem *selected_item = nullptr;
|
||||
TreeItem *edited_item = nullptr;
|
||||
TreeItem *shift_anchor = nullptr;
|
||||
|
||||
TreeItem *popup_pressing_edited_item = nullptr; // Candidate.
|
||||
int popup_pressing_edited_item_column = -1;
|
||||
|
|
@ -743,6 +744,7 @@ private:
|
|||
void _go_right();
|
||||
void _go_down();
|
||||
void _go_up();
|
||||
void _shift_select_range(TreeItem *new_item);
|
||||
|
||||
bool _scroll(bool p_horizontal, float p_pages);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue