diff --git a/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs index 0ef40b0725..aea5d7f155 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs @@ -34,8 +34,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly Dictionary replayState = new Dictionary(); readonly Action onStart; readonly ModData modData; + readonly WebServices services; - Dictionary selectedSpawns; + MapPreview Map { get; set; } ReplayMetadata selectedReplay; volatile bool cancelLoadingReplays; @@ -43,8 +44,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic [ObjectCreator.UseCtor] public ReplayBrowserLogic(Widget widget, ModData modData, Action onExit, Action onStart) { + Map = MapCache.UnknownMap; panel = widget; + services = modData.Manifest.Get(); this.modData = modData; this.onStart = onStart; Game.BeforeGameStart += OnGameStart; @@ -66,31 +69,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic ThreadPool.QueueUserWorkItem(_ => LoadReplays(dir, template)); var watch = panel.Get("WATCH_BUTTON"); - watch.IsDisabled = () => selectedReplay == null || selectedReplay.GameInfo.MapPreview.Status != MapStatus.Available; + watch.IsDisabled = () => selectedReplay == null || Map.Status != MapStatus.Available; watch.OnClick = () => { WatchReplay(); }; panel.Get("REPLAY_INFO").IsVisible = () => selectedReplay != null; - var preview = panel.Get("MAP_PREVIEW"); - preview.SpawnOccupants = () => selectedSpawns; - preview.Preview = () => selectedReplay != null ? selectedReplay.GameInfo.MapPreview : null; - - var titleLabel = panel.GetOrNull("MAP_TITLE"); - if (titleLabel != null) + Ui.LoadWidget("MAP_PREVIEW", panel.Get("MAP_PREVIEW_ROOT"), new WidgetArgs { - titleLabel.IsVisible = () => selectedReplay != null; - - var font = Game.Renderer.Fonts[titleLabel.Font]; - var title = new CachedTransform(m => WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font)); - titleLabel.GetText = () => title.Update(selectedReplay.GameInfo.MapPreview); - } - - var type = panel.GetOrNull("MAP_TYPE"); - if (type != null) - { - var mapType = new CachedTransform(m => m.Categories.FirstOrDefault() ?? ""); - type.GetText = () => mapType.Update(selectedReplay.GameInfo.MapPreview); - } + { "orderManager", null }, + { "getMap", (Func)(() => Map) }, + { "onMouseDown", (Action)((preview, map, mi) => { }) }, + { "getSpawnOccupants", (Func>)(map => LobbyUtils.GetSpawnOccupants(selectedReplay.GameInfo.Players, map)) }, + }); panel.Get("DURATION").GetText = () => WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds); @@ -594,6 +584,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic SelectFirstVisibleReplay(); replayList.Layout.AdjustChildren(); + replayList.ScrollToSelectedItem(); } void SelectFirstVisibleReplay() @@ -604,15 +595,21 @@ namespace OpenRA.Mods.Common.Widgets.Logic void SelectReplay(ReplayMetadata replay) { selectedReplay = replay; - selectedSpawns = (selectedReplay != null) - ? LobbyUtils.GetSpawnOccupants(selectedReplay.GameInfo.Players, selectedReplay.GameInfo.MapPreview) - : new Dictionary(); + Map = (selectedReplay != null) ? selectedReplay.GameInfo.MapPreview : MapCache.UnknownMap; if (replay == null) return; try { + if (Map.Status != MapStatus.Available) + { + if (Map.Status == MapStatus.DownloadAvailable) + LoadMapPreviewRules(Map); + else if (Game.Settings.Game.AllowDownloading) + modData.MapCache.QueryRemoteMapDetails(services.MapRepository, new[] { Map.Uid }, LoadMapPreviewRules); + } + var players = replay.GameInfo.Players .GroupBy(p => p.Team) .OrderBy(g => g.Key); @@ -667,6 +664,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic } } + void LoadMapPreviewRules(MapPreview map) + { + new Task(() => + { + // Force map rules to be loaded on this background thread + map.PreloadRules(); + }).Start(); + } + void WatchReplay() { if (selectedReplay != null && ReplayUtils.PromptConfirmReplayCompatibility(selectedReplay)) diff --git a/mods/cnc/chrome/replaybrowser.yaml b/mods/cnc/chrome/replaybrowser.yaml index 8c46252a52..13f206597e 100644 --- a/mods/cnc/chrome/replaybrowser.yaml +++ b/mods/cnc/chrome/replaybrowser.yaml @@ -193,56 +193,25 @@ Container@REPLAYBROWSER_PANEL: X: 10 Width: PARENT_RIGHT - 20 Height: 25 - Container@MAP_BG_CONTAINER: + Container@MAP_PREVIEW_ROOT: X: PARENT_RIGHT - WIDTH - 20 - Y: 20 + Y: 50 Width: 194 - Height: 30 + 194 - Children: - Label@MAP_BG_TITLE: - Width: PARENT_RIGHT - Height: 25 - Text: Preview - Align: Center - Font: Bold - Background@MAP_BG: - Y: 30 - Width: 194 - Height: 194 - Background: panel-gray - Children: - MapPreview@MAP_PREVIEW: - X: 1 - Y: 1 - Width: 192 - Height: 192 - TooltipContainer: TOOLTIP_CONTAINER + Height: 250 Container@REPLAY_INFO: X: PARENT_RIGHT - WIDTH - 20 - Y: 20 + 30 + 194 + 10 + Y: 250 Width: 194 - Height: PARENT_BOTTOM - 20 - 30 - 194 - 10 - 20 + Height: PARENT_BOTTOM - 260 Children: - Label@MAP_TITLE: - Y: 0 - Width: PARENT_RIGHT - Height: 15 - Font: Bold - Align: Center - Label@MAP_TYPE: - Y: 15 - Width: PARENT_RIGHT - Height: 15 - Font: TinyBold - Align: Center Label@DURATION: - Y: 30 + Y: 20 Width: PARENT_RIGHT Height: 15 Font: Tiny Align: Center ScrollPanel@PLAYER_LIST: - Y: 50 + Y: 40 Width: PARENT_RIGHT Height: PARENT_BOTTOM - 50 IgnoreChildMouseOver: true diff --git a/mods/common/chrome/replaybrowser.yaml b/mods/common/chrome/replaybrowser.yaml index 3f51046c91..07ec997f6e 100644 --- a/mods/common/chrome/replaybrowser.yaml +++ b/mods/common/chrome/replaybrowser.yaml @@ -181,56 +181,25 @@ Background@REPLAYBROWSER_PANEL: X: 10 Width: PARENT_RIGHT - 20 Height: 25 - Container@MAP_BG_CONTAINER: + Container@MAP_PREVIEW_ROOT: X: PARENT_RIGHT - WIDTH - 20 - Y: 20 + Y: 50 Width: 194 - Height: 30 + 194 - Children: - Label@MAP_BG_TITLE: - Width: PARENT_RIGHT - Height: 25 - Text: Preview - Align: Center - Font: Bold - Background@MAP_BG: - Y: 30 - Width: 194 - Height: 194 - Background: dialog3 - Children: - MapPreview@MAP_PREVIEW: - X: 1 - Y: 1 - Width: 192 - Height: 192 - TooltipContainer: TOOLTIP_CONTAINER + Height: 250 Container@REPLAY_INFO: X: PARENT_RIGHT - WIDTH - 20 - Y: 20 + 30 + 194 + 10 + Y: 250 Width: 194 - Height: PARENT_BOTTOM - 20 - 30 - 194 - 10 - 55 + Height: PARENT_BOTTOM - 250 - 45 Children: - Label@MAP_TITLE: - Y: 0 - Width: PARENT_RIGHT - Height: 15 - Font: Bold - Align: Center - Label@MAP_TYPE: - Y: 15 - Width: PARENT_RIGHT - Height: 15 - Font: TinyBold - Align: Center Label@DURATION: - Y: 30 + Y: 20 Width: PARENT_RIGHT Height: 15 Font: Tiny Align: Center ScrollPanel@PLAYER_LIST: - Y: 50 + Y: 40 Width: PARENT_RIGHT Height: PARENT_BOTTOM - 50 IgnoreChildMouseOver: true