Move Production to Mods.Common

This commit is contained in:
reaperrr
2015-01-05 21:15:43 +01:00
parent 0dc65e5cf3
commit 0e1773ac5d
17 changed files with 32 additions and 43 deletions

View File

@@ -0,0 +1,122 @@
#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.Drawing;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ProductionTooltipLogic
{
[ObjectCreator.UseCtor]
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ProductionPaletteWidget palette)
{
var mapRules = palette.World.Map.Rules;
var pm = palette.World.LocalPlayer.PlayerActor.Trait<PowerManager>();
var pr = palette.World.LocalPlayer.PlayerActor.Trait<PlayerResources>();
widget.IsVisible = () => palette.TooltipIcon != null;
var nameLabel = widget.Get<LabelWidget>("NAME");
var hotkeyLabel = widget.Get<LabelWidget>("HOTKEY");
var requiresLabel = widget.Get<LabelWidget>("REQUIRES");
var powerLabel = widget.Get<LabelWidget>("POWER");
var powerIcon = widget.Get<ImageWidget>("POWER_ICON");
var timeLabel = widget.Get<LabelWidget>("TIME");
var timeIcon = widget.Get<ImageWidget>("TIME_ICON");
var costLabel = widget.Get<LabelWidget>("COST");
var costIcon = widget.Get<ImageWidget>("COST_ICON");
var descLabel = widget.Get<LabelWidget>("DESC");
var iconMargin = timeIcon.Bounds.X;
var font = Game.Renderer.Fonts[nameLabel.Font];
var descFont = Game.Renderer.Fonts[descLabel.Font];
var requiresFont = Game.Renderer.Fonts[requiresLabel.Font];
ActorInfo lastActor = null;
tooltipContainer.BeforeRender = () =>
{
if (palette.TooltipIcon == null)
return;
var actor = palette.TooltipIcon.Actor;
if (actor == null || actor == lastActor)
return;
var tooltip = actor.Traits.Get<TooltipInfo>();
var buildable = actor.Traits.Get<BuildableInfo>();
var cost = actor.Traits.Get<ValuedInfo>().Cost;
nameLabel.GetText = () => tooltip.Name;
var hotkey = palette.TooltipIcon.Hotkey;
var nameWidth = font.Measure(tooltip.Name).X;
var hotkeyText = "({0})".F(hotkey.DisplayString());
var hotkeyWidth = hotkey.IsValid() ? font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X : 0;
hotkeyLabel.GetText = () => hotkeyText;
hotkeyLabel.Bounds.X = nameWidth + 2 * nameLabel.Bounds.X;
hotkeyLabel.Visible = hotkey.IsValid();
var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)).Where(s => !s.StartsWith("~"));
var requiresString = prereqs.Any() ? requiresLabel.Text.F(prereqs.JoinWith(", ")) : "";
requiresLabel.GetText = () => requiresString;
var power = actor.Traits.WithInterface<PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(i => i.Amount);
var powerString = power.ToString();
powerLabel.GetText = () => powerString;
powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0)
? Color.White : Color.Red;
powerLabel.IsVisible = () => power != 0;
powerIcon.IsVisible = () => power != 0;
var lowpower = pm.PowerState != PowerState.Normal;
var time = palette.CurrentQueue == null ? 0 : palette.CurrentQueue.GetBuildTime(actor.Name)
* (lowpower ? palette.CurrentQueue.Info.LowPowerSlowdown : 1);
var timeString = WidgetUtils.FormatTime(time);
timeLabel.GetText = () => timeString;
timeLabel.GetColor = () => lowpower ? Color.Red : Color.White;
var costString = cost.ToString();
costLabel.GetText = () => costString;
costLabel.GetColor = () => pr.DisplayCash + pr.DisplayResources >= cost
? Color.White : Color.Red;
var descString = tooltip.Description.Replace("\\n", "\n");
descLabel.GetText = () => descString;
var leftWidth = new[] { nameWidth + hotkeyWidth, requiresFont.Measure(requiresString).X, descFont.Measure(descString).X }.Aggregate(Math.Max);
var rightWidth = new[] { font.Measure(powerString).X, font.Measure(timeString).X, font.Measure(costString).X }.Aggregate(Math.Max);
timeIcon.Bounds.X = powerIcon.Bounds.X = costIcon.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X;
timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin;
widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin;
var leftHeight = font.Measure(tooltip.Name).Y + requiresFont.Measure(requiresString).Y + descFont.Measure(descString).Y;
var rightHeight = font.Measure(powerString).Y + font.Measure(timeString).Y + font.Measure(costString).Y;
widget.Bounds.Height = Math.Max(leftHeight, rightHeight) * 3 / 2 + 3 * nameLabel.Bounds.Y;
lastActor = actor;
};
}
static string ActorName(Ruleset rules, string a)
{
ActorInfo ai;
if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai) && ai.Traits.Contains<TooltipInfo>())
return ai.Traits.Get<TooltipInfo>().Name;
return a;
}
}
}

