diff --git a/OpenRA.Game/Chrome.cs b/OpenRA.Game/Chrome.cs index faa6f121fd..4480d6a528 100644 --- a/OpenRA.Game/Chrome.cs +++ b/OpenRA.Game/Chrome.cs @@ -28,6 +28,7 @@ using OpenRA.Graphics; using OpenRA.Orders; using OpenRA.Support; using OpenRA.Traits; +using OpenRA.Widgets; namespace OpenRA { @@ -135,7 +136,7 @@ namespace OpenRA var widgetYaml = MiniYaml.FromFile("mods/cnc/menus.yaml"); // Hack around a bug in MiniYaml widgetYaml.Values.FirstOrDefault().Value = widgetYaml.Keys.FirstOrDefault(); - rootWidget = ChromeWindow.LoadWidget(widgetYaml.Values.FirstOrDefault()); + rootWidget = WidgetLoader.LoadWidget(widgetYaml.Values.FirstOrDefault()); } List visibleTabs = new List(); @@ -431,11 +432,11 @@ namespace OpenRA var w = 250; var h = 200; - var r = new Rectangle( (Game.viewport.Width - w) / 2, (Game.viewport.Height - h) / 2, w, h ); + var r = new Rectangle( 0, 0, w, h ); DrawDialogBackground(r, "dialog"); DrawCentered("OpenRA Main Menu", new int2(r.Left + w / 2, r.Top + 20), Color.White); - /* + AddUiButton(new int2(r.Left + w/2, r.Top + 70), "Join Game", _ => { @@ -447,7 +448,7 @@ namespace OpenRA { Game.CreateServer(); }); - */ + AddUiButton(new int2(r.Left + w/2, r.Top + 140), "Quit", _ => { diff --git a/OpenRA.Game/Chrome/ChromeWindow.cs b/OpenRA.Game/Chrome/BackgroundWidget.cs similarity index 58% rename from OpenRA.Game/Chrome/ChromeWindow.cs rename to OpenRA.Game/Chrome/BackgroundWidget.cs index f538fbd1da..26d368d82b 100644 --- a/OpenRA.Game/Chrome/ChromeWindow.cs +++ b/OpenRA.Game/Chrome/BackgroundWidget.cs @@ -1,20 +1,12 @@ -using System.Collections.Generic; -using OpenRA.FileFormats; using OpenRA.Graphics; using System.Drawing; +using System.Collections.Generic; -namespace OpenRA +namespace OpenRA.Widgets { - class Widget + class BackgroundWidget : Widget { - public readonly string Id = null; - public readonly int X = 0; - public readonly int Y = 0; - public readonly int Width = 0; - public readonly int Height = 0; - public readonly List Children = new List(); - - public void Draw(SpriteRenderer rgbaRenderer, Renderer renderer) + public override void Draw(SpriteRenderer rgbaRenderer, Renderer renderer) { string collection = "dialog"; @@ -49,42 +41,7 @@ namespace OpenRA renderer.Device.DisableScissor(); - foreach (var child in Children) - child.Draw(rgbaRenderer, renderer); - } - } - - class ChromeWindow - { - public static Widget LoadWidget( MiniYaml node ) - { - Widget widget = NewWidget( node.Value ); - foreach( var child in node.Nodes ) - { - if( child.Key == "Children" ) - { - foreach( var c in child.Value.Nodes ) - { - // Hack around a bug in MiniYaml - c.Value.Value = c.Key; - widget.Children.Add( LoadWidget( c.Value ) ); - } - } - else - FieldLoader.LoadField( widget, child.Key, child.Value ); - } - - return widget; - } - - static Widget NewWidget( string widgetType ) - { - if( widgetType.Contains( "@" ) ) - widgetType = widgetType.Substring( 0, widgetType.IndexOf( "@" ) ); - // TODO: make a particular widget by reflection, or by `switch( widgetType )` - - Log.Write("Creating Widget of type {0}",widgetType); - return new Widget(); + base.Draw(rgbaRenderer,renderer); } } } \ No newline at end of file diff --git a/OpenRA.Game/Chrome/ButtonWidget.cs b/OpenRA.Game/Chrome/ButtonWidget.cs new file mode 100644 index 0000000000..d30251730f --- /dev/null +++ b/OpenRA.Game/Chrome/ButtonWidget.cs @@ -0,0 +1,51 @@ +using OpenRA.Graphics; +using System.Drawing; +using System.Collections.Generic; + +namespace OpenRA.Widgets +{ + class ButtonWidget : Widget + { + public readonly string Text = null; + + public override void Draw(SpriteRenderer rgbaRenderer, Renderer renderer) + { + string collection = "dialog2"; + + Rectangle r = new Rectangle(X,Y,Width,Height); + renderer.Device.EnableScissor(r.Left, r.Top, r.Width, r.Height); + + string[] images = { "border-t", "border-b", "border-l", "border-r", "corner-tl", "corner-tr", "corner-bl", "corner-br", "background" }; + var ss = Graphics.Util.MakeArray(9, n => ChromeProvider.GetImage(renderer, collection,images[n])); + + for( var x = r.Left + (int)ss[2].size.X; x < r.Right - (int)ss[3].size.X; x += (int)ss[8].size.X ) + for( var y = r.Top + (int)ss[0].size.Y; y < r.Bottom - (int)ss[1].size.Y; y += (int)ss[8].size.Y ) + rgbaRenderer.DrawSprite(ss[8], new float2(x, y), "chrome"); + + //draw borders + for (var y = r.Top + (int)ss[0].size.Y; y < r.Bottom - (int)ss[1].size.Y; y += (int)ss[2].size.Y) + { + rgbaRenderer.DrawSprite(ss[2], new float2(r.Left, y), "chrome"); + rgbaRenderer.DrawSprite(ss[3], new float2(r.Right - ss[3].size.X, y), "chrome"); + } + + for (var x = r.Left + (int)ss[2].size.X; x < r.Right - (int)ss[3].size.X; x += (int)ss[0].size.X) + { + rgbaRenderer.DrawSprite(ss[0], new float2(x, r.Top), "chrome"); + rgbaRenderer.DrawSprite(ss[1], new float2(x, r.Bottom - ss[1].size.Y), "chrome"); + } + + rgbaRenderer.DrawSprite(ss[4], new float2(r.Left, r.Top), "chrome"); + rgbaRenderer.DrawSprite(ss[5], new float2(r.Right - ss[5].size.X, r.Top), "chrome"); + rgbaRenderer.DrawSprite(ss[6], new float2(r.Left, r.Bottom - ss[6].size.Y), "chrome"); + rgbaRenderer.DrawSprite(ss[7], new float2(r.Right - ss[7].size.X, r.Bottom - ss[7].size.Y), "chrome"); + rgbaRenderer.Flush(); + + renderer.BoldFont.DrawText(rgbaRenderer, Text, new int2(X+Width/2, Y+Height/2) - new int2(renderer.BoldFont.Measure(Text).X / 2, renderer.BoldFont.Measure(Text).Y/2), Color.White); + + renderer.Device.DisableScissor(); + + base.Draw(rgbaRenderer,renderer); + } + } +} \ No newline at end of file diff --git a/OpenRA.Game/Chrome/LabelWidget.cs b/OpenRA.Game/Chrome/LabelWidget.cs new file mode 100644 index 0000000000..d4e28bc02a --- /dev/null +++ b/OpenRA.Game/Chrome/LabelWidget.cs @@ -0,0 +1,20 @@ +using OpenRA.Graphics; +using System.Drawing; +using System.Collections.Generic; + +namespace OpenRA.Widgets +{ + class LabelWidget : Widget + { + public readonly string Text = null; + + public override void Draw(SpriteRenderer rgbaRenderer, Renderer renderer) + { + Rectangle r = new Rectangle(X,Y,Width,Height); + renderer.Device.EnableScissor(r.Left, r.Top, r.Width, r.Height); + renderer.BoldFont.DrawText(rgbaRenderer, Text, new int2(X+Width/2, Y+Height/2) - new int2(renderer.BoldFont.Measure(Text).X / 2, renderer.BoldFont.Measure(Text).Y/2), Color.White); + renderer.Device.DisableScissor(); + base.Draw(rgbaRenderer,renderer); + } + } +} \ No newline at end of file diff --git a/OpenRA.Game/Chrome/Widget.cs b/OpenRA.Game/Chrome/Widget.cs new file mode 100644 index 0000000000..ce40690d4e --- /dev/null +++ b/OpenRA.Game/Chrome/Widget.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using OpenRA.FileFormats; +using OpenRA.Graphics; + +namespace OpenRA.Widgets +{ + class Widget + { + public readonly string Id = null; + public readonly int X = 0; + public readonly int Y = 0; + public readonly int Width = 0; + public readonly int Height = 0; + public readonly List Children = new List(); + + public virtual void Draw(SpriteRenderer rgbaRenderer, Renderer renderer) + { + foreach (var child in Children) + child.Draw(rgbaRenderer, renderer); + } + } + class ContainerWidget : Widget { } +} \ No newline at end of file diff --git a/OpenRA.Game/Chrome/WidgetLoader.cs b/OpenRA.Game/Chrome/WidgetLoader.cs new file mode 100644 index 0000000000..b978dc8c0b --- /dev/null +++ b/OpenRA.Game/Chrome/WidgetLoader.cs @@ -0,0 +1,67 @@ +using OpenRA.FileFormats; +using OpenRA.Graphics; +using OpenRA.Widgets; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Reflection; + +namespace OpenRA +{ + class WidgetLoader + { + static Pair[] ModAssemblies; + public static void LoadModAssemblies(Manifest m) + { + var asms = new List>(); + + // all the core stuff is in this assembly + asms.Add(Pair.New(typeof(Widget).Assembly, typeof(Widget).Namespace)); + + // add the mods + foreach (var a in m.Assemblies) + asms.Add(Pair.New(Assembly.LoadFile(Path.GetFullPath(a)), Path.GetFileNameWithoutExtension(a))); + ModAssemblies = asms.ToArray(); + } + + public static Widget LoadWidget( MiniYaml node ) + { + var widget = NewWidget( node.Value ); + foreach( var child in node.Nodes ) + { + if( child.Key == "Children" ) + { + foreach( var c in child.Value.Nodes ) + { + // Hack around a bug in MiniYaml + c.Value.Value = c.Key; + widget.Children.Add( LoadWidget( c.Value ) ); + } + } + else + FieldLoader.LoadField( widget, child.Key, child.Value ); + } + + return widget; + } + + static Widget NewWidget( string widgetType ) + { + if( widgetType.Contains( "@" ) ) + widgetType = widgetType.Substring( 0, widgetType.IndexOf( "@" ) ); + + foreach (var mod in ModAssemblies) + { + var fullTypeName = mod.Second + "." + widgetType + "Widget"; + var widget = (Widget)mod.First.CreateInstance(fullTypeName); + if (widget == null) continue; + + Log.Write("Creating Widget of type {0}",widgetType); + return widget; + } + + throw new InvalidOperationException("Cannot locate widget: {0}".F(widgetType)); + } + } +} \ No newline at end of file diff --git a/OpenRA.Game/GameRules/Rules.cs b/OpenRA.Game/GameRules/Rules.cs index 4f165c020e..74d6be2f59 100755 --- a/OpenRA.Game/GameRules/Rules.cs +++ b/OpenRA.Game/GameRules/Rules.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. @@ -66,6 +66,7 @@ namespace OpenRA var yamlRules = m.Rules.Reverse().Select(a => MiniYaml.FromFile(a)).Aggregate(MiniYaml.Merge); ActorInfo.LoadModAssemblies(m); + WidgetLoader.LoadModAssemblies(m); Info = new Dictionary(); foreach( var kv in yamlRules ) Info.Add(kv.Key.ToLowerInvariant(), new ActorInfo(kv.Key.ToLowerInvariant(), kv.Value, yamlRules)); diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 97b8abe32d..184c5595b0 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -276,7 +276,11 @@ - + + + + + diff --git a/mods/cnc/menus.yaml b/mods/cnc/menus.yaml index e29fc2be26..54c8ea9ccd 100644 --- a/mods/cnc/menus.yaml +++ b/mods/cnc/menus.yaml @@ -1,13 +1,35 @@ -Container: - Id:ROOT - X:10 - Y:10 - Width:400 - Height:400 +Background: + Id:MAINMENU_BG + X:400 + Y:200 + Width:250 + Height:200 Children: - Button: - Id:BUTTON1 - X:40 - Y:80 - Width:100 - Height:80 + Label@MAINMENU_LABEL_TITLE: + Id:MAINMENU_LABEL_TITLE + X:445 + Y:220 + Width:160 + Height:25 + Text:OpenRA Main Menu + Button@MAINMENU_BUTTON_JOIN: + Id:MAINMENU_BUTTON_JOIN + X:445 + Y:270 + Width:160 + Height:25 + Text:Join Game + Button@MAINMENU_BUTTON_CREATE: + Id:MAINMENU_BUTTON_CREATE + X:445 + Y:305 + Width:160 + Height:25 + Text:Create Game + Button@MAINMENU_BUTTON_QUIT: + Id:MAINMENU_BUTTON_QUIT + X:445 + Y:340 + Width:160 + Height:25 + Text:Quit