Extract mod selector into its own mod.

This commit is contained in:
Paul Chote
2014-03-23 17:07:10 +13:00
parent fa775a88c1
commit c720cb0b41
36 changed files with 1507 additions and 279 deletions

View File

@@ -0,0 +1,51 @@
#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.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Support;
using OpenRA.Widgets;
namespace OpenRA.Mods.Cnc
{
public class ModChooserLoadScreen : ILoadScreen
{
Sprite sprite;
Rectangle bounds;
public void Init(Manifest m, Dictionary<string, string> info)
{
var sheet = new Sheet("mods/modchooser/chrome.png");
var res = Game.Renderer.Resolution;
bounds = new Rectangle(0, 0, res.Width, res.Height);
sprite = new Sprite(sheet, new Rectangle(0,0,1024,480), TextureChannel.Alpha);
}
public void Display()
{
var r = Game.Renderer;
if (r == null)
return;
r.BeginFrame(float2.Zero, 1f);
WidgetUtils.FillRectWithSprite(bounds, sprite);
r.EndFrame(new NullInputHandler());
}
public void StartGame()
{
Ui.LoadWidget("MODCHOOSER", Ui.Root, new WidgetArgs());
}
}
}

View File

@@ -491,6 +491,7 @@
<Compile Include="Widgets\LogicKeyListenerWidget.cs" />
<Compile Include="Widgets\Logic\ControlGroupLogic.cs" />
<Compile Include="Buildings\LineBuildNode.cs" />
<Compile Include="ModChooserLoadScreen.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -42,15 +42,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic
panel.Get<ButtonWidget>("INSTALL_BUTTON").OnClick = () =>
Ui.OpenWindow("INSTALL_FROMCD_PANEL", args);
panel.Get<ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;
panel.Get<ButtonWidget>("MODS_BUTTON").OnClick = () =>
panel.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
{
Ui.OpenWindow("MODS_PANEL", new WidgetArgs()
{
{ "onExit", () => { } },
{ "onSwitch", Ui.CloseWindow },
});
Game.Settings.Game.PreviousMod = Game.modData.Manifest.Mod.Id;
Game.InitializeWithMod("modchooser", null);
};
}
}

View File