View File

@@ -0,0 +1,324 @@
#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.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Orders;
using OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets
{
public class ProductionIcon
{
public ActorInfo Actor;
public string Name;
public Hotkey Hotkey;
public Sprite Sprite;
public float2 Pos;
public List<ProductionItem> Queued;
}
public class ProductionPaletteWidget : Widget
{
public enum ReadyTextStyleOptions { Solid, AlternatingColor, Blinking }
public readonly ReadyTextStyleOptions ReadyTextStyle = ReadyTextStyleOptions.AlternatingColor;
public readonly Color ReadyTextAltColor = Color.Gold;
public readonly int Columns = 3;
public readonly int2 IconSize = new int2(64, 48);
public readonly int2 IconMargin = int2.Zero;
public readonly int2 IconSpriteOffset = int2.Zero;
public readonly string TabClick = null;
public readonly string DisabledTabClick = null;
public readonly string TooltipContainer;
public readonly string TooltipTemplate = "PRODUCTION_TOOLTIP";
[Translate] public readonly string ReadyText = "";
[Translate] public readonly string HoldText = "";
public int IconCount { get; private set; }
public event Action<int, int> OnIconCountChanged = (a, b) => { };
public ProductionIcon TooltipIcon { get; private set; }
public readonly World World;
readonly OrderManager orderManager;
Lazy<TooltipContainerWidget> tooltipContainer;
ProductionQueue currentQueue;
public ProductionQueue CurrentQueue
{
get { return currentQueue; }
set { currentQueue = value; RefreshIcons(); }
}
public override Rectangle EventBounds { get { return eventBounds; } }
Dictionary<Rectangle, ProductionIcon> icons = new Dictionary<Rectangle, ProductionIcon>();
Animation cantBuild, clock;
Rectangle eventBounds = Rectangle.Empty;
readonly WorldRenderer worldRenderer;
SpriteFont overlayFont;
float2 holdOffset, readyOffset, timeOffset, queuedOffset;
[ObjectCreator.UseCtor]
public ProductionPaletteWidget(OrderManager orderManager, World world, WorldRenderer worldRenderer)
{
this.orderManager = orderManager;
this.World = world;
this.worldRenderer = worldRenderer;
tooltipContainer = Exts.Lazy(() =>
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
cantBuild = new Animation(world, "clock");
cantBuild.PlayFetchIndex("idle", () => 0);
clock = new Animation(world, "clock");
}
public override void Tick()
{
if (CurrentQueue != null && !CurrentQueue.Actor.IsInWorld)
CurrentQueue = null;
if (CurrentQueue != null)
RefreshIcons();
}
public override void MouseEntered()
{
if (TooltipContainer != null)
tooltipContainer.Value.SetTooltip(TooltipTemplate,
new WidgetArgs() { { "palette", this } });
}
public override void MouseExited()
{
if (TooltipContainer != null)
tooltipContainer.Value.RemoveTooltip();
}
public override bool HandleMouseInput(MouseInput mi)
{
var icon = icons.Where(i => i.Key.Contains(mi.Location))
.Select(i => i.Value).FirstOrDefault();
if (mi.Event == MouseInputEvent.Move)
TooltipIcon = icon;
if (icon == null)
return false;
// Only support left and right clicks
if (mi.Button != MouseButton.Left && mi.Button != MouseButton.Right)
return false;
// Eat mouse-up events
if (mi.Event != MouseInputEvent.Down)
return true;
return HandleEvent(icon, mi.Button == MouseButton.Left, mi.Modifiers.HasModifier(Modifiers.Shift));
}
bool HandleEvent(ProductionIcon icon, bool isLeftClick, bool handleMultiple)
{
var actor = World.Map.Rules.Actors[icon.Name];
var first = icon.Queued.FirstOrDefault();
if (isLeftClick)
{
// Pick up a completed building
if (first != null && first.Done && actor.Traits.Contains<BuildingInfo>())
{
Sound.Play(TabClick);
World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue, icon.Name);
}
else if (first != null && first.Paused)
{
// Resume a paused item
Sound.Play(TabClick);
World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, false));
}
else if (CurrentQueue.BuildableItems().Any(a => a.Name == icon.Name))
{
// Queue a new item
Sound.Play(TabClick);
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Country.Race);
World.IssueOrder(Order.StartProduction(CurrentQueue.Actor, icon.Name,
handleMultiple ? 5 : 1));
}
else
Sound.Play(DisabledTabClick);
}
else
{
// Hold/Cancel an existing item
if (first != null)
{
Sound.Play(TabClick);
// instant cancel of things we havent started yet and things that are finished
if (first.Paused || first.Done || first.TotalCost == first.RemainingCost)
{
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Country.Race);
World.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, icon.Name,
handleMultiple ? 5 : 1));
}
else
{
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, World.LocalPlayer.Country.Race);
World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, true));
}
}
else
Sound.Play(DisabledTabClick);
}
return true;
}
public override bool HandleKeyPress(KeyInput e)
{
if (e.Event == KeyInputEvent.Up || CurrentQueue == null)
return false;
var hotkey = Hotkey.FromKeyInput(e);
var toBuild = icons.Values.FirstOrDefault(i => i.Hotkey == hotkey);
return toBuild != null ? HandleEvent(toBuild, true, false) : false;
}
public void RefreshIcons()
{
icons = new Dictionary<Rectangle, ProductionIcon>();
if (CurrentQueue == null)
{
if (IconCount != 0)
{
OnIconCountChanged(IconCount, 0);
IconCount = 0;
}
return;
}
var allBuildables = CurrentQueue.AllItems().OrderBy(a => a.Traits.Get<BuildableInfo>().BuildPaletteOrder);
var oldIconCount = IconCount;
IconCount = 0;
var ks = Game.Settings.Keys;
var rb = RenderBounds;
foreach (var item in allBuildables)
{
var x = IconCount % Columns;
var y = IconCount / Columns;
var rect = new Rectangle(rb.X + x * (IconSize.X + IconMargin.X), rb.Y + y * (IconSize.Y + IconMargin.Y), IconSize.X, IconSize.Y);
var icon = new Animation(World, RenderSimple.GetImage(item));
icon.Play(item.Traits.Get<TooltipInfo>().Icon);
var pi = new ProductionIcon()
{
Actor = item,
Name = item.Name,
Hotkey = ks.GetProductionHotkey(IconCount),
Sprite = icon.Image,
Pos = new float2(rect.Location),
Queued = CurrentQueue.AllQueued().Where(a => a.Item == item.Name).ToList(),
};
icons.Add(rect, pi);
IconCount++;
}
eventBounds = icons.Any() ? icons.Keys.Aggregate(Rectangle.Union) : Rectangle.Empty;
if (oldIconCount != IconCount)
OnIconCountChanged(oldIconCount, IconCount);
}
public override void Draw()
{
var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;
overlayFont = Game.Renderer.Fonts["TinyBold"];
timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
queuedOffset = new float2(4, 2);
holdOffset = iconOffset - overlayFont.Measure(HoldText) / 2;
readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2;
if (CurrentQueue == null)
return;
var buildableItems = CurrentQueue.BuildableItems();
// Icons
foreach (var icon in icons.Values)
{
WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffset, worldRenderer);
// Build progress
if (icon.Queued.Count > 0)
{
var first = icon.Queued[0];
clock.PlayFetchIndex("idle",
() => (first.TotalTime - first.RemainingTime)
* (clock.CurrentSequence.Length - 1) / first.TotalTime);
clock.Tick();
WidgetUtils.DrawSHPCentered(clock.Image, icon.Pos + iconOffset, worldRenderer);
}
else if (!buildableItems.Any(a => a.Name == icon.Name))
WidgetUtils.DrawSHPCentered(cantBuild.Image, icon.Pos + iconOffset, worldRenderer);
}
// Overlays
foreach (var icon in icons.Values)
{
var total = icon.Queued.Count;
if (total > 0)
{
var first = icon.Queued[0];
var waiting = first != CurrentQueue.CurrentItem() && !first.Done;
if (first.Done)
{
if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber / 9 % 2 == 0)
overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, Color.White, Color.Black, 1);
else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor)
overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, ReadyTextAltColor, Color.Black, 1);
}
else if (first.Paused)
overlayFont.DrawTextWithContrast(HoldText,
icon.Pos + holdOffset,
Color.White, Color.Black, 1);
else if (!waiting)
overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.RemainingTimeActual),
icon.Pos + timeOffset,
Color.White, Color.Black, 1);
if (total > 1 || waiting)
overlayFont.DrawTextWithContrast(total.ToString(),
icon.Pos + queuedOffset,
Color.White, Color.Black, 1);
}
}
}
public override string GetCursor(int2 pos)
{
var icon = icons.Where(i => i.Key.Contains(pos))
.Select(i => i.Value).FirstOrDefault();
return icon != null ? base.GetCursor(pos) : null;
}
}
}

