Using Parameters in Gadget Programming

Teodor Filimon, Gadget Developer
June 2008
"The early bird catches the worm."

Introduction

Changes often occur in a program so we have to make sure that it will accept them without hurting the structure upon which it was built. It pays to plan ahead and apply a few tricks, at least to save the time and the headache :-)

Physical Location of Parameters

First of all, the whole idea of isolating parameters is making them easy to find and change, so the best way for us to keep then within a gadget is a separate .js file. Therefore, among the script files you already use, you'll also have a parameters.js file.

Parameters script file
Figure 1: Example of a parameters file

Being a script file, it can be included in main.xml just like the main.js file for example, like this:

<script src="parameters.js" />

Next we'll see how we can actually create and use the parameters, as well as store them across sessions because, depending on the situation, the user may have access to some of them and could change them at will.

Creation of an Object Encapsulating Parameters

What we need to do is to define a type of an object which can help us handle parameters. Let's call it ParametersObject. This type of object (class) will have our desired parameters as properties. We can also instantiate this class into the very object we'll use, and which we'll call, for the sake of clarity, parameters. This way we completely separate the creation from the actual usage. You will find what i used in the Web TV & Radio gadget below (not all gadgets will have so many parameters, but it just goes to show you the variety of problems parameters can take care of):

parameters=new ParametersObject();

function ParametersObject(){ //an object which encapsulates some parameters

	//default size
	this.defaultGadgetWidth=345;
	this.defaultGadgetHeight=254;

	//an empty space in the lateral parts of the gadget which makes it look good relative to other gadgets
	this.lateralEmptySpace=3;

	//minimum size
	this.minWidth=256+2*this.lateralEmptySpace;
	this.minHeight=190;

	this.defaultVolume=25; //in percents
	
	//measured in milliseconds, the parameter below says how much to wait on mouse over before displaying the controls (the mouse could be just passing over the gadget)
	this.safeInterfaceDisplayTime=465;

	this.timeToWaitBeforeCheckingForUpdates=3300000; //55 minutes*60 seconds*1000 milliseconds
	//based on ergonomics statistics of how long people will or should stay in front of the computer, could change
	
	//useful for skinning in the future:
	this.maxOpacity=255;
	this.minVisibleOpacity=160;
	
	//opacity step (higher means less CPU is used) - must be a divisor of 'maxOpacity'
	this.opacityStep=17;
	//the parameter above is strongly connected with the next one (a simple delay in milliseconds)
	this.CPUstep=40;

	this.channelUpdateInterval=255; //in minutes (of gadget usage, not computer usage)

	//URLs for files with update info, stats, etc.
	this.WebTvVersionUrl="http://teodorfilimon.com/files/Web-TV-Radio/WebTvRadioVersion.htm";
	this.WebTvWhatsnew="http://teodorfilimon.com/files/Web-TV-Radio/WebTvRadioWhatsnew.htm";
	this.WebTvCentral="http://teodorfilimon.com/files/Web-TV-Radio/WebTvRadioCentral.php";
	this.WebTvWebPage="http://teodorfilimon.com/index_files/Web-TV-Radio-gadget.html";
    
	//highlight UI elements when user enters the 'All Channels' dialog
	this.highlightAllChannelsWindow=true;

	//...
}

Making the object this way even allows us to create multiple configuration presets which can overwrite the active set of parameters, but that's pretty complex and can be the subject of an entirely different conversation. :-) Before this section ends, also notice the importance of comments for each parameter, especially for open-source projects.

Usage

Next you can see a snippet of code from the same gadget, code which shows you how exactly you can reference a parameter; basically, you just have to access the property within the parameters object, like this: parameters.defaultVolume.

function _onOpen(){

    //setting default options
    options.putDefaultValue("width",parameters.defaultGadgetWidth);
    options.putDefaultValue("height",parameters.defaultGadgetHeight);

    //...

    //resizing to last known size
    view.resizeTo(options.getValue("width"),options.getValue("height"));
}

You can see in this example how some default options are set and when they would come into action. With each resize the "width" and "height" entries in options are changed but the default/first size will be the one you set in the parameters.

Custom Flags

Similar to parameters, you can also define your own flags. Notice in Figure 1 that above the parameters.js file there is a flags.js file. :-) Flags are usually just constants that are named in a relevant way to a state of things. For example, in the Web TV & Radio gadget i needed 2 flags. One was called silent and one was called verbose and they established whether the user would be informed of the current update check or not (some may have chosen automatic updates). This is how they were defined:

flags=new FlagsObject();

function FlagsObject(){ //an object which encapsulates some flags
	
	//...

	this.silent=0;
	this.verbose=1;
}

You can see that the flags object is instantiated just the same as the parameters object. Now all that has to be done is a function which can distinguish between these 2 flags (the flag is passed as a parameter to the function):

function compareVersions(flag){
	if (parameters.version==parameters.availableVersion){
		if (flag==flags.verbose){
			//the user will be told he already has the latest version
			alert(strings.LATEST_VERSION);
		}
	} else {
		if (flag==flags.verbose || options.getValue("lastNotifiedVersion")<parameters.availableVersion){
			//a newer version is available
			//so the user will be shown the new features
			//...
		}
	}
}

This way checkForUpdates(flags.silent); will inform the user about the availability of a new version only when it is found. checkForUpdates(flags.verbose); implies that the user has manually triggered an update check and wants a response, which can also be that no updates are available.

Conclusion

As you have seen, there are a lot of uses for parameters, and they can help you on a short term, when testing and debugging, or on a long term, when maintaining and expanding a gadget.

Resources


Author Bio

Teodor Filimon

I'm a natural born programmer. My first contact with a techno-gadget was Star Trek (remember those cool sensors?). I used to fill up a whole room with drawings of them when I was only 3 years old. Generally, I find a lot of inspiration for intuitive interfaces in things with "star" in their names (like Star Wars, Stargate,... :-) . I like the border between interface and function—it's the essence of a program, I think. Anyway, I'm a software engineering student now, and you can learn more about me and what I'm thinking and doing at my website or blog. My best gadgets are Web TV & Radio and DigiWatch.