public void LoadSkin(string name, string author, InputSource type, XDocument doc, string skinPath) { Name = name; Author = author; Type = type; var bgElems = doc.Root.Elements("background"); if (bgElems.Count() < 1) { throw new ConfigParseException("Skin must contain at least one background."); } foreach (var elem in bgElems) { var imgPath = readStringAttr(elem, "image", false); BitmapImage image = null; uint width = 0; uint height = 0; if (!string.IsNullOrEmpty(imgPath)) { image = loadImage(skinPath, imgPath); width = (uint)image.PixelWidth; var widthAttr = elem.Attributes("width"); if (widthAttr.Count() > 0) { width = uint.Parse(widthAttr.First().Value); } height = (uint)image.PixelHeight; var heightAttr = elem.Attributes("height"); if (heightAttr.Count() > 0) { height = uint.Parse(heightAttr.First().Value); } } else { var widthAttr = elem.Attributes("width"); if (widthAttr.Count() > 0) { width = uint.Parse(widthAttr.First().Value); } var heightAttr = elem.Attributes("height"); if (heightAttr.Count() > 0) { height = uint.Parse(heightAttr.First().Value); } if (width == 0 || height == 0) { throw new ConfigParseException("Element 'background' should either define 'image' with optionally 'width' and 'height' or both 'width' and 'height'."); } } _backgrounds.Add(new Background { Name = readStringAttr(elem, "name"), Image = image, Color = readColorAttr(elem, "color", false), Width = width, Height = height }); } foreach (var elem in doc.Root.Elements("detail")) { _details.Add(new Detail { Config = parseStandardConfig(skinPath, elem), Name = readStringAttr(elem, "name"), }); } foreach (var elem in doc.Root.Elements("button")) { _buttons.Add(new Button { Config = parseStandardConfig(skinPath, elem), Name = readStringAttr(elem, "name") }); } foreach (var elem in doc.Root.Elements("rangebutton")) { var from = readFloatConfig(elem, "from"); var to = readFloatConfig(elem, "to"); if (from > to) { throw new ConfigParseException("Rangebutton 'from' field cannot be greater than 'to' field."); } _rangeButtons.Add(new RangeButton { Config = parseStandardConfig(skinPath, elem), Name = readStringAttr(elem, "name"), From = from, To = to }); } foreach (var elem in doc.Root.Elements("stick")) { _analogSticks.Add(new AnalogStick { Config = parseStandardConfig(skinPath, elem), XName = readStringAttr(elem, "xname"), YName = readStringAttr(elem, "yname"), VisibilityName = readStringAttr(elem, "visname", false), XRange = readUintAttr(elem, "xrange"), OriginalXRange = readUintAttr(elem, "xrange"), YRange = readUintAttr(elem, "yrange"), OriginalYRange = readUintAttr(elem, "yrange"), XReverse = readBoolAttr(elem, "xreverse"), YReverse = readBoolAttr(elem, "yreverse") }); } foreach (var elem in doc.Root.Elements("touchpad")) { _touchPads.Add(new TouchPad { Config = parseStandardConfig(skinPath, elem), XName = readStringAttr(elem, "xname"), YName = readStringAttr(elem, "yname"), XRange = readUintAttr(elem, "xrange"), OriginalXRange = readUintAttr(elem, "xrange"), YRange = readUintAttr(elem, "yrange"), OriginalYRange = readUintAttr(elem, "yrange"), }); } foreach (var elem in doc.Root.Elements("analog")) { var directionAttrs = elem.Attributes("direction"); if (directionAttrs.Count() < 1) { throw new ConfigParseException("Element 'analog' needs attribute 'direction'."); } AnalogTrigger.DirectionValue dir; switch (directionAttrs.First().Value) { case "up": dir = AnalogTrigger.DirectionValue.Up; break; case "down": dir = AnalogTrigger.DirectionValue.Down; break; case "left": dir = AnalogTrigger.DirectionValue.Left; break; case "right": dir = AnalogTrigger.DirectionValue.Right; break; case "fade": dir = AnalogTrigger.DirectionValue.Fade; break; default: throw new ConfigParseException("Element 'analog' attribute 'direction' has illegal value. Valid values are 'up', 'down', 'left', 'right', 'fade'."); } _analogTriggers.Add(new AnalogTrigger { Config = parseStandardConfig(skinPath, elem), Name = readStringAttr(elem, "name"), Direction = dir, IsReversed = readBoolAttr(elem, "reverse"), UseNegative = readBoolAttr(elem, "usenegative") }); } }