View File

@@ -0,0 +1,295 @@
#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.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets
{
public class ProductionTab
{
public string Name;
public ProductionQueue Queue;
}
public class ProductionTabGroup
{
public List<ProductionTab> Tabs = new List<ProductionTab>();
public string Group;
public int NextQueueName = 1;
public bool Alert { get { return Tabs.Any(t => t.Queue.CurrentDone); } }
public void Update(IEnumerable<ProductionQueue> allQueues)
{
var queues = allQueues.Where(q => q.Info.Group == Group).ToList();
var tabs = new List<ProductionTab>();
// Remove stale queues
foreach (var t in Tabs)
{
if (!queues.Contains(t.Queue))
continue;
tabs.Add(t);
queues.Remove(t.Queue);
}
// Add new queues
foreach (var queue in queues)
tabs.Add(new ProductionTab()
{
Name = (NextQueueName++).ToString(),
Queue = queue
});
Tabs = tabs;
}
}
public class ProductionTabsWidget : Widget
{
readonly World world;
public readonly string PaletteWidget = null;
public readonly string TypesContainer = null;
public readonly string BackgroundContainer = null;
public readonly int TabWidth = 30;
public readonly int ArrowWidth = 20;
public Dictionary<string, ProductionTabGroup> Groups;
int contentWidth = 0;
float listOffset = 0;
bool leftPressed = false;
bool rightPressed = false;
Rectangle leftButtonRect;
Rectangle rightButtonRect;
Lazy<ProductionPaletteWidget> paletteWidget;
string queueGroup;
[ObjectCreator.UseCtor]
public ProductionTabsWidget(World world)
{
this.world = world;
Groups = world.Map.Rules.Actors.Values.SelectMany(a => a.Traits.WithInterface<ProductionQueueInfo>())
.Select(q => q.Group).Distinct().ToDictionary(g => g, g => new ProductionTabGroup() { Group = g });
// Only visible if the production palette has icons to display
IsVisible = () => queueGroup != null && Groups[queueGroup].Tabs.Count > 0;
paletteWidget = Exts.Lazy(() => Ui.Root.Get<ProductionPaletteWidget>(PaletteWidget));
}
public bool SelectNextTab(bool reverse)
{
if (queueGroup == null)
return true;
// Prioritize alerted queues
var queues = Groups[queueGroup].Tabs.Select(t => t.Queue)
.OrderByDescending(q => q.CurrentDone ? 1 : 0)
.ToList();
if (reverse) queues.Reverse();
CurrentQueue = queues.SkipWhile(q => q != CurrentQueue)
.Skip(1).FirstOrDefault() ?? queues.FirstOrDefault();
return true;
}
public string QueueGroup
{
get
{
return queueGroup;
}
set
{
listOffset = 0;
queueGroup = value;
SelectNextTab(false);
}
}
public ProductionQueue CurrentQueue
{
get
{
return paletteWidget.Value.CurrentQueue;
}
set
{
paletteWidget.Value.CurrentQueue = value;
queueGroup = value != null ? value.Info.Group : null;
// TODO: Scroll tabs so selected queue is visible
}
}
public override void Draw()
{
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 leftHover = Ui.MouseOverWidget == this && leftButtonRect.Contains(Viewport.LastMousePos);
var rightDisabled = listOffset <= Bounds.Width - rightButtonRect.Width - leftButtonRect.Width - contentWidth;
var rightHover = Ui.MouseOverWidget == this && rightButtonRect.Contains(Viewport.LastMousePos);
WidgetUtils.DrawPanel("panel-black", rb);
ButtonWidget.DrawBackground("button", leftButtonRect, leftDisabled, leftPressed, leftHover, false);
ButtonWidget.DrawBackground("button", rightButtonRect, rightDisabled, rightPressed, rightHover, false);
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", leftPressed || leftDisabled ? "left_pressed" : "left_arrow"),
new float2(leftButtonRect.Left + 2, leftButtonRect.Top + 2));
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", rightPressed || rightDisabled ? "right_pressed" : "right_arrow"),
new float2(rightButtonRect.Left + 2, rightButtonRect.Top + 2));
// Draw tab buttons
Game.Renderer.EnableScissor(new Rectangle(leftButtonRect.Right, rb.Y + 1, rightButtonRect.Left - leftButtonRect.Right - 1, rb.Height));
var origin = new int2(leftButtonRect.Right - 1 + (int)listOffset, leftButtonRect.Y);
var font = Game.Renderer.Fonts["TinyBold"];
contentWidth = 0;
foreach (var tab in Groups[queueGroup].Tabs)
{
var rect = new Rectangle(origin.X + contentWidth, origin.Y, TabWidth, rb.Height);
var hover = !leftHover && !rightHover && Ui.MouseOverWidget == this && rect.Contains(Viewport.LastMousePos);
var baseName = tab.Queue == CurrentQueue ? "button-highlighted" : "button";
ButtonWidget.DrawBackground(baseName, rect, false, false, hover, false);
contentWidth += TabWidth - 1;
var textSize = font.Measure(tab.Name);
var position = new int2(rect.X + (rect.Width - textSize.X) / 2, rect.Y + (rect.Height - textSize.Y) / 2);
font.DrawTextWithContrast(tab.Name, position, tab.Queue.CurrentDone ? Color.Gold : Color.White, Color.Black, 1);
}
Game.Renderer.DisableScissor();
}
void Scroll(int amount)
{
listOffset += amount * Game.Settings.Game.UIScrollSpeed;
listOffset = Math.Min(0, Math.Max(Bounds.Width - rightButtonRect.Width - leftButtonRect.Width - contentWidth, listOffset));
}
// Is added to world.ActorAdded by the SidebarLogic handler
public void ActorChanged(Actor a)
{
if (a.HasTrait<ProductionQueue>())
{
var allQueues = a.World.ActorsWithTrait<ProductionQueue>()
.Where(p => p.Actor.Owner == p.Actor.World.LocalPlayer && p.Actor.IsInWorld && p.Trait.Enabled)
.Select(p => p.Trait).ToArray();
foreach (var g in Groups.Values)
g.Update(allQueues);
if (queueGroup == null)
return;
// Queue destroyed, was last of type: switch to a new group
if (Groups[queueGroup].Tabs.Count == 0)
QueueGroup = Groups.Where(g => g.Value.Tabs.Count > 0)
.Select(g => g.Key).FirstOrDefault();
// Queue destroyed, others of same type: switch to another tab
else if (!Groups[queueGroup].Tabs.Select(t => t.Queue).Contains(CurrentQueue))
SelectNextTab(false);
}
}
public override void Tick()
{
if (leftPressed) Scroll(1);
if (rightPressed) Scroll(-1);
}
public override bool YieldMouseFocus(MouseInput mi)
{
leftPressed = rightPressed = false;
return base.YieldMouseFocus(mi);
}
public override bool HandleMouseInput(MouseInput mi)
{
if (mi.Event == MouseInputEvent.Scroll)
{
Scroll(mi.ScrollDelta);
return true;
}
if (mi.Button != MouseButton.Left)
return true;
if (mi.Event == MouseInputEvent.Down && !TakeMouseFocus(mi))
return true;
if (!HasMouseFocus)
return true;
if (HasMouseFocus && mi.Event == MouseInputEvent.Up)
return YieldMouseFocus(mi);
leftPressed = leftButtonRect.Contains(mi.Location);
rightPressed = rightButtonRect.Contains(mi.Location);
var leftDisabled = listOffset >= 0;
var rightDisabled = listOffset <= Bounds.Width - rightButtonRect.Width - leftButtonRect.Width - contentWidth;
if (leftPressed || rightPressed)
{
if ((leftPressed && !leftDisabled) || (rightPressed && !rightDisabled))
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
else
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickDisabledSound", null);
}
// Check production tabs
var offsetloc = mi.Location - new int2(leftButtonRect.Right - 1 + (int)listOffset, leftButtonRect.Y);
if (offsetloc.X > 0 && offsetloc.X < contentWidth)
{
CurrentQueue = Groups[queueGroup].Tabs[offsetloc.X / (TabWidth - 1)].Queue;
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
}
return true;
}
public override bool HandleKeyPress(KeyInput e)
{
if (e.Event != KeyInputEvent.Down)
return false;
var hotkey = Hotkey.FromKeyInput(e);
if (hotkey == Game.Settings.Keys.NextProductionTabKey)
{
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
return SelectNextTab(false);
}
else if (hotkey == Game.Settings.Keys.PreviousProductionTabKey)
{
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
return SelectNextTab(true);
}
return false;
}
}
}

View File

@@ -0,0 +1,30 @@
#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 OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets
{
public class ProductionTypeButtonWidget : ButtonWidget
{
public readonly string ProductionGroup;
public readonly string HotkeyName;
[ObjectCreator.UseCtor]
public ProductionTypeButtonWidget(Ruleset modRules)
: base(modRules) { }
protected ProductionTypeButtonWidget(ProductionTypeButtonWidget other)
: base(other)
{
ProductionGroup = other.ProductionGroup;
}
}
}