@@ -44,12 +44,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic
mainMenu.Get<ButtonWidget>("MODS_BUTTON").OnClick = () =>
{
menuType = MenuType.None;
Ui.OpenWindow("MODS_PANEL", new WidgetArgs
{
{ "onExit", () => menuType = MenuType.Main },
{ "onSwitch", RemoveShellmapUI }
});
Game.Settings.Game.PreviousMod = Game.modData.Manifest.Mod.Id;
Game.InitializeWithMod("modchooser", null);
};
mainMenu.Get<ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* 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,
@@ -9,50 +9,160 @@
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ModBrowserLogic
{
Mod currentMod;
Widget modList;
ButtonWidget modTemplate;
Mod[] allMods;
Mod selectedMod;
string selectedAuthor;
string selectedDescription;
int modOffset = 0;
Dictionary<string, Sprite> previews;
Dictionary<string, Sprite> logos;
[ObjectCreator.UseCtor]
public ModBrowserLogic(Widget widget, Action onSwitch, Action onExit)
public ModBrowserLogic(Widget widget)
{
var panel = widget;
var modList = panel.Get<ScrollPanelWidget>("MOD_LIST");
var loadButton = panel.Get<ButtonWidget>("LOAD_BUTTON");
loadButton.OnClick = () => LoadMod(currentMod.Id, onSwitch);
loadButton.IsDisabled = () => currentMod.Id == Game.modData.Manifest.Mod.Id;
loadButton.OnClick = () => LoadMod(selectedMod);
loadButton.IsDisabled = () => selectedMod.Id == Game.modData.Manifest.Mod.Id;
panel.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };
currentMod = Game.modData.Manifest.Mod;
panel.Get<ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;
// Mod list
var modTemplate = modList.Get<ScrollItemWidget>("MOD_TEMPLATE");
modList = panel.Get("MOD_LIST");
modTemplate = modList.Get<ButtonWidget>("MOD_TEMPLATE");
panel.Get<LabelWidget>("MOD_DESC").GetText = () => selectedDescription;
panel.Get<LabelWidget>("MOD_TITLE").GetText = () => selectedMod.Title;
panel.Get<LabelWidget>("MOD_AUTHOR").GetText = () => selectedAuthor;
panel.Get<LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Version;
var prevMod = panel.Get<ButtonWidget>("PREV_MOD");
prevMod.OnClick = () => { modOffset -= 1; RebuildModList(); };
prevMod.IsVisible = () => modOffset > 0;
var nextMod = panel.Get<ButtonWidget>("NEXT_MOD");
nextMod.OnClick = () => { modOffset += 1; RebuildModList(); };
nextMod.IsVisible = () => modOffset + 5 < allMods.Length;
panel.Get<RGBASpriteWidget>("MOD_PREVIEW").GetSprite = () =>
{
Sprite ret = null;
previews.TryGetValue(selectedMod.Id, out ret);
return ret;
};
var sheetBuilder = new SheetBuilder(SheetType.BGRA);
previews = new Dictionary<string, Sprite>();
logos = new Dictionary<string, Sprite>();
allMods = Mod.AllMods.Values.Where(m => m.Id != "modchooser")
.OrderBy(m => m.Title)
.ToArray();
// Load preview images, and eat any errors
foreach (var mod in allMods)
{
try
{
var preview = new Bitmap(new[] { "mods", mod.Id, "preview.png" }.Aggregate(Path.Combine));
if (preview.Width != 296 || preview.Height != 196)
continue;
previews.Add(mod.Id, sheetBuilder.Add(preview));
}
catch (Exception) { }
try
{
var logo = new Bitmap(new[] { "mods", mod.Id, "logo.png" }.Aggregate(Path.Combine));
if (logo.Width != 96 || logo.Height != 96)
continue;
logos.Add(mod.Id, sheetBuilder.Add(logo));
}
catch (Exception) { }
}
Mod initialMod = null;
Mod.AllMods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
SelectMod(initialMod ?? Mod.AllMods["ra"]);
RebuildModList();
}
void RebuildModList()
{
modList.RemoveChildren();
foreach (var m in Mod.AllMods)
var width = modTemplate.Bounds.Width;
var height = modTemplate.Bounds.Height;
var innerMargin = modTemplate.Bounds.Left;
var outerMargin = (modList.Bounds.Width - Math.Min(5, allMods.Length) * width - 4 * innerMargin) / 2;
var stride = width + innerMargin;
for (var i = 0; i < 5; i++)
{
var mod = m.Value;
var item = ScrollItemWidget.Setup(modTemplate, () => currentMod == mod, () => currentMod = mod, () => LoadMod(currentMod.Id, onSwitch));
item.Get<LabelWidget>("TITLE").GetText = () => mod.Title;
item.Get<LabelWidget>("VERSION").GetText = () => mod.Version;
item.Get<LabelWidget>("AUTHOR").GetText = () => mod.Author;
var j = i + modOffset;
if (j >= allMods.Length)
break;
var mod = allMods[j];
var item = modTemplate.Clone() as ButtonWidget;
item.Bounds = new Rectangle(outerMargin + i * stride, 0, width, height);
item.IsHighlighted = () => selectedMod == mod;
item.OnClick = () => SelectMod(mod);
item.OnDoubleClick = () => LoadMod(mod);
item.OnKeyPress = e =>
{
if (e.MultiTapCount == 2)
LoadMod(mod);
else
SelectMod(mod);
};
item.TooltipText = mod.Title;
if (j < 9)
item.Key = new Hotkey((Keycode)((int)Keycode.NUMBER_1 + j), Modifiers.None);
Sprite logo = null;
logos.TryGetValue(mod.Id, out logo);
item.Get<RGBASpriteWidget>("MOD_LOGO").GetSprite = () => logo;
item.Get("MOD_NO_LOGO").IsVisible = () => logo == null;
modList.AddChild(item);
}
}
void LoadMod(string mod, Action onSwitch)
void SelectMod(Mod mod)
{
selectedMod = mod;
selectedAuthor = "By " + mod.Author ?? "unknown author";
selectedDescription = (mod.Description ?? "").Replace("\\n", "\n");
var selectedIndex = Array.IndexOf(allMods, mod);
if (selectedIndex - modOffset > 4)
modOffset = selectedIndex - 4;
}
void LoadMod(Mod mod)
{
Game.RunAfterTick(() =>
{
Ui.CloseWindow();
onSwitch();
Game.InitializeWithMod(mod, null);
Game.InitializeWithMod(mod.Id, null);
});
}
}