Fix scaling issues

This commit is contained in:
Gustas
2025-09-26 16:20:52 +03:00
committed by Gustas Kažukauskas
parent b340c42ab1
commit 5ff7c9f269
9 changed files with 95 additions and 60 deletions

View File

@@ -9,7 +9,6 @@
*/
#endregion
using System;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Graphics;
@@ -22,7 +21,7 @@ namespace OpenRA.Mods.Common.Widgets
public class ActorPreviewWidget : Widget
{
public bool Animate = false;
public Func<float> GetScale = () => 1f;
public float Scale = 1f;
readonly WorldRenderer worldRenderer;
readonly WorldViewportSizes viewportSizes;
@@ -59,14 +58,17 @@ namespace OpenRA.Mods.Common.Widgets
var r = preview.SelectMany(p => p.ScreenBounds(worldRenderer, WPos.Zero));
var b = r.Union();
IdealPreviewSize = new int2((int)(b.Width * viewportSizes.DefaultScale), (int)(b.Height * viewportSizes.DefaultScale));
PreviewOffset = -new int2((int)(b.Left * viewportSizes.DefaultScale), (int)(b.Top * viewportSizes.DefaultScale)) - IdealPreviewSize / 2;
var previewTopLeft = new int2((int)(b.Left * viewportSizes.DefaultScale), (int)(b.Top * viewportSizes.DefaultScale));
PreviewOffset = previewTopLeft + IdealPreviewSize / 2;
}
IFinalizedRenderable[] renderables;
public override void PrepareRenderables()
{
var scale = GetScale() * viewportSizes.DefaultScale;
var origin = RenderOrigin + PreviewOffset + new int2(RenderBounds.Size.Width / 2, RenderBounds.Size.Height / 2);
var scale = Scale * viewportSizes.DefaultScale;
var origin = RenderOrigin - new int2(
(int)(PreviewOffset.X * scale - RenderBounds.Size.Width / 2),
(int)(PreviewOffset.Y * scale - RenderBounds.Size.Height / 2));
renderables = preview
.SelectMany(p => p.RenderUI(worldRenderer, origin, scale))

View File

@@ -198,11 +198,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
preview.SetPreview(actor, td);
// Scale templates to fit within the panel
var scale = 1f;
if (scale * preview.IdealPreviewSize.X > ItemTemplate.Bounds.Width)
scale = (ItemTemplate.Bounds.Width - Panel.ItemSpacing) / (float)preview.IdealPreviewSize.X;
// Preview position is assumed to be a margin
var maxPreviewWidth = item.Bounds.Width - 2 * preview.Bounds.X;
var maxPreviewHeight = item.Bounds.Height - 2 * preview.Bounds.Y;
preview.GetScale = () => scale;
var scale = 1f;
if (preview.IdealPreviewSize.X > maxPreviewWidth)
scale = maxPreviewWidth / (float)preview.IdealPreviewSize.X;
if (preview.IdealPreviewSize.Y * scale > maxPreviewHeight)
scale = maxPreviewHeight / (float)preview.IdealPreviewSize.Y;
preview.Scale = scale;
preview.Bounds.Width = (int)(scale * preview.IdealPreviewSize.X);
preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Y);

View File

