HOWTO: Write a Lily UI external

From LilyWiki

Jump to: navigation, search

Here's a quick tutorial to get you started writing a simple UI external object for Lily.

1) If you haven't already, create a folder where you'll keep your code. In the Lily preferences dialog, (Help->Options) select that folder as your "Object Search Path". This will be the root directory where Lily will look for external objects to load. Searching is recursive, so you can create additional directories in this folder to keep things organized. Just don't store .js files that aren't valid Lily objects in here or it will cause problems.

2) Copy the javascript code below and save it in a file called "hellobutton.js" somewhere in your Search Path folder. Restart Firefox and open a new patch document. (Tools->Lily->New). Double click on the patch window and begin typing "hellobutton". You should see the name in the autocomplete list. Create the object and connect a "print" to the outlet. That's it. Clicking the button should print a hearty "hello world!" to the debug window.


/**
*	Construct a new hellobutton object
*	@class
*	@constructor
*	@extends LilyObjectBase
*/
//the name of the constructor is the filename/classname with a prepended "$".
function $hellobutton(args)
{

	//object args are passed as a parameter to the object constructor
	//parse the args- if there's a length, then use it as our label text. otherwise set it to "".
	this.buttonText=(args.length)?args:""; //label text

	//save this to use with the inner function
	var thisPtr=this;

	//create an outlet- args to the outlet constructor are: outlet name, the current context (always this), help text (displayed when the user mouses over the outlet).
	this.outlet1 = new this.outletClass("outlet1",this,"click outputs bang");
		
	//the inspector config- this determines what form elements we see in the inspector window.		
	this.setInspectorConfig([
		{name:"buttonText",value:thisPtr.buttonText,label:"Button Text",type:"string",input:"textarea"}
	]);	
	
	//save the values returned by the inspector- returned in form {valueName:value...}
	//called after the inspector window is saved
	//define this to receive returned inspector values.
	this.saveInspectorValues=function(vals) {
		
		//update the local properties
		for(var x in vals)
			thisPtr[x]=vals[x];
			
		//update the arg str-  contains the original argument string the object was created with. this property is what gets serialized.
		this.args=""+vals["buttonText"];

		//let the browser rendering engine redraw the button when we change the label text.
		this.controller.objResizeControl.clearSize(); //clear out width/height assigned to style.
		this.displayElement.value=vals["buttonText"]; change the button value.
		this.controller.objResizeControl.resetSize(); //calculate the redrawn size and set style size properties to that.
			
	}	

	//pass the UI html to view constructor. use createElID method to create a unique id for each instance.
	this.ui=new LilyObjectView(this,"<input style=\"height:22px;margin:0px\" value=\""+ this.args +"\" id=\""+ this.createElID("hellobutton") +"\" type=\"button\"/>");
	
	//insert it in the patch DOM
	this.ui.draw();

	//click event handler
	function clickFunc()	{
		thisPtr.outlet1.doOutlet("hello world"); //output "hello world" on click.
	}

	//add an click event listener- only listens while when the patch is locked.
	this.controller.attachObserver(this.createElID("hellobutton"),"click",clickFunc,"performance");

	//setting the button element to this.displayElement enables it to be affected by Color/Font menus.
	this.displayElement=thisPtr.ui.getElByID(thisPtr.createElID("hellobutton"));

	//setting the button element to this.resizeElement enables it to be resized with rest of the object.
	this.resizeElement=thisPtr.ui.getElByID(thisPtr.createElID("button"));
	
	return this;
}

//meta data module- required. the module name should take the form "$"+ classname/filename +"MetaData"
var $hellobuttonMetaData = {
	textName:"hellobutton", //the name as it will appear to the user- can be different from the filename/classname
	htmlName:"hellobutton", //same as above, but valid for an xhtml document with appropriate entity substitutions.
	objectCategory:"Sample", //where to file, need not be an existing category
	objectSummary:"Outputs hello world on receiving a click.", //one sentence description for help system
	objectArguments:"Label text" //also for help- object argument list if any, otherwise empty.
}

Personal tools