#region Copyright & License Information /* * Copyright 2007-2015 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.Mods.Common.Traits; using OpenRA.Mods.Common.Widgets; using OpenRA.Network; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic { public class ClassicProductionLogic : ChromeLogic { readonly ProductionPaletteWidget palette; readonly World world; void SetupProductionGroupButton(OrderManager orderManager, ProductionTypeButtonWidget button) { if (button == null) return; // Classic production queues are initialized at game start, and then never change. var queues = world.LocalPlayer.PlayerActor.TraitsImplementing() .Where(q => q.Info.Type == button.ProductionGroup) .ToArray(); Action selectTab = reverse => { palette.CurrentQueue = queues.FirstOrDefault(q => q.Enabled); // When a tab is selected, scroll to the top because the current row position may be invalid for the new tab palette.ScrollToTop(); // Attempt to pick up a completed building (if there is one) so it can be placed palette.PickUpCompletedBuilding(); }; Func getKey = _ => Hotkey.Invalid; if (!string.IsNullOrEmpty(button.HotkeyName)) { var ks = Game.Settings.Keys; var field = ks.GetType().GetField(button.HotkeyName); if (field != null) getKey = _ => (Hotkey)field.GetValue(ks); } button.IsDisabled = () => !queues.Any(q => q.BuildableItems().Any()); button.OnMouseUp = mi => selectTab(mi.Modifiers.HasModifier(Modifiers.Shift)); button.OnKeyPress = e => selectTab(e.Modifiers.HasModifier(Modifiers.Shift)); button.OnClick = () => selectTab(false); button.IsHighlighted = () => queues.Contains(palette.CurrentQueue); button.GetKey = getKey; var chromeName = button.ProductionGroup.ToLowerInvariant(); var icon = button.Get("ICON"); icon.GetImageName = () => button.IsDisabled() ? chromeName + "-disabled" : queues.Any(q => q.CurrentDone) ? chromeName + "-alert" : chromeName; } [ObjectCreator.UseCtor] public ClassicProductionLogic(Widget widget, OrderManager orderManager, World world) { this.world = world; palette = widget.Get("PRODUCTION_PALETTE"); var background = widget.GetOrNull("PALETTE_BACKGROUND"); var foreground = widget.GetOrNull("PALETTE_FOREGROUND"); if (background != null || foreground != null) { Widget backgroundTemplate = null; Widget backgroundBottom = null; Widget foregroundTemplate = null; if (background != null) { backgroundTemplate = background.Get("ROW_TEMPLATE"); backgroundBottom = background.GetOrNull("BOTTOM_CAP"); } if (foreground != null) foregroundTemplate = foreground.Get("ROW_TEMPLATE"); Action updateBackground = (_, icons) => { var rows = Math.Max(palette.MinimumRows, (icons + palette.Columns - 1) / palette.Columns); rows = Math.Min(rows, palette.MaximumRows); if (background != null) { background.RemoveChildren(); var rowHeight = backgroundTemplate.Bounds.Height; for (var i = 0; i < rows; i++) { var row = backgroundTemplate.Clone(); row.Bounds.Y = i * rowHeight; background.AddChild(row); } if (backgroundBottom == null) return; backgroundBottom.Bounds.Y = rows * rowHeight; background.AddChild(backgroundBottom); } if (foreground != null) { foreground.RemoveChildren(); var rowHeight = foregroundTemplate.Bounds.Height; for (var i = 0; i < rows; i++) { var row = foregroundTemplate.Clone(); row.Bounds.Y = i * rowHeight; foreground.AddChild(row); } } }; palette.OnIconCountChanged += updateBackground; // Set the initial palette state updateBackground(0, 0); } var typesContainer = widget.Get("PRODUCTION_TYPES"); foreach (var i in typesContainer.Children) SetupProductionGroupButton(orderManager, i as ProductionTypeButtonWidget); var ticker = widget.Get("PRODUCTION_TICKER"); ticker.OnTick = () => { if (palette.CurrentQueue == null || palette.DisplayedIconCount == 0) { // Select the first active tab foreach (var b in typesContainer.Children) { var button = b as ProductionTypeButtonWidget; if (button == null || button.IsDisabled()) continue; button.OnClick(); break; } } }; // Hook up scroll up and down buttons on the palette var scrollDown = widget.GetOrNull("SCROLL_DOWN_BUTTON"); if (scrollDown != null) { scrollDown.OnClick = palette.ScrollDown; scrollDown.IsVisible = () => palette.TotalIconCount > (palette.MaxIconRowOffset * palette.Columns); scrollDown.IsDisabled = () => !palette.CanScrollDown; } var scrollUp = widget.GetOrNull("SCROLL_UP_BUTTON"); if (scrollUp != null) { scrollUp.OnClick = palette.ScrollUp; scrollUp.IsVisible = () => palette.TotalIconCount > (palette.MaxIconRowOffset * palette.Columns); scrollUp.IsDisabled = () => !palette.CanScrollUp; } SetMaximumVisibleRows(palette); } static void SetMaximumVisibleRows(ProductionPaletteWidget productionPalette) { var screenHeight = Game.Renderer.Resolution.Height; // Get height of currently displayed icons var containerWidget = Ui.Root.GetOrNull("SIDEBAR_PRODUCTION"); if (containerWidget == null) return; var sidebarProductionHeight = containerWidget.Bounds.Y; // Check if icon heights exceed y resolution var maxItemsHeight = screenHeight - sidebarProductionHeight; var maxIconRowOffest = (maxItemsHeight / productionPalette.IconSize.Y) - 1; productionPalette.MaxIconRowOffset = Math.Min(maxIconRowOffest, productionPalette.MaximumRows); } } }