"Something cannot emerge from nothing." - Frank Herbert
More and more gadgets, especially in the Web 2.0 era, have to communicate with the online world to provide fresh data and interactivity between users. But at the same time, unlike a web based gadget, a desktop gadget also has to know what to do when the user is offline.
First of all, we have to realise that gadgets can do a lot of things while online, like fetching news, feeds or images and interacting with other users of the same gadget. So, depending on what we use the gadget for, there are several ways to see if the computer is online or offline:
framework.system.network.online can be used for general purposes; it returns a boolean value (true or false);
function isNetworkOnline() {
return framework.system.network.online;
}
googleTalk.talk_status property. It can return 3 values: gddTalkStatusNotRunning (Google Talk is not running; maybe it's not installed), gddTalkStatusDisconnected (Google Talk is running but disconnected; there might be no Internet connection) and gddTalkStatusConnected; these values are actually 3 integers: 0, 1 and 2. As an example, you can see below how i used this property to take proper actions in Cupid's gadget:
function refresh(){
//...
//check if Google Talk is not running or not installed
if (googleTalk.talk_status==gddTalkStatusNotRunning) {
NoFriendsOnline();
ShowMessage(1);
return 0;
}
//check if Google Talk is running but not connected
if (googleTalk.talk_status==gddTalkStatusDisconnected) {
NoFriendsOnline();
ShowMessage(2);
return 0;
}
//notice how the function will stop when a return will be executed
//therefore it will get here only when Google Talk is connected
Bookmark.visible=true;
ShowMessage(0);
}
More about offline and online detection can be found in JAMES' ARTICLE (NEED LINK).
Ultimately, the user has to see what's going on, but the changes in the interface should be suggestive - as you can see in Figure 1, the most important UI element (big red heart), which would also have no use if Google Talk wasn't running, is replaced by an appropriate message.

Notice how the gadget neither pops out an error which requires immediate attention, nore gives a message like "Error 235: Connection not found" :) Instead it focuses on guiding the user to make the most out of this gadget. Considering the features you're implementing, you can go further by applying diferent modes to the interface (much like it is described in this article), so, for example, when the user goes offline, the gadget will discard the visual space taken by the online functionality.
You've made a gadget that gets news, or latest posts in a feed, or just parses a big XML file. It has to fetch the items on open and after that periodically to keep the data fresh. But what if the next time our gadget will be opened there won't be an internet connection? The best solution is remembering the item array using options. But going even further with the worst case scenario, another question comes to mind: how can i efficiently remember object arrays in the options dictionary? Fortunately there is a solution to this too, and it doesn't involve remembering the entries separately, but all in one string. For this, you can use JSON, a cool data-interchange format. Basically it helps you convert an object (including an array) into a string and back again.
A good example of array memorising is in the Tabbed ToDo List LINK NEEDED gadget. You can see exactly what functions to call for the both-way conversion (array to string and string to array). The tasks, tabs and checkbox values are succesively memorized and recreated using JSON.
function change(){
//memorizes the new todolist
options("todoList")=todoList.toJSONString();
options("tabs")=tabs.toJSONString();
options("values")=values.toJSONString();
//todoList, tabs and values are all arrays
}
function show(){
//shows the remembered todo list
todoList=options("todoList").parseJSON();
values=options("values").parseJSON();
tabs=options("tabs").parseJSON();
//...
}
These functions are defined in a .js script file downloadable at the JSON site. That script has to be included in your main.xml file just as you include main.js.
We've seen how to optimize gadget behaviour accross sessions, but we can't forget about the CPU and memory usage which always have to be very efficient.
Where the CPU is concerned, a specific process that often occurs in programming a gadget is sorting an array. Depending on the array dimensions you choose one of the sorting methods that best suite your case. The sorting is mostly necessary because you always want the user to be presented with items of interest (unchecked tasks in a to-do list, unread items in a news feed, etc.). In such cases don't forget about the Ranking API, which sorts items based on various criteria like number of clicks, publishing time or others. So when you'll use this ranking engine, you won't have to write the actual sorting, but just choose some filters.
But of course the most expensive activity in terms in CPU is one that is repeated periodically. The Javascript methods setInterval and setTimeout are widely used, but they have to used carefully. For example, infinite call cycles should be avoided and timers should be destroyed when they're not used - it's action doesn't necessarily have to be done if it isn't useful.
function myFunction(){
alert("Alert");
}
token=setInterval("myFunction()",10000);
//this timer will call myFunction once every 10 seconds
//when the timer isn't needed it should be deleted
//we can do this using the token returned by setInterval
clearInterval(token);
//you can also delete a timeout, using clearTimeout
You can find out more about these functions, including some that can be particularly helpful when animations are created, by checking out the documentation for the view object.
Similar safeguards should be used to optimize memory usage as well. Declaring variables locally, in functions, is usually better then keeping them global (of course, sometimes that can't be avoided :). Objects should also be deleted or made void if they aren't used anymore. A good example are audioclips. Once they have been played, their variables should be set to null if they are of no more use.
Every environment has it's own rules, workarounds, safeguards and best practices. It's important to know them and to apply them when needed, to create the best application possible.
Many gadgets, everyone!
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 most popular gadgets are DigiWatch and TV Set.