Merge pull request #3135 from ScottNZ/ui

Start moving towards saner RA widget logic
This commit is contained in:
Paul Chote
2013-04-27 03:09:59 -07:00
39 changed files with 1158 additions and 1587 deletions

View File

@@ -10,40 +10,9 @@
using OpenRA.Traits;
using OpenRA.Widgets;
using System.Collections.Generic;
namespace OpenRA.Mods.RA
{
// Legacy crap
public class OpenWidgetAtGameStartInfo : ITraitInfo
{
public readonly string Widget = "INGAME_ROOT";
public readonly string ObserverWidget = null;
public object Create(ActorInitializer init) { return new OpenWidgetAtGameStart(this); }
}
public class OpenWidgetAtGameStart: IWorldLoaded
{
readonly OpenWidgetAtGameStartInfo Info;
public OpenWidgetAtGameStart(OpenWidgetAtGameStartInfo Info)
{
this.Info = Info;
}
public void WorldLoaded(World world)
{
// Remove all open widgets
Ui.ResetAll();
if (world.LocalPlayer != null)
Game.OpenWindow(world, Info.Widget);
else if (Info.ObserverWidget != null)
Game.OpenWindow(world, Info.ObserverWidget);
}
}
// New version
public class LoadWidgetAtGameStartInfo : ITraitInfo
{
public readonly string Widget = null;

View File

@@ -267,7 +267,7 @@
<Compile Include="Move\PathSearch.cs" />
<Compile Include="NukePaletteEffect.cs" />
<Compile Include="NullLoadScreen.cs" />
<Compile Include="OpenWidgetAtGameStart.cs" />
<Compile Include="LoadWidgetAtGameStart.cs" />
<Compile Include="Orders\DeployOrderTargeter.cs" />
<Compile Include="Orders\EnterBuildingOrderTargeter.cs" />
<Compile Include="Orders\PlaceBuildingOrderGenerator.cs" />
@@ -370,6 +370,8 @@
<Compile Include="Valued.cs" />
<Compile Include="WaterPaletteRotation.cs" />
<Compile Include="Widgets\BuildPaletteWidget.cs" />
<Compile Include="Widgets\LogicTickerWidget.cs" />
<Compile Include="Widgets\Logic\IngameMenuLogic.cs" />
<Compile Include="Widgets\Logic\ModBrowserLogic.cs" />
<Compile Include="Widgets\Logic\ColorPickerLogic.cs" />
<Compile Include="Widgets\Logic\ConnectionLogic.cs" />
@@ -378,7 +380,6 @@
<Compile Include="Widgets\Logic\DownloadPackagesLogic.cs" />
<Compile Include="Widgets\Logic\IngameChatLogic.cs" />
<Compile Include="Widgets\Logic\IngameChromeLogic.cs" />
<Compile Include="Widgets\Logic\IngameObserverChromeLogic.cs" />
<Compile Include="Widgets\Logic\LobbyLogic.cs" />
<Compile Include="Widgets\Logic\LobbyUtils.cs" />
<Compile Include="Widgets\Logic\MainMenuButtonsLogic.cs" />

View File

@@ -90,11 +90,7 @@ namespace OpenRA.Mods.RA
Ui.OpenWindow(Info["InstallerMenuWidget"], args);
}
else
{
Game.LoadShellMap();
Ui.ResetAll();
Ui.OpenWindow("MAINMENU_BG");
}
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -19,99 +19,101 @@ namespace OpenRA.Mods.RA.Widgets.Logic
public class IngameChromeLogic
{
Widget gameRoot;
Widget playerRoot;
World world;
[ObjectCreator.UseCtor]
public IngameChromeLogic(World world)
{
var r = Ui.Root;
gameRoot = r.Get("INGAME_ROOT");
var optionsBG = gameRoot.Get("INGAME_OPTIONS_BG");
this.world = world;
gameRoot = Ui.Root.Get("INGAME_ROOT");
playerRoot = gameRoot.Get("PLAYER_ROOT");
// TODO: RA's broken UI wiring makes it unreasonably difficult to
// cache and restore the previous pause state, so opening/closing
// the menu in a paused singleplayer game will un-pause the game.
r.Get<ButtonWidget>("INGAME_OPTIONS_BUTTON").OnClick = () =>
InitRootWidgets();
if (world.LocalPlayer == null)
InitObserverWidgets();
else
InitPlayerWidgets();
}
void InitRootWidgets()
{
var cachedPause = false;
Widget optionsBG = null;
optionsBG = Game.LoadWidget(world, "INGAME_OPTIONS_BG", Ui.Root, new WidgetArgs
{
optionsBG.Visible = !optionsBG.Visible;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(true));
};
var cheatsButton = gameRoot.Get<ButtonWidget>("CHEATS_BUTTON");
cheatsButton.OnClick = () =>
{ "onExit", () =>
{
optionsBG.Visible = false;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(cachedPause));
}
}
});
gameRoot.Get<ButtonWidget>("INGAME_OPTIONS_BUTTON").OnClick = () =>
{
Game.OpenWindow("CHEATS_PANEL", new WidgetArgs() {{"onExit", () => {} }});
optionsBG.Visible ^= true;
if (optionsBG.Visible)
{
cachedPause = world.Paused;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(true));
}
else
world.IssueOrder(Order.PauseGame(cachedPause));
};
cheatsButton.IsVisible = () => world.LocalPlayer != null && world.LobbyInfo.GlobalSettings.AllowCheats;
Game.LoadWidget(world, "CHAT_PANEL", gameRoot, new WidgetArgs());
}
void InitObserverWidgets()
{
var observerWidgets = Game.LoadWidget(world, "OBSERVER_WIDGETS", playerRoot, new WidgetArgs());
Game.LoadWidget(world, "OBSERVER_STATS", observerWidgets, new WidgetArgs());
observerWidgets.Get<ButtonWidget>("INGAME_STATS_BUTTON").OnClick = () => gameRoot.Get("OBSERVER_STATS").Visible ^= true;
}
void InitPlayerWidgets()
{
var playerWidgets = Game.LoadWidget(world, "PLAYER_WIDGETS", playerRoot, new WidgetArgs());
Widget cheats = null;
cheats = Game.LoadWidget(world, "CHEATS_PANEL", playerWidgets, new WidgetArgs
{
{ "onExit", () => cheats.Visible = false }
});
var cheatsButton = playerWidgets.Get<ButtonWidget>("CHEATS_BUTTON");
cheatsButton.OnClick = () => cheats.Visible ^= true;
cheatsButton.IsVisible = () => world.LobbyInfo.GlobalSettings.AllowCheats;
var iop = world.WorldActor.TraitsImplementing<IObjectivesPanel>().FirstOrDefault();
if (iop != null && iop.ObjectivesPanel != null)
{
var objectivesButton = gameRoot.Get<ButtonWidget>("OBJECTIVES_BUTTON");
var objectivesWidget = Game.LoadWidget(world, iop.ObjectivesPanel, Ui.Root, new WidgetArgs());
objectivesWidget.Visible = false;
objectivesButton.OnClick += () => objectivesWidget.Visible = !objectivesWidget.Visible;
objectivesButton.IsVisible = () => world.LocalPlayer != null;
var objectivesButton = playerWidgets.Get<ButtonWidget>("OBJECTIVES_BUTTON");
var objectivesWidget = Game.LoadWidget(world, iop.ObjectivesPanel, playerWidgets, new WidgetArgs());
objectivesButton.Visible = true;
objectivesButton.OnClick += () => objectivesWidget.Visible ^= true;
}
var moneybin = gameRoot.Get("INGAME_MONEY_BIN");
moneybin.Get<OrderButtonWidget>("SELL").GetKey = _ => Game.Settings.Keys.SellKey;
moneybin.Get<OrderButtonWidget>("POWER_DOWN").GetKey = _ => Game.Settings.Keys.PowerDownKey;
moneybin.Get<OrderButtonWidget>("REPAIR").GetKey = _ => Game.Settings.Keys.RepairKey;
var moneyBin = playerWidgets.Get("INGAME_MONEY_BIN");
moneyBin.Get<OrderButtonWidget>("SELL").GetKey = _ => Game.Settings.Keys.SellKey;
moneyBin.Get<OrderButtonWidget>("POWER_DOWN").GetKey = _ => Game.Settings.Keys.PowerDownKey;
moneyBin.Get<OrderButtonWidget>("REPAIR").GetKey = _ => Game.Settings.Keys.RepairKey;
var chatPanel = Game.LoadWidget(world, "CHAT_PANEL", Ui.Root, new WidgetArgs());
gameRoot.AddChild(chatPanel);
optionsBG.Get<ButtonWidget>("DISCONNECT").OnClick = () => LeaveGame(optionsBG, world);
optionsBG.Get<ButtonWidget>("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU");
optionsBG.Get<ButtonWidget>("MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU");
optionsBG.Get<ButtonWidget>("RESUME").OnClick = () =>
var winLossWatcher = playerWidgets.Get<LogicTickerWidget>("WIN_LOSS_WATCHER");
winLossWatcher.OnTick = () =>
{
optionsBG.Visible = false;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(false));
if (world.LocalPlayer.WinState != WinState.Undefined)
Game.RunAfterTick(() =>
{
playerRoot.RemoveChildren();
InitObserverWidgets();
});
};
optionsBG.Get<ButtonWidget>("SURRENDER").OnClick = () =>
{
optionsBG.Visible = false;
world.IssueOrder(new Order("Surrender", world.LocalPlayer.PlayerActor, false));
};
optionsBG.Get("SURRENDER").IsVisible = () => (world.LocalPlayer != null && world.LocalPlayer.WinState == WinState.Undefined);
var postgameBG = gameRoot.Get("POSTGAME_BG");
var postgameText = postgameBG.Get<LabelWidget>("TEXT");
var postGameObserve = postgameBG.Get<ButtonWidget>("POSTGAME_OBSERVE");
var postgameQuit = postgameBG.Get<ButtonWidget>("POSTGAME_QUIT");
postgameQuit.OnClick = () => LeaveGame(postgameQuit, world);
postGameObserve.OnClick = () => postgameQuit.Visible = false;
postGameObserve.IsVisible = () => world.LocalPlayer.WinState != WinState.Won;
postgameBG.IsVisible = () =>
{
return postgameQuit.Visible && world.LocalPlayer != null && world.LocalPlayer.WinState != WinState.Undefined;
};
postgameText.GetText = () =>
{
var state = world.LocalPlayer.WinState;
return state == WinState.Undefined ? "" :
(state == WinState.Lost ? "YOU ARE DEFEATED" : "YOU ARE VICTORIOUS");
};
}
void LeaveGame(Widget pane, World world)
{
Sound.PlayNotification(null, "Speech", "Leave", world.LocalPlayer.Country.Race);
pane.Visible = false;
Game.Disconnect();
Game.LoadShellMap();
Ui.CloseWindow();
Ui.OpenWindow("MAINMENU_BG");
}
}
}

