diff --git a/locale/ui_en.properties b/locale/ui_en.properties index 6fbd52d..b5f3de2 100644 --- a/locale/ui_en.properties +++ b/locale/ui_en.properties @@ -266,3 +266,6 @@ tools/unsaved_discard_text = There are unsaved changes. Discard them? tools/window_maximize = Maximize / restore (double-click the title) tools/window_close = Close tools/menu_title = Tools + +# --- Development cover --- +ui/cover/in_development = In development diff --git a/locale/ui_es.properties b/locale/ui_es.properties index 02eb876..d123637 100644 --- a/locale/ui_es.properties +++ b/locale/ui_es.properties @@ -266,3 +266,6 @@ tools/unsaved_discard_text = Hay cambios sin guardar. ¿Descartarlos? tools/window_maximize = Maximizar / restaurar (doble clic en el título) tools/window_close = Cerrar tools/menu_title = Herramientas + +# --- Development cover --- +ui/cover/in_development = En desarrollo diff --git a/locale/ui_ja.properties b/locale/ui_ja.properties index fdae693..833281f 100644 --- a/locale/ui_ja.properties +++ b/locale/ui_ja.properties @@ -266,3 +266,6 @@ tools/unsaved_discard_text = 保存していない変更があります。破棄 tools/window_maximize = 最大化 / 元に戻す(タイトルをダブルクリック) tools/window_close = 閉じる tools/menu_title = ツール + +# --- Development cover --- +ui/cover/in_development = 開発中 diff --git a/locale/ui_ko.properties b/locale/ui_ko.properties index 4184c1a..7c4a6d6 100644 --- a/locale/ui_ko.properties +++ b/locale/ui_ko.properties @@ -266,3 +266,6 @@ tools/unsaved_discard_text = 저장하지 않은 변경이 있습니다. 버릴 tools/window_maximize = 최대화 / 복원 (제목 더블클릭) tools/window_close = 닫기 tools/menu_title = 도구 + +# --- Development cover --- +ui/cover/in_development = 개발 중 diff --git a/locale/ui_ru.properties b/locale/ui_ru.properties index a302d5b..f985478 100644 --- a/locale/ui_ru.properties +++ b/locale/ui_ru.properties @@ -266,3 +266,6 @@ tools/unsaved_discard_text = Есть несохранённые изменен tools/window_maximize = Развернуть / восстановить (двойной клик по заголовку) tools/window_close = Закрыть tools/menu_title = Инструменты + +# --- Development cover --- +ui/cover/in_development = В разработке diff --git a/locale/ui_vi.properties b/locale/ui_vi.properties index cbb78ad..13fb7ca 100644 --- a/locale/ui_vi.properties +++ b/locale/ui_vi.properties @@ -266,3 +266,6 @@ tools/unsaved_discard_text = Có thay đổi chưa lưu. Bỏ chúng? tools/window_maximize = Phóng to / khôi phục (nhấp đúp vào tiêu đề) tools/window_close = Đóng tools/menu_title = Công cụ + +# --- Development cover --- +ui/cover/in_development = Đang phát triển diff --git a/locale/ui_zh.properties b/locale/ui_zh.properties index fc0e202..abcd2df 100644 --- a/locale/ui_zh.properties +++ b/locale/ui_zh.properties @@ -266,3 +266,6 @@ tools/unsaved_discard_text = 有未保存的更改。要放弃吗? tools/window_maximize = 最大化 / 还原(双击标题) tools/window_close = 关闭 tools/menu_title = 工具 + +# --- Development cover --- +ui/cover/in_development = 开发中 diff --git a/scenes/ui/development_frame.tscn b/scenes/ui/development_frame.tscn new file mode 100644 index 0000000..a882e92 --- /dev/null +++ b/scenes/ui/development_frame.tscn @@ -0,0 +1,56 @@ +[gd_scene format=3] + +[ext_resource type="Texture2D" path="ui_images/development_frame.png" id="1_frame"] +[ext_resource type="Texture2D" path="ui_images/development_plaque_blank.png" id="2_blank"] +[ext_resource type="Script" path="res://mods/ui_base/src/Theming/DevelopmentFrame.cs" id="3_script"] + +[node name="DevelopmentFrame" type="TextureRect"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +texture = ExtResource("1_frame") +expand_mode = 1 +stretch_mode = 0 +script = ExtResource("3_script") + +[node name="Plaque" type="Control" parent="."] +layout_mode = 0 +offset_right = 1536.0 +offset_bottom = 1024.0 +mouse_filter = 2 + +[node name="Backing" type="ColorRect" parent="Plaque"] +layout_mode = 0 +offset_left = 440.0 +offset_top = 895.0 +offset_right = 1096.0 +offset_bottom = 1005.0 +mouse_filter = 2 +color = Color(0, 0, 0, 1) + +[node name="Blank" type="TextureRect" parent="Plaque"] +layout_mode = 0 +offset_left = 440.0 +offset_top = 895.0 +offset_right = 1096.0 +offset_bottom = 1005.0 +mouse_filter = 2 +texture = ExtResource("2_blank") +expand_mode = 1 + +[node name="Caption" type="Label" parent="Plaque"] +layout_mode = 0 +offset_left = 440.0 +offset_top = 895.0 +offset_right = 1096.0 +offset_bottom = 1005.0 +mouse_filter = 2 +theme_override_colors/font_color = Color(1, 0.9, 0, 1) +theme_override_font_sizes/font_size = 72 +text = "ui/cover/in_development" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/src/Theming/DevelopmentFrame.cs b/src/Theming/DevelopmentFrame.cs new file mode 100644 index 0000000..0d30aef --- /dev/null +++ b/src/Theming/DevelopmentFrame.cs @@ -0,0 +1,43 @@ +using Godot; + +namespace Cthangover.Mods.Interface.Theming +{ + /// + /// Keeps the localized plaque in the artwork's coordinate system so the same + /// prefab fits both small gallery covers and large detail views. + /// + public partial class DevelopmentFrame : TextureRect + { + private Control _plaque; + private TextureRect _blank; + private AtlasTexture _blankTexture; + + public override void _Ready() + { + _plaque = GetNode("Plaque"); + _blank = _plaque.GetNode("Blank"); + // Only the generated blank plaque is used; the original frame keeps + // its border and transparent opening. Geometry comes from the prefab. + _blankTexture = new AtlasTexture { Atlas = _blank.Texture, Region = _blank.GetRect() }; + _blank.Texture = _blankTexture; + Resized += FitPlaque; + FitPlaque(); + } + + public override void _ExitTree() + { + Resized -= FitPlaque; + if (_blankTexture != null) + { + _blank.Texture = null; + _blankTexture.Dispose(); + _blankTexture = null; + } + } + + private void FitPlaque() + { + _plaque.Scale = Size / Texture.GetSize(); + } + } +} diff --git a/src/Theming/UiKit.cs b/src/Theming/UiKit.cs index 3d25dc8..1629e1a 100644 --- a/src/Theming/UiKit.cs +++ b/src/Theming/UiKit.cs @@ -1,4 +1,6 @@ using Cthangover.Core.Mods.Resolvers; +using Cthangover.Core.Scenes; +using Cthangover.Core.Utils; using Godot; using Cthangover.Core.UI.Theming; @@ -26,6 +28,14 @@ namespace Cthangover.Mods.Interface.Theming /// public static class UiKit { + /// Creates a non-interactive cover overlay; its scene owns the generated art and layout. + public static Control DevelopmentFrame(string version) + { + var frame = (Control)TscnScenes.LoadAndBuild("scenes/ui/development_frame.tscn"); + frame.Visible = VersionHelper.IsInDevelopment(version); + return frame; + } + /// Rounded frame from tokens; pass transparent border to omit it. public static StyleBoxFlat Frame(int radius, Color background, Color? border = null, int borderWidth = 1) { diff --git a/tests/DevelopmentFrameTests.cs b/tests/DevelopmentFrameTests.cs new file mode 100644 index 0000000..495a73d --- /dev/null +++ b/tests/DevelopmentFrameTests.cs @@ -0,0 +1,32 @@ +namespace Cthangover.Mods.Interface.Theming.Tests +{ + using Cthangover.Core.Mods.Testing; + using Godot; + + /// Checks the real shared prefab and decoded alpha, including the release version without an overlay. + public class DevelopmentFrameTests + { + [ModTest("covers/development_frame")] + static void DevelopmentFrame(ModTestContext ctx) + { + var frame = UiKit.DevelopmentFrame("0.1.0"); + var release = UiKit.DevelopmentFrame("1.0.0"); + try + { + ModAssert.True(frame.Visible, "zero major is marked"); + ModAssert.False(release.Visible, "released package is unmarked"); + ModAssert.Equal((int)Control.MouseFilterEnum.Ignore, (int)frame.MouseFilter, "frame does not intercept cover clicks"); + var texture = ((TextureRect)frame).Texture; + ModAssert.True(texture != null, "generated texture resolves through the mod provider"); + using var image = texture.GetImage(); + ModAssert.True(image.GetPixel(image.GetWidth() / 2, image.GetHeight() / 2).A == 0, "centre leaves the game art visible"); + ModAssert.True(image.GetPixel(image.GetWidth() / 2, 4).A > 0.9f, "hazard tape is visible"); + } + finally + { + frame.Free(); + release.Free(); + } + } + } +} diff --git a/ui_images/development_frame.png b/ui_images/development_frame.png new file mode 100644 index 0000000..36a39e0 Binary files /dev/null and b/ui_images/development_frame.png differ diff --git a/ui_images/development_plaque_blank.png b/ui_images/development_plaque_blank.png new file mode 100644 index 0000000..792a6ad Binary files /dev/null and b/ui_images/development_plaque_blank.png differ