diff --git a/OpenRA.Game/Settings.cs b/OpenRA.Game/Settings.cs index e509fa68b2..c3e07128d8 100644 --- a/OpenRA.Game/Settings.cs +++ b/OpenRA.Game/Settings.cs @@ -244,6 +244,11 @@ namespace OpenRA public Hotkey ObserverCombinedViewKey = new Hotkey(Keycode.MINUS, Modifiers.None); public Hotkey ObserverWorldViewKey = new Hotkey(Keycode.EQUALS, Modifiers.None); + public Hotkey StatisticsBasicKey = new Hotkey(Keycode.F1, Modifiers.None); + public Hotkey StatisticsEconomyKey = new Hotkey(Keycode.F2, Modifiers.None); + public Hotkey StatisticsProductionKey = new Hotkey(Keycode.F3, Modifiers.None); + public Hotkey StatisticsCombatKey = new Hotkey(Keycode.F4, Modifiers.None); + public Hotkey StatisticsGraphKey = new Hotkey(Keycode.UNKNOWN, Modifiers.None); public Hotkey CycleStatusBarsKey = new Hotkey(Keycode.COMMA, Modifiers.None); public Hotkey TogglePixelDoubleKey = new Hotkey(Keycode.PERIOD, Modifiers.None); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/MenuButtonsChromeLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/MenuButtonsChromeLogic.cs index 24ef636aca..dcfb5aab90 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/MenuButtonsChromeLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/MenuButtonsChromeLogic.cs @@ -10,13 +10,15 @@ #endregion using System; +using System.Collections.Generic; using System.Linq; +using OpenRA.Mods.Common.Lint; using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic { + [ChromeLogicArgsHotkeys("StatisticsBasicKey", "StatisticsEconomyKey", "StatisticsProductionKey", "StatisticsCombatKey", "StatisticsGraphKey")] public class MenuButtonsChromeLogic : ChromeLogic { readonly World world; @@ -26,13 +28,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic Widget currentWidget; [ObjectCreator.UseCtor] - public MenuButtonsChromeLogic(Widget widget, World world) + public MenuButtonsChromeLogic(Widget widget, World world, Dictionary logicArgs) { this.world = world; worldRoot = Ui.Root.Get("WORLD_ROOT"); menuRoot = Ui.Root.Get("MENU_ROOT"); + MiniYaml yaml; + var ks = Game.Settings.Keys; + string[] keyNames = Enum.GetNames(typeof(ObserverStatsPanel)); + var statsHotkeys = new NamedHotkey[keyNames.Length]; + for (var i = 0; i < keyNames.Length; i++) + statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? new NamedHotkey(yaml.Value, ks) : new NamedHotkey(); + // System buttons var options = widget.GetOrNull("OPTIONS_BUTTON"); if (options != null) @@ -85,7 +94,29 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (stats != null) { stats.IsDisabled = () => disableSystemButtons || world.Map.Visibility.HasFlag(MapVisibility.MissionSelector); - stats.OnClick = () => OpenMenuPanel(stats); + stats.OnClick = () => OpenMenuPanel(stats, new WidgetArgs() { { "activePanel", ObserverStatsPanel.Basic } }); + } + + var keyListener = widget.GetOrNull("OBSERVER_KEY_LISTENER"); + if (keyListener != null) + { + keyListener.AddHandler(e => + { + if (e.Event == KeyInputEvent.Down && !e.IsRepeat) + { + var key = Hotkey.FromKeyInput(e); + for (var i = 0; i < statsHotkeys.Length; i++) + { + if (key == statsHotkeys[i].GetValue()) + { + OpenMenuPanel(stats, new WidgetArgs() { { "activePanel", i } }); + return true; + } + } + } + + return false; + }); } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs index 077b0dba55..91565042c6 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.Common.Lint; using OpenRA.Mods.Common.Traits; using OpenRA.Network; using OpenRA.Traits; @@ -21,30 +22,40 @@ using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic { + public enum ObserverStatsPanel { Basic, Economy, Production, Combat, Graph } + + [ChromeLogicArgsHotkeys("StatisticsBasicKey", "StatisticsEconomyKey", "StatisticsProductionKey", "StatisticsCombatKey", "StatisticsGraphKey")] public class ObserverStatsLogic : ChromeLogic { - ContainerWidget basicStatsHeaders; - ContainerWidget economyStatsHeaders; - ContainerWidget productionStatsHeaders; - ContainerWidget combatStatsHeaders; - ContainerWidget earnedThisMinuteGraphHeaders; - ScrollPanelWidget playerStatsPanel; - ScrollItemWidget basicPlayerTemplate; - ScrollItemWidget economyPlayerTemplate; - ScrollItemWidget productionPlayerTemplate; - ScrollItemWidget combatPlayerTemplate; - ContainerWidget earnedThisMinuteGraphTemplate; - ScrollItemWidget teamTemplate; - DropDownButtonWidget statsDropDown; - IEnumerable players; - World world; - WorldRenderer worldRenderer; + readonly ContainerWidget basicStatsHeaders; + readonly ContainerWidget economyStatsHeaders; + readonly ContainerWidget productionStatsHeaders; + readonly ContainerWidget combatStatsHeaders; + readonly ContainerWidget earnedThisMinuteGraphHeaders; + readonly ScrollPanelWidget playerStatsPanel; + readonly ScrollItemWidget basicPlayerTemplate; + readonly ScrollItemWidget economyPlayerTemplate; + readonly ScrollItemWidget productionPlayerTemplate; + readonly ScrollItemWidget combatPlayerTemplate; + readonly ContainerWidget earnedThisMinuteGraphTemplate; + readonly ScrollItemWidget teamTemplate; + readonly IEnumerable players; + readonly World world; + readonly WorldRenderer worldRenderer; [ObjectCreator.UseCtor] - public ObserverStatsLogic(World world, WorldRenderer worldRenderer, Widget widget, Action onExit) + public ObserverStatsLogic(World world, WorldRenderer worldRenderer, Widget widget, Action onExit, ObserverStatsPanel activePanel, Dictionary logicArgs) { this.world = world; this.worldRenderer = worldRenderer; + + MiniYaml yaml; + var ks = Game.Settings.Keys; + string[] keyNames = Enum.GetNames(typeof(ObserverStatsPanel)); + var statsHotkeys = new NamedHotkey[keyNames.Length]; + for (var i = 0; i < keyNames.Length; i++) + statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? new NamedHotkey(yaml.Value, ks) : new NamedHotkey(); + players = world.Players.Where(p => !p.NonCombatant); basicStatsHeaders = widget.Get("BASIC_STATS_HEADERS"); @@ -64,79 +75,40 @@ namespace OpenRA.Mods.Common.Widgets.Logic teamTemplate = playerStatsPanel.Get("TEAM_TEMPLATE"); - statsDropDown = widget.Get("STATS_DROPDOWN"); - statsDropDown.GetText = () => "Basic"; - statsDropDown.OnMouseDown = _ => + var statsDropDown = widget.Get("STATS_DROPDOWN"); + Func createStatsOption = (title, headers, a) => { - var options = new List + return new StatsDropDownOption { - new StatsDropDownOption + Title = title, + IsSelected = () => headers.Visible, + OnClick = () => { - Title = "Basic", - IsSelected = () => basicStatsHeaders.Visible, - OnClick = () => - { - ClearStats(); - statsDropDown.GetText = () => "Basic"; - DisplayStats(BasicStats); - } - }, - new StatsDropDownOption - { - Title = "Economy", - IsSelected = () => economyStatsHeaders.Visible, - OnClick = () => - { - ClearStats(); - statsDropDown.GetText = () => "Economy"; - DisplayStats(EconomyStats); - } - }, - new StatsDropDownOption - { - Title = "Production", - IsSelected = () => productionStatsHeaders.Visible, - OnClick = () => - { - ClearStats(); - statsDropDown.GetText = () => "Production"; - DisplayStats(ProductionStats); - } - }, - new StatsDropDownOption - { - Title = "Combat", - IsSelected = () => combatStatsHeaders.Visible, - OnClick = () => - { - ClearStats(); - statsDropDown.GetText = () => "Combat"; - DisplayStats(CombatStats); - } - }, - new StatsDropDownOption - { - Title = "Earnings (graph)", - IsSelected = () => earnedThisMinuteGraphHeaders.Visible, - OnClick = () => - { - ClearStats(); - statsDropDown.GetText = () => "Earnings (graph)"; - EarnedThisMinuteGraph(); - } + ClearStats(); + statsDropDown.GetText = () => title; + a(); } }; - Func setupItem = (option, template) => - { - var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); - item.Get("LABEL").GetText = () => option.Title; - return item; - }; - statsDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem); }; - ClearStats(); - DisplayStats(BasicStats); + var statsDropDownOptions = new StatsDropDownOption[] + { + createStatsOption("Basic", basicStatsHeaders, () => DisplayStats(BasicStats)), + createStatsOption("Economy", economyStatsHeaders, () => DisplayStats(EconomyStats)), + createStatsOption("Production", productionStatsHeaders, () => DisplayStats(ProductionStats)), + createStatsOption("Combat", combatStatsHeaders, () => DisplayStats(CombatStats)), + createStatsOption("Earnings (graph)", earnedThisMinuteGraphHeaders, () => EarnedThisMinuteGraph()) + }; + + Func setupItem = (option, template) => + { + var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); + item.Get("LABEL").GetText = () => option.Title; + return item; + }; + + statsDropDown.OnMouseDown = _ => statsDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, statsDropDownOptions, setupItem); + statsDropDownOptions[(int)activePanel].OnClick(); var close = widget.GetOrNull("CLOSE"); if (close != null) @@ -146,6 +118,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic Ui.Root.RemoveChild(widget); onExit(); }; + + var keyListener = statsDropDown.Get("STATS_DROPDOWN_KEYHANDLER"); + keyListener.AddHandler(e => + { + if (e.Event == KeyInputEvent.Down && !e.IsRepeat) + { + var key = Hotkey.FromKeyInput(e); + for (var i = 0; i < statsHotkeys.Length; i++) + { + if (key == statsHotkeys[i].GetValue()) + { + statsDropDownOptions[i].OnClick(); + return true; + } + } + } + + return false; + }); } void ClearStats() diff --git a/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs index 9e2a7f4acd..bff52773ee 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs @@ -502,7 +502,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic { "ReplaySpeedSlowKey", "Slow speed" }, { "ReplaySpeedRegularKey", "Regular speed" }, { "ReplaySpeedFastKey", "Fast speed" }, - { "ReplaySpeedMaxKey", "Maximum speed" } + { "ReplaySpeedMaxKey", "Maximum speed" }, + { "StatisticsBasicKey", "Basic statistics" }, + { "StatisticsEconomyKey", "Economy statistics" }, + { "StatisticsProductionKey", "Production statistics" }, + { "StatisticsCombatKey", "Combat statistics" }, + { "StatisticsGraphKey", "Statistics graph" } }; var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing); diff --git a/mods/cnc/chrome/ingame-observerstats.yaml b/mods/cnc/chrome/ingame-observerstats.yaml index 6b48e530cd..05f561ae7f 100644 --- a/mods/cnc/chrome/ingame-observerstats.yaml +++ b/mods/cnc/chrome/ingame-observerstats.yaml @@ -1,5 +1,10 @@ Background@INGAME_OBSERVERSTATS_BG: Logic: ObserverStatsLogic + StatisticsBasicKey: StatisticsBasic + StatisticsEconomyKey: StatisticsEconomy + StatisticsProductionKey: StatisticsProduction + StatisticsCombatKey: StatisticsCombat + StatisticsGraphKey: StatisticsGraph X: (WINDOW_RIGHT - WIDTH) / 2 Y: (WINDOW_BOTTOM - HEIGHT) / 2 Width: 1005 @@ -24,6 +29,8 @@ Background@INGAME_OBSERVERSTATS_BG: Width: 185 Height: 25 Font: Bold + Children: + LogicKeyListener@STATS_DROPDOWN_KEYHANDLER: Container@BASIC_STATS_HEADERS: X: 0 Y: 0 diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index b090acdfda..acb8751ed4 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -106,7 +106,13 @@ Container@PERF_WIDGETS: Container@OBSERVER_WIDGETS: Logic: MenuButtonsChromeLogic + StatisticsBasicKey: StatisticsBasic + StatisticsEconomyKey: StatisticsEconomy + StatisticsProductionKey: StatisticsProduction + StatisticsCombatKey: StatisticsCombat + StatisticsGraphKey: StatisticsGraph Children: + LogicKeyListener@OBSERVER_KEY_LISTENER: MenuButton@OPTIONS_BUTTON: Key: escape X: WINDOW_RIGHT - 260 - WIDTH @@ -123,7 +129,7 @@ Container@OBSERVER_WIDGETS: ImageCollection: order-icons ImageName: options MenuButton@OBSERVER_STATS_BUTTON: - Key: F1 + Key: StatisticsBasic X: WINDOW_RIGHT - 260 - WIDTH Y: 35 Width: 30 diff --git a/mods/common/chrome/ingame-observer.yaml b/mods/common/chrome/ingame-observer.yaml index ff37b870e4..ef4b5ee3cd 100644 --- a/mods/common/chrome/ingame-observer.yaml +++ b/mods/common/chrome/ingame-observer.yaml @@ -1,6 +1,12 @@ Container@OBSERVER_WIDGETS: Logic: MenuButtonsChromeLogic + StatisticsBasicKey: StatisticsBasic + StatisticsEconomyKey: StatisticsEconomy + StatisticsProductionKey: StatisticsProduction + StatisticsCombatKey: StatisticsCombat + StatisticsGraphKey: StatisticsGraph Children: + LogicKeyListener@OBSERVER_KEY_LISTENER: MenuButton@OPTIONS_BUTTON: Width: 160 Height: 25 @@ -9,6 +15,7 @@ Container@OBSERVER_WIDGETS: Key: escape DisableWorldSounds: true MenuButton@OBSERVER_STATS_BUTTON: + Key: StatisticsBasic MenuContainer: INGAME_OBSERVERSTATS_BG HideIngameUI: False Pause: False @@ -16,9 +23,8 @@ Container@OBSERVER_WIDGETS: Y: 0 Width: 160 Height: 25 - Text: Statistics (F1) + Text: Statistics Font: Bold - Key: f1 Container@GAME_TIMER_BLOCK: Logic: GameTimerLogic X: (WINDOW_RIGHT - WIDTH) / 2 diff --git a/mods/common/chrome/ingame-observerstats.yaml b/mods/common/chrome/ingame-observerstats.yaml index c9d560cc39..436aaabd02 100644 --- a/mods/common/chrome/ingame-observerstats.yaml +++ b/mods/common/chrome/ingame-observerstats.yaml @@ -1,5 +1,10 @@ Background@INGAME_OBSERVERSTATS_BG: Logic: ObserverStatsLogic + StatisticsBasicKey: StatisticsBasic + StatisticsEconomyKey: StatisticsEconomy + StatisticsProductionKey: StatisticsProduction + StatisticsCombatKey: StatisticsCombat + StatisticsGraphKey: StatisticsGraph X: 25 Y: 50 Width: 1025 @@ -24,6 +29,8 @@ Background@INGAME_OBSERVERSTATS_BG: Width: 185 Height: 25 Font: Bold + Children: + LogicKeyListener@STATS_DROPDOWN_KEYHANDLER: Container@BASIC_STATS_HEADERS: X: 0 Y: 0 diff --git a/mods/ra/chrome/ingame-observer.yaml b/mods/ra/chrome/ingame-observer.yaml index 233f41a77b..e72c558e50 100644 --- a/mods/ra/chrome/ingame-observer.yaml +++ b/mods/ra/chrome/ingame-observer.yaml @@ -31,14 +31,20 @@ Container@OBSERVER_WIDGETS: TooltipTemplate: SIMPLE_TOOLTIP Container@TOP_BUTTONS: Logic: MenuButtonsChromeLogic + StatisticsBasicKey: StatisticsBasic + StatisticsEconomyKey: StatisticsEconomy + StatisticsProductionKey: StatisticsProduction + StatisticsCombatKey: StatisticsCombat + StatisticsGraphKey: StatisticsGraph X: 9 Y: 7 Children: + LogicKeyListener@OBSERVER_KEY_LISTENER: MenuButton@OBSERVER_STATS_BUTTON: + Key: StatisticsBasic MenuContainer: INGAME_OBSERVERSTATS_BG HideIngameUI: false Pause: false - Key: F1 X: 160 Width: 28 Height: 28 diff --git a/mods/ts/chrome/ingame-observer.yaml b/mods/ts/chrome/ingame-observer.yaml index 8c25c1a47c..4862c6b95e 100644 --- a/mods/ts/chrome/ingame-observer.yaml +++ b/mods/ts/chrome/ingame-observer.yaml @@ -1,6 +1,12 @@ Container@OBSERVER_WIDGETS: Logic: MenuButtonsChromeLogic + StatisticsBasicKey: StatisticsBasic + StatisticsEconomyKey: StatisticsEconomy + StatisticsProductionKey: StatisticsProduction + StatisticsCombatKey: StatisticsCombat + StatisticsGraphKey: StatisticsGraph Children: + LogicKeyListener@OBSERVER_KEY_LISTENER: MenuButton@OPTIONS_BUTTON: Width: 160 Height: 25 @@ -9,6 +15,7 @@ Container@OBSERVER_WIDGETS: Key: escape DisableWorldSounds: true MenuButton@OBSERVER_STATS_BUTTON: + Key: StatisticsBasic MenuContainer: INGAME_OBSERVERSTATS_BG HideIngameUI: False Pause: False @@ -16,9 +23,8 @@ Container@OBSERVER_WIDGETS: Y: 0 Width: 160 Height: 25 - Text: Statistics (F1) + Text: Statistics Font: Bold - Key: f1 Container@GAME_TIMER_BLOCK: Logic: GameTimerLogic X: (WINDOW_RIGHT - WIDTH) / 2 diff --git a/mods/ts/chrome/ingame-observerstats.yaml b/mods/ts/chrome/ingame-observerstats.yaml index 083c5fb567..5fef5a3ef3 100644 --- a/mods/ts/chrome/ingame-observerstats.yaml +++ b/mods/ts/chrome/ingame-observerstats.yaml @@ -1,5 +1,10 @@ Background@INGAME_OBSERVERSTATS_BG: Logic: ObserverStatsLogic + StatisticsBasicKey: StatisticsBasic + StatisticsEconomyKey: StatisticsEconomy + StatisticsProductionKey: StatisticsProduction + StatisticsCombatKey: StatisticsCombat + StatisticsGraphKey: StatisticsGraph X: 25 Y: 50 Width: 1025 @@ -24,6 +29,8 @@ Background@INGAME_OBSERVERSTATS_BG: Width: 185 Height: 25 Font: Bold + Children: + LogicKeyListener@STATS_DROPDOWN_KEYHANDLER: Container@BASIC_STATS_HEADERS: X: 0 Y: 0