diff --git a/OpenRA.FileFormats/Graphics/IInputHandler.cs b/OpenRA.FileFormats/Graphics/IInputHandler.cs index 61a8d37304..29d7c56291 100755 --- a/OpenRA.FileFormats/Graphics/IInputHandler.cs +++ b/OpenRA.FileFormats/Graphics/IInputHandler.cs @@ -27,13 +27,15 @@ namespace OpenRA public MouseButton Button; public int2 Location; public Modifiers Modifiers; + public int MultiTapCount; - public MouseInput( MouseInputEvent ev, MouseButton button, int2 location, Modifiers mods ) + public MouseInput( MouseInputEvent ev, MouseButton button, int2 location, Modifiers mods, int multiTapCount ) { this.Event = ev; this.Button = button; this.Location = location; this.Modifiers = mods; + this.MultiTapCount = multiTapCount; } } diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index 4bf94d91bc..e3c3331cf1 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -68,8 +68,26 @@ namespace OpenRA.Widgets { if (world.OrderGenerator is UnitOrderGenerator) { - var newSelection = SelectActorsInBox(world, dragStart, xy); - world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); + if (mi.MultiTapCount == 2) + { + var unit = world.FindUnitsAtMouse(mi.Location).FirstOrDefault(); + + Rectangle visibleWorld = Game.viewport.ViewBounds(world); + var newSelection = world.FindUnits(Game.viewport.ViewToWorldPx(new int2(visibleWorld.Left, visibleWorld.Top)), + Game.viewport.ViewToWorldPx(new int2(visibleWorld.Right, visibleWorld.Bottom))) + .Where(a => a.HasTrait() + && a.World.LocalShroud.IsVisible(a) + && unit != null + && a.Info.Name == unit.Info.Name + && a.Owner == unit.Owner); + + world.Selection.Combine(world, newSelection, true, false); + } + else + { + var newSelection = SelectActorsInBox(world, dragStart, xy); + world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); + } } dragStart = dragEnd = xy; diff --git a/OpenRA.Renderer.SdlCommon/MultiTapDetection.cs b/OpenRA.Renderer.SdlCommon/MultiTapDetection.cs new file mode 100644 index 0000000000..939f5669a1 --- /dev/null +++ b/OpenRA.Renderer.SdlCommon/MultiTapDetection.cs @@ -0,0 +1,101 @@ +#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.Collections.Generic; +using System.Windows.Forms; +using Tao.Sdl; +using OpenRA; +using OpenRA.FileFormats; + +public static class MultiTapDetection +{ + public static bool MultiTapDetected = false; + public static string VirtualKeyNameOfDetectedMultiTap = ""; + public static int MouseButtonTapsCounted = 1; + + static Cache KeyHistoryCache = new Cache(_ => new TapHistory(DateTime.Now - TimeSpan.FromSeconds(1))); + static Cache ClickHistoryCache = new Cache(_ => new TapHistory(DateTime.Now - TimeSpan.FromSeconds(1))); + + + public static void DetectFromMouse(byte MBName, int2 xy) + { + var clickHistory = ClickHistoryCache[MBName]; + + clickHistory.FirstRelease = clickHistory.SecondRelease; + clickHistory.SecondRelease = clickHistory.ThirdRelease; + clickHistory.ThirdRelease.First = DateTime.Now; + clickHistory.ThirdRelease.Second = xy; + + TimeSpan DurationAfterSecondRelease = clickHistory.ThirdRelease.First - clickHistory.SecondRelease.First; + TimeSpan DurationAfterFirstRelease = clickHistory.SecondRelease.First - clickHistory.FirstRelease.First; + + if ((DurationAfterSecondRelease.TotalMilliseconds < SystemInformation.DoubleClickTime) + && ((clickHistory.ThirdRelease.Second - clickHistory.SecondRelease.Second).Length < 4) + && ((clickHistory.ThirdRelease.Second - clickHistory.SecondRelease.Second).Length < 4)) + { + MultiTapDetected = true; + MouseButtonTapsCounted = 2; + + if ((DurationAfterFirstRelease.TotalMilliseconds < SystemInformation.DoubleClickTime) + && ((clickHistory.SecondRelease.Second - clickHistory.FirstRelease.Second).Length < 4) + && ((clickHistory.SecondRelease.Second - clickHistory.FirstRelease.Second).Length < 4)) + { + MouseButtonTapsCounted = 3; + } + } + else + { + MultiTapDetected = false; + MouseButtonTapsCounted = 1; + } + + } + + public static void DetectFromKeyboard(string KeyName) + { + var keyHistory = KeyHistoryCache[KeyName]; + + keyHistory.FirstRelease = keyHistory.SecondRelease; + keyHistory.SecondRelease = keyHistory.ThirdRelease; + keyHistory.ThirdRelease.First = DateTime.Now; + + TimeSpan DurationAfterSecondRelease = keyHistory.ThirdRelease.First - keyHistory.SecondRelease.First; + TimeSpan DurationAfterFirstRelease = keyHistory.SecondRelease.First - keyHistory.FirstRelease.First; + + if (DurationAfterSecondRelease.TotalMilliseconds < SystemInformation.DoubleClickTime) + { + MultiTapDetected = true; + VirtualKeyNameOfDetectedMultiTap = "DoubleTapOf_" + KeyName; + + if (DurationAfterFirstRelease.TotalMilliseconds < SystemInformation.DoubleClickTime) + { + VirtualKeyNameOfDetectedMultiTap = "TripleTapOf_" + KeyName; + } + } + else + { + MultiTapDetected = false; + VirtualKeyNameOfDetectedMultiTap = ""; + } + } +} + +class TapHistory +{ + public Pair FirstRelease; + public Pair SecondRelease; + public Pair ThirdRelease; + + public TapHistory(DateTime now) + { + this.FirstRelease.First = this.SecondRelease.First = this.ThirdRelease.First = now; + } +} \ No newline at end of file diff --git a/OpenRA.Renderer.SdlCommon/OpenRA.Renderer.SdlCommon.csproj b/OpenRA.Renderer.SdlCommon/OpenRA.Renderer.SdlCommon.csproj index 3829ba431a..eccc32354f 100644 --- a/OpenRA.Renderer.SdlCommon/OpenRA.Renderer.SdlCommon.csproj +++ b/OpenRA.Renderer.SdlCommon/OpenRA.Renderer.SdlCommon.csproj @@ -1,4 +1,4 @@ - + Debug @@ -32,8 +32,11 @@ + + + False ..\thirdparty\Tao\Tao.OpenGl.dll @@ -45,6 +48,7 @@ + @@ -61,4 +65,4 @@ - + \ No newline at end of file diff --git a/OpenRA.Renderer.SdlCommon/SdlInput.cs b/OpenRA.Renderer.SdlCommon/SdlInput.cs index 66eefb1e1b..14d10383aa 100644 --- a/OpenRA.Renderer.SdlCommon/SdlInput.cs +++ b/OpenRA.Renderer.SdlCommon/SdlInput.cs @@ -70,7 +70,7 @@ namespace OpenRA.Renderer.SdlCommon lastButtonBits |= button; inputHandler.OnMouseInput( new MouseInput( - MouseInputEvent.Down, button, new int2( e.button.x, e.button.y ), mods ) ); + MouseInputEvent.Down, button, new int2( e.button.x, e.button.y ), mods, 1 ) ); } break; case Sdl.SDL_MOUSEBUTTONUP: @@ -84,8 +84,11 @@ namespace OpenRA.Renderer.SdlCommon var button = MakeButton( e.button.button ); lastButtonBits &= ~button; + MultiTapDetection.DetectFromMouse( e.button.button, new int2( e.button.x , e.button.y ) ); + inputHandler.OnMouseInput( new MouseInput( - MouseInputEvent.Up, button, new int2( e.button.x, e.button.y ), mods ) ); + MouseInputEvent.Up, button, new int2( e.button.x, e.button.y ), mods, + MultiTapDetection.MouseButtonTapsCounted ) ); } break; case Sdl.SDL_MOUSEMOTION: @@ -94,7 +97,7 @@ namespace OpenRA.Renderer.SdlCommon MouseInputEvent.Move, lastButtonBits, new int2( e.motion.x, e.motion.y ), - mods ); + mods, 0 ); } break; case Sdl.SDL_KEYDOWN: @@ -123,6 +126,14 @@ namespace OpenRA.Renderer.SdlCommon VirtKey = e.key.keysym.sym }; + MultiTapDetection.DetectFromKeyboard( Sdl.SDL_GetKeyName( e.key.keysym.sym ) ); + + if ( MultiTapDetection.MultiTapDetected ) + { + keyEvent.KeyName = MultiTapDetection.VirtualKeyNameOfDetectedMultiTap; + // More info-changes here. + } + inputHandler.OnKeyInput( keyEvent ); } break; }