@@ -43,25 +43,35 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
foreach (var resourceType in resourceRenderer.ResourceTypes)
{
var newResourcePreviewTemplate = ScrollItemWidget.Setup(layerPreviewTemplate,
var item = ScrollItemWidget.Setup(layerPreviewTemplate,
() => editor.CurrentBrush is EditorResourceBrush brush && brush.ResourceType == resourceType,
() => editor.SetBrush(new EditorResourceBrush(editor, resourceType, worldRenderer)));
newResourcePreviewTemplate.Bounds.X = 0;
newResourcePreviewTemplate.Bounds.Y = 0;
var preview = item.Get<ResourcePreviewWidget>("LAYER_PREVIEW");
preview.SetResourceType(resourceType);
var layerPreview = newResourcePreviewTemplate.Get<ResourcePreviewWidget>("LAYER_PREVIEW");
var size = layerPreview.IdealPreviewSize;
layerPreview.IsVisible = () => true;
layerPreview.ResourceType = resourceType;
layerPreview.Bounds.Width = size.Width;
layerPreview.Bounds.Height = size.Height;
newResourcePreviewTemplate.Bounds.Width = size.Width + layerPreview.Bounds.X * 2;
newResourcePreviewTemplate.Bounds.Height = size.Height + layerPreview.Bounds.Y * 2;
newResourcePreviewTemplate.IsVisible = () => true;
newResourcePreviewTemplate.GetTooltipText = () => resourceType;
// Scale templates to fit within the panel
// Preview position is assumed to be a margin
var maxPreviewWidth = item.Bounds.Width - 2 * preview.Bounds.X;
var maxPreviewHeight = item.Bounds.Height - 2 * preview.Bounds.Y;
layerTemplateList.AddChild(newResourcePreviewTemplate);
var scale = 1f;
if (preview.IdealPreviewSize.Width > maxPreviewWidth)
scale = maxPreviewWidth / (float)preview.IdealPreviewSize.Width;
if (preview.IdealPreviewSize.Height * scale > maxPreviewHeight)
scale = maxPreviewHeight / (float)preview.IdealPreviewSize.Height;
preview.Scale = scale;
preview.Bounds.Width = (int)(scale * preview.IdealPreviewSize.Width);
preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Height);
item.Bounds.Width = preview.Bounds.Width + 2 * preview.Bounds.X;
item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y;
item.IsVisible = () => true;
item.GetTooltipText = () => resourceType;
layerTemplateList.AddChild(item);
}
}
}

View File

@@ -116,11 +116,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
preview.SetTemplate(terrainInfo.Templates[tileId]);
// Scale templates to fit within the panel
var scale = 1f;
if (scale * preview.IdealPreviewSize.X > ItemTemplate.Bounds.Width)
scale = (ItemTemplate.Bounds.Width - Panel.ItemSpacing) / (float)preview.IdealPreviewSize.X;
// Preview position is assumed to be a margin
var maxPreviewWidth = item.Bounds.Width - 2 * preview.Bounds.X;
var maxPreviewHeight = item.Bounds.Height - 2 * preview.Bounds.Y;
preview.GetScale = () => scale;
var scale = 1f;
if (preview.IdealPreviewSize.X > maxPreviewWidth)
scale = maxPreviewWidth / (float)preview.IdealPreviewSize.X;
if (preview.IdealPreviewSize.Y * scale > maxPreviewHeight)
scale = maxPreviewHeight / (float)preview.IdealPreviewSize.Y;
preview.Scale = scale;
preview.Bounds.Width = (int)(scale * preview.IdealPreviewSize.X);
preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Y);

View File

