Merge pull request #7457 from pchote/actorpreviews
Introduce ActorPreviewWidget (and other related changes).
This commit is contained in:
116
OpenRA.Mods.Common/Widgets/ActorPreviewWidget.cs
Normal file
116
OpenRA.Mods.Common/Widgets/ActorPreviewWidget.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Widgets
|
||||
{
|
||||
public class ActorPreviewWidget : Widget
|
||||
{
|
||||
public bool Animate = false;
|
||||
public Func<float> GetScale = () => 1f;
|
||||
|
||||
readonly WorldRenderer worldRenderer;
|
||||
|
||||
IActorPreview[] preview = new IActorPreview[0];
|
||||
public int2 PreviewOffset { get; private set; }
|
||||
public int2 IdealPreviewSize { get; private set; }
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ActorPreviewWidget(WorldRenderer worldRenderer)
|
||||
{
|
||||
this.worldRenderer = worldRenderer;
|
||||
}
|
||||
|
||||
protected ActorPreviewWidget(ActorPreviewWidget other)
|
||||
: base(other)
|
||||
{
|
||||
preview = other.preview;
|
||||
worldRenderer = other.worldRenderer;
|
||||
}
|
||||
|
||||
public override Widget Clone() { return new ActorPreviewWidget(this); }
|
||||
|
||||
public void SetPreview(ActorInfo actor, Player owner, TypeDictionary td)
|
||||
{
|
||||
var init = new ActorPreviewInitializer(actor, owner, worldRenderer, td);
|
||||
preview = actor.Traits.WithInterface<IRenderActorPreviewInfo>()
|
||||
.SelectMany(rpi => rpi.RenderPreview(init))
|
||||
.ToArray();
|
||||
|
||||
// Calculate the preview bounds
|
||||
PreviewOffset = int2.Zero;
|
||||
IdealPreviewSize = int2.Zero;
|
||||
|
||||
var r = preview
|
||||
.SelectMany(p => p.Render(worldRenderer, WPos.Zero))
|
||||
.OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey)
|
||||
.Select(rr => rr.PrepareRender(worldRenderer));
|
||||
|
||||
if (r.Any())
|
||||
{
|
||||
var b = r.First().ScreenBounds(worldRenderer);
|
||||
foreach (var rr in r.Skip(1))
|
||||
b = Rectangle.Union(b, rr.ScreenBounds(worldRenderer));
|
||||
|
||||
IdealPreviewSize = new int2(b.Width, b.Height);
|
||||
PreviewOffset = -new int2(b.Left, b.Top) - IdealPreviewSize / 2;
|
||||
}
|
||||
}
|
||||
|
||||
IFinalizedRenderable[] renderables;
|
||||
public override void PrepareRenderables()
|
||||
{
|
||||
renderables = preview
|
||||
.SelectMany(p => p.Render(worldRenderer, WPos.Zero))
|
||||
.OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey)
|
||||
.Select(r => r.PrepareRender(worldRenderer))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
// HACK: The split between world and UI shaders is a giant PITA because it isn't
|
||||
// feasible to maintain two parallel sets of renderables for the two cases.
|
||||
// Instead, we temporarily hijack the world rendering context and set the position
|
||||
// and zoom values to give the desired screen position and size.
|
||||
var scale = GetScale();
|
||||
var origin = RenderOrigin + new int2(RenderBounds.Size.Width / 2, RenderBounds.Size.Height / 2);
|
||||
|
||||
// The scale affects world -> screen transform, which we don't want when drawing the (fixed) UI.
|
||||
if (scale != 1f)
|
||||
origin = (1f / scale * origin.ToFloat2()).ToInt2();
|
||||
|
||||
Game.Renderer.Flush();
|
||||
Game.Renderer.SetViewportParams(-origin - PreviewOffset, scale);
|
||||
|
||||
foreach (var r in renderables)
|
||||
r.Render(worldRenderer);
|
||||
|
||||
Game.Renderer.Flush();
|
||||
Game.Renderer.SetViewportParams(worldRenderer.Viewport.TopLeft, worldRenderer.Viewport.Zoom);
|
||||
}
|
||||
|
||||
public override void Tick()
|
||||
{
|
||||
if (Animate)
|
||||
foreach (var p in preview)
|
||||
p.Tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
@@ -17,16 +18,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
public class ColorPickerLogic
|
||||
{
|
||||
[ObjectCreator.UseCtor]
|
||||
public ColorPickerLogic(Widget widget, HSLColor initialColor, Action<HSLColor> onChange, WorldRenderer worldRenderer)
|
||||
public ColorPickerLogic(Widget widget, World world, HSLColor initialColor, Action<HSLColor> onChange, WorldRenderer worldRenderer)
|
||||
{
|
||||
var ticker = widget.GetOrNull<LogicTickerWidget>("ANIMATE_PREVIEW");
|
||||
if (ticker != null)
|
||||
{
|
||||
var preview = widget.Get<SpriteSequenceWidget>("PREVIEW");
|
||||
var anim = preview.GetAnimation();
|
||||
anim.PlayRepeating(anim.CurrentSequence.Name);
|
||||
ticker.OnTick = anim.Tick;
|
||||
}
|
||||
string actorType;
|
||||
if (!ChromeMetrics.TryGet<string>("ColorPickerActorType", out actorType))
|
||||
actorType = "mcv";
|
||||
|
||||
var preview = widget.GetOrNull<ActorPreviewWidget>("PREVIEW");
|
||||
var actor = world.Map.Rules.Actors[actorType];
|
||||
preview.SetPreview(actor, world.WorldActor.Owner, new TypeDictionary());
|
||||
|
||||
var hueSlider = widget.Get<SliderWidget>("HUE");
|
||||
var mixer = widget.Get<ColorMixerWidget>("MIXER");
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
readonly OrderManager orderManager;
|
||||
readonly bool skirmishMode;
|
||||
readonly Ruleset modRules;
|
||||
readonly World shellmapWorld;
|
||||
|
||||
enum PanelType { Players, Options, Kick, ForceStart }
|
||||
PanelType panel = PanelType.Players;
|
||||
@@ -108,6 +109,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
this.onExit = onExit;
|
||||
this.skirmishMode = skirmishMode;
|
||||
this.modRules = modRules;
|
||||
shellmapWorld = worldRenderer.World;
|
||||
|
||||
orderManager.AddChatLine += AddChatLine;
|
||||
Game.LobbyInfoChanged += UpdateCurrentMap;
|
||||
@@ -699,7 +701,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
else
|
||||
LobbyUtils.SetupEditableNameWidget(template, slot, client, orderManager);
|
||||
|
||||
LobbyUtils.SetupEditableColorWidget(template, slot, client, orderManager, colorPreview);
|
||||
LobbyUtils.SetupEditableColorWidget(template, slot, client, orderManager, shellmapWorld, colorPreview);
|
||||
LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, countries);
|
||||
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, Map);
|
||||
LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, Map);
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
}
|
||||
|
||||
public static void ShowColorDropDown(DropDownButtonWidget color, Session.Client client,
|
||||
OrderManager orderManager, ColorPreviewManagerWidget preview)
|
||||
OrderManager orderManager, World world, ColorPreviewManagerWidget preview)
|
||||
{
|
||||
Action onExit = () =>
|
||||
{
|
||||
@@ -143,7 +143,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
Action<HSLColor> onChange = c => preview.Color = c;
|
||||
|
||||
var colorChooser = Game.LoadWidget(orderManager.World, "COLOR_CHOOSER", null, new WidgetArgs()
|
||||
var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
|
||||
{
|
||||
{ "onChange", onChange },
|
||||
{ "initialColor", client.Color }
|
||||
@@ -377,11 +377,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
};
|
||||
}
|
||||
|
||||
public static void SetupEditableColorWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, ColorPreviewManagerWidget colorPreview)
|
||||
public static void SetupEditableColorWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, World world, ColorPreviewManagerWidget colorPreview)
|
||||
{
|
||||
var color = parent.Get<DropDownButtonWidget>("COLOR");
|
||||
color.IsDisabled = () => (s != null && s.LockColor) || orderManager.LocalClient.IsReady;
|
||||
color.OnMouseDown = _ => ShowColorDropDown(color, c, orderManager, colorPreview);
|
||||
color.OnMouseDown = _ => ShowColorDropDown(color, c, orderManager, world, colorPreview);
|
||||
|
||||
SetupColorWidget(color, s, c);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user