diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index d570463595..8a7c526797 100755 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -228,6 +228,7 @@ + diff --git a/OpenRA.Game/Widgets/SliderWidget.cs b/OpenRA.Game/Widgets/SliderWidget.cs new file mode 100644 index 0000000000..040fdaf4cf --- /dev/null +++ b/OpenRA.Game/Widgets/SliderWidget.cs @@ -0,0 +1,158 @@ +using System; +using System.Drawing; + +namespace OpenRA.Widgets +{ + public class SliderWidget : Widget + { + public event Action OnChange; + public Func GetOffset; + public float Offset = 0; + public int Ticks = 0; + public int TrackHeight = 5; + + int2 lastMouseLocation; + bool isMoving = false; + + public SliderWidget () : base() + { + GetOffset = () => Offset; + OnChange = x => Offset = x; + } + + public SliderWidget(Widget other) + : base(other) + { + OnChange = (other as SliderWidget).OnChange; + GetOffset = (other as SliderWidget).GetOffset; + Offset = (other as SliderWidget).Offset; + Ticks = (other as SliderWidget).Ticks; + TrackHeight = (other as SliderWidget).TrackHeight; + lastMouseLocation = (other as SliderWidget).lastMouseLocation; + isMoving = (other as SliderWidget).isMoving; + } + + public override bool HandleInput(MouseInput mi) + { + if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) + return false; + + if (!Focused) + return false; + + switch (mi.Event) + { + case MouseInputEvent.Up: + { + if (Focused) + { + isMoving = false; + base.LoseFocus(mi); + } + } + break; + + case MouseInputEvent.Down: + { + if (thumbRect.Contains(mi.Location.ToPoint())) + { + isMoving = true; + lastMouseLocation = mi.Location; + } + else if (Ticks != 0) + { + var pos = GetOffset(); + + // Offset slightly the direction we want to move so we don't get stuck on a tick + var delta = 0.001; + var targetTick = (float)((mi.Location.X > thumbRect.Right) ? Math.Ceiling((pos+delta)*(Ticks-1)) + : Math.Floor((pos-delta)*(Ticks-1))); + OnChange(targetTick/(Ticks-1)); + + if (thumbRect.Contains(mi.Location.ToPoint())) + { + isMoving = true; + lastMouseLocation = mi.Location; + } + return true; + } + else // No ticks; move to the mouse position + { + var thumb = thumbRect; + var center = thumb.X + thumb.Width/2; + var newOffset = OffsetBy((mi.Location.X - center)*1f/(RenderBounds.Width-thumb.Width)); + if (newOffset != GetOffset()) + { + OnChange(newOffset); + + if (thumbRect.Contains(mi.Location.ToPoint())) + { + isMoving = true; + lastMouseLocation = mi.Location; + } + return true; + } + } + } + break; + + case MouseInputEvent.Move: + { + if ((mi.Location.X != lastMouseLocation.X) && isMoving) + { + var newOffset = OffsetBy((mi.Location.X - lastMouseLocation.X)*1f/(RenderBounds.Width-thumbRect.Width)); + if (newOffset != Offset) + { + lastMouseLocation = mi.Location; + OnChange(newOffset); + } + } + } + break; + } + + return thumbRect.Contains(mi.Location.X,mi.Location.Y); + } + + float OffsetBy(float amount) + { + var centerPos = GetOffset() + amount; + if (centerPos < 0) centerPos = 0; + if (centerPos > 1) centerPos = 1; + return centerPos; + } + + public override Widget Clone() { return new SliderWidget(this); } + + Rectangle thumbRect + { get { + var width = RenderBounds.Height; + var height = RenderBounds.Height; + var origin = (int)((RenderBounds.X + width/2) + GetOffset()*(RenderBounds.Width - width) - width/2f); + return new Rectangle(origin, RenderBounds.Y, width, height); + } } + + public override void DrawInner(World world) { + if (!IsVisible()) + return; + + var trackWidth = RenderBounds.Width - thumbRect.Width; + var trackOrigin = RenderBounds.X + thumbRect.Width/2; + var trackRect = new Rectangle(trackOrigin-1, RenderBounds.Y + (RenderBounds.Height - TrackHeight)/2, trackWidth+2, TrackHeight); + + // Tickmarks (hacked until we have real art) + for (int i = 0; i < Ticks; i++) + { + var tickRect = new Rectangle(trackOrigin -1 + (int)(i*trackWidth*1f/(Ticks-1)), + RenderBounds.Y + RenderBounds.Height/2, 2, RenderBounds.Height/2); + WidgetUtils.DrawPanel("dialog2", tickRect); + } + // Track + WidgetUtils.DrawPanel("dialog3", trackRect); + + // Thumb + WidgetUtils.DrawPanel("dialog2", thumbRect); + } + } +} +