Skip to content

Commit

Permalink
Fix ingame menu tab display.
Browse files Browse the repository at this point in the history
  • Loading branch information
pchote committed Aug 7, 2021
1 parent dd85a4a commit 55c8bbf
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 91 deletions.
162 changes: 87 additions & 75 deletions OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoLogic.cs
Expand Up @@ -10,6 +10,7 @@
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.Common.Scripting;
using OpenRA.Mods.Common.Traits;
Expand All @@ -21,107 +22,78 @@ public enum IngameInfoPanel { AutoSelect, Map, Objectives, Debug, Chat }

class GameInfoLogic : ChromeLogic
{
readonly World world;
readonly Action<bool> hideMenu;
readonly IObjectivesPanel iop;
IngameInfoPanel activePanel;
bool hasError;

[ObjectCreator.UseCtor]
public GameInfoLogic(Widget widget, World world, IngameInfoPanel activePanel, Action<bool> hideMenu)
public GameInfoLogic(Widget widget, World world, IngameInfoPanel initialPanel, Action<bool> hideMenu)
{
var lp = world.LocalPlayer;
var numTabs = 0;
var panels = new Dictionary<IngameInfoPanel, (string Panel, string Label, Action<ButtonWidget, Widget> Setup)>()
{
{ IngameInfoPanel.Objectives, ("OBJECTIVES_PANEL", "Objectives", SetupObjectivesPanel) },
{ IngameInfoPanel.Map, ("MAP_PANEL", "Briefing", SetupMapPanel) },
{ IngameInfoPanel.Debug, ("DEBUG_PANEL", "Debug", SetupDebugPanel) },
{ IngameInfoPanel.Chat, ("CHAT_PANEL", "Chat", SetupChatPanel) }
};

widget.IsVisible = () => activePanel != IngameInfoPanel.AutoSelect;
this.world = world;
this.hideMenu = hideMenu;
activePanel = initialPanel;

var visiblePanels = new List<IngameInfoPanel>();

// Objectives/Stats tab
var scriptContext = world.WorldActor.TraitOrDefault<LuaScript>();
var hasError = scriptContext != null && scriptContext.FatalErrorOccurred;
var iop = world.WorldActor.TraitsImplementing<IObjectivesPanel>().FirstOrDefault();
var hasObjectivesPanel = hasError || (iop != null && iop.PanelName != null);
hasError = scriptContext != null && scriptContext.FatalErrorOccurred;
iop = world.WorldActor.TraitsImplementing<IObjectivesPanel>().FirstOrDefault();

if (hasObjectivesPanel)
{
numTabs++;
var objectivesTabButton = widget.Get<ButtonWidget>(string.Concat("BUTTON", numTabs.ToString()));
objectivesTabButton.GetText = () => "Objectives";
objectivesTabButton.IsVisible = () => numTabs > 1 && !hasError;
objectivesTabButton.OnClick = () => activePanel = IngameInfoPanel.Objectives;
objectivesTabButton.IsHighlighted = () => activePanel == IngameInfoPanel.Objectives;

var panel = hasError ? "SCRIPT_ERROR_PANEL" : iop.PanelName;
var objectivesPanel = widget.Get<ContainerWidget>("OBJECTIVES_PANEL");
objectivesPanel.IsVisible = () => activePanel == IngameInfoPanel.Objectives;

Game.LoadWidget(world, panel, objectivesPanel, new WidgetArgs()
{
{ "hideMenu", hideMenu }
});

if (activePanel == IngameInfoPanel.AutoSelect)
activePanel = IngameInfoPanel.Objectives;
}
if (hasError || (iop != null && iop.PanelName != null))
visiblePanels.Add(IngameInfoPanel.Objectives);

// Briefing tab
var missionData = world.WorldActor.Info.TraitInfoOrDefault<MissionDataInfo>();
if (missionData != null && !string.IsNullOrEmpty(missionData.Briefing))
{
numTabs++;
var mapTabButton = widget.Get<ButtonWidget>(string.Concat("BUTTON", numTabs.ToString()));
mapTabButton.Text = "Briefing";
mapTabButton.IsVisible = () => numTabs > 1 && !hasError;
mapTabButton.OnClick = () => activePanel = IngameInfoPanel.Map;
mapTabButton.IsHighlighted = () => activePanel == IngameInfoPanel.Map;

var mapPanel = widget.Get<ContainerWidget>("MAP_PANEL");
mapPanel.IsVisible = () => activePanel == IngameInfoPanel.Map;

Game.LoadWidget(world, "MAP_PANEL", mapPanel, new WidgetArgs());

if (activePanel == IngameInfoPanel.AutoSelect)
activePanel = IngameInfoPanel.Map;
}
visiblePanels.Add(IngameInfoPanel.Map);

// Debug/Cheats tab
// Can't use DeveloperMode.Enabled because there is a hardcoded hack to *always*
// enable developer mode for singleplayer games, but we only want to show the button
// if it has been explicitly enabled
var def = world.Map.Rules.Actors[SystemActors.Player].TraitInfo<DeveloperModeInfo>().CheckboxEnabled;
var developerEnabled = world.LobbyInfo.GlobalSettings.OptionOrDefault("cheats", def);
if (lp != null && developerEnabled)
{
numTabs++;
var debugTabButton = widget.Get<ButtonWidget>(string.Concat("BUTTON", numTabs.ToString()));
debugTabButton.Text = "Debug";
debugTabButton.IsVisible = () => numTabs > 1 && !hasError;
debugTabButton.IsDisabled = () => world.IsGameOver;
debugTabButton.OnClick = () => activePanel = IngameInfoPanel.Debug;
debugTabButton.IsHighlighted = () => activePanel == IngameInfoPanel.Debug;
if (world.LocalPlayer != null && developerEnabled)
visiblePanels.Add(IngameInfoPanel.Debug);

var debugPanelContainer = widget.Get<ContainerWidget>("DEBUG_PANEL");
debugPanelContainer.IsVisible = () => activePanel == IngameInfoPanel.Debug;

Game.LoadWidget(world, "DEBUG_PANEL", debugPanelContainer, new WidgetArgs());
if (world.LobbyInfo.NonBotClients.Count() > 1)
visiblePanels.Add(IngameInfoPanel.Chat);

if (activePanel == IngameInfoPanel.AutoSelect)
activePanel = IngameInfoPanel.Debug;
}
var numTabs = visiblePanels.Count;
var tabContainer = !hasError ? widget.GetOrNull($"TAB_CONTAINER_{numTabs}") : null;
if (tabContainer != null)
tabContainer.IsVisible = () => true;

if (world.LobbyInfo.NonBotClients.Count() > 1)
for (var i = 0; i < numTabs; i++)
{
numTabs++;
var chatPanelContainer = widget.Get<ContainerWidget>("CHAT_PANEL");
var chatTabButton = widget.Get<ButtonWidget>(string.Concat("BUTTON", numTabs.ToString()));
chatTabButton.Text = "Chat";
chatTabButton.IsVisible = () => numTabs > 1 && !hasError;
chatTabButton.IsHighlighted = () => activePanel == IngameInfoPanel.Chat;
chatTabButton.OnClick = () =>
{
activePanel = IngameInfoPanel.Chat;
chatPanelContainer.Get<TextFieldWidget>("CHAT_TEXTFIELD").TakeKeyboardFocus();
};
var type = visiblePanels[i];
var info = panels[type];
var tabButton = tabContainer?.Get<ButtonWidget>($"BUTTON{i + 1}");

chatPanelContainer.IsVisible = () => activePanel == IngameInfoPanel.Chat;
if (tabButton != null)
{
tabButton.Text = info.Label;
tabButton.OnClick = () => activePanel = type;
tabButton.IsHighlighted = () => activePanel == type;
}

Game.LoadWidget(world, "CHAT_CONTAINER", chatPanelContainer, new WidgetArgs() { { "isMenuChat", true } });
var panelContainer = widget.Get<ContainerWidget>(info.Panel);
panelContainer.IsVisible = () => activePanel == type;
info.Setup(tabButton, panelContainer);

if (activePanel == IngameInfoPanel.AutoSelect)
chatTabButton.OnClick();
activePanel = type;
}

// Handle empty space when tabs aren't displayed
Expand All @@ -148,5 +120,45 @@ public GameInfoLogic(Widget widget, World world, IngameInfoPanel activePanel, Ac
if (bgNoTabs != null)
bgNoTabs.IsVisible = () => numTabs == 1;
}

void SetupObjectivesPanel(ButtonWidget objectivesTabButton, Widget objectivesPanelContainer)
{
var panel = hasError ? "SCRIPT_ERROR_PANEL" : iop.PanelName;
Game.LoadWidget(world, panel, objectivesPanelContainer, new WidgetArgs()
{
{ "hideMenu", hideMenu }
});
}

void SetupMapPanel(ButtonWidget mapTabButton, Widget mapPanelContainer)
{
Game.LoadWidget(world, "MAP_PANEL", mapPanelContainer, new WidgetArgs());
}

void SetupDebugPanel(ButtonWidget debugTabButton, Widget debugPanelContainer)
{
if (debugTabButton != null)
debugTabButton.IsDisabled = () => world.IsGameOver;

Game.LoadWidget(world, "DEBUG_PANEL", debugPanelContainer, new WidgetArgs());

if (activePanel == IngameInfoPanel.AutoSelect)
activePanel = IngameInfoPanel.Debug;
}

void SetupChatPanel(ButtonWidget chatTabButton, Widget chatPanelContainer)
{
if (chatTabButton != null)
{
var lastOnClick = chatTabButton.OnClick;
chatTabButton.OnClick = () =>
{
lastOnClick();
chatPanelContainer.Get<TextFieldWidget>("CHAT_TEXTFIELD").TakeKeyboardFocus();
};
}

Game.LoadWidget(world, "CHAT_CONTAINER", chatPanelContainer, new WidgetArgs() { { "isMenuChat", true } });
}
}
}
4 changes: 2 additions & 2 deletions OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs
Expand Up @@ -39,7 +39,7 @@ public class IngameMenuLogic : ChromeLogic

