167 lines
5.7 KiB
C#
167 lines
5.7 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2014 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.RA.Widgets.Logic
|
|
{
|
|
public class MapChooserLogic
|
|
{
|
|
string selectedUid;
|
|
|
|
// May be a subset of available maps if a mode filter is active
|
|
List<string> visibleMaps;
|
|
|
|
ScrollPanelWidget scrollpanel;
|
|
ScrollItemWidget itemTemplate;
|
|
string mapFilter;
|
|
string gameMode;
|
|
|
|
[ObjectCreator.UseCtor]
|
|
internal MapChooserLogic(Widget widget, string initialMap, Action onExit, Action<string> onSelect, MapVisibility filter)
|
|
{
|
|
selectedUid = WidgetUtils.ChooseInitialMap(initialMap);
|
|
|
|
var approving = new Action(() => { Ui.CloseWindow(); onSelect(selectedUid); });
|
|
var canceling = new Action(() => { Ui.CloseWindow(); onExit(); });
|
|
|
|
widget.Get<ButtonWidget>("BUTTON_OK").OnClick = approving;
|
|
widget.Get<ButtonWidget>("BUTTON_CANCEL").OnClick = canceling;
|
|
|
|
scrollpanel = widget.Get<ScrollPanelWidget>("MAP_LIST");
|
|
scrollpanel.Layout = new GridLayout(scrollpanel);
|
|
|
|
itemTemplate = scrollpanel.Get<ScrollItemWidget>("MAP_TEMPLATE");
|
|
|
|
var gameModeDropdown = widget.GetOrNull<DropDownButtonWidget>("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<Pair<string, int>, string> showItem =
|
|
x => "{0} ({1})".F(x.First ?? "All Game Types", x.Second);
|
|
|
|
Func<Pair<string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
|
|
{
|
|
var item = ScrollItemWidget.Setup(template,
|
|
() => gameMode == ii.First,
|
|
() => { gameMode = ii.First; EnumerateMaps(onSelect, filter); });
|
|
item.Get<LabelWidget>("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<TextFieldWidget>("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<ButtonWidget>("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.Count == 0;
|
|
}
|
|
|
|
EnumerateMaps(onSelect, filter);
|
|
}
|
|
|
|
void EnumerateMaps(Action<string> 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<LabelWidget>("TITLE");
|
|
titleLabel.GetText = () => preview.Title;
|
|
|
|
var previewWidget = item.Get<MapPreviewWidget>("PREVIEW");
|
|
previewWidget.Preview = () => preview;
|
|
|
|
var detailsWidget = item.GetOrNull<LabelWidget>("DETAILS");
|
|
if (detailsWidget != null)
|
|
detailsWidget.GetText = () => "{0} ({1} players)".F(preview.Type, preview.PlayerCount);
|
|
|
|
var authorWidget = item.GetOrNull<LabelWidget>("AUTHOR");
|
|
if (authorWidget != null)
|
|
authorWidget.GetText = () => "Created by {0}".F(preview.Author);
|
|
|
|
var sizeWidget = item.GetOrNull<LabelWidget>("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).ToList();
|
|
if (visibleMaps.Contains(selectedUid))
|
|
scrollpanel.ScrollToItem(selectedUid);
|
|
}
|
|
}
|
|
}
|