diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs
index 789f78b0a7..d55847bad7 100644
--- a/OpenRA.Game/Game.cs
+++ b/OpenRA.Game/Game.cs
@@ -38,6 +38,9 @@ namespace OpenRA
public static World world;
internal static Viewport viewport;
public static Controller controller;
+ public static Widget RootWidget {
+ get { return Chrome.rootWidget; }
+ }
internal static Chrome chrome;
internal static UserSettings Settings;
diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj
index f35057e164..4c0979be90 100755
--- a/OpenRA.Game/OpenRA.Game.csproj
+++ b/OpenRA.Game/OpenRA.Game.csproj
@@ -229,6 +229,7 @@
+
diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs
index fbd3c8090b..8326c57eea 100644
--- a/OpenRA.Game/Traits/TraitsInterfaces.cs
+++ b/OpenRA.Game/Traits/TraitsInterfaces.cs
@@ -150,16 +150,6 @@ namespace OpenRA.Traits
void Cancel(Actor self);
}
- public interface IChromeButton
- {
- string Image { get; }
- bool Enabled { get; }
- bool Pressed { get; }
- void OnClick();
- string Description { get; }
- string LongDesc { get; }
- }
-
public interface IRenderOverlay { void Render(); }
public interface INotifyIdle { void Idle(Actor self); }
diff --git a/OpenRA.Game/Widgets/ButtonWidget.cs b/OpenRA.Game/Widgets/ButtonWidget.cs
index 78cabed4ae..8949d14c23 100644
--- a/OpenRA.Game/Widgets/ButtonWidget.cs
+++ b/OpenRA.Game/Widgets/ButtonWidget.cs
@@ -13,7 +13,7 @@ using System.Drawing;
namespace OpenRA.Widgets
{
- class ButtonWidget : Widget
+ public class ButtonWidget : Widget
{
public string Text = "";
public bool Bold = false;
diff --git a/OpenRA.Game/Widgets/MoneyBinWidget.cs b/OpenRA.Game/Widgets/MoneyBinWidget.cs
index ae88b03ca6..34bd83a306 100644
--- a/OpenRA.Game/Widgets/MoneyBinWidget.cs
+++ b/OpenRA.Game/Widgets/MoneyBinWidget.cs
@@ -70,59 +70,6 @@ namespace OpenRA.Widgets
x -= 14;
}
}
-
- var origin = new int2(Game.viewport.Width - 200, 2);
-
- foreach (var cb in world.WorldActor.traits.WithInterface())
- {
- var state = cb.Enabled ? cb.Pressed ? "pressed" : "normal" : "disabled";
- var image = ChromeProvider.GetImage(Game.chrome.renderer, cb.Image + "-button", state);
-
- origin.X -= (int)image.size.X + chromeButtonGap;
-
- var button = cb;
- var rect = new Rectangle(origin.X, origin.Y, (int)image.size.X, (int)image.size.Y);
- AddButton(rect, _ => { if (button.Enabled) button.OnClick(); });
-
- if (rect.Contains(Game.chrome.lastMousePos.ToPoint()))
- {
- rect = rect.InflateBy(3, 3, 3, 3);
- var pos = new int2(rect.Left, rect.Top);
- var m = pos + new int2(rect.Width, rect.Height);
- var br = pos + new int2(rect.Width, rect.Height + 20);
-
- var u = Game.chrome.renderer.RegularFont.Measure(cb.LongDesc.Replace("\\n", "\n"));
-
- br.X -= u.X;
- br.Y += u.Y;
- br += new int2(-15, 25);
-
- var border = WidgetUtils.GetBorderSizes("dialog4");
-
- WidgetUtils.DrawPanelPartial("dialog4", rect
- .InflateBy(0, 0, 0, border[1]),
- PanelSides.Top | PanelSides.Left | PanelSides.Right);
-
- WidgetUtils.DrawPanelPartial("dialog4", new Rectangle(br.X, m.Y, pos.X - br.X, br.Y - m.Y)
- .InflateBy(0, 0, border[3], 0),
- PanelSides.Top | PanelSides.Left | PanelSides.Bottom);
-
- WidgetUtils.DrawPanelPartial("dialog4", new Rectangle(pos.X, m.Y, m.X - pos.X, br.Y - m.Y)
- .InflateBy(border[2], border[0], 0, 0),
- PanelSides.Right | PanelSides.Bottom);
-
- pos.X = br.X + 8;
- pos.Y = m.Y + 8;
- Game.chrome.renderer.BoldFont.DrawText(cb.Description, pos, Color.White);
-
- pos += new int2(0, 20);
- Game.chrome.renderer.RegularFont.DrawText(cb.LongDesc.Replace("\\n", "\n"), pos, Color.White);
- }
-
- Game.chrome.renderer.RgbaSpriteRenderer.DrawSprite(image, origin, "chrome");
- }
-
- Game.chrome.renderer.RgbaSpriteRenderer.Flush();
}
public override bool HandleInput(MouseInput mi)
@@ -137,7 +84,6 @@ namespace OpenRA.Widgets
action(mi);
return true;
}
-
return false;
}
}
diff --git a/OpenRA.Game/Widgets/OrderButtonWidget.cs b/OpenRA.Game/Widgets/OrderButtonWidget.cs
new file mode 100644
index 0000000000..702e24e6b5
--- /dev/null
+++ b/OpenRA.Game/Widgets/OrderButtonWidget.cs
@@ -0,0 +1,66 @@
+using System;
+using OpenRA.Graphics;
+using System.Drawing;
+namespace OpenRA.Widgets
+{
+ public class OrderButtonWidget : ButtonWidget
+ {
+ public Func Enabled = () => true;
+ public Func Pressed = () => false;
+
+ public string Image, Description, LongDesc = "";
+
+ public Func GetImage, GetDescription, GetLongDesc;
+
+ public OrderButtonWidget()
+ {
+ GetImage = () => Enabled() ? Pressed() ? "pressed" : "normal" : "disabled";
+ GetDescription = () => Description;
+ GetLongDesc = () => LongDesc;
+ }
+
+ public override void DrawInner (World world)
+ {
+ var image = ChromeProvider.GetImage(Game.chrome.renderer, Image + "-button", GetImage());
+ var rect = new Rectangle(RenderBounds.X, RenderBounds.Y, (int)image.size.X, (int)image.size.Y);
+
+ if (rect.Contains(Game.chrome.lastMousePos.ToPoint()))
+ {
+ rect = rect.InflateBy(3, 3, 3, 3);
+ var pos = new int2(rect.Left, rect.Top);
+ var m = pos + new int2(rect.Width, rect.Height);
+ var br = pos + new int2(rect.Width, rect.Height + 20);
+
+ var u = Game.chrome.renderer.RegularFont.Measure(GetLongDesc().Replace("\\n", "\n"));
+
+ br.X -= u.X;
+ br.Y += u.Y;
+ br += new int2(-15, 25);
+
+ var border = WidgetUtils.GetBorderSizes("dialog4");
+
+ WidgetUtils.DrawPanelPartial("dialog4", rect
+ .InflateBy(0, 0, 0, border[1]),
+ PanelSides.Top | PanelSides.Left | PanelSides.Right);
+
+ WidgetUtils.DrawPanelPartial("dialog4", new Rectangle(br.X, m.Y, pos.X - br.X, br.Y - m.Y)
+ .InflateBy(0, 0, border[3], 0),
+ PanelSides.Top | PanelSides.Left | PanelSides.Bottom);
+
+ WidgetUtils.DrawPanelPartial("dialog4", new Rectangle(pos.X, m.Y, m.X - pos.X, br.Y - m.Y)
+ .InflateBy(border[2], border[0], 0, 0),
+ PanelSides.Right | PanelSides.Bottom);
+
+ pos.X = br.X + 8;
+ pos.Y = m.Y + 8;
+ Game.chrome.renderer.BoldFont.DrawText(GetDescription(), pos, Color.White);
+
+ pos += new int2(0, 20);
+ Game.chrome.renderer.RegularFont.DrawText(GetLongDesc().Replace("\\n", "\n"), pos, Color.White);
+ }
+
+ Game.chrome.renderer.RgbaSpriteRenderer.DrawSprite(image, new int2(RenderBounds.X, RenderBounds.Y), "chrome");
+ }
+ }
+}
+
diff --git a/OpenRA.Mods.RA/Chrome/PowerDownButton.cs b/OpenRA.Mods.RA/Chrome/PowerDownButton.cs
deleted file mode 100755
index 49a5e12aeb..0000000000
--- a/OpenRA.Mods.RA/Chrome/PowerDownButton.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-#region Copyright & License Information
-/*
- * Copyright 2007-2010 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 LICENSE.
- */
-#endregion
-
-using OpenRA.Mods.RA.Orders;
-using OpenRA.Traits;
-
-// TODO: Migrate these to be real widgets, and kill all the weird infrastructure that's holding these up.
-
-namespace OpenRA.Mods.RA
-{
- class PowerDownButtonInfo : TraitInfo { }
-
- class PowerDownButton : IChromeButton
- {
- public string Image { get { return "power"; } }
- public bool Enabled { get { return true; } }
- public bool Pressed { get { return Game.controller.orderGenerator is PowerDownOrderGenerator; } }
- public void OnClick() { Game.controller.ToggleInputMode(); }
-
- public string Description { get { return "Powerdown"; } }
- public string LongDesc { get { return "Disable unneeded structures so their \npower can be used elsewhere"; } }
- }
-
- class SellButtonInfo : TraitInfo { }
-
- class SellButton : IChromeButton
- {
- public string Image { get { return "sell"; } }
- public bool Enabled { get { return true; } }
- public bool Pressed { get { return Game.controller.orderGenerator is SellOrderGenerator; } }
- public void OnClick() { Game.controller.ToggleInputMode(); }
-
- public string Description { get { return "Sell"; } }
- public string LongDesc { get { return "Sell buildings, reclaiming a \nproportion of their build cost"; } }
- }
-
- class RepairButtonInfo : ITraitInfo
- {
- public readonly bool RequiresConstructionYard = true;
- public object Create(ActorInitializer init) { return new RepairButton(); }
- }
-
- class RepairButton : IChromeButton
- {
- public RepairButton() { }
-
- public string Image { get { return "repair"; } }
- public bool Enabled
- {
- get
- {
- // WTF: why are these buttons even traits?
- return RepairOrderGenerator.PlayerIsAllowedToRepair( Game.world );
- }
- }
-
- public bool Pressed { get { return Game.controller.orderGenerator is RepairOrderGenerator; } }
- public void OnClick() { Game.controller.ToggleInputMode(); }
-
- public string Description { get { return "Repair"; } }
- public string LongDesc
- {
- get
- {
- var s = "Repair damaged buildings";
- return Enabled ? s : s + "\n\nRequires: Construction Yard";
- }
- }
- }
-
-
-}
diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
index b61eedb8e8..6ccbe28e0c 100644
--- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
+++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -107,7 +107,6 @@
-
@@ -208,6 +207,7 @@
+
@@ -236,6 +236,6 @@ ralint ra
-
+
\ No newline at end of file
diff --git a/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs b/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs
index 3d2e5864bf..9f8f55f766 100755
--- a/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs
+++ b/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs
@@ -48,9 +48,6 @@ namespace OpenRA.Mods.RA.Orders
public static bool PlayerIsAllowedToRepair( World world )
{
- if( !world.WorldActor.Info.Traits.Get().RequiresConstructionYard )
- return true;
-
return Game.world.Queries.OwnedBy[ Game.world.LocalPlayer ]
.WithTrait().Where( x => x.Actor.Info.Traits.Get().Produces.Contains( "Building" ) )
.Any();
diff --git a/OpenRA.Mods.RA/Widgets/Delegates/OrderButtonsChromeDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/OrderButtonsChromeDelegate.cs
new file mode 100644
index 0000000000..f50f403e03
--- /dev/null
+++ b/OpenRA.Mods.RA/Widgets/Delegates/OrderButtonsChromeDelegate.cs
@@ -0,0 +1,50 @@
+
+#region Copyright & License Information
+/*
+ * Copyright 2007-2010 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 LICENSE.
+ */
+#endregion
+
+using OpenRA.Widgets;
+using OpenRA.Mods.RA.Orders;
+
+namespace OpenRA.Mods.RA.Widgets.Delegates
+{
+ public class OrderButtonsChromeDelegate : IWidgetDelegate
+ {
+ public OrderButtonsChromeDelegate()
+ {
+ var r = Game.RootWidget;
+ var gameRoot = r.GetWidget("INGAME_ROOT");
+
+ var moneybin = gameRoot.GetWidget("INGAME_MONEY_BIN");
+
+ var sell = moneybin.GetWidget("SELL");
+ if (sell != null)
+ {
+ sell.Pressed = () => Game.controller.orderGenerator is SellOrderGenerator;
+ sell.OnMouseDown = mi => { Game.controller.ToggleInputMode(); return true; };
+ }
+
+ var powerdown = moneybin.GetWidget("POWER_DOWN");
+ if (powerdown != null)
+ {
+ powerdown.Pressed = () => Game.controller.orderGenerator is PowerDownOrderGenerator;
+ powerdown.OnMouseDown = mi => { Game.controller.ToggleInputMode(); return true; };
+ }
+
+ var repair = moneybin.GetWidget("REPAIR");
+ if (repair != null)
+ {
+ repair.Enabled = () => { return RepairOrderGenerator.PlayerIsAllowedToRepair( Game.world ); };
+ repair.Pressed = () => Game.controller.orderGenerator is RepairOrderGenerator;
+ repair.OnMouseDown = mi => { Game.controller.ToggleInputMode(); return true; };
+ repair.GetLongDesc = () => { return repair.Enabled() ? repair.LongDesc : repair.LongDesc + "\n\nRequires: Construction Yard"; };
+ }
+ }
+ }
+}
diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml
index 20707576c5..68e725f079 100644
--- a/mods/cnc/chrome/ingame.yaml
+++ b/mods/cnc/chrome/ingame.yaml
@@ -77,6 +77,27 @@ Container@ROOT:
Width:320
Height: 32
SplitOreAndCash: yes
+ Children:
+ OrderButton@SELL:
+ Id:SELL
+ Delegate:OrderButtonsChromeDelegate
+ X:39
+ Y:0
+ Width:30
+ Height:30
+ Image:sell
+ Description:Sell
+ LongDesc:Sell buildings, reclaiming a \nproportion of their build cost
+ OrderButton@REPAIR:
+ Id:REPAIR
+ Delegate:OrderButtonsChromeDelegate
+ X:75
+ Y:0
+ Width:30
+ Height:30
+ Image:repair
+ Description:Repair
+ LongDesc:Repair damaged buildings
Background@INGAME_OPTIONS_BG:
Id:INGAME_OPTIONS_BG
X:(WINDOW_RIGHT - WIDTH)/2
diff --git a/mods/cnc/system.yaml b/mods/cnc/system.yaml
index f3d6c247ed..cf0f6e5b52 100644
--- a/mods/cnc/system.yaml
+++ b/mods/cnc/system.yaml
@@ -94,8 +94,6 @@ World:
Country@nod:
Name: Nod
Race: nod
- SellButton:
- RepairButton:
ChoosePaletteOnSelect:
BibLayer:
ResourceLayer:
diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml
index d751e60af5..55595b4351 100644
--- a/mods/ra/chrome/ingame.yaml
+++ b/mods/ra/chrome/ingame.yaml
@@ -74,6 +74,37 @@ Container@ROOT:
Width:320
Height: 32
SplitOreAndCash:No
+ Children:
+ OrderButton@SELL:
+ Id:SELL
+ Delegate:OrderButtonsChromeDelegate
+ X:3
+ Y:0
+ Width:30
+ Height:30
+ Image:sell
+ Description:Sell
+ LongDesc:Sell buildings, reclaiming a \nproportion of their build cost
+ OrderButton@POWER_DOWN:
+ Id:POWER_DOWN
+ Delegate:OrderButtonsChromeDelegate
+ X:39
+ Y:0
+ Width:30
+ Height:30
+ Image:power
+ Description:Powerdown
+ LongDesc:Disable unneeded structures so their \npower can be used elsewhere
+ OrderButton@REPAIR:
+ Id:REPAIR
+ Delegate:OrderButtonsChromeDelegate
+ X:75
+ Y:0
+ Width:30
+ Height:30
+ Image:repair
+ Description:Repair
+ LongDesc:Repair damaged buildings
Background@INGAME_OPTIONS_BG:
Id:INGAME_OPTIONS_BG
X:(WINDOW_RIGHT - WIDTH)/2
diff --git a/mods/ra/system.yaml b/mods/ra/system.yaml
index 2cbf1a9523..e0db906d9a 100644
--- a/mods/ra/system.yaml
+++ b/mods/ra/system.yaml
@@ -148,9 +148,6 @@ World:
Country@1:
Name: Soviet
Race: soviet
- SellButton:
- RepairButton:
- PowerDownButton:
BibLayer:
ResourceLayer:
ResourceType@ore: