Repository: godotengine/godot
File: editor/plugins/texture_editor_plugin.cpp (C++)

Code before:
		// It's okay that these colors are static since the grid color is static too.
		metadata_label->add_theme_color_override(SceneStringName(font_color), Color(1, 1, 1));
		metadata_label->add_theme_color_override("font_shadow_color", Color(0, 0, 0));

		metadata_label->add_theme_font_size_override(SceneStringName(font_size), 14 * EDSCALE);
		metadata_label->add_theme_color_override("font_outline_color", Color(0, 0, 0));
		metadata_label->add_theme_constant_override("outline_size", 8 * EDSCALE);

		metadata_label->set_h_size_flags(Control::SIZE_SHRINK_END);
		metadata_label->set_v_size_flags(Control::SIZE_SHRINK_END);

		add_child(metadata_label);
	}
}

bool EditorInspectorPluginTexture::can_handle(Object *p_object) {
	return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<CompressedTexture2D>(p_object) != nullptr || Object::cast_to<PortableCompressedTexture2D>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr || Object::cast_to<Image>(p_object) != nullptr;
}

void EditorInspectorPluginTexture::parse_begin(Object *p_object) {
	Ref<Texture> texture(Object::cast_to<Texture>(p_object));
	if (texture.is_null()) {
		Ref<Image> image(Object::cast_to<Image>(p_object));
		texture = ImageTexture::create_from_image(image);

		ERR_FAIL_COND_MSG(texture.is_null(), "Failed to create the texture from an invalid image.");
	}

	add_custom_control(memnew(TexturePreview(texture, true)));
}

TextureEditorPlugin::TextureEditorPlugin() {
	Ref<EditorInspectorPluginTexture> plugin;
	plugin.instantiate();
	add_inspector_plugin(plugin);
}


Review comment (suggestion):
Hmm, actually half of this 2-width border will be behind the texture display area (ReferenceRect draws the border with its center being on the rect edge), meaning it could add some visual noise in case the overlapping checkerboard's / the displayed texture's border pixel colors are semi-transparent.

So correct would be to draw only the 1-width border part outside the texture display area, so no overlapping could happen. The question is how exactly to achieve this. AFAICT can't use MarginContainer(s) for 0.5 offsets as they support only integer margins. One way would be to replace this ReferenceRect with a plain Control and manually draw needed rect on its `draw` signal, like `border_drawer.draw_rect(Vector2(-0.5, -0.5), border_drawer.get_size() + Vector2(1, 1), border_color, false, 1.0);`

Alternative could be e.g. adding different border placement mode(s) to ReferenceRect so you could pick to draw the border inside the rect instead of on its edge (then you could just change such mode and set the width to `1`). But this might be overdoing/overcomplicating, not sure.

---

BTW note that the hierarchy could be flatten a little (so all fitting-in would be done directly by the containers, and there would be no need for `draw_behind_parent`), like:

| Current | More flat |
|--------|--------|
|![8c8pHDaBji](https://github.com/user-attachments/assets/6b2c28ff-71f9-4ae2-af18-e612fdf3c0f2)|![FHvGNszGyu](https://github.com/user-attachments/assets/99480c19-a2d7-41da-8f92-ff7d4f46d731)|

Seems simpler to me, but probably fine as is / not a big deal. :upside_down_face:

Code after:
	add_child(bg_rect);

	margin_container = memnew(MarginContainer);
	const float outline_width = Math::round(EDSCALE);
	margin_container->add_theme_constant_override("margin_right", outline_width);
	margin_container->add_theme_constant_override("margin_top", outline_width);
	margin_container->add_theme_constant_override("margin_left", outline_width);
	margin_container->add_theme_constant_override("margin_bottom", outline_width);
	add_child(margin_container);

	centering_container = memnew(AspectRatioContainer);
	margin_container->add_child(centering_container);

	checkerboard = memnew(TextureRect);
	checkerboard->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE);
	checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE);
	checkerboard->set_texture_repeat(CanvasItem::TEXTURE_REPEAT_ENABLED);
	centering_container->add_child(checkerboard);

	texture_display = memnew(TextureRect);
	texture_display->set_texture_filter(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
	texture_display->set_texture(p_texture);
	texture_display->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE);
	centering_container->add_child(texture_display);

	texture_display->connect(SceneStringName(draw), callable_mp(this, &TexturePreview::_draw_outline));

	if (p_texture.is_valid()) {
		_update_texture_display_ratio();
		p_texture->connect_changed(callable_mp(this, &TexturePreview::_update_texture_display_ratio));
	}

	if (p_show_metadata) {
		metadata_label = memnew(Label);

		if (p_texture.is_valid()) {
			_update_metadata_label_text();
			p_texture->connect_changed(callable_mp(this, &TexturePreview::_update_metadata_label_text));
		}

		// It's okay that these colors are static since the grid color is static too.
		metadata_label->add_theme_color_override(SceneStringName(font_color), Color(1, 1, 1));
		metadata_label->add_theme_color_override("font_shadow_color", Color(0, 0, 0));

		metadata_label->add_theme_font_size_override(SceneStringName(font_size), 14 * EDSCALE);
		metadata_label->add_theme_color_override("font_outline_color", Color(0, 0, 0));
		metadata_label->add_theme_constant_override("outline_size", 8 * EDSCALE);

		metadata_label->set_h_size_flags(Control::SIZE_SHRINK_END);
		metadata_label->set_v_size_flags(Control::SIZE_SHRINK_END);