Toggling Menus with the Menu button in 100% Markup
Here's a quick one: How do you have an HD DVD menu that opens and closes when you click the Menu button, but doesn't require any script?
It's pretty easy, but it relies on using a dummy element to hold your state; in this case whether the menu "can open" or whether the menu "can close." For this example (which is incredibly ugly), we'll have a hidden div called "CurrentMenuState" that is at x=0px when the menu "can open", and at x=300px when the menu "can close". I chose those numbers rather arbitrarily.
Comments in the XML should make it clear what is happening:
<?xml version="1.0"?>
<root xml:lang="en" xmlns="https://www.dvdforum.org/2005/ihd" xmlns:style="https://www.dvdforum.org/2005/ihd#style" xmlns:state="https://www.dvdforum.org/2005/ihd#state">
<head>
<styling>
<!--Default style for buttonson the menu; just something basic-->
<style id="MenuButton"
style:position="absolute"
style:width="300px" style:height="100px"
style:x="100px"
style:opacity="0.5" />
</styling>
<timing clock="page">
<defs>
<!--Animations to slide the menu open and closed-->
<animate id="OpenMenu" style:x="-500px;0px" />
<animate id="CloseMenu" style:x="0px;-500px" />
<!--Make something display-->
<set id="Show" style:display="auto" />
<!--Make something opaque-->
<set id="MakeOpaque" style:opacity="1"/>
<!--Two states the menu can be in-->
<set id="STATE_MENU_CAN_OPEN" style:x="0px"/>
<set id="STATE_MENU_CAN_CLOSE" style:x="300px"/>
</defs>
<par>
<!--Dummy animation; highlight the menu buttons when clicked-->
<cue begin="class('MenuButton')[state:actioned()]" dur="0.5s" use="MakeOpaque" />
<!--Open the menu; begin when the button is clicked and state is CAN_OPEN.-->
<!--end when the button is clicked and the state is CAN_CLOSE.-->
<par begin="(id('ToggleMenu')[state:actioned()] and id('CurrentMenuState')[style:x()='0px'])"
end="(id('ToggleMenu')[state:actioned()] and id('CurrentMenuState')[style:x()='300px'])">
<!--Update state to CAN_CLOSE-->
<cue select="id('CurrentMenuState')" dur="1s" fill="hold" use="STATE_MENU_CAN_CLOSE" />
<!--
Comments
Anonymous
October 12, 2006
Nice post ;) Very helpful. I had a much more difficult time implementing this in the script.Anonymous
October 13, 2006
You mentioned that you could have used an input vs. the hidden div. But what about a button? Then you use state:value to track the menu state. Right? What would be the downsides of doing it that way?Anonymous
October 16, 2006
Trouble is that the end is evaluated at the same time as the begin, so if you both begin and end when the button is clicked, the cue will never become active.Anonymous
October 25, 2006
Hi Peter, Thanks for the sample code... everything makes perfect sense, however I can't get this example to work using Sonic's emulator. Works great in iHDSim, but blows up Sonic with an 'Abnormal Program Termination', leaving no useful clue in the debug window or HDDVDValidator Any tips/advice to get this work outside of iHDSim? Thanks in advance!Anonymous
October 25, 2006
It might be the boolean conditions they don't like. Try something like this instead (on all the XPaths):
id('ToggleMenu')[state:actioned() and style:x(id('CurrentMenuState'))='300px']
where instead of and-ing together two nodesets co-erced to booleans, the entire expression is put inside a predicate.
- Anonymous
October 26, 2006
Thanks for the help Peter, the problem was in the XPath syntax. In case anyone else is running into this problem, the open menu and close menu XPaths work when written like this: <par begin="id('ToggleMenu')[state:actioned() and (id('CurrentMenuState')[style:x()='0px'])]" end="id('ToggleMenu')[state:actioned() and (id('CurrentMenuState')[style:x()='300px'])]"> <par begin="id('ToggleMenu')[state:actioned() and (id('CurrentMenuState')[style:x()='300px'])]" end="id('MenuContainer')[style:x()='-500px' or (id('ToggleMenu')[state:actioned() and (id('CurrentMenuState')[style:x()='0px'])])]">