You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-21 14:57:09 +00:00
Add indicator to linked Resources
This commit is contained in:
@@ -89,12 +89,45 @@ void EditorResourcePicker::_update_resource() {
|
||||
preview_rect->set_texture(Ref<Texture2D>());
|
||||
|
||||
assign_button->set_custom_minimum_size(assign_button_min_size);
|
||||
|
||||
if (edited_resource == Ref<Resource>()) {
|
||||
assign_button->set_button_icon(Ref<Texture2D>());
|
||||
assign_button->set_text(TTR("<empty>"));
|
||||
assign_button->set_tooltip_text("");
|
||||
make_unique_button->set_disabled(true);
|
||||
make_unique_button->set_visible(false);
|
||||
} else {
|
||||
Ref<Resource> parent_res = _has_parent_resource();
|
||||
bool unique_enable = _is_uniqueness_enabled();
|
||||
bool unique_recursive_enabled = _is_uniqueness_enabled(true);
|
||||
bool is_internal = EditorNode::get_singleton()->is_resource_internal_to_scene(edited_resource);
|
||||
int num_of_copies = EditorNode::get_singleton()->get_resource_count(edited_resource);
|
||||
make_unique_button->set_button_icon(get_editor_theme_icon(SNAME("Instance")));
|
||||
make_unique_button->set_visible((num_of_copies > 1 || !is_internal) && !Object::cast_to<Script>(edited_resource.ptr()));
|
||||
make_unique_button->set_disabled((!unique_enable && !unique_recursive_enabled) || !editable);
|
||||
|
||||
String tooltip;
|
||||
|
||||
if (num_of_copies > 1) {
|
||||
tooltip = vformat(TTR("This Resource is used in (%d) places."), num_of_copies);
|
||||
} else if (!is_internal) {
|
||||
tooltip = TTR("This Resource is external to scene.");
|
||||
}
|
||||
|
||||
if (!editable) {
|
||||
tooltip += "\n" + TTR("The Resource cannot be edited in the inspector and can't be made unique directly.") + "\n";
|
||||
} else {
|
||||
tooltip += unique_enable ? TTR(" Left-click to make it unique.") + "\n" : "\n";
|
||||
|
||||
if (unique_recursive_enabled) {
|
||||
tooltip += TTR("It is possible to make its subresources unique. Right-click to make them unique.") + "\n";
|
||||
}
|
||||
|
||||
if (!unique_enable && EditorNode::get_singleton()->get_editor_selection()->get_full_selected_node_list().size() == 1) {
|
||||
tooltip += TTR("In order to duplicate it, make its parent Resource unique.") + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
make_unique_button->set_tooltip_text(tooltip);
|
||||
assign_button->set_button_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->()));
|
||||
|
||||
if (!edited_resource->get_name().is_empty()) {
|
||||
@@ -134,7 +167,10 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const
|
||||
}
|
||||
|
||||
if (p_preview.is_valid()) {
|
||||
preview_rect->set_offset(SIDE_LEFT, assign_button->get_button_icon()->get_width() + assign_button->get_theme_stylebox(CoreStringName(normal))->get_content_margin(SIDE_LEFT) + get_theme_constant(SNAME("h_separation"), SNAME("Button")));
|
||||
int thumbnail_size = (int)EDITOR_GET("filesystem/file_dialog/thumbnail_size") * EDSCALE;
|
||||
if (assign_button->get_button_icon().is_valid()) {
|
||||
preview_rect->set_offset(SIDE_LEFT, assign_button->get_button_icon()->get_width() + assign_button->get_theme_stylebox(CoreStringName(normal))->get_content_margin(SIDE_LEFT) + get_theme_constant(SNAME("h_separation"), SNAME("Button")));
|
||||
}
|
||||
|
||||
// Resource-specific stretching.
|
||||
if (Ref<GradientTexture1D>(edited_resource).is_valid() || Ref<Gradient>(edited_resource).is_valid()) {
|
||||
@@ -142,13 +178,15 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const
|
||||
assign_button->set_custom_minimum_size(assign_button_min_size);
|
||||
} else {
|
||||
preview_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
|
||||
int thumbnail_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size");
|
||||
thumbnail_size *= EDSCALE;
|
||||
assign_button->set_custom_minimum_size(assign_button_min_size.max(Size2(1, thumbnail_size)));
|
||||
}
|
||||
|
||||
preview_rect->set_texture(p_preview);
|
||||
assign_button->set_text("");
|
||||
|
||||
if (preview_rect->get_size().x <= thumbnail_size) {
|
||||
assign_button->set_button_icon(Ref<Texture2D>());
|
||||
preview_rect->set_offset(SIDE_LEFT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,10 +302,28 @@ void EditorResourcePicker::_update_menu_items() {
|
||||
if (!_is_custom_type_script()) {
|
||||
edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Clear")), TTR("Clear"), OBJ_MENU_CLEAR);
|
||||
}
|
||||
bool unique_enabled = _is_uniqueness_enabled();
|
||||
edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Duplicate")), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE);
|
||||
edit_menu->set_item_disabled(-1, !unique_enabled);
|
||||
|
||||
if (!unique_enabled) {
|
||||
if (EditorNode::get_singleton()->is_resource_internal_to_scene(edited_resource) && EditorNode::get_singleton()->get_resource_count(edited_resource) == 1) {
|
||||
edit_menu->set_item_tooltip(-1, TTRC("This Resource is already unique."));
|
||||
} else if (_has_parent_resource().is_valid()) {
|
||||
edit_menu->set_item_tooltip(-1, TTRC("In order to duplicate it, make its parent Resource unique."));
|
||||
}
|
||||
}
|
||||
|
||||
if (_has_sub_resources(edited_resource)) {
|
||||
unique_enabled = _is_uniqueness_enabled(true);
|
||||
edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Duplicate")), TTR("Make Unique (Recursive)"), OBJ_MENU_MAKE_UNIQUE_RECURSIVE);
|
||||
edit_menu->set_item_disabled(-1, !unique_enabled);
|
||||
if (!unique_enabled) {
|
||||
Ref<Resource> parent_res = _has_parent_resource();
|
||||
if (EditorNode::get_singleton()->get_editor_selection()->get_full_selected_node_list().size() == 1) {
|
||||
edit_menu->set_item_tooltip(-1, (parent_res.is_valid() && EditorNode::get_singleton()->get_resource_count(parent_res) > 1) ? TTRC("In order to duplicate recursively, make its parent Resource unique.") : TTRC("Subresources have already been made unique."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Save")), TTR("Save"), OBJ_MENU_SAVE);
|
||||
@@ -403,7 +459,6 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
|
||||
if (edited_resource.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<Resource> unique_resource = edited_resource->duplicate();
|
||||
ERR_FAIL_COND(unique_resource.is_null()); // duplicate() may fail.
|
||||
|
||||
@@ -632,6 +687,14 @@ void EditorResourcePicker::_button_input(const Ref<InputEvent> &p_event) {
|
||||
}
|
||||
}
|
||||
|
||||
void EditorResourcePicker::_on_unique_button_pressed() {
|
||||
if (Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) {
|
||||
_edit_menu_cbk(OBJ_MENU_MAKE_UNIQUE);
|
||||
} else if (Input::get_singleton()->is_mouse_button_pressed(MouseButton::RIGHT)) {
|
||||
_edit_menu_cbk(_is_uniqueness_enabled(true) ? OBJ_MENU_MAKE_UNIQUE_RECURSIVE : OBJ_MENU_MAKE_UNIQUE);
|
||||
}
|
||||
}
|
||||
|
||||
String EditorResourcePicker::_get_owner_path() const {
|
||||
EditorProperty *property = Object::cast_to<EditorProperty>(get_parent());
|
||||
if (!property) {
|
||||
@@ -953,12 +1016,14 @@ void EditorResourcePicker::_bind_methods() {
|
||||
void EditorResourcePicker::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
EditorNode::get_singleton()->connect("resource_counter_changed", callable_mp(this, &EditorResourcePicker::_update_resource));
|
||||
_update_resource();
|
||||
[[fallthrough]];
|
||||
}
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
const int icon_width = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));
|
||||
assign_button->add_theme_constant_override("icon_max_width", icon_width);
|
||||
make_unique_button->add_theme_constant_override("icon_max_width", icon_width);
|
||||
if (edit_menu) {
|
||||
edit_menu->add_theme_constant_override("icon_max_width", icon_width);
|
||||
}
|
||||
@@ -971,6 +1036,10 @@ void EditorResourcePicker::_notification(int p_what) {
|
||||
draw_style_box(get_theme_stylebox(SceneStringName(panel), SNAME("Tree")), Rect2(Point2(), get_size()));
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_RESIZED: {
|
||||
_update_resource();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_DRAG_BEGIN: {
|
||||
if (editable && _is_drop_valid(get_viewport()->gui_get_drag_data())) {
|
||||
dropping = true;
|
||||
@@ -987,9 +1056,13 @@ void EditorResourcePicker::_notification(int p_what) {
|
||||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
Callable resource_saved = callable_mp(this, &EditorResourcePicker::_resource_saved);
|
||||
Callable resource_counter_changed = callable_mp(this, &EditorResourcePicker::_update_resource);
|
||||
if (EditorNode::get_singleton()->is_connected("resource_saved", resource_saved)) {
|
||||
EditorNode::get_singleton()->disconnect("resource_saved", resource_saved);
|
||||
}
|
||||
if (EditorNode::get_singleton()->is_connected("resource_counter_changed", resource_counter_changed)) {
|
||||
EditorNode::get_singleton()->disconnect("resource_counter_changed", resource_counter_changed);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@@ -1234,7 +1307,6 @@ void EditorResourcePicker::_duplicate_selected_resources() {
|
||||
|
||||
if (meta.size() == 1) { // Root.
|
||||
edited_resource = unique_resource;
|
||||
_resource_changed();
|
||||
continue;
|
||||
}
|
||||
Array parent_meta = item->get_parent()->get_metadata(0);
|
||||
@@ -1278,9 +1350,71 @@ void EditorResourcePicker::_duplicate_selected_resources() {
|
||||
dict[meta[2]] = unique_resource;
|
||||
}
|
||||
}
|
||||
_resource_changed();
|
||||
}
|
||||
|
||||
bool EditorResourcePicker::_is_uniqueness_enabled(bool p_check_recursive) {
|
||||
Ref<Resource> parent_resource = _has_parent_resource();
|
||||
EditorNode *en = EditorNode::get_singleton();
|
||||
bool internal_to_scene = en->is_resource_internal_to_scene(edited_resource);
|
||||
List<Node *> node_list = en->get_editor_selection()->get_full_selected_node_list();
|
||||
|
||||
// Todo: Implement a more elegant solution for multiple selected Nodes. This should suffice for the time being.
|
||||
if (node_list.size() > 1 && !p_check_recursive) {
|
||||
return node_list.size() != EditorNode::get_singleton()->get_resource_count(edited_resource) || !internal_to_scene;
|
||||
}
|
||||
|
||||
if (!internal_to_scene) {
|
||||
if (parent_resource.is_valid() && (!EditorNode::get_singleton()->is_resource_internal_to_scene(parent_resource) || en->get_resource_count(parent_resource) > 1)) {
|
||||
return false;
|
||||
} else if (!p_check_recursive) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int parent_counter = en->get_resource_count(parent_resource);
|
||||
bool above_threshold = parent_resource.is_valid() ? (en->get_resource_count(parent_resource) <= 1 && en->get_resource_count(edited_resource) > 1) : en->get_resource_count(edited_resource) > 1;
|
||||
if (!p_check_recursive) {
|
||||
return above_threshold;
|
||||
}
|
||||
|
||||
if (p_check_recursive && parent_counter <= 1) {
|
||||
List<Ref<Resource>> nested_resources;
|
||||
en->gather_resources(edited_resource, nested_resources, true, true);
|
||||
|
||||
for (Ref<Resource> R : nested_resources) {
|
||||
// Take into account Nested External Resources.
|
||||
if (en->get_resource_count(R) > 1 || !EditorNode::get_singleton()->is_resource_internal_to_scene(R)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Ref<Resource> EditorResourcePicker::_has_parent_resource() {
|
||||
Node *current_node = this->get_parent();
|
||||
while (current_node != nullptr) {
|
||||
EditorProperty *ep = Object::cast_to<EditorProperty>(current_node);
|
||||
if (ep && Object::cast_to<Resource>(ep->get_edited_object())) {
|
||||
return Object::cast_to<Resource>(ep->get_edited_object());
|
||||
}
|
||||
current_node = current_node->get_parent();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) {
|
||||
make_unique_button = memnew(Button);
|
||||
make_unique_button->set_flat(true);
|
||||
make_unique_button->set_accessibility_name(TTRC("Number of Linked Resources."));
|
||||
make_unique_button->set_tooltip_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
|
||||
make_unique_button->set_button_mask(MouseButtonMask::LEFT | MouseButtonMask::RIGHT);
|
||||
make_unique_button->set_action_mode(BaseButton::ACTION_MODE_BUTTON_PRESS);
|
||||
add_child(make_unique_button);
|
||||
make_unique_button->connect(SceneStringName(pressed), callable_mp(this, &EditorResourcePicker::_on_unique_button_pressed));
|
||||
|
||||
assign_button = memnew(Button);
|
||||
assign_button->set_flat(true);
|
||||
assign_button->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
Reference in New Issue
Block a user