View File

@@ -0,0 +1,54 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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 OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
class IngameMenuLogic
{
[ObjectCreator.UseCtor]
public IngameMenuLogic(Widget widget, World world, Action onExit)
{
widget.Get<ButtonWidget>("DISCONNECT").OnClick = () =>
{
onExit();
LeaveGame(world);
};
widget.Get<ButtonWidget>("SETTINGS").OnClick = () =>
{
widget.Visible = false;
Ui.OpenWindow("SETTINGS_MENU", new WidgetArgs { { "onExit", () => { widget.Visible = true; } } });
};
widget.Get<ButtonWidget>("MUSIC").OnClick = () =>
{
widget.Visible = false;
Ui.OpenWindow("MUSIC_MENU", new WidgetArgs { { "onExit", () => { widget.Visible = true; } } });
};
widget.Get<ButtonWidget>("RESUME").OnClick = () => onExit();
widget.Get<ButtonWidget>("SURRENDER").OnClick = () =>
{
world.IssueOrder(new Order("Surrender", world.LocalPlayer.PlayerActor, false));
onExit();
};
widget.Get("SURRENDER").IsVisible = () => world.LocalPlayer != null && world.LocalPlayer.WinState == WinState.Undefined;
}
void LeaveGame(World world)
{
Sound.PlayNotification(null, "Speech", "Leave", world.LocalPlayer == null ? null : world.LocalPlayer.Country.Race);
Game.Disconnect();
Ui.CloseWindow();
Game.LoadShellMap();
}
}
}