@@ -179,7 +179,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
typeDictionary.Add(inits);
previewWidget.SetPreview(actor, typeDictionary);
previewWidget.GetScale = () => selectedInfo.Scale;
previewWidget.Scale = selectedInfo.Scale;
if (portraitWidget != null)
{

View File

@@ -20,7 +20,9 @@ namespace OpenRA.Mods.Common.Widgets
{
public class ResourcePreviewWidget : Widget
{
public Func<float> GetScale = () => 1f;
public float Scale = 1f;
public Size IdealPreviewSize { get; private set; }
readonly WorldRenderer worldRenderer;
readonly WorldViewportSizes viewportSizes;
@@ -29,23 +31,30 @@ namespace OpenRA.Mods.Common.Widgets
string resourceType;
IResourceRenderer resourceRenderer;
int2 spriteOffset;
public string ResourceType
public void SetResourceType(string value)
{
get => resourceType;
resourceType = value;
if (resourceType != null)
resourceRenderer = resourceRenderers.FirstOrDefault(r => r.ResourceTypes.Contains(resourceType));
else
resourceRenderer = null;
set
var bounds = resourceRenderer?.RenderUIPreview(worldRenderer, resourceType, int2.Zero, viewportSizes.DefaultScale)
.FirstOrDefault()
.PrepareRender(worldRenderer)
?.ScreenBounds(worldRenderer);
if (bounds != null)
{
resourceType = value;
if (resourceType != null)
resourceRenderer = resourceRenderers.FirstOrDefault(r => r.ResourceTypes.Contains(resourceType));
else
resourceRenderer = null;
spriteOffset = -bounds.Value.Location;
IdealPreviewSize = bounds.Value.Size;
}
else
IdealPreviewSize = new Size((int)(tileSize.Width * viewportSizes.DefaultScale), (int)(tileSize.Height * viewportSizes.DefaultScale));
}
public Size IdealPreviewSize { get; }
[ObjectCreator.UseCtor]
public ResourcePreviewWidget(ModData modData, WorldRenderer worldRenderer, World world)
{
@@ -53,15 +62,12 @@ namespace OpenRA.Mods.Common.Widgets
viewportSizes = modData.Manifest.Get<WorldViewportSizes>();
resourceRenderers = world.WorldActor.TraitsImplementing<IResourceRenderer>().ToArray();
tileSize = world.Map.Rules.TerrainInfo.TileSize;
IdealPreviewSize = new Size(
(int)(viewportSizes.DefaultScale * tileSize.Width),
(int)(viewportSizes.DefaultScale * tileSize.Height));
}
protected ResourcePreviewWidget(ResourcePreviewWidget other)
: base(other)
{
GetScale = other.GetScale;
Scale = other.Scale;
worldRenderer = other.worldRenderer;
viewportSizes = other.viewportSizes;
resourceRenderers = other.resourceRenderers;
@@ -78,12 +84,8 @@ namespace OpenRA.Mods.Common.Widgets
if (resourceRenderer == null)
return;
var scale = GetScale() * viewportSizes.DefaultScale;
var origin = RenderOrigin + new int2(
(int)(0.5f * (RenderBounds.Size.Width - scale * tileSize.Width)),
(int)(0.5f * (RenderBounds.Size.Height - scale * tileSize.Height)));
foreach (var r in resourceRenderer.RenderUIPreview(worldRenderer, resourceType, origin, scale))
var scale = Scale * viewportSizes.DefaultScale;
foreach (var r in resourceRenderer.RenderUIPreview(worldRenderer, resourceType, RenderOrigin + spriteOffset, scale))
r.PrepareRender(worldRenderer).Render(worldRenderer);
}
}

View File

@@ -9,7 +9,6 @@
*/
#endregion
using System;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Terrain;
using OpenRA.Mods.Common.Traits;
@@ -19,7 +18,7 @@ namespace OpenRA.Mods.Common.Widgets
{
public class TerrainTemplatePreviewWidget : Widget
{
public Func<float> GetScale = () => 1f;
public float Scale = 1f;
readonly ITiledTerrainRenderer terrainRenderer;
readonly WorldRenderer worldRenderer;
@@ -27,7 +26,7 @@ namespace OpenRA.Mods.Common.Widgets
TerrainTemplateInfo template;
public int2 PreviewOffset { get; private set; }
public int2 PreviewPos { get; private set; }
public int2 IdealPreviewSize { get; private set; }
[ObjectCreator.UseCtor]
@@ -48,7 +47,7 @@ namespace OpenRA.Mods.Common.Widgets
viewportSizes = other.viewportSizes;
terrainRenderer = other.terrainRenderer;
template = other.template;
GetScale = other.GetScale;
Scale = other.Scale;
}
public override TerrainTemplatePreviewWidget Clone() { return new TerrainTemplatePreviewWidget(this); }
@@ -60,7 +59,7 @@ namespace OpenRA.Mods.Common.Widgets
IdealPreviewSize = new int2((int)(b.Width * viewportSizes.DefaultScale), (int)(b.Height * viewportSizes.DefaultScale));
// Measured from the middle of the widget to the middle of the top-left cell of the template
PreviewOffset = -new int2((int)(b.Left * viewportSizes.DefaultScale), (int)(b.Top * viewportSizes.DefaultScale)) - IdealPreviewSize / 2;
PreviewPos = new int2((int)(b.Left * viewportSizes.DefaultScale), (int)(b.Top * viewportSizes.DefaultScale));
}
public override void Draw()
@@ -68,8 +67,8 @@ namespace OpenRA.Mods.Common.Widgets
if (template == null)
return;
var scale = GetScale() * viewportSizes.DefaultScale;
var origin = RenderOrigin + PreviewOffset + new int2(RenderBounds.Size.Width / 2, RenderBounds.Size.Height / 2);
var scale = Scale * viewportSizes.DefaultScale;
var origin = RenderOrigin - new int2((int)(PreviewPos.X * scale), (int)(PreviewPos.Y * scale));
foreach (var r in terrainRenderer.RenderUIPreview(worldRenderer, template, origin, scale))
r.PrepareRender(worldRenderer).Render(worldRenderer);

View File

@@ -325,7 +325,8 @@ Container@EDITOR_WORLD_ROOT:
Children:
ScrollItem@TILEPREVIEW_TEMPLATE:
Visible: false
Width: PARENT_WIDTH - 35
Width: (PARENT_WIDTH - 24) / 2 - 6
Height: PARENT_WIDTH / 2
TooltipContainer: TOOLTIP_CONTAINER
Children:
TerrainTemplatePreview@TILE_PREVIEW:
@@ -347,6 +348,8 @@ Container@EDITOR_WORLD_ROOT:
Children:
ScrollItem@LAYERPREVIEW_TEMPLATE:
Visible: false
Width: (PARENT_WIDTH - 24) / 2 - 6
Height: PARENT_WIDTH / 2
IgnoreChildMouseOver: true
TooltipContainer: TOOLTIP_CONTAINER
Children:
@@ -412,7 +415,8 @@ Container@EDITOR_WORLD_ROOT:
Children:
ScrollItem@ACTORPREVIEW_TEMPLATE:
Visible: false
Width: PARENT_WIDTH - 35
Width: (PARENT_WIDTH - 24) / 2 - 6
Height: PARENT_WIDTH / 2
TooltipContainer: TOOLTIP_CONTAINER
TooltipTemplate: SIMPLE_TOOLTIP
IgnoreChildMouseOver: true

View File

@@ -291,7 +291,8 @@ Container@EDITOR_WORLD_ROOT:
Children:
ScrollItem@TILEPREVIEW_TEMPLATE:
Visible: false
Width: PARENT_WIDTH - 35
Width: (PARENT_WIDTH - 24) / 2 - 6
Height: PARENT_WIDTH / 2
TooltipContainer: TOOLTIP_CONTAINER
Children:
TerrainTemplatePreview@TILE_PREVIEW:
@@ -315,6 +316,8 @@ Container@EDITOR_WORLD_ROOT:
Children:
ScrollItem@LAYERPREVIEW_TEMPLATE:
Visible: false
Width: (PARENT_WIDTH - 24) / 2 - 6
Height: PARENT_WIDTH / 2
IgnoreChildMouseOver: true
TooltipContainer: TOOLTIP_CONTAINER
Children:
@@ -377,7 +380,8 @@ Container@EDITOR_WORLD_ROOT:
Children:
ScrollItem@ACTORPREVIEW_TEMPLATE:
Visible: false
Width: PARENT_WIDTH - 35
Width: (PARENT_WIDTH - 24) / 2 - 6
Height: PARENT_WIDTH / 2
TooltipContainer: TOOLTIP_CONTAINER
TooltipTemplate: SIMPLE_TOOLTIP
IgnoreChildMouseOver: true