#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.Linq; using OpenRA.Primitives; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic { public class MapChooserLogic { string selectedUid; // May be a subset of available maps if a mode filter is active string[] visibleMaps; ScrollPanelWidget scrollpanel; ScrollItemWidget itemTemplate; string mapFilter; string gameMode; [ObjectCreator.UseCtor] internal MapChooserLogic(Widget widget, string initialMap, Action onExit, Action onSelect, MapVisibility filter) { selectedUid = WidgetUtils.ChooseInitialMap(initialMap); var approving = new Action(() => { Ui.CloseWindow(); onSelect(selectedUid); }); var canceling = new Action(() => { Ui.CloseWindow(); onExit(); }); widget.Get("BUTTON_OK").OnClick = approving; widget.Get("BUTTON_CANCEL").OnClick = canceling; scrollpanel = widget.Get("MAP_LIST"); scrollpanel.Layout = new GridLayout(scrollpanel); itemTemplate = scrollpanel.Get("MAP_TEMPLATE"); var gameModeDropdown = widget.GetOrNull("GAMEMODE_FILTER"); if (gameModeDropdown != null) { var selectableMaps = Game.ModData.MapCache.Where(m => m.Status == MapStatus.Available && (m.Map.Visibility & filter) != 0); var gameModes = selectableMaps .GroupBy(m => m.Type) .Select(g => Pair.New(g.Key, g.Count())).ToList(); // 'all game types' extra item gameModes.Insert(0, Pair.New(null as string, selectableMaps.Count())); Func, string> showItem = x => "{0} ({1})".F(x.First ?? "All Game Types", x.Second); Func, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) => { var item = ScrollItemWidget.Setup(template, () => gameMode == ii.First, () => { gameMode = ii.First; EnumerateMaps(onSelect, filter); }); item.Get("LABEL").GetText = () => showItem(ii); return item; }; gameModeDropdown.OnClick = () => gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, gameModes, setupItem); gameModeDropdown.GetText = () => showItem(gameModes.First(m => m.First == gameMode)); } var mapfilterInput = widget.GetOrNull("MAPFILTER_INPUT"); if (mapfilterInput != null) { mapfilterInput.TakeKeyboardFocus(); mapfilterInput.OnEscKey = () => { if (mapfilterInput.Text.Length == 0) canceling(); else { mapFilter = mapfilterInput.Text = null; EnumerateMaps(onSelect, filter); } return true; }; mapfilterInput.OnEnterKey = () => { approving(); return true; }; mapfilterInput.OnTextEdited = () => { mapFilter = mapfilterInput.Text; EnumerateMaps(onSelect, filter); }; } var randomMapButton = widget.GetOrNull("RANDOMMAP_BUTTON"); if (randomMapButton != null) { randomMapButton.OnClick = () => { var uid = visibleMaps.Random(Game.CosmeticRandom); selectedUid = uid; scrollpanel.ScrollToItem(uid, smooth: true); }; randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Length == 0; } EnumerateMaps(onSelect, filter); } void EnumerateMaps(Action onSelect, MapVisibility filter) { var maps = Game.ModData.MapCache .Where(m => m.Status == MapStatus.Available && (m.Map.Visibility & filter) != 0) .Where(m => gameMode == null || m.Type == gameMode) .Where(m => mapFilter == null || m.Title.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0 || m.Author.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) .OrderBy(m => m.PlayerCount) .ThenBy(m => m.Title); scrollpanel.RemoveChildren(); foreach (var loop in maps) { var preview = loop; // Access the minimap to trigger async generation of the minimap. preview.GetMinimap(); var item = ScrollItemWidget.Setup(preview.Uid, itemTemplate, () => selectedUid == preview.Uid, () => selectedUid = preview.Uid, () => { Ui.CloseWindow(); onSelect(preview.Uid); }); item.IsVisible = () => item.RenderBounds.IntersectsWith(scrollpanel.RenderBounds); var titleLabel = item.Get("TITLE"); titleLabel.GetText = () => preview.Title; var previewWidget = item.Get("PREVIEW"); previewWidget.Preview = () => preview; var detailsWidget = item.GetOrNull("DETAILS"); if (detailsWidget != null) detailsWidget.GetText = () => "{0} ({1} players)".F(preview.Type, preview.PlayerCount); var authorWidget = item.GetOrNull("AUTHOR"); if (authorWidget != null) authorWidget.GetText = () => "Created by {0}".F(preview.Author); var sizeWidget = item.GetOrNull("SIZE"); if (sizeWidget != null) { var size = preview.Bounds.Width + "x" + preview.Bounds.Height; var numberPlayableCells = preview.Bounds.Width * preview.Bounds.Height; if (numberPlayableCells >= 120 * 120) size += " (Huge)"; else if (numberPlayableCells >= 90 * 90) size += " (Large)"; else if (numberPlayableCells >= 60 * 60) size += " (Medium)"; else size += " (Small)"; sizeWidget.GetText = () => size; } scrollpanel.AddChild(item); } visibleMaps = maps.Select(m => m.Uid).ToArray(); if (visibleMaps.Contains(selectedUid)) scrollpanel.ScrollToItem(selectedUid); } } }