Skip to content

Instantly share code, notes, and snippets.

@TravisTheTechie
Created June 15, 2011 19:38
Show Gist options
  • Save TravisTheTechie/1027904 to your computer and use it in GitHub Desktop.
Save TravisTheTechie/1027904 to your computer and use it in GitHub Desktop.
Balsamiq Parsing
public class BalsamiqParser
{
public IEnumerable<PageObjectHierarchy> GenerateHierarchy(XDocument balsamiqXml)
{
// xml to objects
var items = balsamiqXml
.Descendants("control")
.Select(control => new PageObjectHierarchy
{
ControlTypeId = (string)control.Attribute("controlTypeID"),
XCoordinate = Convert.ToInt32((string)control.Attribute("x")),
YCoordinate = Convert.ToInt32((string)control.Attribute("y")),
Width = Convert.ToInt32((string)control.Attribute("w")),
Height = Convert.ToInt32((string)control.Attribute("h")),
MeasuredWidth = Convert.ToInt32((string)control.Attribute("measuredW")),
MeasuredHeight = Convert.ToInt32((string)control.Attribute("measuredH")),
Text = control.Descendants("text").Count() > 0 ? control.Descendants("text").ElementAt(0).Value : null,
Depth = 1
})
.ToList();
// Look for control intersections
for (int i = 0; i < items.Count; i++)
{
var control = items[i];
if (control.Width == -1 || control.Height == -1)
continue;
foreach (var poh in items.Except(new[] { control }))
{
if (control.Inersects(poh))
{
control.Children.Add(poh);
poh.Parents.Add(control);
}
}
}
// build the proper depth trees so we can pick the right parent/child
var currentDepth = 1;
IEnumerable<PageObjectHierarchy> workingSet = items;
while (workingSet.Count() > 0)
{
foreach (var item in workingSet)
{
item.Children.ToList().ForEach(child => child.Depth = item.Depth + 1);
}
currentDepth++;
workingSet = items.Where(x => x.Depth >= currentDepth);
}
// clean up tree
items = items.Where(x => x.Depth == 1).ToList();
items.ForEach(ReduceTree);
return items;
}
private static void ReduceTree(PageObjectHierarchy currentItem)
{
currentItem.Parents
.Where(x => x.Depth != currentItem.Depth - 1)
.ToList()
.ForEach(bp => RemoveParentChildRelationship(currentItem, bp));
for (int i = 0; i < currentItem.Children.Count; i++)
{
ReduceTree(currentItem.Children[i]);
}
}
private static void RemoveParentChildRelationship(PageObjectHierarchy currentItem, PageObjectHierarchy parentToRemove)
{
parentToRemove.Children.Remove(currentItem);
currentItem.Parents.Remove(parentToRemove);
}
}
public class PageObjectHierarchy
{
public PageObjectHierarchy()
{
Children = new List<PageObjectHierarchy>();
Parents = new List<PageObjectHierarchy>();
}
public string ControlTypeId { get; set; }
public int XCoordinate { get; set; }
public int YCoordinate { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int MeasuredWidth { get; set; }
public int MeasuredHeight { get; set; }
public string Text { get; set; }
public IList<PageObjectHierarchy> Children { get; private set; }
public IList<PageObjectHierarchy> Parents { get; private set; }
public int Depth { get; set; }
}
public static class PageObjectHierarchyExtentions
{
public static bool Inersects(this PageObjectHierarchy control, PageObjectHierarchy poh)
{
return control.XCoordinate <= poh.XCoordinate && poh.XCoordinate <= control.XCoordinate + (control.Width == -1 ? control.MeasuredWidth : control.Width) &&
control.YCoordinate <= poh.YCoordinate && poh.YCoordinate <= control.YCoordinate + (control.Height == -1 ? control.MeasuredHeight : control.Height);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment