From cf8de3b316f35ed296b6fb51fd6b4ad643bda66f Mon Sep 17 00:00:00 2001 From: Lightning_A Date: Sun, 21 Mar 2021 15:33:17 -0600 Subject: [PATCH] Add viewport preview plugin and refactor TextureEditorPlugin --- editor/editor_node.cpp | 2 + editor/plugins/texture_editor_plugin.cpp | 146 +++++------------- editor/plugins/texture_editor_plugin.h | 18 +-- .../viewport_preview_editor_plugin.cpp | 50 ++++++ .../plugins/viewport_preview_editor_plugin.h | 56 +++++++ 5 files changed, 156 insertions(+), 116 deletions(-) create mode 100644 editor/plugins/viewport_preview_editor_plugin.cpp create mode 100644 editor/plugins/viewport_preview_editor_plugin.h diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 3babec4e11..f1d69fa0b5 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -160,6 +160,7 @@ #include "editor/plugins/tile_map_editor_plugin.h" #include "editor/plugins/tile_set_editor_plugin.h" #include "editor/plugins/version_control_editor_plugin.h" +#include "editor/plugins/viewport_preview_editor_plugin.h" #include "editor/plugins/visual_shader_editor_plugin.h" #include "editor/progress_dialog.h" #include "editor/project_export.h" @@ -6795,6 +6796,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(PhysicalBonePlugin(this))); add_editor_plugin(memnew(MeshEditorPlugin(this))); add_editor_plugin(memnew(MaterialEditorPlugin(this))); + add_editor_plugin(memnew(ViewportPreviewEditorPlugin(this))); for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) { add_editor_plugin(EditorPlugins::create(i, this)); diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 89fe66e05d..bf2c0adca0 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -30,129 +30,67 @@ #include "texture_editor_plugin.h" -#include "core/io/resource_loader.h" -#include "core/project_settings.h" -#include "editor/editor_settings.h" +#include "editor/editor_scale.h" +#include "scene/resources/dynamic_font.h" -void TextureEditor::_gui_input(Ref p_event) { +TextureRect *TexturePreview::get_texture_display() { + return texture_display; } -void TextureEditor::_notification(int p_what) { - if (p_what == NOTIFICATION_READY) { - //get_scene()->connect("node_removed",this,"_node_removed"); - } +TexturePreview::TexturePreview(Ref p_texture, bool p_show_metadata) { + TextureRect *checkerboard = memnew(TextureRect); + checkerboard->set_texture(get_icon("Checkerboard", "EditorIcons")); + checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE); + checkerboard->set_custom_minimum_size(Size2(0.0, 256.0) * EDSCALE); + add_child(checkerboard); - if (p_what == NOTIFICATION_DRAW) { - Ref checkerboard = get_icon("Checkerboard", "EditorIcons"); - Size2 size = get_size(); + texture_display = memnew(TextureRect); + texture_display->set_texture(p_texture); + texture_display->set_anchors_preset(TextureRect::PRESET_WIDE); + texture_display->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); + texture_display->set_expand(true); + add_child(texture_display); - draw_texture_rect(checkerboard, Rect2(Point2(), size), true); - - int tex_width = texture->get_width() * size.height / texture->get_height(); - int tex_height = size.height; - - if (tex_width > size.width) { - tex_width = size.width; - tex_height = texture->get_height() * tex_width / texture->get_width(); - } - - // Prevent the texture from being unpreviewable after the rescale, so that we can still see something - if (tex_height <= 0) { - tex_height = 1; - } - if (tex_width <= 0) { - tex_width = 1; - } - - int ofs_x = (size.width - tex_width) / 2; - int ofs_y = (size.height - tex_height) / 2; - - if (Object::cast_to(*texture)) { - // In the case of CurveTextures we know they are 1 in height, so fill the preview to see the gradient - ofs_y = 0; - tex_height = size.height; - } else if (Object::cast_to(*texture)) { - ofs_y = size.height / 4.0; - tex_height = size.height / 2.0; - } - - draw_texture_rect(texture, Rect2(ofs_x, ofs_y, tex_width, tex_height)); - - Ref font = get_font("font", "Label"); + if (p_show_metadata) { + Label *metadata_label = memnew(Label); String format; - if (Object::cast_to(*texture)) { - format = Image::get_format_name(Object::cast_to(*texture)->get_format()); - } else if (Object::cast_to(*texture)) { - format = Image::get_format_name(Object::cast_to(*texture)->get_format()); + if (Object::cast_to(*p_texture)) { + format = Image::get_format_name(Object::cast_to(*p_texture)->get_format()); + } else if (Object::cast_to(*p_texture)) { + format = Image::get_format_name(Object::cast_to(*p_texture)->get_format()); } else { - format = texture->get_class(); - } - String text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " " + format; - - Size2 rect = font->get_string_size(text); - - Vector2 draw_from = size - rect + Size2(-2, font->get_ascent() - 2); - if (draw_from.x < 0) { - draw_from.x = 0; + format = p_texture->get_class(); } - draw_string(font, draw_from + Vector2(2, 2), text, Color(0, 0, 0, 0.5), size.width); - draw_string(font, draw_from - Vector2(2, 2), text, Color(0, 0, 0, 0.5), size.width); - draw_string(font, draw_from, text, Color(1, 1, 1, 1), size.width); + metadata_label->set_text(itos(p_texture->get_width()) + "x" + itos(p_texture->get_height()) + " " + format); + + Ref metadata_label_font = get_font("expression", "EditorFonts")->duplicate(); + metadata_label_font->set_size(16 * EDSCALE); + metadata_label_font->set_outline_size(2 * EDSCALE); + metadata_label_font->set_outline_color(Color::named("black")); + metadata_label->add_font_override("font", metadata_label_font); + + // It's okay that these colors are static since the grid color is static too. + metadata_label->add_color_override("font_color", Color::named("white")); + metadata_label->add_color_override("font_color_shadow", Color::named("black")); + + metadata_label->add_constant_override("shadow_as_outline", 1); + metadata_label->set_h_size_flags(Control::SIZE_SHRINK_END); + metadata_label->set_v_size_flags(Control::SIZE_SHRINK_END); + + add_child(metadata_label); } } -void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) { - if (!is_visible()) { - return; - } - update(); -} - -void TextureEditor::edit(Ref p_texture) { - if (!texture.is_null()) { - texture->remove_change_receptor(this); - } - - texture = p_texture; - - if (!texture.is_null()) { - texture->add_change_receptor(this); - update(); - } else { - hide(); - } -} - -void TextureEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_gui_input"), &TextureEditor::_gui_input); -} - -TextureEditor::TextureEditor() { - set_custom_minimum_size(Size2(1, 150)); -} - -TextureEditor::~TextureEditor() { - if (!texture.is_null()) { - texture->remove_change_receptor(this); - } -} -// bool EditorInspectorPluginTexture::can_handle(Object *p_object) { return Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr; } void EditorInspectorPluginTexture::parse_begin(Object *p_object) { - Texture *texture = Object::cast_to(p_object); - if (!texture) { - return; - } - Ref m(texture); + Ref texture(Object::cast_to(p_object)); - TextureEditor *editor = memnew(TextureEditor); - editor->edit(m); - add_custom_control(editor); + add_custom_control(memnew(TexturePreview(texture, true))); } TextureEditorPlugin::TextureEditorPlugin(EditorNode *p_node) { diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h index 240d929cfb..19d8284356 100644 --- a/editor/plugins/texture_editor_plugin.h +++ b/editor/plugins/texture_editor_plugin.h @@ -35,21 +35,15 @@ #include "editor/editor_plugin.h" #include "scene/resources/texture.h" -class TextureEditor : public Control { - GDCLASS(TextureEditor, Control); +class TexturePreview : public MarginContainer { + GDCLASS(TexturePreview, MarginContainer); - Ref texture; - -protected: - void _notification(int p_what); - void _gui_input(Ref p_event); - void _changed_callback(Object *p_changed, const char *p_prop); - static void _bind_methods(); +private: + TextureRect *texture_display; public: - void edit(Ref p_texture); - TextureEditor(); - ~TextureEditor(); + TextureRect *get_texture_display(); + TexturePreview(Ref p_texture, bool p_show_metadata); }; class EditorInspectorPluginTexture : public EditorInspectorPlugin { diff --git a/editor/plugins/viewport_preview_editor_plugin.cpp b/editor/plugins/viewport_preview_editor_plugin.cpp new file mode 100644 index 0000000000..03cd57b8d5 --- /dev/null +++ b/editor/plugins/viewport_preview_editor_plugin.cpp @@ -0,0 +1,50 @@ +/*************************************************************************/ +/* viewport_preview_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "viewport_preview_editor_plugin.h" + +bool EditorInspectorPluginViewportPreview::can_handle(Object *p_object) { + return Object::cast_to(p_object) != nullptr; +} + +void EditorInspectorPluginViewportPreview::parse_begin(Object *p_object) { + Viewport *viewport = Object::cast_to(p_object); + + TexturePreview *viewport_preview = memnew(TexturePreview(viewport->get_texture(), false)); + // Otherwise `viewport_preview`'s `texture_display` doesn't update properly when `viewport`'s size changes. + viewport->connect("size_changed", viewport_preview->get_texture_display(), "update"); + add_custom_control(viewport_preview); +} + +ViewportPreviewEditorPlugin::ViewportPreviewEditorPlugin(EditorNode *p_node) { + Ref plugin; + plugin.instance(); + add_inspector_plugin(plugin); +} diff --git a/editor/plugins/viewport_preview_editor_plugin.h b/editor/plugins/viewport_preview_editor_plugin.h new file mode 100644 index 0000000000..03e33e7986 --- /dev/null +++ b/editor/plugins/viewport_preview_editor_plugin.h @@ -0,0 +1,56 @@ +/*************************************************************************/ +/* viewport_preview_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VIEWPORT_PREVIEW_EDITOR_PLUGIN_H +#define VIEWPORT_PREVIEW_EDITOR_PLUGIN_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "editor/plugins/texture_editor_plugin.h" +#include "scene/main/viewport.h" + +class EditorInspectorPluginViewportPreview : public EditorInspectorPluginTexture { + GDCLASS(EditorInspectorPluginViewportPreview, EditorInspectorPluginTexture); + +public: + virtual bool can_handle(Object *p_object); + virtual void parse_begin(Object *p_object); +}; + +class ViewportPreviewEditorPlugin : public EditorPlugin { + GDCLASS(ViewportPreviewEditorPlugin, EditorPlugin); + +public: + virtual String get_name() const { return "SubViewportPreview"; } + + ViewportPreviewEditorPlugin(EditorNode *p_node); +}; + +#endif // VIEWPORT_PREVIEW_EDITOR_PLUGIN_H