diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/CommandBarLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/CommandBarLogic.cs index d1cdfe4fa3..dc83ecf226 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/CommandBarLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/CommandBarLogic.cs @@ -10,7 +10,9 @@ #endregion using System; +using System.Collections.Generic; using System.Linq; +using OpenRA.Graphics; using OpenRA.Mods.Common.Orders; using OpenRA.Mods.Common.Traits; using OpenRA.Orders; @@ -40,10 +42,14 @@ namespace OpenRA.Mods.Common.Widgets TraitPair[] selectedDeploys = { }; [ObjectCreator.UseCtor] - public CommandBarLogic(Widget widget, World world) + public CommandBarLogic(Widget widget, World world, Dictionary logicArgs) { this.world = world; + var highlightOnButtonPress = false; + if (logicArgs.ContainsKey("HighlightOnButtonPress")) + highlightOnButtonPress = FieldLoader.GetValue("HighlightOnButtonPress", logicArgs["HighlightOnButtonPress"].Value); + var attackMoveButton = widget.GetOrNull("ATTACK_MOVE"); if (attackMoveButton != null) { @@ -133,7 +139,14 @@ namespace OpenRA.Mods.Common.Widgets scatterButton.IsDisabled = () => { UpdateStateIfNecessary(); return scatterDisabled; }; scatterButton.IsHighlighted = () => scatterHighlighted > 0; - scatterButton.OnClick = () => PerformKeyboardOrderOnSelection(a => new Order("Scatter", a, false)); + scatterButton.OnClick = () => + { + if (highlightOnButtonPress) + scatterHighlighted = 2; + + PerformKeyboardOrderOnSelection(a => new Order("Scatter", a, false)); + }; + scatterButton.OnKeyPress = ki => { scatterHighlighted = 2; scatterButton.OnClick(); }; } @@ -144,7 +157,14 @@ namespace OpenRA.Mods.Common.Widgets deployButton.IsDisabled = () => { UpdateStateIfNecessary(); return !selectedDeploys.Any(Exts.IsTraitEnabled); }; deployButton.IsHighlighted = () => deployHighlighted > 0; - deployButton.OnClick = PerformDeployOrderOnSelection; + deployButton.OnClick = () => + { + if (highlightOnButtonPress) + deployHighlighted = 2; + + PerformDeployOrderOnSelection(); + }; + deployButton.OnKeyPress = ki => { deployHighlighted = 2; deployButton.OnClick(); }; } @@ -155,7 +175,14 @@ namespace OpenRA.Mods.Common.Widgets stopButton.IsDisabled = () => { UpdateStateIfNecessary(); return stopDisabled; }; stopButton.IsHighlighted = () => stopHighlighted > 0; - stopButton.OnClick = () => PerformKeyboardOrderOnSelection(a => new Order("Stop", a, false)); + stopButton.OnClick = () => + { + if (highlightOnButtonPress) + stopHighlighted = 2; + + PerformKeyboardOrderOnSelection(a => new Order("Stop", a, false)); + }; + stopButton.OnKeyPress = ki => { stopHighlighted = 2; stopButton.OnClick(); }; } @@ -193,7 +220,15 @@ namespace OpenRA.Mods.Common.Widgets void BindButtonIcon(ButtonWidget button) { var icon = button.Get("ICON"); - icon.GetImageName = () => button.IsDisabled() ? icon.ImageName + "-disabled" : icon.ImageName; + var hasDisabled = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-disabled") != null; + var hasActive = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-active") != null; + var hasActiveHover = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-active-hover") != null; + var hasHover = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-hover") != null; + + icon.GetImageName = () => hasActive && button.IsHighlighted() ? + (hasActiveHover && Ui.MouseOverWidget == button ? icon.ImageName + "-active-hover" : icon.ImageName + "-active") : + hasDisabled && button.IsDisabled() ? icon.ImageName + "-disabled" : + hasHover && Ui.MouseOverWidget == button ? icon.ImageName + "-hover" : icon.ImageName; } bool IsForceModifiersActive(Modifiers modifiers) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/StanceSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/StanceSelectorLogic.cs index edfa7d10e7..1375edb262 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/StanceSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/StanceSelectorLogic.cs @@ -11,6 +11,7 @@ using System; using System.Linq; +using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; using OpenRA.Widgets; @@ -48,8 +49,15 @@ namespace OpenRA.Mods.Common.Widgets void BindStanceButton(ButtonWidget button, UnitStance stance) { var icon = button.Get("ICON"); - icon.GetImageName = () => button.IsDisabled() ? icon.ImageName + "-disabled" : - button.IsHighlighted() ? icon.ImageName + "-active" : icon.ImageName; + var hasDisabled = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-disabled") != null; + var hasActive = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-active") != null; + var hasActiveHover = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-active-hover") != null; + var hasHover = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-hover") != null; + + icon.GetImageName = () => hasActive && button.IsHighlighted() ? + (hasActiveHover && Ui.MouseOverWidget == button ? icon.ImageName + "-active-hover" : icon.ImageName + "-active") : + hasDisabled && button.IsDisabled() ? icon.ImageName + "-disabled" : + hasHover && Ui.MouseOverWidget == button ? icon.ImageName + "-hover" : icon.ImageName; button.IsDisabled = () => { UpdateStateIfNecessary(); return !actorStances.Any(); }; button.IsHighlighted = () => actorStances.Any( diff --git a/mods/ts/chrome.yaml b/mods/ts/chrome.yaml index 06f5a76a2d..b23714af38 100644 --- a/mods/ts/chrome.yaml +++ b/mods/ts/chrome.yaml @@ -6,6 +6,7 @@ sidebar-gdi: chrome.png background-top: 0,0,235,260 background-iconrow: 0,260,235,52 background-bottom: 0,312,235,26 + background-commandbar: 87,461,425,51 sidebar-button-gdi: chrome.png background: 235,119,30,31 @@ -106,6 +107,70 @@ cash-icons-gdi: chrome.png cash-normal: 480,144,16,16 cash-critical: 496,144,16,16 +command-icons-gdi: chrome.png + attack-move: 304,331,26,26 + attack-move-disabled: 304,357,26,26 + attack-move-active: 304,383,26,26 + attack-move-hover: 304,409,26,26 + attack-move-active-hover: 304,435,26,26 + force-move: 330,331,24,24 + force-move-disabled: 330,357,26,26 + force-move-active: 330,383,26,26 + force-move-hover: 330,409,26,26 + force-move-active-hover: 330,435,26,26 + force-attack: 356,331,26,26 + force-attack-disabled: 356,357,26,26 + force-attack-active: 356,383,26,26 + force-attack-hover: 356,409,26,26 + force-attack-active-hover: 356,435,26,26 + guard: 382,331,24,24 + guard-disabled: 382,357,26,26 + guard-active: 382,383,26,26 + guard-hover: 382,409,26,26 + guard-active-hover: 382,435,26,26 + deploy: 408,331,24,24 + deploy-disabled: 408,357,26,26 + deploy-active: 408,383,26,26 + deploy-hover: 408,409,26,26 + deploy-active-hover: 408,435,26,26 + scatter: 434,331,26,26 + scatter-disabled: 434,357,26,26 + scatter-active: 434,383,26,26 + scatter-hover: 434,409,26,26 + scatter-active-hover: 434,435,26,26 + stop: 460,331,26,26 + stop-disabled: 460,357,26,26 + stop-active: 460,383,26,26 + stop-hover: 460,409,26,26 + stop-active-hover: 460,435,26,26 + queue-orders: 486,331,26,26 + queue-orders-disabled: 486,357,26,26 + queue-orders-active: 486,383,26,26 + queue-orders-hover: 486,409,26,26 + queue-orders-active-hover: 486,435,26,26 + +stance-icons-gdi: chrome.png + attack-anything: 424,176,22,22 + attack-anything-disabled: 424,198,22,22 + attack-anything-active: 424,220,22,22 + attack-anything-hover: 424,242,22,22 + attack-anything-active-hover: 424,264,22,22 + defend: 446,176,22,22 + defend-disabled: 446,198,22,22 + defend-active: 446,220,22,22 + defend-hover: 446,242,22,22 + defend-active-hover: 446,264,22,22 + return-fire: 468,176,22,22 + return-fire-disabled: 468,198,22,22 + return-fire-active: 468,220,22,22 + return-fire-hover: 468,242,22,22 + return-fire-active-hover: 468,264,22,22 + hold-fire: 490,176,22,22 + hold-fire-disabled: 490,198,22,22 + hold-fire-active: 490,220,22,22 + hold-fire-hover: 490,242,22,22 + hold-fire-active-hover: 490,264,22,22 + # ---------------------------------------------------------------------- # NOD # ---------------------------------------------------------------------- @@ -114,6 +179,7 @@ sidebar-nod: chrome.png background-top: 512,0,235,260 background-iconrow: 512,260,235,52 background-bottom: 512,312,235,26 + background-commandbar: 599,461,425,51 sidebar-button-nod: chrome.png background: 747,119,30,31 @@ -217,6 +283,70 @@ cash-icons-nod: chrome.png cash-normal: 992,144,16,16 cash-critical: 1008,144,16,16 +command-icons-nod: chrome.png + attack-move: 816,331,26,26 + attack-move-disabled: 816,357,26,26 + attack-move-active: 816,383,26,26 + attack-move-hover: 816,409,26,26 + attack-move-active-hover: 816,435,26,26 + force-move: 842,331,24,24 + force-move-disabled: 842,357,26,26 + force-move-active: 842,383,26,26 + force-move-hover: 842,409,26,26 + force-move-active-hover: 842,435,26,26 + force-attack: 868,331,26,26 + force-attack-disabled: 868,357,26,26 + force-attack-active: 868,383,26,26 + force-attack-hover: 868,409,26,26 + force-attack-active-hover: 868,435,26,26 + guard: 894,331,24,24 + guard-disabled: 894,357,26,26 + guard-active: 894,383,26,26 + guard-hover: 894,409,26,26 + guard-active-hover: 894,435,26,26 + deploy: 920,331,24,24 + deploy-disabled: 920,357,26,26 + deploy-active: 920,383,26,26 + deploy-hover: 920,409,26,26 + deploy-active-hover: 920,435,26,26 + scatter: 946,331,26,26 + scatter-disabled: 946,357,26,26 + scatter-active: 946,383,26,26 + scatter-hover: 946,409,26,26 + scatter-active-hover: 946,435,26,26 + stop: 972,331,26,26 + stop-disabled: 972,357,26,26 + stop-active: 972,383,26,26 + stop-hover: 972,409,26,26 + stop-active-hover: 972,435,26,26 + queue-orders: 998,331,26,26 + queue-orders-disabled: 998,357,26,26 + queue-orders-active: 998,383,26,26 + queue-orders-hover: 998,409,26,26 + queue-orders-active-hover: 998,435,26,26 + +stance-icons-nod: chrome.png + attack-anything: 936,176,22,22 + attack-anything-disabled: 936,198,22,22 + attack-anything-active: 936,220,22,22 + attack-anything-hover: 936,242,22,22 + attack-anything-active-hover: 936,264,22,22 + defend: 958,176,22,22 + defend-disabled: 958,198,22,22 + defend-active: 958,220,22,22 + defend-hover: 958,242,22,22 + defend-active-hover: 958,264,22,22 + return-fire: 980,176,22,22 + return-fire-disabled: 980,198,22,22 + return-fire-active: 980,220,22,22 + return-fire-hover: 980,242,22,22 + return-fire-active-hover: 980,264,22,22 + hold-fire: 1002,176,22,22 + hold-fire-disabled: 1002,198,22,22 + hold-fire-active: 1002,220,22,22 + hold-fire-hover: 1002,242,22,22 + hold-fire-active-hover: 1002,264,22,22 + # ---------------------------------------------------------------------- # GENERIC # ---------------------------------------------------------------------- diff --git a/mods/ts/chrome/ingame-player.yaml b/mods/ts/chrome/ingame-player.yaml index aabf3e38fd..d1bafb0d8a 100644 --- a/mods/ts/chrome/ingame-player.yaml +++ b/mods/ts/chrome/ingame-player.yaml @@ -3,9 +3,6 @@ Container@PLAYER_WIDGETS: LogicKeyListener@CONTROLGROUP_KEYHANDLER: Logic: ControlGroupLogic LogicTicker@SIDEBAR_TICKER: - UnitCommand: - Width: WINDOW_RIGHT - Height: WINDOW_BOTTOM Container@SUPPORT_POWERS: Logic: SupportPowerBinLogic X: 10 @@ -18,6 +15,247 @@ Container@PLAYER_WIDGETS: ReadyText: READY HoldText: ON HOLD ClockPalette: iconclock + Image@COMMAND_BAR_BACKGROUND: + Logic: AddFactionSuffixLogic + X: 5 + Y: WINDOW_BOTTOM - HEIGHT - 5 + Width: 449 + Height: 51 + ImageCollection: sidebar + ImageName: background-commandbar + ClickThrough: False + Container@COMMAND_BAR: + Logic: CommandBarLogic + HighlightOnButtonPress: True + X: 19 + Y: WINDOW_BOTTOM - HEIGHT - 20 + Width: 275 + Height: 26 + Children: + Button@ATTACK_MOVE: + Width: 35 + Height: 32 + VisualHeight: 0 + Background: + Key: AttackMove + DisableKeySound: true + TooltipText: Attack Move + TooltipDesc: Selected units will move to the desired location\nand attack any enemies they encounter en route.\n\nLeft-click icon then right-click on target location. + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 5 + Y: 3 + ImageCollection: command-icons + ImageName: attack-move + Button@FORCE_MOVE: + X: 35 + Width: 35 + Height: 32 + VisualHeight: 0 + Background: + DisableKeySound: true + TooltipText: Force Move + TooltipDesc: Selected units will move to the desired location\n - Default activity for the target is suppressed\n - Vehicles will attempt to crush enemies at the target location\n - Units entering transports will consider nearby alternatives\n - Carryalls will not release their cargo at the target location\n\nLeft-click icon then right-click on target.\nHold {(Alt)} to activate temporarily while commanding units. + TooltipContainer: TOOLTIP_CONTAINER + TooltipTemplate: BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 5 + Y: 3 + ImageCollection: command-icons + ImageName: force-move + Button@FORCE_ATTACK: + X: 70 + Width: 35 + Height: 32 + VisualHeight: 0 + Background: + DisableKeySound: true + TooltipText: Force Attack + TooltipDesc: Selected units will attack the targeted unit or location\nignoring their default activity for the target.\n\nLeft-click icon then right-click on target.\nHold {(Ctrl)} to activate temporarily while commanding units. + TooltipContainer: TOOLTIP_CONTAINER + TooltipTemplate: BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 5 + Y: 3 + ImageCollection: command-icons + ImageName: force-attack + Button@GUARD: + X: 105 + Width: 35 + Height: 32 + VisualHeight: 0 + Background: + Key: Guard + DisableKeySound: true + TooltipText: Guard + TooltipDesc: Selected units will follow the targeted unit.\n\nLeft-click icon then right-click on target unit. + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 5 + Y: 3 + ImageCollection: command-icons + ImageName: guard + Button@DEPLOY: + X: 140 + Width: 35 + Height: 32 + VisualHeight: 0 + Background: + Key: Deploy + DisableKeyRepeat: true + DisableKeySound: true + TooltipText: Deploy + TooltipDesc: Selected units will perform their default deploy activity\n - MCVs will unpack into a Construction Yard\n - Construction Yards will re-pack into a MCV\n - Transports will unload their passengers\n - Tick Tanks, Artillery, Juggernauts,\n and Mobile Sensor arrays will deploy\n - Aircraft will return to base\n\nActs immediately on selected units. + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 5 + Y: 3 + ImageCollection: command-icons + ImageName: deploy + Button@SCATTER: + X: 175 + Width: 35 + Height: 32 + VisualHeight: 0 + Background: + Key: Scatter + DisableKeyRepeat: true + DisableKeySound: true + TooltipText: Scatter + TooltipDesc: Selected units will stop their current activity\nand move to a nearby location.\n\nActs immediately on selected units. + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 5 + Y: 3 + ImageCollection: command-icons + ImageName: scatter + Button@STOP: + X: 210 + Width: 35 + Height: 32 + VisualHeight: 0 + Background: + Key: Stop + DisableKeyRepeat: true + DisableKeySound: true + TooltipText: Stop + TooltipDesc: Selected units will stop their current activity.\n\nActs immediately on selected units. + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 5 + Y: 3 + ImageCollection: command-icons + ImageName: stop + Button@QUEUE_ORDERS: + X: 245 + Width: 35 + Height: 32 + VisualHeight: 0 + Background: + DisableKeySound: true + TooltipText: Waypoint Mode + TooltipDesc: Use Waypoint Mode to give multiple linking commands\nto the selected units. Units will execute the commands\nimmediately upon receiving them.\n\nLeft-click icon then give commands in the game world.\nHold {(Shift)} to activate temporarily while commanding units. + TooltipContainer: TOOLTIP_CONTAINER + TooltipTemplate: BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 5 + Y: 3 + ImageCollection: command-icons + ImageName: queue-orders + Container@STANCE_BAR: + Logic: StanceSelectorLogic + X: 306 + Y: WINDOW_BOTTOM - HEIGHT - 20 + Width: 138 + Height: 26 + Children: + Button@STANCE_ATTACKANYTHING: + Width: 28 + Height: 32 + VisualHeight: 0 + Background: + Key: StanceAttackAnything + DisableKeyRepeat: true + TooltipText: Attack Anything Stance + TooltipDesc: Set the selected units to Attack Anything stance:\n - Units will attack enemy units and structures on sight\n - Units will pursue attackers across the battlefield + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 4 + Y: 5 + ImageCollection: stance-icons + ImageName: attack-anything + Button@STANCE_DEFEND: + X: 28 + Width: 28 + Height: 32 + VisualHeight: 0 + Background: + Key: StanceDefend + DisableKeyRepeat: true + TooltipText: Defend Stance + TooltipDesc: Set the selected units to Defend stance:\n - Units will attack enemy units on sight\n - Units will not move or pursue enemies + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 4 + Y: 5 + ImageCollection: stance-icons + ImageName: defend + Button@STANCE_RETURNFIRE: + X: 56 + Width: 28 + Height: 32 + VisualHeight: 0 + Background: + Key: StanceReturnFire + DisableKeyRepeat: true + TooltipText: Return Fire Stance + TooltipDesc: Set the selected units to Return Fire stance:\n - Units will retaliate against enemies that attack them\n - Units will not move or pursue enemies + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 4 + Y: 5 + ImageCollection: stance-icons + ImageName: return-fire + Button@STANCE_HOLDFIRE: + X: 84 + Width: 28 + Height: 32 + VisualHeight: 0 + Background: + Key: StanceHoldFire + DisableKeyRepeat: true + TooltipText: Hold Fire Stance + TooltipDesc: Set the selected units to Hold Fire stance:\n - Units will not fire upon enemies\n - Units will not move or pursue enemies + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + Logic: AddFactionSuffixLogic + X: 4 + Y: 5 + ImageCollection: stance-icons + ImageName: hold-fire Image@SIDEBAR_BACKGROUND_TOP: Logic: AddFactionSuffixLogic X: WINDOW_RIGHT - 235