This is just a quick post to pass the time between the instalments of my ongoing series on Media Center development. The objective of this article is to show you how to build a simple progress bar control using MCML. I wrote this article in response to the statistic than several people landed on my site after searching for “progress bar mcml” on Google (thank you, Google Analytics!). Hopefully future visits will not go unrewarded this time 🙂
Concept
The progress bar is mostly comprised of static content; A bottom-most <ColorFill> element is mostly obscured and forms a border around the control. Within a slightly smaller area, two other <ColorFill> elements are overlayed onto eachother; one fills the available space and represents the background, while the other represents the fill and scales according to the percentage of the progress it is displaying. Finally, the top-most element is <Text> which expresses the progress as a written percentage.
Implementation
Code
The VectorTransformer class is used by the progress bar:
/// <summary> /// Transformer for converting one or more fractional values into a Vector3 representation. /// </summary> public class VectorTransformer : ITransformer { /// <summary> /// Format string that dictates which dimension of the vector is /// represented by the value, e.g. "{0},1,1". The remaining dimensions /// are taken from the format string itself. /// </summary> public string Format { get; set; } /// <summary> /// Transforms the input value into a Vector3 representation. /// </summary> /// <param name="value">Input value.</param> /// <returns>Output value.</returns> public object Transform(object value) { string[] parts = String.Format(Format, value).Split(','); return new Vector3( Single.Parse(parts[0]), Single.Parse(parts[1]), Single.Parse(parts[2]) ); } }
Markup
Usage
<UI Name="ProgressBarTest"> <Locals> <cor:Single Name="ProgressPercent" Single="0.16" /> </Locals> <Rules> <Binding Source="[ProgressPercent]" Target="[ProgressBar.Value]" /> </Rules> <Content> <me:ProgressBar Name="ProgressBar" Size="500,60" /> </Content> </UI>
Obviously, a practical example would bind the Value property of the progress bar to a changing variable rather than a constant value as used in this example. The Size property is optional and simply sets the size of the control.
Explanation
The only aspect of the content model that really needs to be explained is the <ColorFill> element used to represent the “fill” portion of the bar. We manipulate its Scale property in order to make it represent the progress. Unless otherwise specified, the origin used for scaling (and indeed transforming in any other way) an element in MCML is the vector (0,0,0).
At this point, i’ll note that you use Transformers in MCML whenever you need to convert, transform or format a value as part of a <Set> or <Binding> rule. There are several built-in transformers such as MathTransformer and FormatTransformer. The VectorTransformer class allows us to transform a single scalar fraction (i.e. the progress “value”) into a Vector3 (used by the Media Center SDK) which is constant in two dimensions and variable in the other. Due to the default origin, all we need to do is manipulate the X-axis scale to get the element to behave as desired. We use a FormatTransformer later on to format the fraction into a percentage (without any decimal places) using the standard .NET format string “P0”.
Final Words
Visually, this progress bar control is quite simplistic, but it does not look out of place within the Media Center UI. A more visually complex control might use the standard button background graphic (which, if you recall, uses nine-grid scaling to avoid looking skewed or jagged) and its “pressed” animation graphic, applied in the same manner as the Windows Vista/7-style progress bar, which pulses periodically while idle. Nevertheless, my implementation does the job at hand and provides both an indicator of progress and something to look at during a lengthy asynchronous operation. In my next article, I will deliver more information on my network browsing/copying add-in for Media Center, as originally promised.