diff options
Diffstat (limited to 'scene/gui/tree.cpp')
| -rw-r--r-- | scene/gui/tree.cpp | 958 |
1 files changed, 527 insertions, 431 deletions
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index bc7b7485d8..d864d9fce7 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -464,7 +464,7 @@ void TreeItem::deselect(int p_column) { _cell_deselected(p_column); } -void TreeItem::add_button(int p_column, const Ref<Texture> &p_button, int p_id, bool p_disabled) { +void TreeItem::add_button(int p_column, const Ref<Texture> &p_button, int p_id, bool p_disabled, const String &p_tooltip) { ERR_FAIL_INDEX(p_column, cells.size()); ERR_FAIL_COND(!p_button.is_valid()); @@ -474,6 +474,7 @@ void TreeItem::add_button(int p_column, const Ref<Texture> &p_button, int p_id, p_id = cells[p_column].buttons.size(); button.id = p_id; button.disabled = p_disabled; + button.tooltip = p_tooltip; cells[p_column].buttons.push_back(button); _changed_notify(p_column); } @@ -609,6 +610,18 @@ Color TreeItem::get_custom_bg_color(int p_column) const { return cells[p_column].bg_color; } +void TreeItem::set_custom_as_button(int p_column, bool p_button) { + + ERR_FAIL_INDEX(p_column, cells.size()); + cells[p_column].custom_button = p_button; +} + +bool TreeItem::is_custom_set_as_button(int p_column) const { + + ERR_FAIL_INDEX_V(p_column, cells.size(), false); + return cells[p_column].custom_button; +} + void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("set_cell_mode", "column", "mode"), &TreeItem::set_cell_mode); @@ -669,7 +682,10 @@ void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_custom_bg_color", "column"), &TreeItem::clear_custom_bg_color); ClassDB::bind_method(D_METHOD("get_custom_bg_color", "column"), &TreeItem::get_custom_bg_color); - ClassDB::bind_method(D_METHOD("add_button", "column", "button:Texture", "button_idx", "disabled"), &TreeItem::add_button, DEFVAL(-1), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("set_custom_as_button", "column", "enable"), &TreeItem::set_custom_as_button); + ClassDB::bind_method(D_METHOD("is_custom_set_as_button", "column"), &TreeItem::is_custom_set_as_button); + + ClassDB::bind_method(D_METHOD("add_button", "column", "button:Texture", "button_idx", "disabled", "tooltip"), &TreeItem::add_button, DEFVAL(-1), DEFVAL(false), DEFVAL("")); ClassDB::bind_method(D_METHOD("get_button_count", "column"), &TreeItem::get_button_count); ClassDB::bind_method(D_METHOD("get_button:Texture", "column", "button_idx"), &TreeItem::get_button); ClassDB::bind_method(D_METHOD("set_button", "column", "button_idx", "button:Texture"), &TreeItem::set_button); @@ -731,6 +747,10 @@ TreeItem::~TreeItem() { tree->pressing_for_editor = false; } + if (tree && tree->cache.hover_item == this) { + tree->cache.hover_item = NULL; + } + if (tree && tree->selected_item == this) tree->selected_item = NULL; @@ -771,6 +791,11 @@ void Tree::update_cache() { cache.select_arrow = get_icon("select_arrow"); cache.updown = get_icon("updown"); + cache.custom_button = get_stylebox("custom_button"); + cache.custom_button_hover = get_stylebox("custom_button_hover"); + cache.custom_button_pressed = get_stylebox("custom_button_pressed"); + cache.custom_button_font_highlight = get_color("custom_button_font_highlight"); + cache.font_color = get_color("font_color"); cache.font_color_selected = get_color("font_color_selected"); cache.guide_color = get_color("guide_color"); @@ -832,6 +857,9 @@ int Tree::compute_item_height(TreeItem *p_item) const { if (s.height > height) height = s.height; } + if (p_item->cells[i].mode == TreeItem::CELL_MODE_CUSTOM && p_item->cells[i].custom_button) { + height += cache.custom_button->get_minimum_size().height; + } } break; default: {} @@ -876,8 +904,8 @@ void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, co bmsize.width = p_cell.icon_max_w; } - p_cell.draw_icon(ci, rect.pos + Size2i(0, Math::floor((real_t)(rect.size.y - bmsize.y) / 2)), bmsize); - rect.pos.x += bmsize.x + cache.hseparation; + p_cell.draw_icon(ci, rect.position + Size2i(0, Math::floor((real_t)(rect.size.y - bmsize.y) / 2)), bmsize); + rect.position.x += bmsize.x + cache.hseparation; rect.size.x -= bmsize.x + cache.hseparation; } @@ -892,8 +920,8 @@ void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, co if (p_cell.suffix != String()) text += " " + p_cell.suffix; - rect.pos.y += Math::floor((rect.size.y - font->get_height()) / 2.0) + font->get_ascent(); - font->draw(ci, rect.pos, text, p_color, rect.size.x); + rect.position.y += Math::floor((rect.size.y - font->get_height()) / 2.0) + font->get_ascent(); + font->draw(ci, rect.position, text, p_color, rect.size.x); } #if 0 @@ -1006,16 +1034,16 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 Rect2i item_rect = Rect2i(Point2i(ofs, p_pos.y) - cache.offset + p_draw_ofs, Size2i(w, label_h)); Rect2i cell_rect = item_rect; if (i != 0) { - cell_rect.pos.x -= cache.hseparation; + cell_rect.position.x -= cache.hseparation; cell_rect.size.x += cache.hseparation; } - VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(cell_rect.pos.x, cell_rect.pos.y + cell_rect.size.height), cell_rect.pos + cell_rect.size, cache.guide_color, 1); + VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(cell_rect.position.x, cell_rect.position.y + cell_rect.size.height), cell_rect.position + cell_rect.size, cache.guide_color, 1); if (i == 0) { if (p_item->cells[0].selected && select_mode == SELECT_ROW) { - Rect2i row_rect = Rect2i(Point2i(cache.bg->get_margin(MARGIN_LEFT), item_rect.pos.y), Size2i(get_size().width - cache.bg->get_minimum_size().width, item_rect.size.y)); + Rect2i row_rect = Rect2i(Point2i(cache.bg->get_margin(MARGIN_LEFT), item_rect.position.y), Size2i(get_size().width - cache.bg->get_minimum_size().width, item_rect.size.y)); //Rect2 r = Rect2i(row_rect.pos,row_rect.size); //r.grow(cache.selected->get_margin(MARGIN_LEFT)); if (has_focus()) @@ -1027,34 +1055,34 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (p_item->cells[i].selected && select_mode != SELECT_ROW) { - Rect2i r(item_rect.pos, item_rect.size); + Rect2i r(item_rect.position, item_rect.size); if (p_item->cells[i].text.size() > 0) { float icon_width = p_item->cells[i].get_icon_size().width; - r.pos.x += icon_width; + r.position.x += icon_width; r.size.x -= icon_width; } //r.grow(cache.selected->get_margin(MARGIN_LEFT)); if (has_focus()) { cache.selected_focus->draw(ci, r); - p_item->set_meta("__focus_rect", Rect2(r.pos, r.size)); + p_item->set_meta("__focus_rect", Rect2(r.position, r.size)); } else { cache.selected->draw(ci, r); } if (text_editor->is_visible_in_tree()) { - text_editor->set_position(get_global_position() + r.pos); + text_editor->set_position(get_global_position() + r.position); } } if (p_item->cells[i].custom_bg_color) { Rect2 r = cell_rect; - r.pos.x -= cache.hseparation; + r.position.x -= cache.hseparation; r.size.x += cache.hseparation; if (p_item->cells[i].custom_bg_outline) { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y, r.size.x, 1), p_item->cells[i].bg_color); - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y + r.size.y - 1, r.size.x, 1), p_item->cells[i].bg_color); - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y, 1, r.size.y), p_item->cells[i].bg_color); - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x + r.size.x - 1, r.pos.y, 1, r.size.y), p_item->cells[i].bg_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), p_item->cells[i].bg_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y + r.size.y - 1, r.size.x, 1), p_item->cells[i].bg_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, 1, r.size.y), p_item->cells[i].bg_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x + r.size.x - 1, r.position.y, 1, r.size.y), p_item->cells[i].bg_color); } else { VisualServer::get_singleton()->canvas_item_add_rect(ci, r, p_item->cells[i].bg_color); } @@ -1065,22 +1093,22 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 Rect2 r = cell_rect; if (drop_mode_section == -1 || drop_mode_section == 0) { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y, r.size.x, 1), cache.drop_position_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), cache.drop_position_color); } if (drop_mode_section == 0) { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y, 1, r.size.y), cache.drop_position_color); - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x + r.size.x - 1, r.pos.y, 1, r.size.y), cache.drop_position_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, 1, r.size.y), cache.drop_position_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x + r.size.x - 1, r.position.y, 1, r.size.y), cache.drop_position_color); } if (drop_mode_section == 1 || drop_mode_section == 0) { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y + r.size.y, r.size.x, 1), cache.drop_position_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y + r.size.y, r.size.x, 1), cache.drop_position_color); } } Color col = p_item->cells[i].custom_color ? p_item->cells[i].color : get_color(p_item->cells[i].selected ? "font_color_selected" : "font_color"); - Point2i text_pos = item_rect.pos; + Point2i text_pos = item_rect.position; text_pos.y += Math::floor((item_rect.size.y - font->get_height()) / 2) + font_ascent; switch (p_item->cells[i].mode) { @@ -1093,7 +1121,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 Ref<Texture> checked = cache.checked; Ref<Texture> unchecked = cache.unchecked; - Point2i check_ofs = item_rect.pos; + Point2i check_ofs = item_rect.position; check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2); if (p_item->cells[i].checked) { @@ -1108,7 +1136,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 text_pos.x += check_w; item_rect.size.x -= check_w; - item_rect.pos.x += check_w; + item_rect.position.x += check_w; draw_item_rect(p_item->cells[i], item_rect, col); @@ -1136,7 +1164,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 font->draw(ci, text_pos, s, col, item_rect.size.x - downarrow->get_width()); //? - Point2i arrow_pos = item_rect.pos; + Point2i arrow_pos = item_rect.position; arrow_pos.x += item_rect.size.x - downarrow->get_width(); arrow_pos.y += Math::floor(((item_rect.size.y - downarrow->get_height())) / 2.0); @@ -1156,7 +1184,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (!p_item->cells[i].editable) break; - Point2i updown_pos = item_rect.pos; + Point2i updown_pos = item_rect.position; updown_pos.x += item_rect.size.x - updown->get_width(); updown_pos.y += Math::floor(((item_rect.size.y - updown->get_height())) / 2.0); @@ -1175,7 +1203,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } Point2i icon_ofs = (item_rect.size - icon_size) / 2; - icon_ofs += item_rect.pos; + icon_ofs += item_rect.position; draw_texture_rect(p_item->cells[i].icon, Rect2(icon_ofs, icon_size)); //p_item->cells[i].icon->draw(ci, icon_ofs); @@ -1201,12 +1229,28 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 Ref<Texture> downarrow = cache.select_arrow; Rect2i ir = item_rect; - ir.size.width -= downarrow->get_width(); - draw_item_rect(p_item->cells[i], ir, col); - Point2i arrow_pos = item_rect.pos; + Point2i arrow_pos = item_rect.position; arrow_pos.x += item_rect.size.x - downarrow->get_width(); arrow_pos.y += Math::floor(((item_rect.size.y - downarrow->get_height())) / 2.0); + ir.size.width -= downarrow->get_width(); + + if (p_item->cells[i].custom_button) { + if (cache.hover_item == p_item && cache.hover_cell == i) { + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + draw_style_box(cache.custom_button_pressed, ir); + } else { + draw_style_box(cache.custom_button_hover, ir); + col = cache.custom_button_font_highlight; + } + } else { + draw_style_box(cache.custom_button, ir); + } + ir.size -= cache.custom_button->get_minimum_size(); + ir.position += cache.custom_button->get_offset(); + } + + draw_item_rect(p_item->cells[i], ir, col); downarrow->draw(ci, arrow_pos); @@ -1409,10 +1453,12 @@ void Tree::_range_click_timeout() { } click_handled = false; - InputModifierState mod = InputModifierState(); // should be irrelevant.. + Ref<InputEventMouseButton> mb; + mb.instance(); + ; blocked++; - propagate_mouse_event(pos + cache.offset, 0, 0, false, root, BUTTON_LEFT, mod); + propagate_mouse_event(pos + cache.offset, 0, 0, false, root, BUTTON_LEFT, mb); blocked--; if (range_click_timer->is_one_shot()) { @@ -1429,7 +1475,7 @@ void Tree::_range_click_timeout() { } } -int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const InputModifierState &p_mod) { +int Tree::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) { int item_h = compute_item_height(p_item) + cache.vseparation; @@ -1517,10 +1563,11 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool if (p_doubleclick && (!c.editable || c.mode == TreeItem::CELL_MODE_CUSTOM || c.mode == TreeItem::CELL_MODE_ICON /*|| c.mode==TreeItem::CELL_MODE_CHECK*/)) { //it' s confusing for check emit_signal("item_activated"); + incr_search.clear(); return -1; } - if (select_mode == SELECT_MULTI && p_mod.command && c.selectable) { + if (select_mode == SELECT_MULTI && p_mod->get_command() && c.selectable) { if (!c.selected || p_button == BUTTON_RIGHT) { @@ -1542,7 +1589,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool if (c.selectable) { - if (select_mode == SELECT_MULTI && p_mod.shift && selected_item && selected_item != p_item) { + if (select_mode == SELECT_MULTI && p_mod->get_shift() && selected_item && selected_item != p_item) { bool inrange = false; @@ -1693,11 +1740,18 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool case TreeItem::CELL_MODE_CUSTOM: { edited_item = p_item; edited_col = col; - custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - cache.offset.y), Size2(get_column_width(col), item_h)); - emit_signal("custom_popup_edited", ((bool)(x >= (col_width - item_h / 2)))); + bool on_arrow = x > col_width - cache.select_arrow->get_width(); bring_up_editor = false; - item_edited(col, p_item); + + if (on_arrow || !p_item->cells[col].custom_button) { + custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - cache.offset.y), Size2(get_column_width(col), item_h)); + emit_signal("custom_popup_edited", ((bool)(x >= (col_width - item_h / 2)))); + } + + if (!p_item->cells[col].custom_button || !on_arrow) { + item_edited(col, p_item); + } click_handled = true; return -1; } break; @@ -1837,516 +1891,540 @@ void Tree::popup_select(int p_option) { item_edited(popup_edited_item_col, popup_edited_item); } -void Tree::_gui_input(InputEvent p_event) { +void Tree::_gui_input(Ref<InputEvent> p_event) { - switch (p_event.type) { + Ref<InputEventKey> k = p_event; - case InputEvent::KEY: { + if (k.is_valid()) { - if (!p_event.key.pressed) - break; - if (p_event.key.mod.alt || p_event.key.mod.command || (p_event.key.mod.shift && p_event.key.unicode == 0) || p_event.key.mod.meta) - break; - if (!root) - return; + if (!k->is_pressed()) + return; + if (k->get_alt() || k->get_command() || (k->get_shift() && k->get_unicode() == 0) || k->get_metakey()) + return; + if (!root) + return; - if (hide_root && !root->get_next_visible()) - return; + if (hide_root && !root->get_next_visible()) + return; - switch (p_event.key.scancode) { + switch (k->get_scancode()) { #define EXIT_BREAK \ { \ if (!cursor_can_exit_tree) accept_event(); \ break; \ } - case KEY_RIGHT: { - - //TreeItem *next = NULL; - if (!selected_item) - break; - if (select_mode == SELECT_ROW) - EXIT_BREAK; - if (selected_col >= (columns.size() - 1)) - EXIT_BREAK; - if (select_mode == SELECT_MULTI) { - selected_col++; - emit_signal("cell_selected"); - } else { - - selected_item->select(selected_col + 1); - } + case KEY_RIGHT: { + + //TreeItem *next = NULL; + if (!selected_item) + break; + if (select_mode == SELECT_ROW) + EXIT_BREAK; + if (selected_col >= (columns.size() - 1)) + EXIT_BREAK; + if (select_mode == SELECT_MULTI) { + selected_col++; + emit_signal("cell_selected"); + } else { - update(); - ensure_cursor_is_visible(); - accept_event(); + selected_item->select(selected_col + 1); + } - } break; - case KEY_LEFT: { + update(); + ensure_cursor_is_visible(); + accept_event(); - //TreeItem *next = NULL; - if (!selected_item) - break; - if (select_mode == SELECT_ROW) - EXIT_BREAK; - if (selected_col <= 0) - EXIT_BREAK; - if (select_mode == SELECT_MULTI) { - selected_col--; - emit_signal("cell_selected"); - } else { + } break; + case KEY_LEFT: { + + //TreeItem *next = NULL; + if (!selected_item) + break; + if (select_mode == SELECT_ROW) + EXIT_BREAK; + if (selected_col <= 0) + EXIT_BREAK; + if (select_mode == SELECT_MULTI) { + selected_col--; + emit_signal("cell_selected"); + } else { - selected_item->select(selected_col - 1); - } + selected_item->select(selected_col - 1); + } - update(); - accept_event(); + update(); + accept_event(); - } break; - case KEY_DOWN: { + } break; + case KEY_DOWN: { - TreeItem *next = NULL; - if (!selected_item) { + TreeItem *next = NULL; + if (!selected_item) { - next = hide_root ? root->get_next_visible() : root; - selected_item = 0; - } else { + next = hide_root ? root->get_next_visible() : root; + selected_item = 0; + } else { - next = selected_item->get_next_visible(); + 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 (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 (select_mode == SELECT_MULTI) { - if (!next) - EXIT_BREAK; + if (!next) + EXIT_BREAK; - selected_item = next; - emit_signal("cell_selected"); - update(); - } else { + selected_item = next; + emit_signal("cell_selected"); + update(); + } else { - int col = selected_col < 0 ? 0 : selected_col; + 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); - } + 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(); + ensure_cursor_is_visible(); + accept_event(); - } break; - case KEY_UP: { + } break; + case KEY_UP: { - TreeItem *prev = NULL; - if (!selected_item) { - prev = get_last_item(); - selected_col = 0; - } else { + 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; - } + 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 (select_mode == SELECT_MULTI) { - if (!prev) - break; - selected_item = prev; - emit_signal("cell_selected"); - update(); - } else { + 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); - } + 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(); + ensure_cursor_is_visible(); + accept_event(); - } break; - case KEY_PAGEDOWN: { + } break; + case KEY_PAGEDOWN: { - TreeItem *next = NULL; - if (!selected_item) - break; - next = selected_item; + TreeItem *next = NULL; + if (!selected_item) + break; + next = selected_item; - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; i++) { - TreeItem *_n = next->get_next_visible(); - if (_n) { - next = _n; - } else { + TreeItem *_n = next->get_next_visible(); + if (_n) { + next = _n; + } else { - break; - } - } - if (next == selected_item) break; + } + } + if (next == selected_item) + break; - if (select_mode == SELECT_MULTI) { + if (select_mode == SELECT_MULTI) { - selected_item = next; - emit_signal("cell_selected"); - update(); - } else { + 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); - } + 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: { + ensure_cursor_is_visible(); + } break; + case KEY_PAGEUP: { - TreeItem *prev = NULL; - if (!selected_item) - break; - prev = selected_item; + TreeItem *prev = NULL; + if (!selected_item) + break; + prev = selected_item; - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; i++) { - TreeItem *_n = prev->get_prev_visible(); - if (_n) { - prev = _n; - } else { + TreeItem *_n = prev->get_prev_visible(); + if (_n) { + prev = _n; + } else { - break; - } - } - if (prev == selected_item) break; + } + } + if (prev == selected_item) + break; - if (select_mode == SELECT_MULTI) { + if (select_mode == SELECT_MULTI) { - selected_item = prev; - emit_signal("cell_selected"); - update(); - } else { + 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); - } + 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(); + ensure_cursor_is_visible(); - } break; - case KEY_F2: - case KEY_RETURN: - case KEY_ENTER: { - - if (selected_item) { - //bring up editor if possible - if (!edit_selected()) { - emit_signal("item_activated"); - } + } break; + case KEY_F2: + case KEY_RETURN: + case KEY_ENTER: { + + if (selected_item) { + //bring up editor if possible + if (!edit_selected()) { + emit_signal("item_activated"); + incr_search.clear(); } - accept_event(); + } + 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); - } + } 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(); + } + accept_event(); - } break; - default: { + } break; + default: { - if (p_event.key.unicode > 0) { + if (k->get_unicode() > 0) { - _do_incr_search(String::chr(p_event.key.unicode)); - accept_event(); + _do_incr_search(String::chr(k->get_unicode())); + accept_event(); - return; - } else { - if (p_event.key.scancode != KEY_SHIFT) - last_keypress = 0; - } - } break; + return; + } else { + if (k->get_scancode() != KEY_SHIFT) + last_keypress = 0; + } + } break; - last_keypress = 0; - } + last_keypress = 0; + } + } - } break; + Ref<InputEventMouseMotion> mm = p_event; - case InputEvent::MOUSE_MOTION: { + if (mm.is_valid()) { - if (cache.font.is_null()) // avoid a strange case that may fuckup stuff - update_cache(); - const InputEventMouseMotion &b = p_event.mouse_motion; + if (cache.font.is_null()) // avoid a strange case that may fuckup stuff + update_cache(); - Ref<StyleBox> bg = cache.bg; + Ref<StyleBox> bg = cache.bg; - Point2 pos = Point2(b.x, b.y) - bg->get_offset(); + Point2 pos = mm->get_position() - bg->get_offset(); - Cache::ClickType old_hover = cache.hover_type; - int old_index = cache.hover_index; + Cache::ClickType old_hover = cache.hover_type; + int old_index = cache.hover_index; - cache.hover_type = Cache::CLICK_NONE; - cache.hover_index = 0; - if (show_column_titles) { - pos.y -= _get_title_button_height(); - if (pos.y < 0) { - pos.x += cache.offset.x; - int len = 0; - for (int i = 0; i < columns.size(); i++) { - - len += get_column_width(i); - if (pos.x < len) { - - cache.hover_type = Cache::CLICK_TITLE; - cache.hover_index = i; - update(); - break; - } + cache.hover_type = Cache::CLICK_NONE; + cache.hover_index = 0; + if (show_column_titles) { + pos.y -= _get_title_button_height(); + if (pos.y < 0) { + pos.x += cache.offset.x; + int len = 0; + for (int i = 0; i < columns.size(); i++) { + + len += get_column_width(i); + if (pos.x < len) { + + cache.hover_type = Cache::CLICK_TITLE; + cache.hover_index = i; + update(); + break; } } } + } - if (drop_mode_flags && root) { + if (root) { - Point2 mpos = Point2(b.x, b.y); - mpos -= cache.bg->get_offset(); - mpos.y -= _get_title_button_height(); - if (mpos.y >= 0) { + Point2 mpos = mm->get_position(); + mpos -= cache.bg->get_offset(); + mpos.y -= _get_title_button_height(); + if (mpos.y >= 0) { - if (h_scroll->is_visible_in_tree()) - mpos.x += h_scroll->get_value(); - if (v_scroll->is_visible_in_tree()) - mpos.y += v_scroll->get_value(); + if (h_scroll->is_visible_in_tree()) + mpos.x += h_scroll->get_value(); + if (v_scroll->is_visible_in_tree()) + mpos.y += v_scroll->get_value(); - int col, h, section; - TreeItem *it = _find_item_at_pos(root, mpos, col, h, section); + int col, h, section; + TreeItem *it = _find_item_at_pos(root, mpos, col, h, section); - if (it != drop_mode_over || section != drop_mode_section) { - drop_mode_over = it; - drop_mode_section = section; - update(); - } + if (drop_mode_flags && it != drop_mode_over || section != drop_mode_section) { + drop_mode_over = it; + drop_mode_section = section; + update(); } - } - if (cache.hover_type != old_hover || cache.hover_index != old_index) { - update(); + if (it != cache.hover_item || col != cache.hover_cell) { + cache.hover_item = it; + cache.hover_cell = col; + update(); + } } + } - if (pressing_for_editor && popup_edited_item && (popup_edited_item->get_cell_mode(popup_edited_item_col) == TreeItem::CELL_MODE_RANGE || popup_edited_item->get_cell_mode(popup_edited_item_col) == TreeItem::CELL_MODE_RANGE_EXPRESSION)) { - //range drag + if (cache.hover_type != old_hover || cache.hover_index != old_index) { + update(); + } - if (!range_drag_enabled) { + if (pressing_for_editor && popup_edited_item && (popup_edited_item->get_cell_mode(popup_edited_item_col) == TreeItem::CELL_MODE_RANGE || popup_edited_item->get_cell_mode(popup_edited_item_col) == TreeItem::CELL_MODE_RANGE_EXPRESSION)) { + //range drag - Vector2 cpos = Vector2(b.x, b.y); - if (cpos.distance_to(pressing_pos) > 2) { - range_drag_enabled = true; - range_drag_capture_pos = cpos; - range_drag_base = popup_edited_item->get_range(popup_edited_item_col); - Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); - } - } else { + if (!range_drag_enabled) { - TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col]; - float diff_y = -b.relative_y; - diff_y = Math::pow(ABS(diff_y), 1.8f) * SGN(diff_y); - diff_y *= 0.1; - range_drag_base = CLAMP(range_drag_base + c.step * diff_y, c.min, c.max); - popup_edited_item->set_range(popup_edited_item_col, range_drag_base); - item_edited(popup_edited_item_col, popup_edited_item); + Vector2 cpos = mm->get_position(); + if (cpos.distance_to(pressing_pos) > 2) { + range_drag_enabled = true; + range_drag_capture_pos = cpos; + range_drag_base = popup_edited_item->get_range(popup_edited_item_col); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); } + } else { + + TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col]; + float diff_y = -mm->get_relative().y; + diff_y = Math::pow(ABS(diff_y), 1.8f) * SGN(diff_y); + diff_y *= 0.1; + range_drag_base = CLAMP(range_drag_base + c.step * diff_y, c.min, c.max); + popup_edited_item->set_range(popup_edited_item_col, range_drag_base); + item_edited(popup_edited_item_col, popup_edited_item); } + } - if (drag_touching && !drag_touching_deaccel) { + if (drag_touching && !drag_touching_deaccel) { - drag_accum -= b.relative_y; - v_scroll->set_value(drag_from + drag_accum); - drag_speed = -b.speed_y; - } - } break; - case InputEvent::MOUSE_BUTTON: { + drag_accum -= mm->get_relative().y; + v_scroll->set_value(drag_from + drag_accum); + drag_speed = -mm->get_speed().y; + } + } + + Ref<InputEventMouseButton> b = p_event; - if (cache.font.is_null()) // avoid a strange case that may fuckup stuff - update_cache(); - const InputEventMouseButton &b = p_event.mouse_button; + if (b.is_valid()) { + if (cache.font.is_null()) // avoid a strange case that may fuckup stuff + update_cache(); - if (!b.pressed) { + if (!b->is_pressed()) { - if (b.button_index == BUTTON_LEFT) { + if (b->get_button_index() == BUTTON_LEFT) { - if (single_select_defer) { - select_single_item(single_select_defer, root, single_select_defer_column); - single_select_defer = NULL; + Point2 pos = b->get_position() - cache.bg->get_offset(); + if (show_column_titles) { + pos.y -= _get_title_button_height(); + + if (pos.y < 0) { + pos.x += cache.offset.x; + int len = 0; + for (int i = 0; i < columns.size(); i++) { + + len += get_column_width(i); + if (pos.x < len) { + emit_signal("column_title_pressed", i); + break; + } + } } + } + + if (single_select_defer) { + select_single_item(single_select_defer, root, single_select_defer_column); + single_select_defer = NULL; + } - range_click_timer->stop(); + range_click_timer->stop(); - if (pressing_for_editor) { + if (pressing_for_editor) { - if (range_drag_enabled) { + if (range_drag_enabled) { - range_drag_enabled = false; - Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); - warp_mouse(range_drag_capture_pos); + range_drag_enabled = false; + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); + warp_mouse(range_drag_capture_pos); + } else { + Rect2 rect = get_selected()->get_meta("__focus_rect"); + if (rect.has_point(Point2(b->get_position().x, b->get_position().y))) { + edit_selected(); } else { - Rect2 rect = get_selected()->get_meta("__focus_rect"); - if (rect.has_point(Point2(p_event.mouse_button.x, p_event.mouse_button.y))) { - edit_selected(); - } else { - emit_signal("item_double_clicked"); - } + emit_signal("item_double_clicked"); } - pressing_for_editor = false; } + pressing_for_editor = false; + } - if (cache.click_type == Cache::CLICK_BUTTON) { - // make sure in case of wrong reference after reconstructing whole TreeItems - cache.click_item = get_item_at_pos(cache.click_pos); - emit_signal("button_pressed", cache.click_item, cache.click_column, cache.click_id); - } - cache.click_type = Cache::CLICK_NONE; - cache.click_index = -1; - cache.click_id = -1; - cache.click_item = NULL; - cache.click_column = 0; + if (cache.click_type == Cache::CLICK_BUTTON) { + // make sure in case of wrong reference after reconstructing whole TreeItems + cache.click_item = get_item_at_pos(cache.click_pos); + emit_signal("button_pressed", cache.click_item, cache.click_column, cache.click_id); + } + cache.click_type = Cache::CLICK_NONE; + cache.click_index = -1; + cache.click_id = -1; + cache.click_item = NULL; + cache.click_column = 0; - if (drag_touching) { + if (drag_touching) { - if (drag_speed == 0) { - drag_touching_deaccel = false; - drag_touching = false; - set_fixed_process(false); - } else { + if (drag_speed == 0) { + drag_touching_deaccel = false; + drag_touching = false; + set_fixed_process(false); + } else { - drag_touching_deaccel = true; - } + drag_touching_deaccel = true; } - update(); } - break; + update(); } + return; + } - if (range_drag_enabled) - break; - - switch (b.button_index) { - case BUTTON_RIGHT: - case BUTTON_LEFT: { - Ref<StyleBox> bg = cache.bg; + if (range_drag_enabled) + return; - Point2 pos = Point2(b.x, b.y) - bg->get_offset(); - cache.click_type = Cache::CLICK_NONE; - if (show_column_titles && b.button_index == BUTTON_LEFT) { - pos.y -= _get_title_button_height(); - - if (pos.y < 0) { - pos.x += cache.offset.x; - int len = 0; - for (int i = 0; i < columns.size(); i++) { - - len += get_column_width(i); - if (pos.x < len) { - - cache.click_type = Cache::CLICK_TITLE; - cache.click_index = i; - //cache.click_id=; - update(); - break; - } + switch (b->get_button_index()) { + case BUTTON_RIGHT: + case BUTTON_LEFT: { + Ref<StyleBox> bg = cache.bg; + + Point2 pos = b->get_position() - bg->get_offset(); + cache.click_type = Cache::CLICK_NONE; + if (show_column_titles && b->get_button_index() == BUTTON_LEFT) { + pos.y -= _get_title_button_height(); + + if (pos.y < 0) { + pos.x += cache.offset.x; + int len = 0; + for (int i = 0; i < columns.size(); i++) { + + len += get_column_width(i); + if (pos.x < len) { + + cache.click_type = Cache::CLICK_TITLE; + cache.click_index = i; + //cache.click_id=; + update(); + break; } - break; - } - } - if (!root || (!root->get_children() && hide_root)) { - if (b.button_index == BUTTON_RIGHT && allow_rmb_select) { - emit_signal("empty_tree_rmb_selected", get_local_mouse_pos()); } break; } + } + if (!root || (!root->get_children() && hide_root)) { + if (b->get_button_index() == BUTTON_RIGHT && allow_rmb_select) { + emit_signal("empty_tree_rmb_selected", get_local_mouse_pos()); + } + break; + } - click_handled = false; - pressing_for_editor = false; + click_handled = false; + pressing_for_editor = false; - blocked++; - bool handled = propagate_mouse_event(pos + cache.offset, 0, 0, b.doubleclick, root, b.button_index, b.mod); - blocked--; + blocked++; + bool handled = propagate_mouse_event(pos + cache.offset, 0, 0, b->is_doubleclick(), root, b->get_button_index(), b); + blocked--; - if (pressing_for_editor) { - pressing_pos = Point2(b.x, b.y); - } + if (pressing_for_editor) { + pressing_pos = b->get_position(); + } - if (b.button_index == BUTTON_RIGHT) - break; + if (b->get_button_index() == BUTTON_RIGHT) + break; - if (drag_touching) { - set_fixed_process(false); - drag_touching_deaccel = false; - drag_touching = false; - drag_speed = 0; - drag_from = 0; - } + if (drag_touching) { + set_fixed_process(false); + drag_touching_deaccel = false; + drag_touching = false; + drag_speed = 0; + drag_from = 0; + } - if (!click_handled) { - drag_speed = 0; - drag_accum = 0; - //last_drag_accum=0; - drag_from = v_scroll->get_value(); - drag_touching = OS::get_singleton()->has_touchscreen_ui_hint(); - drag_touching_deaccel = false; - if (drag_touching) { - set_fixed_process(true); - } + if (!click_handled) { + drag_speed = 0; + drag_accum = 0; + //last_drag_accum=0; + drag_from = v_scroll->get_value(); + drag_touching = OS::get_singleton()->has_touchscreen_ui_hint(); + drag_touching_deaccel = false; + if (drag_touching) { + set_fixed_process(true); } + } - } break; - case BUTTON_WHEEL_UP: { - - v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() / 8); - } break; - case BUTTON_WHEEL_DOWN: { + } break; + case BUTTON_WHEEL_UP: { - v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() / 8); - } break; - } + v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); + } break; + case BUTTON_WHEEL_DOWN: { - } break; + v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8); + } break; + } } } @@ -2379,7 +2457,7 @@ bool Tree::edit_selected() { edited_item = s; edited_col = col; - custom_popup_rect = Rect2i(get_global_position() + rect.pos, rect.size); + custom_popup_rect = Rect2i(get_global_position() + rect.position, rect.size); emit_signal("custom_popup_edited", false); item_edited(col, s); @@ -2394,7 +2472,7 @@ bool Tree::edit_selected() { } popup_menu->set_size(Size2(rect.size.width, 0)); - popup_menu->set_position(get_global_position() + rect.pos + Point2i(0, rect.size.height)); + popup_menu->set_position(get_global_position() + rect.position + Point2i(0, rect.size.height)); popup_menu->popup(); popup_edited_item = s; popup_edited_item_col = col; @@ -2402,7 +2480,7 @@ bool Tree::edit_selected() { } else if (c.mode == TreeItem::CELL_MODE_STRING || c.mode == TreeItem::CELL_MODE_RANGE || c.mode == TreeItem::CELL_MODE_RANGE_EXPRESSION) { - Point2i textedpos = get_global_position() + rect.pos; + Point2i textedpos = get_global_position() + rect.position; text_editor->set_position(textedpos); text_editor->set_size(rect.size); text_editor->clear(); @@ -2649,7 +2727,7 @@ void Tree::_notification(int p_what) { ofs += tbrect.size.width; //text int clip_w = tbrect.size.width - sb->get_minimum_size().width; - f->draw_halign(ci, tbrect.pos + Point2i(sb->get_offset().x, (tbrect.size.height - f->get_height()) / 2 + f->get_ascent()), HALIGN_CENTER, clip_w, columns[i].title, cache.title_button_color); + f->draw_halign(ci, tbrect.position + Point2i(sb->get_offset().x, (tbrect.size.height - f->get_height()) / 2 + f->get_ascent()), HALIGN_CENTER, clip_w, columns[i].title, cache.title_button_color); } } } @@ -3010,7 +3088,7 @@ void Tree::ensure_cursor_is_visible() { int screenh = get_size().height - h_scroll->get_combined_minimum_size().height; if (ofs + h > v_scroll->get_value() + screenh) - v_scroll->call_deferred("set_val", ofs - screenh + h); + v_scroll->call_deferred("set_value", ofs - screenh + h); else if (ofs < v_scroll->get_value()) v_scroll->set_value(ofs); } @@ -3031,11 +3109,11 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column) const { int ofs = get_item_offset(p_item); int height = compute_item_height(p_item); Rect2 r; - r.pos.y = ofs; + r.position.y = ofs; r.size.height = height; if (p_column == -1) { - r.pos.x = 0; + r.position.x = 0; r.size.x = get_size().width; } else { @@ -3043,7 +3121,7 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column) const { for (int i = 0; i < p_column; i++) { accum += get_column_width(i); } - r.pos.x = accum; + r.position.x = accum; r.size.x = get_column_width(p_column); } @@ -3290,6 +3368,19 @@ String Tree::get_tooltip(const Point2 &p_pos) const { if (it) { + TreeItem::Cell &c = it->cells[col]; + int col_width = get_column_width(col); + for (int j = c.buttons.size() - 1; j >= 0; j--) { + Ref<Texture> b = c.buttons[j].texture; + Size2 size = b->get_size() + cache.button_pressed->get_minimum_size(); + if (pos.x > col_width - size.width) { + String tooltip = c.buttons[j].tooltip; + if (tooltip != "") { + return tooltip; + } + } + col_width -= size.width; + } String ret; if (it->get_tooltip(col) == "") ret = it->get_text(col); @@ -3434,12 +3525,14 @@ void Tree::_bind_methods() { ADD_SIGNAL(MethodInfo("item_rmb_selected", PropertyInfo(Variant::VECTOR2, "pos"))); ADD_SIGNAL(MethodInfo("empty_tree_rmb_selected", PropertyInfo(Variant::VECTOR2, "pos"))); ADD_SIGNAL(MethodInfo("item_edited")); + ADD_SIGNAL(MethodInfo("item_custom_button_pressed")); ADD_SIGNAL(MethodInfo("item_double_clicked")); ADD_SIGNAL(MethodInfo("item_collapsed", PropertyInfo(Variant::OBJECT, "item"))); //ADD_SIGNAL( MethodInfo("item_doubleclicked" ) ); ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::OBJECT, "item"), PropertyInfo(Variant::INT, "column"), PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("custom_popup_edited", PropertyInfo(Variant::BOOL, "arrow_clicked"))); ADD_SIGNAL(MethodInfo("item_activated")); + ADD_SIGNAL(MethodInfo("column_title_pressed", PropertyInfo(Variant::INT, "column"))); BIND_CONSTANT(SELECT_SINGLE); BIND_CONSTANT(SELECT_ROW); @@ -3539,6 +3632,9 @@ Tree::Tree() { force_edit_checkbox_only_on_checkbox = false; set_clip_contents(true); + + cache.hover_item = NULL; + cache.hover_cell = -1; } Tree::~Tree() { |