The samples lately may have seemed a bit "script heavy" for a system that is supposed to be markup based, so today we have a drop-down menu system driven entirely from markup, savvy?
Of course the menu doesn't do anything without script (it is just a visual thing; any actual behaviour like changing chapters or switching audio tracks is done with a couple of lines of code) and in order to avoid a download I'm just going to paste the markup that uses background colours (rather than pretty images) but you will get the idea.
The Markup
Here it is in one big chunk:
<?
<
<set style:opacity="1"/> </cue> </par> </timing> </head>
</
OK, so how's it work?
The Layout
The layout consists of a menu bar with three button elements, nominally "settings" (yellow), "chapters" (red), and "audio" (blue). These buttons all have an id and they also have a class stating which button they are not (so, for example, the "audio" button has a class saying it is "NotSettings" and "NotChapters").
Then there div elements (for each of the sub-menus), each of which contains three more button elements that have a class set to the kind of button that they are (so, for example, the audio sub-menu has buttons with the class set to "AudioButton").
The use of these class attributes makes the animation trivial. Also the navIndex attribute is used quite a bit to ensure that the menus work nicely with cursor navigation.
The Styling
Pretty basic, really, Set some default size and colour parameters.
The Timing
This is quite simple. There are three very similar blocks repeated for each of the three menus (they are copy-paste jobs with the id and class values renamed). We'll consider just the first one:
<par begin="id('settings')[state:actioned()]" end="(class('SettingsButton')[state:actioned()] or class('NotSettings')[state:focused()])">
<cue begin="0s" dur="0.3s" select="id('settingsMenu')" fill="hold"> <animate style:height="0px;400px"/> </cue>
<cue begin="0s" dur="1s" select="id('settings')" fill="hold"> <set style:navDown="settings1" style:navUp="settings3"/> </cue> </par>
The par will begin when the settings button is actioned (clicked), and end when either one of the sub-menu buttons is actioned (class is "SettingsButton") or when a different top-level button gets focused (class is "NotSettings"). Inside the par, we animate the settingsMenu over a dur of 0.3 seconds and then hold it at the open position. We also set the navUp and navDown attributes so that the up / down keys work naturally with the expanded menu.
There's also the case of highlighting the focused button:
<cue begin="//button[state:focused() and count(//button[style:opacity()='1'])=0]" end="defaultNode()[state:focused() != 'true']">
<set style:opacity="1"/> </cue>
·No-one has the focus, and count(//button[style:opacity()='1'])=0 is true
·Button A gets the focus, and the begin is true
·Button A becomes 100% opaque, and count(//button[style:opacity()='1'])=0 becomes false, thus making the entire begin false and making it eligible to re-start as soon as it ends
·Button A loses the focus, so the end is true and the cue stops. Now count(//button[style:opacity()='1'])=0 is true again
·Button B gets the focus, and can immediately begin the cue because it has already done the false / true flip-flop
The Script
Surprise! There isn't any :-)
You can simply copy-and-paste the markup into an XMU file along with a bog-standard XPL and XMF (from any of the previous samples, for example) to watch it work.