View File

@@ -1,67 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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 OpenRA.Traits;
using OpenRA.Widgets;
using OpenRA.Network;
using System;
using System.Drawing;
using System.Linq;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngameObserverChromeLogic
{
Widget gameRoot;
// WTF duplication
[ObjectCreator.UseCtor]
public IngameObserverChromeLogic(World world)
{
var r = Ui.Root;
gameRoot = r.Get("OBSERVER_ROOT");
var optionsBG = gameRoot.Get("INGAME_OPTIONS_BG");
r.Get<ButtonWidget>("INGAME_OPTIONS_BUTTON").OnClick = () =>
{
optionsBG.Visible = !optionsBG.Visible;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(true));
};
optionsBG.Get<ButtonWidget>("DISCONNECT").OnClick = () =>
{
optionsBG.Visible = false;
Game.Disconnect();
Game.LoadShellMap();
Ui.CloseWindow();
Ui.OpenWindow("MAINMENU_BG");
};
optionsBG.Get<ButtonWidget>("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU");
optionsBG.Get<ButtonWidget>("MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU");
optionsBG.Get<ButtonWidget>("RESUME").OnClick = () =>
{
optionsBG.Visible = false;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(false));
};
optionsBG.Get<ButtonWidget>("SURRENDER").IsVisible = () => false;
Ui.Root.Get<ButtonWidget>("INGAME_STATS_BUTTON").OnClick = () => gameRoot.Get("OBSERVER_STATS").Visible ^= true;
if (!world.IsShellmap)
{
var chatPanel = Game.LoadWidget(world, "CHAT_PANEL", Ui.Root, new WidgetArgs());
gameRoot.AddChild(chatPanel);
}
}
}
}

View File

