Difference between revisions of "EZUI"

From Sirikata Wiki
Jump to navigation Jump to search
(redirected to Flatland page)
 
(23 intermediate revisions by the same user not shown)
Line 1: Line 1:
EZUI is a user interface creation tool developed by Ben Christel.  It is designed to allow an application developer to add code to an [[entity]]'s script that specifies the UI's appearance and logic.  The UI will then appear on a user's screen when the user interacts with one of the entity's [[presence|presences]].
+
#REDIRECT [[Flatland]]
 
 
EZUI was designed with the following goals in mind:
 
* Facilitating rapid development of dialog-like UIs associated with a particular presence in the world
 
* Enabling multiple users to interact with a presence simultaneously using the UI
 
* Allowing application developers to easily collect and store data input by the user
 
* Facilitating communication between the presence controlling the UI and the avatar interacting with it
 
* Automating the synchronization of data between the UI and the controlling presence
 
 
 
== Tutorial ==
 
 
 
===Setting up EZUI===
 
 
 
To use EZUI, you'll need the following files in your Sirikata directory:
 
 
 
 
 
*share/ogre/data/ezui/[http://dl.dropbox.com/u/549683/Sirikata-EZUI/ogre_data_ezui/ezui.js ezui.js]
 
*share/js/scripts/std/[http://dl.dropbox.com/u/549683/Sirikata-EZUI/default.em default.em]
 
*share/js/scripts/std/graphics/[http://dl.dropbox.com/u/549683/Sirikata-EZUI/graphics/ezui.em ezui.em]
 
*share/js/scripts/std/graphics/[http://dl.dropbox.com/u/549683/Sirikata-EZUI/graphics/ezuiViewer.em ezuiViewer.em]
 
*share/js/scripts/std/graphics/[http://dl.dropbox.com/u/549683/Sirikata-EZUI/graphics/default.em default.em]
 
 
 
 
 
 
 
If you've edited your own std/default.em and std/graphics/default.em (for example, if you've added scripts to the default presence or created your own UIs or keybindings) you'll want to patch those files manually.  The section below describes how to do that.
 
 
 
====Manually Patching std/default.em and std/graphics/default.em====
 
 
 
Lines preceded with <code>/*add*/</code> are to be added.  Other lines are shown for context.  Line numbers may differ if you've edited these files yourself.
 
 
 
=====In std/default.em=====
 
 
 
<div style="font-size:120%">
 
<source lang="javascript">
 
system.require('std/core/repeatingTimer.em');
 
/*add*/ system.require('std/graphics/ezui.em');
 
</source>
 
</div>
 
 
 
=====In std/graphics/default.em=====
 
 
 
(line 48)
 
<div style="font-size:120%">
 
<source lang="javascript">
 
system.require('std/graphics/axes.em');
 
/*add*/ system.require('std/graphics/ezuiViewer.em');
 
</source>
 
</div>
 
 
 
...
 
 
 
(line 79)
 
<div style="font-size:120%">
 
<source lang="javascript">
 
this._loadingUIs++; this._setMesh = new std.graphics.SetMesh(this._simulator, ui_finish_cb);
 
/*add*/ this._loadingUIs++; this._ezui = new std.ezui.EZUI(this, ui_finish_cb);
 
</source>
 
</div>
 
 
 
...
 
 
 
(line 91)
 
<div style="font-size:120%">
 
<source lang="javascript">
 
this._loadingUIs++; this._setMesh.onReset(ui_finish_cb);
 
/*add*/ this._loadingUIs++; this._ezui.onReset(ui_finish_cb);
 
</source>
 
</div>
 
 
 
...
 
 
 
(line 157)
 
<div style="font-size:120%">
 
<source lang="javascript">
 
this._binding.addAction('stopDrag', std.core.bind(this.stopDrag, this));
 
/*add*/ this._binding.addFloat2Action('showEZUI', std.core.bind(this.showEZUI, this));
 
/*add*/ this._binding.addAction('hideEZUI', std.core.bind(this.hideEZUI, this));
 
</source>
 
</div>
 
 
 
...
 
 
 
(line 230)
 
<div style="font-size:120%">
 
<source lang="javascript">
 
{ key: ['mouse-release', 1, '*'], action: 'stopDrag' },
 
/*add*/ { key: ['mouse-press', 3, 'none'], action: 'showEZUI' },
 
</source>
 
</div>
 
 
 
...
 
 
 
(end of the file)
 
 
 
<div style="font-size:120%">
 
<source lang="javascript">
 
 
 
            redo: function(action) {
 
                movable.setOrientation(new util.Quaternion());
 
            }
 
        });
 
    }
 
   
 
/*add*/    std.graphics.DefaultGraphics.prototype.showEZUI = function (x, y) {
 
/*add*/        var ignore_self = this._camera.mode() == 'first';
 
/*add*/      var clicked = this._simulator.pick(x, y, ignore_self);
 
/*add*/        this._ezui.show(clicked, x, y);
 
/*add*/    };
 
   
 
/*add*/    std.graphics.DefaultGraphics.prototype.hideEZUI = function () {
 
/*add*/        this._ezui.hide();
 
/*add*/    };
 
   
 
})();
 
