![]() |
User Interaction TutorialIn this tutorial we will deal with responding to the mouse pointer, and look at some of the classes that are useful in aiding user interaction. Detecting Mouse ButtonsThe <onclick> tag provides the necessary means to detect mouse button presses of left, right, middle and even more buttons according to how many are available. Use of the onclick tag requires that you initialise it to a render object that you want to receive mouse button information from. Adding extra parameters is optional, but if necessary you can select what type of click should be monitored (e.g. a double click), and the button that should be monitored (e.g. the middle button). The following example demonstrates the onclick class being used to create a box that destroys itself when you click on it:
<render name="box" width="50" height="30" colour="128,128,128">
<onclick>
<action static object="[box]" call="free"/>
</onclick>
</render>
Note how we used the <action> tag to kill the button for us. Whenever you use the onclick class, you must choose another class to perform the actual response to the click for you. There is no limit to the amount of classes that you can place within an onclick object, so if necessary you can perform a list of actions as you wish. Here is another example that extends on the button code that we wrote in the previous tutorial. Click the button and you will notice that it depresses itself and the text changes colour from black to blue.
<dml>
<box frame="1" highlight="230,230,230" shadow="60,60,60" colour="180,180,180" raised/>
<box frame="2" highlight="230,230,230" shadow="60,60,60" colour="180,180,180" sunken/>
<text name="clicktext" colour="#000000" align="center" face="arial:12" string="Click Me"/>
<onclick frame="2" releaseframe="1" name="click">
<set static object="[clicktext]" colour="50,50,255"/>
</onclick>
</dml>
For more information on the frame and releaseframe attributes as well as other functions of the onclick class, refer to its class manual. Reacting to Pointer MovementResponding to the movement of the mouse pointer is an interactive technique that has become more popular over the progression of computer interfaces. Typically it is used to provide visual feedback, but responding to movement in a DML script allows you to create feedback mechanisms of your own devising. In this next example we will use the <movement> tag to alter the colour of a drawable area inside a larger container. As the pointer moves in and out of the area, the colour will change to reflect the pointer's position.
<dml>
<set object="[container]" colour="#c0c0e0"/>
<render name="box" x="25%" y="25%" xoffset="25%" yoffset="25%" colour="#000000">
<movement enter>
<set static object="[box]" &colour="#f00000"/>
</movement>
<movement exit>
<set static object="[box]" &colour="#000000"/>
<movement>
</render>
</dml>
As you can see, two movement tags were used - the first for movement entering the rendered area, and the second for leaving the area. We also introduced use of the set command, which performs the colour alteration when signalled by each movement object.
A more common reaction to pointer movement is to change the frame of a rendered area, typically for highlighting purposes. This is achieved through the frame and exitframe fields of the movement class. You can read more about this and more functionality in the movement class manual. The Resize Class and Graphics PositioningIt's not often that an operating system will allow so much control over its operations that you can set your own resizing areas, but Athene and DML make it possible with ease. Resizing is commonly used to rearrange the width and height of windows from the right or bottom edges, but by using the resize class you can apply this concept to anything that you please, and at any graphical position. In this example we will stick with a simple demonstration which allows the user to resize the rendered area on the bottom and right hand sides:
<render name="main" width="400" height="400">
<!-- Horizontal resize area on right hand side -->
<resize xoffset="5" y="0" height="[main.height]" width="5"
direction="horizontal"/>
<!-- Vertical resize area at the bottom -->
<resize yoffset="5" x="0" height="5" width="[main.width]"
direction="vertical"/>
</render>
As you can see, creating a resize area is as simple as specifying the coordinates and size of the area itself. In order to be activated, all the user has to do is move the mouse pointer over the area, then click and drag to set its new width and/or height. A more important question surrounds the rendered area that you are resizing though. What happens to rendered children inside of the resized area for instance? Often we will want them to be resized automatically, but this can be a complicated exercise when some objects need to be resized, while others may need to remain at fixed sizes, or placed at specific points on the right and bottom margins. In order to cope with this, it is up to you to correctly program your rendered areas so that they maintain themselves correctly when resized. You need to take the following render fields into account when considering resize behaviour: width xoffset x height yoffset y The xoffset and yoffset fields provide an alternative to specifying x and y coordinates and/or width and height dimensions. Setting an offset in conjunction with its related dimension (e.g. xoffset paired with the width) will result in the rendered area being permanently offset from the opposite edge of the container. For instance, if the xoffset is set to 10 and the width is set to any given value, then the rendered area will be permanently offset 10 units from the right-hand margin. This is guaranteed even if the container of the rendered area is resized. If an offset field is set in conjunction with its related coordinate (e.g. xoffset paired with the x coordinate) then the rendered area will have a dynamic width setting. For instance, if the x coordinate is set to 20 and the xoffset is set to 10, then the actual width of the area will be calculated from the formula "Width = ContainerWidth - XOffset - X". If the result is such that the calculated width is less than zero (e.g. "25-20-10 = -5" then the rendered area will disappear until the width of the container increases to the point where the calculated width turns to a positive value. Like HTML, you may specify percentages in any of the aforementioned fields if you want to have the dimensions and coordinates to be calculated in relative terms. Setting the width to 50% would result in the width of the rendered area taking up 50% of the size of the container. Percentage based values are automatically re-calculated when necessary, so even if the container is resized, any children based on percentages will have their graphics updated to retain their correct proportions. Learning how to create a complex interface that resizes itself correctly is something that takes a lot of practice, but is ultimately very rewarding when you see it working. If you have any trouble in creating such an interface, it is recommended that you look at some existing applications to see how they do it.
Copyright Rocklyte Ltd © 2002-2007. |