@@ -14,33 +14,62 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
public class MainMenuButtonsLogic
{
enum MenuType { Main, None }
MenuType Menu = MenuType.Main;
Widget rootMenu;
[ObjectCreator.UseCtor]
public MainMenuButtonsLogic(Widget widget)
{
rootMenu = widget;
rootMenu.IsVisible = () => Menu == MenuType.Main;
Game.modData.WidgetLoader.LoadWidget( new WidgetArgs(), Ui.Root, "PERF_BG" );
widget.Get<ButtonWidget>("MAINMENU_BUTTON_JOIN").OnClick = () => OpenGamePanel("JOINSERVER_BG");
widget.Get<ButtonWidget>("MAINMENU_BUTTON_CREATE").OnClick = () => OpenGamePanel("CREATESERVER_BG");
widget.Get<ButtonWidget>("MAINMENU_BUTTON_DIRECTCONNECT").OnClick = () => OpenGamePanel("DIRECTCONNECT_BG");
widget.Get<ButtonWidget>("MAINMENU_BUTTON_SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU");
widget.Get<ButtonWidget>("MAINMENU_BUTTON_MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU");
widget.Get<ButtonWidget>("MAINMENU_BUTTON_SETTINGS").OnClick = () =>
{
Menu = MenuType.None;
Ui.OpenWindow("SETTINGS_MENU", new WidgetArgs()
{
{ "onExit", () => Menu = MenuType.Main }
});
};
widget.Get<ButtonWidget>("MAINMENU_BUTTON_MUSIC").OnClick = () =>
{
Menu = MenuType.None;
Ui.OpenWindow("MUSIC_MENU", new WidgetArgs()
{
{ "onExit", () => Menu = MenuType.Main }
});
};
widget.Get<ButtonWidget>("MAINMENU_BUTTON_MODS").OnClick = () =>
{
Menu = MenuType.None;
Ui.OpenWindow("MODS_PANEL", new WidgetArgs()
{
{ "onExit", () => {} },
{ "onExit", () => Menu = MenuType.Main },
{ "onSwitch", RemoveShellmapUI }
});
};
widget.Get<ButtonWidget>("MAINMENU_BUTTON_REPLAY_VIEWER").OnClick = () =>
{
Menu = MenuType.None;
Ui.OpenWindow("REPLAYBROWSER_BG", new WidgetArgs()
{
{ "onExit", () => {} },
{ "onExit", () => Menu = MenuType.Main },
{ "onStart", RemoveShellmapUI }
});
};
widget.Get<ButtonWidget>("MAINMENU_BUTTON_QUIT").OnClick = () => Game.Exit();
}
@@ -51,18 +80,20 @@ namespace OpenRA.Mods.RA.Widgets.Logic
void OpenGamePanel(string id)
{
Menu = MenuType.None;
Ui.OpenWindow(id, new WidgetArgs()
{
{ "onExit", () => {} },
{ "onExit", () => Menu = MenuType.Main },
{ "openLobby", () => OpenLobbyPanel() }
});
}
void OpenLobbyPanel()
{
Menu = MenuType.None;
Game.OpenWindow("SERVER_LOBBY", new WidgetArgs()
{
{ "onExit", () => { Game.Disconnect(); } },
{ "onExit", () => { Game.Disconnect(); Menu = MenuType.Main; } },
{ "onStart", RemoveShellmapUI },
{ "addBots", false }
});

View File

@@ -32,7 +32,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic
() => Play( Game.Settings.Sound.Repeat ? CurrentSong : GetNextSong() ));
}
public MusicPlayerLogic()
[ObjectCreator.UseCtor]
public MusicPlayerLogic(Action onExit)
{
bg = Ui.Root.Get("MUSIC_MENU");
CurrentSong = GetNextSong();
@@ -41,7 +42,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
bg.Get( "BUTTON_PLAY" ).IsVisible = () => !Sound.MusicPlaying;
bg.Get<ButtonWidget>("BUTTON_CLOSE").OnClick =
() => { Game.Settings.Save(); Ui.CloseWindow(); };
() => { Game.Settings.Save(); Ui.CloseWindow(); onExit(); };
bg.Get("BUTTON_INSTALL").IsVisible = () => false;

View File

@@ -21,7 +21,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
Widget bg;
public SettingsMenuLogic()
[ObjectCreator.UseCtor]
public SettingsMenuLogic(Action onExit)
{
bg = Ui.Root.Get<BackgroundWidget>("SETTINGS_MENU");
var tabs = bg.Get<ContainerWidget>("TAB_CONTAINER");
@@ -247,6 +248,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
int.TryParse(maxFrameRate.Text, out gs.MaxFramerate);
Game.Settings.Save();
Ui.CloseWindow();
onExit();
};
}

View File

@@ -0,0 +1,21 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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 OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
public class LogicTickerWidget : Widget
{
public Action OnTick = () => { };
public override void Tick() { OnTick(); }
}
}