Path: blob/master/modules/objectdb_profiler/editor/data_viewers/object_view.cpp
20900 views
/**************************************************************************/1/* object_view.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "object_view.h"3132#include "editor/editor_node.h"33#include "editor/themes/editor_scale.h"34#include "scene/gui/rich_text_label.h"35#include "scene/gui/split_container.h"3637SnapshotObjectView::SnapshotObjectView() {38set_name(TTRC("Objects"));39}4041void SnapshotObjectView::show_snapshot(GameStateSnapshot *p_data, GameStateSnapshot *p_diff_data) {42SnapshotView::show_snapshot(p_data, p_diff_data);4344item_data_map.clear();45data_item_map.clear();4647set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);48set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);4950objects_view = memnew(HSplitContainer);51add_child(objects_view);52objects_view->set_anchors_preset(LayoutPreset::PRESET_FULL_RECT);5354VBoxContainer *object_column = memnew(VBoxContainer);55object_column->set_anchors_preset(LayoutPreset::PRESET_FULL_RECT);56objects_view->add_child(object_column);57object_column->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);58object_column->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);5960object_list = memnew(Tree);6162filter_bar = memnew(TreeSortAndFilterBar(object_list, TTRC("Filter Objects")));63object_column->add_child(filter_bar);64int sort_idx = 0;65if (diff_data) {66filter_bar->add_sort_option(TTRC("Snapshot"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);67}68filter_bar->add_sort_option(TTRC("Class"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);69filter_bar->add_sort_option(TTRC("Name"), TreeSortAndFilterBar::SortType::ALPHA_SORT, sort_idx++);70filter_bar->add_sort_option(TTRC("Inbound References"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, sort_idx++);71TreeSortAndFilterBar::SortOptionIndexes default_sort = filter_bar->add_sort_option(72TTRC("Outbound References"), TreeSortAndFilterBar::SortType::NUMERIC_SORT, sort_idx++);7374// Tree of objects.75object_list->set_select_mode(Tree::SelectMode::SELECT_ROW);76object_list->set_custom_minimum_size(Size2(200, 0) * EDSCALE);77object_list->set_hide_folding(false);78object_column->add_child(object_list);79object_list->set_hide_root(true);80object_list->set_columns(diff_data ? 5 : 4);81object_list->set_column_titles_visible(true);82object_list->set_theme_type_variation("TreeSecondary");8384int offset = 0;85if (diff_data) {86object_list->set_column_title(0, TTRC("Snapshot"));87object_list->set_column_expand(0, false);88object_list->set_column_title_tooltip_text(0, "A: " + snapshot_data->name + ", B: " + diff_data->name);89offset++;90}9192object_list->set_column_title(offset + 0, TTRC("Class"));93object_list->set_column_expand(offset + 0, true);94object_list->set_column_title_tooltip_text(offset + 0, TTRC("Object's class"));95object_list->set_column_title(offset + 1, TTRC("Object"));96object_list->set_column_expand(offset + 1, true);97object_list->set_column_expand_ratio(offset + 1, 2);98object_list->set_column_title_tooltip_text(offset + 1, TTRC("Object's name"));99object_list->set_column_title(offset + 2, TTRC("In"));100object_list->set_column_expand(offset + 2, false);101object_list->set_column_clip_content(offset + 2, false);102object_list->set_column_title_tooltip_text(offset + 2, TTRC("Number of inbound references"));103object_list->set_column_custom_minimum_width(offset + 2, 30 * EDSCALE);104object_list->set_column_title(offset + 3, TTRC("Out"));105object_list->set_column_expand(offset + 3, false);106object_list->set_column_clip_content(offset + 3, false);107object_list->set_column_title_tooltip_text(offset + 3, TTRC("Number of outbound references"));108object_list->set_column_custom_minimum_width(offset + 2, 30 * EDSCALE);109object_list->connect(SceneStringName(item_selected), callable_mp(this, &SnapshotObjectView::_object_selected));110object_list->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);111object_list->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);112113object_details = memnew(VBoxContainer);114object_details->set_custom_minimum_size(Size2(200, 0) * EDSCALE);115objects_view->add_child(object_details);116object_details->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);117object_details->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);118119object_list->create_item();120_insert_data(snapshot_data, TTRC("A"));121if (diff_data) {122_insert_data(diff_data, TTRC("B"));123}124125filter_bar->select_sort(default_sort.descending);126filter_bar->apply();127object_list->set_selected(object_list->get_root()->get_first_child());128// Expand the left panel as wide as we can. Passing `INT_MAX` or any very large int will have the opposite effect129// and shrink the left panel as small as it can go. So, pass an int we know is larger than the current panel, but not130// 'very' large (whatever that exact number is).131objects_view->set_split_offset(get_viewport_rect().size.x);132}133134void SnapshotObjectView::_insert_data(GameStateSnapshot *p_snapshot, const String &p_name) {135for (const KeyValue<ObjectID, SnapshotDataObject *> &pair : p_snapshot->objects) {136TreeItem *item = object_list->create_item(object_list->get_root());137int offset = 0;138if (diff_data) {139item->set_text(0, p_name);140item->set_tooltip_text(0, p_snapshot->name);141item->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);142offset = 1;143}144item->set_auto_translate_mode(offset + 0, AUTO_TRANSLATE_MODE_DISABLED);145item->set_auto_translate_mode(offset + 1, AUTO_TRANSLATE_MODE_DISABLED);146item->set_text(offset + 0, pair.value->type_name);147item->set_text(offset + 1, pair.value->get_name());148item->set_text(offset + 2, String::num_uint64(pair.value->inbound_references.size()));149item->set_text(offset + 3, String::num_uint64(pair.value->outbound_references.size()));150item_data_map[item] = pair.value;151data_item_map[pair.value] = item;152}153}154155void SnapshotObjectView::_object_selected() {156reference_item_map.clear();157158for (int i = 0; i < object_details->get_child_count(); i++) {159object_details->get_child(i)->queue_free();160}161162SnapshotDataObject *d = item_data_map[object_list->get_selected()];163EditorNode::get_singleton()->push_item(static_cast<Object *>(d));164165DarkPanelContainer *object_panel = memnew(DarkPanelContainer);166VBoxContainer *object_panel_content = memnew(VBoxContainer);167object_panel_content->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);168object_panel_content->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);169object_details->add_child(object_panel);170object_panel->add_child(object_panel_content);171object_panel_content->add_child(memnew(SpanningHeader(d->get_name())));172173ScrollContainer *properties_scroll = memnew(ScrollContainer);174properties_scroll->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);175properties_scroll->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_AUTO);176properties_scroll->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);177properties_scroll->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);178object_panel_content->add_child(properties_scroll);179180VBoxContainer *properties_container = memnew(VBoxContainer);181properties_container->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);182properties_scroll->add_child(properties_container);183properties_container->add_theme_constant_override("separation", 8);184185inbound_tree = _make_references_list(properties_container, TTRC("Inbound References"), TTRC("Source"), TTRC("Other object referencing this object"), TTRC("Property"), TTRC("Property of other object referencing this object"));186inbound_tree->connect(SceneStringName(item_selected), callable_mp(this, &SnapshotObjectView::_reference_selected).bind(inbound_tree));187TreeItem *ib_root = inbound_tree->create_item();188for (const KeyValue<String, ObjectID> &ob : d->inbound_references) {189TreeItem *i = inbound_tree->create_item(ib_root);190i->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);191i->set_auto_translate_mode(1, AUTO_TRANSLATE_MODE_DISABLED);192193SnapshotDataObject *target = d->snapshot->objects[ob.value];194i->set_text(0, target->get_name());195i->set_text(1, ob.key);196reference_item_map[i] = data_item_map[target];197}198199outbound_tree = _make_references_list(properties_container, TTRC("Outbound References"), TTRC("Property"), TTRC("Property of this object referencing other object"), TTRC("Target"), TTRC("Other object being referenced"));200outbound_tree->connect(SceneStringName(item_selected), callable_mp(this, &SnapshotObjectView::_reference_selected).bind(outbound_tree));201TreeItem *ob_root = outbound_tree->create_item();202for (const KeyValue<String, ObjectID> &ob : d->outbound_references) {203TreeItem *i = outbound_tree->create_item(ob_root);204i->set_auto_translate_mode(0, AUTO_TRANSLATE_MODE_DISABLED);205i->set_auto_translate_mode(1, AUTO_TRANSLATE_MODE_DISABLED);206207SnapshotDataObject *target = d->snapshot->objects[ob.value];208i->set_text(0, ob.key);209i->set_text(1, target->get_name());210reference_item_map[i] = data_item_map[target];211}212}213214void SnapshotObjectView::_reference_selected(Tree *p_source_tree) {215TreeItem *ref_item = p_source_tree->get_selected();216Tree *other_tree = p_source_tree == inbound_tree ? outbound_tree : inbound_tree;217other_tree->deselect_all();218TreeItem *other = reference_item_map[ref_item];219if (other) {220if (!other->is_visible()) {221// Clear the filter if we can't see the node we just chose.222filter_bar->clear_filter();223}224other->get_tree()->deselect_all();225other->get_tree()->set_selected(other);226other->get_tree()->ensure_cursor_is_visible();227}228}229230Tree *SnapshotObjectView::_make_references_list(Control *p_container, const String &p_name, const String &p_col_1, const String &p_col_1_tooltip, const String &p_col_2, const String &p_col_2_tooltip) {231VBoxContainer *vbox = memnew(VBoxContainer);232vbox->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);233vbox->set_v_size_flags(SizeFlags::SIZE_EXPAND_FILL);234vbox->add_theme_constant_override("separation", 4);235p_container->add_child(vbox);236237vbox->set_custom_minimum_size(Vector2(300, 0) * EDSCALE);238239RichTextLabel *lbl = memnew(RichTextLabel("[center]" + p_name + "[center]"));240lbl->set_fit_content(true);241lbl->set_use_bbcode(true);242vbox->add_child(lbl);243Tree *tree = memnew(Tree);244tree->set_hide_folding(true);245vbox->add_child(tree);246tree->set_select_mode(Tree::SelectMode::SELECT_ROW);247tree->set_hide_root(true);248tree->set_columns(2);249tree->set_column_titles_visible(true);250tree->set_column_title(0, p_col_1);251tree->set_column_expand(0, true);252tree->set_column_title_tooltip_text(0, p_col_1_tooltip);253tree->set_column_clip_content(0, false);254tree->set_column_title(1, p_col_2);255tree->set_column_expand(1, true);256tree->set_column_clip_content(1, false);257tree->set_column_title_tooltip_text(1, p_col_2_tooltip);258tree->set_v_scroll_enabled(false);259tree->set_h_size_flags(SizeFlags::SIZE_EXPAND_FILL);260261return tree;262}263264265