Use Evaluator for positioning; Refactoring; Position elements relative to parents; Broke clicks outside of parent rect

This commit is contained in:
Paul Chote
2010-03-15 19:56:29 +13:00
parent 9ecb0d57f1
commit b70420e373
5 changed files with 79 additions and 50 deletions

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -29,7 +29,6 @@ namespace OpenRA.FileFormats
default: s.Push(int.Parse(t)); break;
}
}
return s.Pop();
}
@@ -43,7 +42,6 @@ namespace OpenRA.FileFormats
static IEnumerable<string> ToPostfix(IEnumerable<string> toks, Dictionary<string, int> syms)
{
var s = new Stack<string>();
foreach (var t in toks)
{
if (t[0] == '(') s.Push(t);
@@ -53,14 +51,20 @@ namespace OpenRA.FileFormats
while ((temp = s.Pop()) != "(") yield return temp;
}
else if (char.IsNumber(t[0])) yield return t;
else if (char.IsLetter(t[0])) yield return syms[t].ToString();
else if (char.IsLetter(t[0]))
{
if (!syms.ContainsKey(t))
throw new InvalidOperationException("Substitution `{0}` undefined".F(t));
yield return syms[t].ToString();;
}
else
{
while (s.Count > 0 && Prec[t] <= Prec[s.Peek()]) yield return s.Pop();
s.Push(t);
}
}
while (s.Count > 0) yield return s.Pop();
}

View File

@@ -134,6 +134,7 @@ namespace OpenRA
// Hack around a bug in MiniYaml
widgetYaml.Values.FirstOrDefault().Value = widgetYaml.Keys.FirstOrDefault();
WidgetLoader.rootWidget = WidgetLoader.LoadWidget(widgetYaml.Values.FirstOrDefault());
WidgetLoader.rootWidget.Initialize();
}
List<string> visibleTabs = new List<string>();

View File

@@ -23,44 +23,66 @@ namespace OpenRA.Widgets
// Calculated internally
public Rectangle Bounds;
public Rectangle ClickRect;
public Rectangle EventBounds;
public Widget Parent = null;
public virtual void Initialize()
{
Log.Write("{0} has parent {1}", Id, Parent == null ? "NULL" : Parent.Id);
// Evaluate the bounds rectangle
Bounds = new Rectangle(int.Parse(X),int.Parse(Y),int.Parse(Width),int.Parse(Height));
Rectangle parentBounds = (Parent == null) ? new Rectangle(0,0,Game.viewport.Width,Game.viewport.Height) : Parent.Bounds;
Dictionary<string, int> substitutions = new Dictionary<string, int>();
substitutions.Add("WINDOW_RIGHT", Game.viewport.Width);
substitutions.Add("WINDOW_BOTTOM", Game.viewport.Height);
substitutions.Add("PARENT_RIGHT", parentBounds.Width);
substitutions.Add("PARENT_BOTTOM", parentBounds.Height);
int width = Evaluator.Evaluate(Width, substitutions);
int height = Evaluator.Evaluate(Height, substitutions);
substitutions.Add("WIDTH", width);
substitutions.Add("HEIGHT", height);
Bounds = new Rectangle(parentBounds.X + Evaluator.Evaluate(X, substitutions),
parentBounds.Y + Evaluator.Evaluate(Y, substitutions),
width,
height);
// Create the clickrect
ClickRect = Bounds;
EventBounds = Bounds;
foreach (var child in Children)
ClickRect = Rectangle.Union(ClickRect, child.Bounds);
{
child.Initialize();
EventBounds = Rectangle.Union(EventBounds, child.Bounds);
}
}
public virtual void UpdateEventBounds()
{
EventBounds = Bounds;
foreach (var child in Children)
EventBounds = Rectangle.Union(EventBounds, child.Bounds);
Parent.UpdateEventBounds();
}
public virtual bool HandleInput(MouseInput mi)
{
if (!Visible)
// Are we able to handle this event?
if (!Visible || !EventBounds.Contains(mi.Location.X,mi.Location.Y))
return false;
// Do any of our children handle this?
bool caught = false;
if (ClickRect.Contains(mi.Location.X,mi.Location.Y))
// Can any of our children handle this?
foreach (var child in Children)
{
foreach (var child in Children)
{
caught = child.HandleInput(mi);
if (caught)
break;
}
if (child.HandleInput(mi))
return true;
}
// Child has handled the event
if (caught)
return true;
// Mousedown
if (Delegate != null && mi.Event == MouseInputEvent.Down && ClickRect.Contains(mi.Location.X,mi.Location.Y))
if (Delegate != null && mi.Event == MouseInputEvent.Down)
{
foreach (var mod in Game.ModAssemblies)
{
@@ -84,6 +106,9 @@ namespace OpenRA.Widgets
public void AddChild(Widget child)
{
child.Parent = this;
Log.Write("{0} setting parent {1}", child.Id, Id);
Children.Add( child );
}

View File

@@ -30,10 +30,9 @@ namespace OpenRA
else
FieldLoader.LoadField( widget, child.Key, child.Value );
}
widget.Initialize();
return widget;
}
static Widget NewWidget( string widgetType )
{
if( widgetType.Contains( "@" ) )

View File

@@ -2,39 +2,39 @@ Container:
Children:
Background@MAINMENU_BG:
Id:MAINMENU_BG
X:400
X:WINDOW_RIGHT/2 - 125
Y:200
Width:250
Height:200
Children:
Label@MAINMENDelegateU_LABEL_TITLE:
Label@MAINMENU_LABEL_TITLE:
Id:MAINMENU_LABEL_TITLE
X:445
Y:220
Width:160
X:0
Y:20
Width:250
Height:25
Text:OpenRA Main Menu
Align:Center
Button@MAINMENU_BUTTON_JOIN:
Id:MAINMENU_BUTTON_JOIN
X:445
Y:270
X:45
Y:70
Width:160
Height:25
Text:Join Game
Delegate:MainMenuButtonsDelegate
Button@MAINMENU_BUTTON_CREATE:
Id:MAINMENU_BUTTON_CREATE
X:445
Y:305
X:45
Y:110
Width:160
Height:25
Text:Create Game
Delegate:MainMenuButtonsDelegate
Button@MAINMENU_BUTTON_QUIT:
Id:MAINMENU_BUTTON_QUIT
X:445
Y:340
X:45
Y:150
Width:160
Height:25
Text:Quit
@@ -49,37 +49,37 @@ Container:
Children:
Label@CREATESERVER_LABEL_TITLE:
Id:CREATESERVER_LABEL_TITLE
X:445
Y:220
Width:160
X:0
Y:20
Width:250
Height:25
Text:Create Server
Align:Center
Button@CREATESERVER_CHECKBOX_HIDDEN:
Id:CREATESERVER_CHECKBOX_HIDDEN
X:400
Y:260
X:100
Y:60
Width:20
Height:20
Label@CREATESERVER_LABEL_HIDDENGAME:
Id:CREATESERVER_LABEL_HIDDENGAME
X:435
Y:260
X:135
Y:60
Width:300
Height:25
Text:Hide from Server Browser
Button@CREATESERVER_BUTTON_CANCEL:
Id:CREATESERVER_BUTTON_CANCEL
X:400
Y:300
X:100
Y:100
Width:160
Height:25
Text:Cancel
Delegate:MainMenuButtonsDelegate
Button@CREATESERVER_BUTTON_START:
Id:CREATESERVER_BUTTON_START
X:570
Y:300
X:270
Y:100
Width:160
Height:25
Text:Create