[ObjectCreator.UseCtor]
public IngameMenuLogic(Widget widget, ModData modData, World world, Action onExit, WorldRenderer worldRenderer,
IngameInfoPanel activePanel, Dictionary<string, MiniYaml> logicArgs)
IngameInfoPanel initialPanel, Dictionary<string, MiniYaml> logicArgs)
{
this.modData = modData;
this.world = world;
Expand Down Expand Up @@ -103,7 +103,7 @@ public class IngameMenuLogic : ChromeLogic
Action<bool> requestHideMenu = h => hideMenu = h;
var gameInfoPanel = Game.LoadWidget(world, "GAME_INFO_PANEL", panelRoot, new WidgetArgs()
{
{ "activePanel", activePanel },
{ "initialPanel", initialPanel },
{ "hideMenu", requestHideMenu }
});

Expand Down
Expand Up @@ -47,7 +47,7 @@ public MenuButtonsChromeLogic(Widget widget, ModData modData, World world, Dicti
blinking = false;
OpenMenuPanel(options, new WidgetArgs()
{
{ "activePanel", IngameInfoPanel.AutoSelect }
{ "initialPanel", IngameInfoPanel.AutoSelect }
});
};
options.IsHighlighted = () => blinking && Game.LocalTick % 50 < 25;
Expand Down Expand Up @@ -79,7 +79,7 @@ public MenuButtonsChromeLogic(Widget widget, ModData modData, World world, Dicti
debug.IsDisabled = () => disableSystemButtons;
debug.OnClick = () => OpenMenuPanel(debug, new WidgetArgs()
{
{ "activePanel", IngameInfoPanel.Debug }
{ "initialPanel", IngameInfoPanel.Debug }
});
}

Expand Down
67 changes: 60 additions & 7 deletions mods/cnc/chrome/ingame-info.yaml
Expand Up @@ -20,31 +20,84 @@ Container@GAME_INFO_PANEL:
Align: Center
Font: BigBold
Contrast: true
Container@TAB_CONTAINER:
Container@TAB_CONTAINER_2:
Visible: False
Children:
Button@BUTTON1:
Y: 5
Width: 140
Height: 35
Button@BUTTON2:
X: 150
Y: 5
Width: 140
Height: 35
Container@TAB_CONTAINER_3:
Visible: False
Children:
Button@BUTTON1:
Y: 5
Width: 140
Height: 35
Visible: False
Button@BUTTON2:
X: 150
Y: 5
Width: 140
Height: 35
Visible: False
Button@BUTTON3:
X: 300
Y: 5
Width: 140
Height: 35
Visible: False
Container@TAB_CONTAINER_4:
Visible: False
Children:
Button@BUTTON1:
Y: 5
Width: 121
Height: 35
Button@BUTTON2:
X: 131
Y: 5
Width: 120
Height: 35
Button@BUTTON3:
X: 261
Y: 5
Width: 120
Height: 35
Button@BUTTON4:
X: 450
X: 391
Y: 5
Width: 140
Width: 121
Height: 35
Container@TAB_CONTAINER_5:
Visible: False
Children:
Button@BUTTON1:
Y: 5
Width: 99
Height: 35
Button@BUTTON2:
X: 104
Y: 5
Width: 98
Height: 35
Button@BUTTON3:
X: 207
Y: 5
Width: 98
Height: 35
Button@BUTTON4:
X: 310
Y: 5
Width: 98
Height: 35
Button@BUTTON5:
X: 413
Y: 5
Width: 99
Height: 35
Visible: False
Background@BACKGROUND:
Y: 39
Width: PARENT_RIGHT
Expand Down

0 comments on commit 55c8bbf

Please sign in to comment.