diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 666468f438..a89da70834 100755 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -16,6 +17,16 @@ using OpenRA.Support; namespace OpenRA.Graphics { + [Flags] + public enum ScrollDirection + { + None = 0, + Up = 1, + Left = 2, + Down = 4, + Right = 8 + } + public class Viewport { readonly int2 screenSize; @@ -164,4 +175,17 @@ namespace OpenRA.Graphics return (b.HasValue) ? Rectangle.Intersect(cachedRect, b.Value) : cachedRect; } } + + public static class ViewportExts + { + public static bool Includes(this ScrollDirection d, ScrollDirection s) + { + return (d & s) == s; + } + + public static ScrollDirection Set(this ScrollDirection d, ScrollDirection s, bool val) + { + return (d.Includes(s) != val) ? d ^ s : d; + } + } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs b/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs index 8af7316fec..a9eb5b9ce1 100755 --- a/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs +++ b/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs @@ -15,16 +15,6 @@ using OpenRA.Graphics; namespace OpenRA.Widgets { - [Flags] - public enum ScrollDirection - { - None = 0, - Up = 1, - Left = 2, - Down = 4, - Right = 8 - } - public class ViewportScrollControllerWidget : Widget { public int EdgeScrollThreshold = 15; @@ -32,8 +22,9 @@ namespace OpenRA.Widgets ScrollDirection Keyboard; ScrollDirection Edge; - public ViewportScrollControllerWidget() : base() { } - protected ViewportScrollControllerWidget(ViewportScrollControllerWidget widget) : base(widget) {} + public ViewportScrollControllerWidget() : base() {} + protected ViewportScrollControllerWidget(ViewportScrollControllerWidget widget) + : base(widget) {} public override bool HandleMouseInput(MouseInput mi) { @@ -136,17 +127,4 @@ namespace OpenRA.Widgets public override Widget Clone() { return new ViewportScrollControllerWidget(this); } } - - public static class ViewportExts - { - public static bool Includes(this ScrollDirection d, ScrollDirection s) - { - return (d & s) == s; - } - - public static ScrollDirection Set(this ScrollDirection d, ScrollDirection s, bool val) - { - return (d.Includes(s) != val) ? d ^ s : d; - } - } } diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj index 85ea902e06..90b4284301 100644 --- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj +++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj @@ -101,8 +101,8 @@ - + diff --git a/OpenRA.Mods.Cnc/Widgets/CncWorldInteractionControllerWidget.cs b/OpenRA.Mods.Cnc/Widgets/CncWorldInteractionControllerWidget.cs new file mode 100644 index 0000000000..5953732d1d --- /dev/null +++ b/OpenRA.Mods.Cnc/Widgets/CncWorldInteractionControllerWidget.cs @@ -0,0 +1,219 @@ +#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 System; +using System.Linq; +using OpenRA.FileFormats; +using OpenRA.Graphics; +using OpenRA.Traits; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Cnc.Widgets +{ + public class CncWorldInteractionControllerWidget : WorldInteractionControllerWidget + { + public readonly string TooltipTemplate = "WORLD_TOOLTIP"; + public readonly string TooltipContainer; + Lazy tooltipContainer; + + public enum WorldTooltipType { None, Unexplored, Actor } + public WorldTooltipType TooltipType { get; private set; } + public IToolTip ActorTooltip { get; private set; } + + public int EdgeScrollThreshold = 15; + ScrollDirection Keyboard; + ScrollDirection Edge; + + [ObjectCreator.UseCtor] + public CncWorldInteractionControllerWidget([ObjectCreator.Param] World world, + [ObjectCreator.Param] WorldRenderer worldRenderer) + : base(world, worldRenderer) + { + tooltipContainer = new Lazy(() => + Widget.RootWidget.GetWidget(TooltipContainer)); + } + + public override void MouseEntered() + { + if (TooltipContainer == null) + return; + + tooltipContainer.Value.SetTooltip( + Widget.LoadWidget(TooltipTemplate, null, new WidgetArgs() {{ "world", world }, { "wic", this }})); + } + + public override void MouseExited() + { + if (TooltipContainer == null) return; + tooltipContainer.Value.RemoveTooltip(); + } + + public void UpdateMouseover() + { + TooltipType = WorldTooltipType.None; + var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2(); + if (!world.Map.IsInMap(cell)) + return; + + if (world.LocalPlayer != null && !world.LocalPlayer.Shroud.IsExplored(cell)) + { + TooltipType = WorldTooltipType.Unexplored; + return; + } + + var actor = world.FindUnitsAtMouse(Viewport.LastMousePos).FirstOrDefault(); + if (actor == null) + return; + + ActorTooltip = actor.TraitsImplementing().FirstOrDefault(); + if (ActorTooltip != null) + TooltipType = WorldTooltipType.Actor; + } + + public override bool HandleMouseInput(MouseInput mi) + { + if (mi.Event == MouseInputEvent.Move) + UpdateMouseover(); + + var scrolltype = Game.Settings.Game.MouseScroll; + if (scrolltype != OpenRA.GameRules.MouseScrollType.Disabled && mi.Event == MouseInputEvent.Move && + (mi.Button == MouseButton.Middle || mi.Button == (MouseButton.Left | MouseButton.Right))) + { + var d = scrolltype == OpenRA.GameRules.MouseScrollType.Inverted ? -1 : 1; + Game.viewport.Scroll((Viewport.LastMousePos - mi.Location) * d); + } + + return base.HandleMouseInput(mi); + } + + public override string GetCursor(int2 pos) + { + if (!Game.Settings.Game.ViewportEdgeScroll || Widget.MouseOverWidget != this) + return base.GetCursor(pos); + + if (Edge.Includes(ScrollDirection.Up) && Edge.Includes(ScrollDirection.Left)){ + ScrollDirection BlockedDirections = Game.viewport.GetBlockedDirections(); + if(BlockedDirections.Includes(ScrollDirection.Up) && BlockedDirections.Includes(ScrollDirection.Left)) + return "scroll-tl-blocked"; + else + return "scroll-tl"; + } + if (Edge.Includes(ScrollDirection.Up) && Edge.Includes(ScrollDirection.Right)){ + ScrollDirection BlockedDirections = Game.viewport.GetBlockedDirections(); + if (BlockedDirections.Includes(ScrollDirection.Up) && BlockedDirections.Includes(ScrollDirection.Right)) + return "scroll-tr-blocked"; + else + return "scroll-tr"; + } + if (Edge.Includes(ScrollDirection.Down) && Edge.Includes(ScrollDirection.Left)){ + ScrollDirection BlockedDirections = Game.viewport.GetBlockedDirections(); + if (BlockedDirections.Includes(ScrollDirection.Down) && BlockedDirections.Includes(ScrollDirection.Left)) + return "scroll-bl-blocked"; + else + return "scroll-bl"; + } + if (Edge.Includes(ScrollDirection.Down) && Edge.Includes(ScrollDirection.Right)){ + ScrollDirection BlockedDirections = Game.viewport.GetBlockedDirections(); + if (BlockedDirections.Includes(ScrollDirection.Down) && BlockedDirections.Includes(ScrollDirection.Right)) + return "scroll-br-blocked"; + else + return "scroll-br"; + } + + if (Edge.Includes(ScrollDirection.Up)) + if (Game.viewport.GetBlockedDirections().Includes(ScrollDirection.Up)) + return "scroll-t-blocked"; + else + return "scroll-t"; + if (Edge.Includes(ScrollDirection.Down)) + if (Game.viewport.GetBlockedDirections().Includes(ScrollDirection.Down)) + return "scroll-b-blocked"; + else + return "scroll-b"; + if (Edge.Includes(ScrollDirection.Left)) + if (Game.viewport.GetBlockedDirections().Includes(ScrollDirection.Left)) + return "scroll-l-blocked"; + else + return "scroll-l"; + if (Edge.Includes(ScrollDirection.Right)) + if (Game.viewport.GetBlockedDirections().Includes(ScrollDirection.Right)) + return "scroll-r-blocked"; + else + return "scroll-r"; + + return base.GetCursor(pos); + } + + public override bool LoseFocus(MouseInput mi) + { + Keyboard = ScrollDirection.None; + return base.LoseFocus(mi); + } + + public override bool HandleKeyPress(KeyInput e) + { + switch (e.KeyName) + { + case "up": Keyboard = Keyboard.Set(ScrollDirection.Up, (e.Event == KeyInputEvent.Down)); return true; + case "down": Keyboard = Keyboard.Set(ScrollDirection.Down, (e.Event == KeyInputEvent.Down)); return true; + case "left": Keyboard = Keyboard.Set(ScrollDirection.Left, (e.Event == KeyInputEvent.Down)); return true; + case "right": Keyboard = Keyboard.Set(ScrollDirection.Right, (e.Event == KeyInputEvent.Down)); return true; + } + return false; + } + + float2 cachedLocation; + public override void Tick() + { + if (Game.viewport.Location != cachedLocation) + { + UpdateMouseover(); + cachedLocation = Game.viewport.Location; + } + + Edge = ScrollDirection.None; + if (Game.Settings.Game.ViewportEdgeScroll && Game.HasInputFocus && Widget.MouseOverWidget == this) + { + // Check for edge-scroll + if (Viewport.LastMousePos.X < EdgeScrollThreshold) + Edge = Edge.Set(ScrollDirection.Left, true); + if (Viewport.LastMousePos.Y < EdgeScrollThreshold) + Edge = Edge.Set(ScrollDirection.Up, true); + if (Viewport.LastMousePos.X >= Game.viewport.Width - EdgeScrollThreshold) + Edge = Edge.Set(ScrollDirection.Right, true); + if (Viewport.LastMousePos.Y >= Game.viewport.Height - EdgeScrollThreshold) + Edge = Edge.Set(ScrollDirection.Down, true); + } + + if(Keyboard != ScrollDirection.None || Edge != ScrollDirection.None) + { + var scroll = new float2(0, 0); + + // Modified to use the ViewportEdgeScrollStep setting - Gecko + if (Keyboard.Includes(ScrollDirection.Up) || Edge.Includes(ScrollDirection.Up)) + scroll += new float2(0, -1); + if (Keyboard.Includes(ScrollDirection.Right) || Edge.Includes(ScrollDirection.Right)) + scroll += new float2(1, 0); + if (Keyboard.Includes(ScrollDirection.Down) || Edge.Includes(ScrollDirection.Down)) + scroll += new float2(0, 1); + if (Keyboard.Includes(ScrollDirection.Left) || Edge.Includes(ScrollDirection.Left)) + scroll += new float2(-1, 0); + + float length = Math.Max(1, scroll.Length); + scroll.X = (scroll.X / length) * Game.Settings.Game.ViewportEdgeScrollStep; + scroll.Y = (scroll.Y / length) * Game.Settings.Game.ViewportEdgeScrollStep; + + Game.viewport.Scroll(scroll); + } + + base.Tick(); + } + } +} \ No newline at end of file diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/WorldTooltipLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/WorldTooltipLogic.cs index 6b3c37480d..ce9cef285d 100644 --- a/OpenRA.Mods.Cnc/Widgets/Logic/WorldTooltipLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/Logic/WorldTooltipLogic.cs @@ -10,7 +10,7 @@ using OpenRA.Support; using OpenRA.Widgets; -using T = OpenRA.Mods.Cnc.Widgets.TooltipWorldInteractionControllerWidget; +using T = OpenRA.Mods.Cnc.Widgets.CncWorldInteractionControllerWidget; namespace OpenRA.Mods.Cnc.Widgets.Logic { @@ -18,7 +18,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic { [ObjectCreator.UseCtor] public WorldTooltipLogic([ObjectCreator.Param] Widget widget, - [ObjectCreator.Param] TooltipWorldInteractionControllerWidget wic) + [ObjectCreator.Param] CncWorldInteractionControllerWidget wic) { widget.IsVisible = () => wic.TooltipType != T.WorldTooltipType.None; diff --git a/OpenRA.Mods.Cnc/Widgets/TooltipWorldInteractionControllerWidget.cs b/OpenRA.Mods.Cnc/Widgets/TooltipWorldInteractionControllerWidget.cs deleted file mode 100644 index 09074f619a..0000000000 --- a/OpenRA.Mods.Cnc/Widgets/TooltipWorldInteractionControllerWidget.cs +++ /dev/null @@ -1,94 +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.FileFormats; -using OpenRA.Graphics; -using OpenRA.Traits; -using OpenRA.Widgets; -using System.Linq; - -namespace OpenRA.Mods.Cnc.Widgets -{ - public class TooltipWorldInteractionControllerWidget : WorldInteractionControllerWidget - { - public readonly string TooltipTemplate = "WORLD_TOOLTIP"; - public readonly string TooltipContainer; - Lazy tooltipContainer; - - public enum WorldTooltipType { None, Unexplored, Actor } - public WorldTooltipType TooltipType { get; private set; } - public IToolTip ActorTooltip { get; private set; } - - [ObjectCreator.UseCtor] - public TooltipWorldInteractionControllerWidget([ObjectCreator.Param] World world, - [ObjectCreator.Param] WorldRenderer worldRenderer) - : base(world, worldRenderer) - { - tooltipContainer = new Lazy(() => - Widget.RootWidget.GetWidget(TooltipContainer)); - } - - public override void MouseEntered() - { - if (TooltipContainer == null) - return; - - tooltipContainer.Value.SetTooltip( - Widget.LoadWidget(TooltipTemplate, null, new WidgetArgs() {{ "world", world }, { "wic", this }})); - } - - public override void MouseExited() - { - if (TooltipContainer == null) return; - tooltipContainer.Value.RemoveTooltip(); - } - - public void UpdateMouseover() - { - TooltipType = WorldTooltipType.None; - var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2(); - if (!world.Map.IsInMap(cell)) - return; - - if (world.LocalPlayer != null && !world.LocalPlayer.Shroud.IsExplored(cell)) - { - TooltipType = WorldTooltipType.Unexplored; - return; - } - - var actor = world.FindUnitsAtMouse(Viewport.LastMousePos).FirstOrDefault(); - if (actor == null) - return; - - ActorTooltip = actor.TraitsImplementing().FirstOrDefault(); - if (ActorTooltip != null) - TooltipType = WorldTooltipType.Actor; - } - - public override bool HandleMouseInput(MouseInput mi) - { - if (mi.Event == MouseInputEvent.Move) - UpdateMouseover(); - - return base.HandleMouseInput(mi); - } - - float2 cachedLocation; - public override void Tick() - { - if (Game.viewport.Location != cachedLocation) - { - UpdateMouseover(); - cachedLocation = Game.viewport.Location; - } - base.Tick(); - } - } -} \ No newline at end of file diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index 5b50816f43..40ab272d5f 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -2,9 +2,6 @@ Container@INGAME_ROOT: Id:INGAME_ROOT Logic:CncIngameChromeLogic Children: - ViewportScrollController: - Width:WINDOW_RIGHT - Height:WINDOW_BOTTOM Timer@GAME_TIMER: Id:GAME_TIMER X: WINDOW_RIGHT/2 @@ -13,18 +10,6 @@ Container@INGAME_ROOT: Id:STRATEGIC_PROGRESS X: WINDOW_RIGHT/2 Y: 40 - TooltipWorldInteractionController: - Id:INTERACTION_CONTROLLER - Width:WINDOW_RIGHT - Height:WINDOW_BOTTOM - TooltipContainer:TOOLTIP_CONTAINER - Button@CHEATS_BUTTON: - Id:CHEATS_BUTTON - X:WINDOW_RIGHT-400 - Y:5 - Width:140 - Height:35 - Text:Cheats ChatDisplay@CHAT_DISPLAY: Id:CHAT_DISPLAY X:250 @@ -58,6 +43,18 @@ Container@INGAME_ROOT: Y:WINDOW_BOTTOM-HEIGHT-10 Width:200 Height:200 + CncWorldInteractionController: + Id:INTERACTION_CONTROLLER + Width:WINDOW_RIGHT + Height:WINDOW_BOTTOM + TooltipContainer:TOOLTIP_CONTAINER + Button@CHEATS_BUTTON: + Id:CHEATS_BUTTON + X:WINDOW_RIGHT-400 + Y:5 + Width:140 + Height:35 + Text:Cheats Container@PLAYER_WIDGETS: Id:PLAYER_WIDGETS Visible:false