Wednesday, February 7, 2007

Navigating - and Another MCMLPad Warning

There's another minor bug/issue in MCMLPad - something you should be aware of once you start doing more advanced development.

To navigste from 'page' to 'page' (eg. between UI's) you can use the <Navigate> action within any Rule.

The only required member of this tag is URI - the address to the next page. Most frequently, this will be a link to an MCML file that you have enclosed in a resource (usually the same DLL that contains your .NET application).

You can also pass objects in this Navigate tag. Since Navigate opens another UI as the main interface, you pass objects to this new UI exactly the same way that you do between UI's in a single interface - by passing them as properties.

So, for example, you can create a property on the base-UI in 'Page2.mcml', and set it with the Navigate tag in 'Page1.mcml'. This is how you can continue to pass information between pages and propagate information through your entire application.

ONE WORD OF WARNING: MCMPad has a small glitch (I hesistate to call it a 'bug', but it IS annoying) where pressing F5 to refresh the page will NOT work correctly for any page that has been passed a property. The property will not be re-sent, which means that any strings will be reset to empty and any objects will be set to 'null', which will normally mean that MCMLPad will close with an exception.

Monday, February 5, 2007

Input Handling

Welcome back for another blog entry.

Today we have a quick tip on input handling (and playing with .NET variables) in your MCML interfaces.

Every object in your MCML interface has an Input object associated with it. This is what allows you to find out if the item has mouse or keyboard focus. It ALSO lets you control how that focus works.

To tell if the mouse is hovering over an object, you need to check the [Input.MouseFocus] property. Since every object has it's own 'Input' object, the properties of Input will always refer to this object only (or it's children, if you are using DeepFocus).

<UI Name = "Selectable">
  <Rules>
    <Condition Target="[Input.MouseFocus] Value="true"\>
      <Actions>
        <Set Target=[TextObject.Color]" Value="Red"\>
      </Actions>
    </Condition>
  <\Rules>
  <Content>
    <Text Content="Push Me" Color="White" Name="TextObject"\>
  <\Content>
<\UI>

The trick to using their advanced properties is simple, but can throw you if you are new to MCML. Objects like Input are NOT actually XML tags, despite the fact that in the documentation they are shown as XML. Instead, they are .NET objects, and you set the properties of the Input object through the Default tag of your Rules object.

For example, we can mark a panel as being able to receive focus with the KeyInteractive property.

<UI Name = "Selectable>
  <Rules>
    <Default Target="[Input. KeyInteractive] Value="true"\>
  <\Rules>
  <Content>
    <Text Content="Push Me"\>
  <\Content>
<\UI>

This creates a text object that you can navigate to with you remote/keyboard.

One more hint - MCML's default is that a mouse-focus event always fired off a matching key-focus event. Sometimes, this just isn't right.

For example, in the AreaBar (the pivot bar, or the blue list of sorting options that appears in most genuine Media Center screens), you find that when you navigate by key-press or remote, you automatically select the next area/option that you navigate to.

When using a MOUSE, you only HIGHLIGHT it. You have to click the mouse button to select the option.

However, the default behaviour for Media Center is to automatically set 'KeyFocus' to true every time 'MouseFocus' is. This sort of thing is great for regular buttons, but isn't effective for this particular control.

So to emulate this behavior, you need to use

<Rules>
  <Default Target="[Input. KeyFocusOnMouseEnter] Value="false"\>
<\Rules>

This prevents [Input.KeyFocus] from being true every time that [Input.MouseFocus] is.