</source>
 
</div>
 
 
 
===Hello World===
 
 
 
* You should use <code>system.require('std/graphics/ezui.em')</code> to ensure that the required files are included.
 
* The Emerson function <code>ezui.script()</code> takes a string containing JavaScript to be executed when the GUI loads.  The code passed to <code>ezui.script()</code> is executed every time a user opens the GUI.  In between invocations of the GUI, its contents are cleared.
 
* The <code>write()</code> function takes a string as a parameter.  This string is appended to the GUI's HTML, similar to the way document.write() works in a plain HTML document.
 
 
 
====The Code====
 
 
 
<div style="font-size:120%">
 
<source lang="javascript">
 
system.require('std/graphics/ezui.em');
 
ezui.script(@
 
write('Hello, World!');
 
@);
 
</source>
 
</div>
 
 
 
====Test the UI====
 
 
 
You can test the code above by opening a scripting window on any presence in the world and running the code.  Then right-click on the presence you just scripted and the UI should appear.
 
 
 
===Creating Buttons And Sections===
 
 
 
* Buttons are represented as JavaScript objects.  However, when you want to make a button appear on the screen, you can treat it as if it's a string of HTML code.  Button objects can be passed to write() or concatenated with strings.
 
* The <code>button()</code> function is used to create a button.  This function takes the following parameters:
 
** the text on the button
 
** a callback function that is called when the user clicks the button
 
* The <code>sections()</code> function is used to divide the UI into sections.  <code>sections</code> takes any number of strings as parameters; these strings are used as section IDs.  Note that the strings passed to <code>sections()</code> must be valid HTML ID attribute values (i.e. they must begin with a letter and contain only letters, numbers, and underscores).  <code>sections()</code> returns a string that can be passed to <code>write()</code> or <code>append()</code>.
 
* The <code>append()</code> function is used to append text or HTML to a specific section of the UI.  The function takes the following parameters:
 
** The ID of the section
 
** The text to append to the section
 
* The button callback is called with the button's text as a parameter.  This allows the UI to determine which button was clicked if multiple buttons use the same callback.
 
 
 
====The Code====
 
 
 
<div style="font-size:120%">
 
<source lang="javascript">
 
system.require('std/graphics/ezui.em');
 
ezui.script(@
 
write(sections('buttons', 'output'));
 
var b1 = button('button 1', buttonCB);
 
var b2 = button('button 2', buttonCB);
 
append('buttons', b1+'<br />'+b2);
 
function buttonCB (text) {
 
append('output', 'You clicked '+text+'!<br />');
 
}
 
@);
 
</source>
 
</div>
 
 
 
===Sending Messages to the Controlling Presence===
 
* The '''controlling presence''' (or simply ''controller'') is the presence that you script with the <code>ezui.script()</code> call.
 
* You can notify the controller that a button on your UI was pressed by setting <code>notifyController</code> as the button's callback function.
 
* The <code>ezui.onButtonPressed()</code> function lets you specify a function to execute when your controller gets notified of a button event.  Note that <code>ezui.onButtonPressed()</code> is called in the controller's main script, not the UI script inside ezui.script.  The callback function must also be defined in the controller's main script.  The callback can take the button's text as a parameter.
 
 
 
====The Code====
 
 
 
<div style="font-size:120%">
 
<source lang="javascript">
 
system.require('std/graphics/ezui.em');
 
ezui.script(@
 
var upButton = button('up', notifyController);
 
var downButton = button('down', notifyController);
 
var stopButton = button('stop', notifyController);
 
write(upButton+'<br />');
 
write(stopButton+'<br />');
 
write(downButton+'<br />');
 
@);
 
 
 
ezui.onButtonPressed(move);
 
function move (buttonText) {
 
if (buttonText == "up") {
 
system.self.setVelocity(<0, 1, 0>);
 
}
 
else if (buttonText == "down") {
 
system.self.setVelocity(<0, -1, 0>);
 
}
 
else if (buttonText == "stop") {
 
system.self.setVelocity(<0, 0, 0>);
 
}
 
}
 
</source>
 
</div>
 

Latest revision as of 17:24, 26 August 2011

Redirect to: