diff --git a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs index 0bf27db972..8fe35cfa75 100755 --- a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs @@ -15,82 +15,170 @@ using OpenRA.FileFormats; using OpenRA.Graphics; using OpenRA.Mods.RA; using OpenRA.Widgets; +using System; namespace OpenRA.Mods.Cnc.Widgets { class ProductionTabsWidget : Widget { - public string QueueType = null; - string cachedQueueType = null; + string queueType; + public string QueueType + { + get + { + return queueType; + } + set + { + queueType = value; + ListOffset = 0; + ResetButtons(); + Widget.RootWidget.GetWidget(PaletteWidget) + .CurrentQueue = VisibleQueues.Keys.FirstOrDefault(); + } + } + public string PaletteWidget = null; - - List> buttons = new List>(); - List VisibleQueues = new List(); + public float ScrollVelocity = 4f; + public int TabWidth = 30; + public int ArrowWidth = 20; + Dictionary VisibleQueues = new Dictionary(); + + int ContentWidth = 0; + float ListOffset = 0; + bool leftPressed = false; + bool rightPressed = false; + Rectangle leftButtonRect; + Rectangle rightButtonRect; readonly World world; - + [ObjectCreator.UseCtor] public ProductionTabsWidget( [ObjectCreator.Param] World world ) { this.world = world; } - public override void Tick() + public override void DrawInner() + { + var rb = RenderBounds; + + leftButtonRect = new Rectangle(rb.X, rb.Y, ArrowWidth, rb.Height); + rightButtonRect = new Rectangle(rb.Right - ArrowWidth, rb.Y, ArrowWidth, rb.Height); + + var leftDisabled = ListOffset >= 0; + var rightDisabled = ListOffset <= Bounds.Width - rightButtonRect.Width - leftButtonRect.Width - ContentWidth; + + WidgetUtils.DrawPanel("panel-black", rb); + ButtonWidget.DrawBackground("button", leftButtonRect, leftDisabled, + leftPressed, leftButtonRect.Contains(Viewport.LastMousePos)); + ButtonWidget.DrawBackground("button", rightButtonRect, rightDisabled, + rightPressed, rightButtonRect.Contains(Viewport.LastMousePos)); + + WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", leftPressed || leftDisabled ? "up_pressed" : "up_arrow"), + new float2(leftButtonRect.Left + 2, leftButtonRect.Top + 2)); + WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", rightPressed || rightDisabled ? "down_pressed" : "down_arrow"), + new float2(rightButtonRect.Left + 2, rightButtonRect.Top + 2)); + + Game.Renderer.EnableScissor(leftButtonRect.Right, rb.Y + 1, rightButtonRect.Left - leftButtonRect.Right - 1, rb.Height); + + var palette = Widget.RootWidget.GetWidget(PaletteWidget); + // TODO: Draw children buttons + var i = 1; + foreach (var queue in VisibleQueues) + { + ButtonWidget.DrawBackground("button", queue.Value, false, queue.Key == palette.CurrentQueue, queue.Value.Contains(Viewport.LastMousePos)); + + SpriteFont font = Game.Renderer.Fonts["TinyBold"]; + var text = i.ToString(); + int2 textSize = font.Measure(text); + int2 position = new int2(queue.Value.X + (queue.Value.Width - textSize.X)/2, queue.Value.Y + (queue.Value.Height - textSize.Y)/2); + font.DrawTextWithContrast(text, position, Color.White, Color.Black, 1); + i++; + } + + Game.Renderer.DisableScissor(); + } + + void Scroll(int direction) + { + ListOffset += direction*ScrollVelocity; + ListOffset = Math.Min(0,Math.Max(Bounds.Width - rightButtonRect.Width - leftButtonRect.Width - ContentWidth, ListOffset)); + } + + public void ResetButtons() { VisibleQueues.Clear(); + ContentWidth = 0; + var rb = RenderBounds; + var origin = new int2(leftButtonRect.Right - 1 + (int)ListOffset, leftButtonRect.Y); - VisibleQueues = world.ActorsWithTrait() + var queues = world.ActorsWithTrait() .Where(p => p.Actor.Owner == world.LocalPlayer && p.Trait.Info.Type == QueueType) .Select(p => p.Trait).ToList(); - var palette = Widget.RootWidget.GetWidget(PaletteWidget); - if (VisibleQueues.Count() == 0) - palette.CurrentQueue = null; - else if (palette.CurrentQueue == null || cachedQueueType != QueueType) + foreach (var queue in queues) { - palette.CurrentQueue = VisibleQueues.First(); - cachedQueueType = QueueType; + var rect = new Rectangle(origin.X + ContentWidth, origin.Y, TabWidth, rb.Height); + VisibleQueues.Add(queue, rect); + ContentWidth += TabWidth - 1; } + } + + public override void Tick() + { + if (leftPressed) Scroll(1); + if (rightPressed) Scroll(-1); + + ResetButtons(); base.Tick(); } + + public override bool LoseFocus(MouseInput mi) + { + leftPressed = rightPressed = false; + return base.LoseFocus(mi); + } public override bool HandleMouseInput(MouseInput mi) - { - if (mi.Event != MouseInputEvent.Down) - return false; - - var queue = buttons.Where(a => a.First.Contains(mi.Location)) - .Select(a => a.Second).FirstOrDefault(); - if (queue == null) - return true; - - var palette = Widget.RootWidget.GetWidget(PaletteWidget); - - palette.CurrentQueue = queue; - return true; - } - - public override void DrawInner() - { - if (!IsVisible()) return; - buttons.Clear(); - int x = 0; - var palette = Widget.RootWidget.GetWidget(PaletteWidget); - - // Giant hack - var width = 30; - - foreach (var queue in VisibleQueues) + { + if (mi.Button == MouseButton.WheelDown) { - var foo = queue; - var rect = new Rectangle(RenderBounds.X + x,RenderBounds.Y,width, RenderBounds.Height); - var state = palette.CurrentQueue == queue ? 2 : - rect.Contains(Viewport.LastMousePos) ? 1 : 0; - x += width; - - WidgetUtils.DrawRGBA(ChromeProvider.GetImage("button", "background"), new int2(rect.Location)); - buttons.Add(Pair.New(rect, foo)); + Scroll(-1); + return true; } + + if (mi.Button == MouseButton.WheelUp) + { + Scroll(1); + return true; + } + + if (mi.Button != MouseButton.Left) + return false; + + if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) + return false; + + if (!Focused) + return false; + + if (Focused && mi.Event == MouseInputEvent.Up) + return LoseFocus(mi); + + leftPressed = leftButtonRect.Contains(mi.Location.X, mi.Location.Y); + rightPressed = rightButtonRect.Contains(mi.Location.X, mi.Location.Y); + + var queue = VisibleQueues.Where(a => a.Value.Contains(mi.Location)) + .Select(a => a.Key).FirstOrDefault(); + + if (queue != null) + { + var palette = Widget.RootWidget.GetWidget(PaletteWidget); + palette.CurrentQueue = queue; + } + + return (leftPressed || rightPressed || queue != null); } } } diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index fc887f1d54..efb3538c67 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -213,13 +213,13 @@ Container@INGAME_ROOT: Id:PRODUCTION_TABS PaletteWidget:PRODUCTION_PALETTE X:WINDOW_RIGHT - 200 - Y:260 - Width:192 - Height:15 + Y:259 + Width:190 + Height:20 ProductionPalette: Id:PRODUCTION_PALETTE X:WINDOW_RIGHT - 200 - Y:275 + Y:280 TabClick: button.aud Background@FMVPLAYER: Id:FMVPLAYER