diff --git a/OpenRA.Game/Widgets/ButtonWidget.cs b/OpenRA.Game/Widgets/ButtonWidget.cs index 9173891190..c041f790fa 100644 --- a/OpenRA.Game/Widgets/ButtonWidget.cs +++ b/OpenRA.Game/Widgets/ButtonWidget.cs @@ -26,6 +26,7 @@ namespace OpenRA.Widgets public string Background = "button"; public bool Depressed = false; public int VisualHeight = ChromeMetrics.Get("ButtonDepth"); + public int BaseLine = 0; public string Font = ChromeMetrics.Get("ButtonFont"); public Color TextColor = ChromeMetrics.Get("ButtonTextColor"); public Color TextColorDisabled = ChromeMetrics.Get("ButtonTextColorDisabled"); @@ -78,6 +79,7 @@ namespace OpenRA.Widgets Text = other.Text; Font = other.Font; + BaseLine = other.BaseLine; TextColor = other.TextColor; TextColorDisabled = other.TextColorDisabled; Contrast = other.Contrast; @@ -202,7 +204,7 @@ namespace OpenRA.Widgets var contrast = GetContrastColor(); var s = font.Measure(text); var stateOffset = (Depressed) ? new int2(VisualHeight, VisualHeight) : new int2(0, 0); - var position = new int2(rb.X + (UsableWidth - s.X) / 2, rb.Y + (Bounds.Height - s.Y) / 2); + var position = new int2(rb.X + (UsableWidth - s.X) / 2, rb.Y - BaseLine + (Bounds.Height - s.Y) / 2); DrawBackground(rb, disabled, Depressed, Ui.MouseOverWidget == this, highlighted); if (Contrast) diff --git a/OpenRA.Game/Widgets/CheckboxWidget.cs b/OpenRA.Game/Widgets/CheckboxWidget.cs index 29a2726ac4..52b71c6c2d 100644 --- a/OpenRA.Game/Widgets/CheckboxWidget.cs +++ b/OpenRA.Game/Widgets/CheckboxWidget.cs @@ -19,7 +19,6 @@ namespace OpenRA.Widgets public string CheckType = "checked"; public Func GetCheckType; public Func IsChecked = () => false; - public int BaseLine = 1; public int CheckOffset = 2; public bool HasPressedState = ChromeMetrics.Get("CheckboxPressedState"); @@ -36,7 +35,6 @@ namespace OpenRA.Widgets CheckType = other.CheckType; GetCheckType = other.GetCheckType; IsChecked = other.IsChecked; - BaseLine = other.BaseLine; CheckOffset = other.CheckOffset; HasPressedState = other.HasPressedState; } diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index 8403ef675e..423d0ab8d5 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -34,6 +34,7 @@ namespace OpenRA.Widgets public int ItemSpacing = 2; public int ButtonDepth = ChromeMetrics.Get("ButtonDepth"); public string Background = "scrollpanel-bg"; + public string Button = "scrollpanel-button"; public int ContentHeight; public ILayout Layout; public int MinimumThumbSize = 10; @@ -140,12 +141,12 @@ namespace OpenRA.Widgets var thumbHover = Ui.MouseOverWidget == this && thumbRect.Contains(Viewport.LastMousePos); WidgetUtils.DrawPanel(Background, backgroundRect); - WidgetUtils.DrawPanel("scrollpanel-bg", scrollbarRect); - ButtonWidget.DrawBackground("button", upButtonRect, UpDisabled, UpPressed, upHover, false); - ButtonWidget.DrawBackground("button", downButtonRect, DownDisabled, DownPressed, downHover, false); + WidgetUtils.DrawPanel(Background, scrollbarRect); + ButtonWidget.DrawBackground(Button, upButtonRect, UpDisabled, UpPressed, upHover, false); + ButtonWidget.DrawBackground(Button, downButtonRect, DownDisabled, DownPressed, downHover, false); if (thumbHeight > 0) - ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, HasMouseFocus && thumbHover, thumbHover, false); + ButtonWidget.DrawBackground(Button, thumbRect, false, HasMouseFocus && thumbHover, thumbHover, false); var upOffset = !UpPressed || UpDisabled ? 4 : 4 + ButtonDepth; var downOffset = !DownPressed || DownDisabled ? 4 : 4 + ButtonDepth; diff --git a/OpenRA.Mods.RA/Widgets/Logic/GameTimerLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/GameTimerLogic.cs index c3b048f404..ae92f18f7c 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/GameTimerLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/GameTimerLogic.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic if (world.Timestep == 1) return "Max Speed"; - return "{0:F1}x Speed".F(Game.Timestep * 1f / world.Timestep); + return "{0}% Speed".F(Game.Timestep * 100 / world.Timestep); }; if (timer != null) @@ -54,6 +54,16 @@ namespace OpenRA.Mods.RA.Widgets.Logic status.IsVisible = shouldShowStatus; status.GetText = statusText; } + + var percentage = widget.GetOrNull("GAME_TIMER_PERCENTAGE"); + if (percentage != null) + { + var connection = orderManager.Connection as ReplayConnection; + if (connection != null && connection.TickCount != 0) + percentage.GetText = () => "({0}%)".F(orderManager.NetFrameNumber * 100 / connection.TickCount); + else + timer.Bounds.Width += percentage.Bounds.Width; + } } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/ReplayControlBarLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ReplayControlBarLogic.cs index f8b08ff32c..745ada8f82 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ReplayControlBarLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ReplayControlBarLogic.cs @@ -8,41 +8,88 @@ */ #endregion +using System.Collections.Generic; +using OpenRA.Network; using OpenRA.Widgets; namespace OpenRA.Mods.RA.Widgets.Logic { public class ReplayControlBarLogic { + enum PlaybackSpeed { Regular, Slow, Fast, Maximum } + + readonly Dictionary timesteps = new Dictionary() + { + { PlaybackSpeed.Regular, Game.Timestep }, + { PlaybackSpeed.Slow, Game.Timestep * 2 }, + { PlaybackSpeed.Fast, Game.Timestep / 2 }, + { PlaybackSpeed.Maximum, 1 }, + }; [ObjectCreator.UseCtor] - public ReplayControlBarLogic(Widget widget, World world) + public ReplayControlBarLogic(Widget widget, World world, OrderManager orderManager) { if (world.IsReplay) { var container = widget.Get("REPLAY_PLAYER"); + var connection = (ReplayConnection)orderManager.Connection; + var replayNetTicks = connection.TickCount; var background = widget.Parent.GetOrNull("OBSERVER_CONTROL_BG"); if (background != null) background.Bounds.Height += container.Bounds.Height; container.Visible = true; + var speed = PlaybackSpeed.Regular; var pauseButton = widget.Get("BUTTON_PAUSE"); - pauseButton.IsHighlighted = () => world.Timestep == 0; + pauseButton.IsVisible = () => world.Timestep != 0 && orderManager.NetFrameNumber < replayNetTicks; pauseButton.OnClick = () => world.Timestep = 0; + var playButton = widget.Get("BUTTON_PLAY"); + playButton.IsVisible = () => world.Timestep == 0 || orderManager.NetFrameNumber >= replayNetTicks; + playButton.OnClick = () => world.Timestep = timesteps[speed]; + playButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + var slowButton = widget.Get("BUTTON_SLOW"); - slowButton.IsHighlighted = () => world.Timestep > Game.Timestep; - slowButton.OnClick = () => world.Timestep = Game.Timestep * 2; + slowButton.IsHighlighted = () => speed == PlaybackSpeed.Slow; + slowButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + slowButton.OnClick = () => + { + speed = PlaybackSpeed.Slow; + if (world.Timestep != 0) + world.Timestep = timesteps[speed]; + }; - var normalSpeedButton = widget.Get("BUTTON_NORMALSPEED"); - normalSpeedButton.IsHighlighted = () => world.Timestep == Game.Timestep; - normalSpeedButton.OnClick = () => world.Timestep = Game.Timestep; + var normalSpeedButton = widget.Get("BUTTON_REGULAR"); + normalSpeedButton.IsHighlighted = () => speed == PlaybackSpeed.Regular; + normalSpeedButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + normalSpeedButton.OnClick = () => + { + speed = PlaybackSpeed.Regular; + if (world.Timestep != 0) + world.Timestep = timesteps[speed]; + }; - var fastforwardButton = widget.Get("BUTTON_FASTFORWARD"); - fastforwardButton.IsHighlighted = () => world.Timestep == 1; - fastforwardButton.OnClick = () => world.Timestep = 1; + var fastButton = widget.Get("BUTTON_FAST"); + fastButton.IsHighlighted = () => speed == PlaybackSpeed.Fast; + fastButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + fastButton.OnClick = () => + { + speed = PlaybackSpeed.Fast; + if (world.Timestep != 0) + world.Timestep = timesteps[speed]; + }; + + var maximumButton = widget.Get("BUTTON_MAXIMUM"); + maximumButton.IsHighlighted = () => speed == PlaybackSpeed.Maximum; + maximumButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + maximumButton.OnClick = () => + { + speed = PlaybackSpeed.Maximum; + if (world.Timestep != 0) + world.Timestep = timesteps[speed]; + }; } } } diff --git a/artsrc/cnc/chrome.svg b/artsrc/cnc/chrome.svg index 8d63ed0646..bd2285be2b 100644 --- a/artsrc/cnc/chrome.svg +++ b/artsrc/cnc/chrome.svg @@ -2,6 +2,7 @@ + + + - image/svg+xml - + @@ -1187,11 +1192,6 @@ d="m 293.4933,422.60165 6.8192,6.99268 0.0273,-7.03284 6.82877,6.91201 0.005,-7.62083 2.29527,0.005 -0.005,14.25414 -2.23215,0.005 -0.0158,-6.65429 -6.81074,6.06193 -0.0904,-5.97264 -6.83307,5.97605 z" style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - + + + + + + + + + + + + + + +