Skip Navigation Links / Posts / Posts By Category

Posts for Category: Sidebar Gadgets

Feed for this Category
World Cup Cricket - Google Search Ranking

I just noticed that my little World Cup Cricket Gadget now appears on the first page of Google results for the term "World Cup Cricket":

http://www.google.com/search?hl=en&rls=com.microsoft%3A*&q=World+Cup+Cricket

Cool! smile_regular  In other good news, downloads have finally topped the 100 mark as represented by the following daily download graph:

And as we can see in the following chart, downloads from Australian users total the most at 34, closely followed with downloads by users from India (23) and the Americas (20):

Lastly I thought that I'd show the UI of the Gadget that is displayed for a match in progress. In the following picture we can see that India are playing Sri Lanka.  From the text at the bottom of the gadget we can deduce that Sri Lanka must have batted first and that India now require 228 runs at 5.36 runs per over to win.  Originally I had hoped to have a detailed view - to see match scores and stuff - but given the short timeframe in getting this gadget up and running there just wasn't the scope to get that feature written.

I've also noticed that all of this extra attention - both through the World Cup Cricket Gadget and My Book - hasn't done my blog subscriptions any harm as the subscription count now stands at over 300! smile_nerd

posted on 3/24/2007 5:55:38 AM ( 0 Comments )


Things are hotting up in the World Cup

The round of 8 starts this weekend and Saturday (West Indies time) will see a battle between the top two teams Australia and South Africa.  So far we've seen some huge wins by the top teams versus some of the cricketing minnows; we've also seen some massive upsets - including the Scottish victory over Pakistan!  Added to that they are now treating the sudden death of Pakistan's cricket coach - Bob Woolmer - as suspicious.

Anyways, my little Cricket World Cup Gadget is still chugging away with another dozen or so downloads since my post yesterday:

The biggest downloaders so far have been the Aussies, followed by the cricket mad Indians, then followed by "The Americas" - what happened to those crazy Kiwis?  Have they already accepted that they cannot win? smile_omg  Here's the overall download graph by country:

One thing that has surprised me is that I haven't had a single comment or feature request email so far... woohoo! smile_regular  Regardless, I think that I'll sit back and wait for the Sri Lanka v Bangladesh game tonight.  It should be interesting.

posted on 3/21/2007 9:30:12 PM ( 1 Comments )


World Cup Cricket Gadget - Small download increase

Downloads of my World Cup Cricket Gadget slowed over the weekend but have increased slightly on Monday and Tuesday so far.  Today I thought that I'd show the "View" that is presented to the user for a completed game:

In that picture you can see that you are presented with the information about the result of the match, including who was named man of the match.  The following graphs provide some insights into the 62 downloads that have occurred so far:

 

Download By Country:

Download By Date:

posted on 3/20/2007 6:16:29 PM ( 0 Comments )


World Cup Cricket Gadget - Progress Report

OK, so I'm back in Australia and wanted to provide a little status report on the progress of my World Cup Cricket Gadget.

The Gadget itself allows you select a game from a list and display the details of that game.  The list looks like so:

As you can see, the list is divided into 3 groups: Current, Future, and Completed.  Selecting a Completed game will display the result for that game.  Selecting a Current Game will display a progress score if that game has started.

The gadget hasn't exactly set the world on fire.  In the 4 days that it's been online here are the download stats on a per country basis:

 

On a per-day basis the download figures look like this:

 

posted on 3/19/2007 10:58:02 PM ( 0 Comments )


The World Cup Cricket Gadget - CTP Edition

In my world - the world of .NET development - there has been an increasing trend to release CTP (Community Tech Preview) branded software.  In releasing software early, Microsoft can get software out early to users while not increasing the user expectation to the point where they will cop too much flack that the product is not yet complete.  In the same tone I bring you the World Cup Cricket Gadget (CTP Edition).

To get the gadget I simply ask that you select your country before I present you with the link to your gadget.  Over the next month I'll attempt to provide some statistics about where the Gadget is being used and how many downloads I get.  It will be fairly primative but interesting nontheless.

Let's get one thing straight upfront - there are some pretty significant improvements which can be made to the gadget.  People asked and I have delivered.  If you play nicely and be patient, then I'll take the time to produce richer versions when I get back to Australia on Sunday.  Because of the demand I really wanted to get this release out before my flight from Seattle to Sydney tomorrow.  This version really just allows you to:

  • See what games are coming up
  • View scores and man-of-the-match information about completed games
  • View constantly updating scores of matches in progress

Things that I can forsee coming in the next couple of releases:

  • 1-click install - no need to save as a .zip and rename to .gadget, simply click and install
  • richer information about upcoming games
  • more information about in-progress and completed games

So keep your eyes on my blog and I'll announce it as I release enhancements.

Cheers!

posted on 3/16/2007 4:47:11 PM ( 0 Comments )


World Cup Gadget

This week I've had received quite a few emails and comments on my blog from people all over the world asking me to release a Sidebar Gadget to display scores from the Cricket World Cup.  The catalyst for these requests was a post that I did about a cricket gadget a little while back:

My little Cricket Gadget

I'm still in Seattle until tomorrow but I'll try to write one today and release it before my flight back to Australia tomorrow.  I'll post a new blog entry if and when I have it ready.

posted on 3/16/2007 12:25:08 AM ( 0 Comments )


Code Camp Oz 2007 Countdown Sidebar Gadget

Mitch has put out a Code Camp Oz sidebar gadget: 

Link to Code Camp Oz 2007 Sidebar Gadget « notgartner

It's a simple countdown gadget based off of the codebase of the Vista countdown gadget.  I'm hoping that we'll also see much more detailed gadgets for Code Camp.  Some ideas include a "Session roster" gadget and an "Attendee interviews" gadget. 

I think that it would also be cool to have a "fun and geeky" gadget that could get (virtually) passed around at Code Camp.   I'm thinking of a gadget that allows attendees to "collaborate" in some way - it would be an interesting use of gadgets to "connect" people during a major event.

posted on 1/1/2007 9:27:21 AM ( 0 Comments )


How to build a Vista Sidebar Gadget with a Flyout Window

This article discusses how to create a Vista Sidebar Gadget using a technique called "screen scraping" to fetch data from an external web page.  I'm not sure what the actual protocols are for using data from another site but at the very least I think that you should first gain the permission of the owner of the web page before doing so.  If you would like to learn more about screen scraping then this Wikipedia article is a great place to start: Screen Scraping article on Wikipedia.

 

The code that accompanies this article can be downloaded from here.

 

Getting Started

To get things started create a folder named ScraperGadget and add the following things into it:

  1. An HTML file named ScraperGadget.html
  2. An HTML file named Flyout.html
  3. An XML manifest file named Gadget.xml
  4. A JavaScript file named Main.js
  5. A CSS file named Main.css
  6. A CSS file named Flyout.css
  7. Create a folder named "Images" and add an icon for yourself and one for the gadget. 

In my images folder I have the following images for my icons:

Scraper Gadget images

Adding a Manifest

Open the Gadget.xml file and add the following content for your manifest definition:

<?xml version="1.0" encoding="utf-8"?>
<gadget>
    <name>Dilbert Homepage Scraper Gadget</name>
    <namespace>MarkItUp.Gadgets</namespace>
    <version>1.0</version>
    <author name="Darren Neimke">
        <info url="http://MarkItUp.com" />
        <logo src="images/MarkItUpIcon.jpg"/>
    </author>
    <copyright>MarkItUp.com 2006</copyright>
    <description>
        A Gadget allows a user to display content from the Dilbert home page
        which is located here: http://dilbertblog.typepad.com/.
    </description>
    <icons>
        <icon height="48" width="48" src="images/scraper.jpg"/>
    </icons>
    <hosts>
        <host name="sidebar">
            <base type="HTML" apiVersion="1.0.0" src="scrapergadget.html"/>
            <permissions>Full</permissions>
            <platform minPlatformVersion="1.0"/>
            <defaultImage src="images/scraper.jpg"/>
        </host>
    </hosts>
</gadget>

 To learn more about the makeup of a Gadget manifest file, view the following MSDN article:

http://msdn2.microsoft.com/en-us/library/aa965879.aspx

Defining the HTML User Interface

Finally, add some HTML into the ScraperGadget.html file to get things started:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <title>Dilbert Homepage Scraper Gadget - Main</title>
        <script src="main.js" language="javascript" type="text/javascript"></script>
        <link href="main.css" rel="stylesheet" type="text/css" />
    </head>
    <body onload="initializeMain();">
        <ul id="myList"></ul>
        <div id="errorView"></div>
    </body>
</html>

That's all that we need at this stage for the main view of our gadget which will ultimately display a list of the titles of the posts on the main page of the Dilbert website.  You can see how the gadget has a reference to both the main.js file and also the main.css file and if you take a look at the body tag, you can see that we call a function named initializeMain() to get things rolling.

A pinch of CSS

To make our gadget look a little nice we can add some CSS code to spice up the UL and LI elements and alter the default font sizes to get more text into our small viewing space.  Here is the code for Main.css:

body {
    margin: 4px;
    width: 130px;
    height: 245px;
    font: 9pt Calibri;
    color: #000;
    background-color:#cccccc;
}

a {
    color: #ffffff;
    text-decoration: none;
    text-overflow:ellipsis;
}

a:hover {
    color: red;
    text-decoration: underline;
}

ul {
    width: 90%;
    border: 1px solid #000;
    background-color: #8aa;
    padding: 0px 5px ;
    cursor: default;
    margin-left: 0px;
}

ul li {
    list-style-type: none;
    margin: 0px;
    position: relative;
}

ul li:hover {
background-color: #ffa;
color: #000;
}

 

The Javascript behavior code

The initializeMain function is responsible for grabbing the source of the page that we are scraping, breaking it down into an object model, and then displaying elements of that object model onto the page.  Here is the content of the initializeMain function:

 

function initializeMain() {
    try {
        var scraper = new WebScraper() ;
        gPageString = scraper.Scrape(gURL) ;
        parseDocument() ;
        renderDocument() ;
    } catch ( ex ) {
        displayError( ex.message ) ;
    }
}

There's some error handling and other stuff in there but it's mostly just fetching data and formatting it on the page.  You can learn about the underlying screen scraping code by reading the following article and by downloading the source files for this article and going through them:

http://markitup.com/Posts/Post.aspx?postId=96d2941f-591f-4363-b5a5-0535ef710f1b

One interesting thing about the parsing of the HTML is that we break it down into an object model before we display it - this makes the data much simpler to work with when the gadget is running.  Here's the code for the Article data class that we store each article's data in:

function Article(title, body, index) {
    this.Title = title ;
    this.Body = body ;
    this.Index = index ;
}

Each instance of this class will have a Title, Body, and Index property that we can access when we want to use the data.  In the parseDocument function we actually grab each article from the page, create an Article object for each one, and store the whole lot of them in a globally-scoped Array so that we can use and access the data on-demand quite easily.  The code for the parseDocument function is shown here:

function parseDocument() {
    var titlePattern = "<h3 class=\"entry-header\">(([^<]|.)+?)</h3>" ;
    var bodyPattern = "<div class=\"entry-body\">(([^<]|.)+?)</div>" ;
    var matches = new RegexHelper().Matches( gPageString, titlePattern ) ;

    var titles = new Array() ;
    for( i=0; i<matches.length; i++ ) {
        titles[i] = matches[i].Groups[0] ;
    }

    matches = new RegexHelper().Matches( gPageString, bodyPattern ) ;
    for( i=0; i<matches.length; i++ ) {
        var body = matches[i].Groups[0] ;
        var article = new Article(titles[i], body, i) ;
        gArticles[i] = article ;
    }
}

Once we have our array (gArticles) of Article objects, all that remains is to render a list of their titles in our gadget - this task is performed by the renderDocument function:

function renderDocument() {

    for( i=0; i<gArticles.length; i++ ) {
        var article = gArticles[i] ;
        var text = document.createTextNode(article.Title);
        var e = document.createElement("li");
        var a = document.createElement("a");
        a.dataIndex = article.Index; // custom prop

        a.attachEvent('onclick', handleClick);

        a.appendChild(text);
        e.appendChild(a);
        myList.appendChild(e);
    }
}

It's important to highlight that the way that this code wires up the handleClick event hander is not by any means cross-browser compatible, but it's running in the gadget runtime which is the same as IE so that's not important.  The handleClick event handler is a simple function that will be invoked whenever the user clicks on a title and will display the content in a gadget Flyout window.  For now simply add the following code for handleClick function in the main.js file and we'll test our gadget:

function handleClick(event){
    var selectedIndex = event.srcElement.dataIndex ;
    errorView.innerHTML = "You clicked on article " + selectedIndex ;
}

As you can see, this code will simply display the index of the article that was clicked on in our errorView DIV element.

An Initial Test of our Gadget

The simplest way to test the gadget is to open the ScraperGadget.html file in a browser to check that everything runs OK.  Running the page and clicking on an article heading show give you a result similar to this:

Scraper Gadget in browser

Once you've got it working in the browser it's time to package up the gadget and get it running in the Vista Sidebar.  Open the ScraperGadget folder and create a .zip file of all the contents.  When the .zip package is created, rename it to ScraperGadget.gadget (NOTE the .gadget extension!).  Upon renaming to a .gadget file, the icon should change to indicate that the package is now a gadget package.  Double-click on this file to begin the installation.

ScraperGadget gadget file

Double-click on the gadget and press 'Install' when asked.  After doing that the gadget should now appear in the Sidebar like so:

ScraperGadget gadget file

The Dilbert screen scraping gadget is displayed at the head of the list here - just above my custom Cricket Gadgetsmile_regular  If you open the Sidebar gallery (by pressing the + icon at the top of the Sidebar, you will see how the gadget has used the data in the manifest file to display information about itself:

ScraperGadget in gadget gallery

 

Adding the Flyout code

Now we've tested out gadget and can see that the important bits are all working as they should be.  We've rendered the UI for the default view and have our object model stored nicely in memory.  It's time to open that Flyout.html file and get started with creating the flyout behavior.  When we've finished we'll have a flyout that will display the stories behind those headlines, here's a peek at the finished product:

ScraperGadget with flyout

 The behaviour here is similar to the RSS Gadget that comes as a standard gadget with Windows Vista.  In the picture you can see that the user has clicked on the first article in the list and this has then displayed the entire post content in the flyout window.  The title of article is displayed at the top of the flyout and the body of the article is displayed in a scrollable DIV element.  If the user clicks on the same article title in the list, the flyout will close but if they click on another title then its content will be displayed in the flyout.

Just as with the main window, the HTML for the flyout is dirt simple:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <title>Dilbert Homepage Scraper Gadget - Main</title>
        <script src="main.js" language="javascript" type="text/javascript"></script>
        <link href="flyout.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <div id="flyoutBackground">
            <h4 id="title"></h4>
            <div id="bodyContent"></div>
        </div>
    </body>
</html>

You can find the CSS for those elements in the download for this article.

Loading the Flyout Window

It's now time to revisit that handleClick function which receives the clicks from the links in the list and add the code for displaying the Flyout.

var gSelectedIndex = -1 ;

function handleClick(event) {
    var idx = event.srcElement.dataIndex ;

    if( idx == gSelectedIndex ) {
        gSelectedIndex = -1 ;
        System.Gadget.Flyout.show = false ;
    }else{
        gSelectedIndex = idx ;
        if(System.Gadget.Flyout.show) {
            addContentToFlyout();
        } else {
            System.Gadget.Flyout.show = true;
            System.Gadget.Flyout.onShow = function() {
                addContentToFlyout();
            }

            System.Gadget.Flyout.onHide = function() {
                gSelectedIndex = -1 ;
            }
        }
    }
}

Here we can see that the handleClick function gets the index of the link that was clicked and compares it against the previously clicked item in the list; if it's the same as the previous selection then we reset the selected index and hide the flyout.  If the index is different to the previously selected one we check to see whether the flyout window is open and then load the content into it with our addContentToFlyout function.  You can also see that whenever the flyout is shown we wire up event handlers for the onShow and onHide events.

Finally, the code for adding content to the flyout is dirt simple:

function addContentToFlyout() {
    try {
        if(System.Gadget.Flyout.show) {
            var flyoutDoc = System.Gadget.Flyout.document;
            var article = gArticles[gSelectedIndex] ;
            flyoutDoc.getElementById("title").innerHTML = article.Title ;
            flyoutDoc.getElementById("bodyContent").innerHTML = article.Body ;
        }
    } catch ( ex ) {
        displayError( ex.message ) ;
    }
}

We simply get a handle to the document in the Flyout window, grab the current article object from our list of articles and then bind the Title and Body properties of that object to some HTML elements in the window.

I encourage you to download the code that accompanies this article and to play around with customizing it for your own purposes.

posted on 12/30/2006 4:33:00 PM ( 24 Comments )


Letter to the ABC - please give us a Cricket Gadget

I sent the following email to the ABC this morning:

To ABC Sports Online, my name is Darren Neimke and I work for an Australian IT company called Readify. I’m an avid follower of your cricket broadcasts and regularly visit your cricket scorecard pages to get score updates. I’ve seen that you have a Konfabulator cricket desktop widget for getting the scores directly on your desktop but I wondered whether you have plans to create a Vista Sidebar Gadget? Sidebar Gadgets are similar to Konfabulator widgets except for the important distinction that Vista Sidebar comes as a standard component of Windows Vista – meaning that *everyone* who has Windows Vista will have it installed. This will mean that the reach of Vista Sidebar Gadgets will be significantly greater than Konfabulator widgets.

Here’s a brief overview of how Vista Sidebar Gadgets work. When you add a Vista Sidebar Gadget to the Windows Vista Sidebar, it appears in its normal state. Here’s a picture of my desktop with 3 gadgets displayed in their default docked state – a Notes Gadget, a Flickr Calendar Gadget, and a Virtual Earth mapping Gadget:

GadgetsStandard.PNG

When you hover over a Gadget, a settings selector appears which allows you to display the Settings window for the gadget. Here the settings window for my Notes Gadget is displayed allowing me to change the colour and the font settings of my notes:

GadgetSettings.PNG

You can also add a Flyout feature for displaying detailed information from your Gadget. Here the detailed Flyout is displayed for my Virtual Earth gadget:

GadgetFlyout.PNG

I was thinking that we could do something similar for a cricket gadget and use the Settings view to allow the user to select different cricket games to view and use the Flyout for displaying detailed scorecard views. Here is a conceptual view of how I would see an ABC Cricket Vista Sidebar Gadget:

CricketGadget.PNG

If you would like some advice about creating Vista Sidebar Gadgets I would love to help out – heck, I’d even create it for you free of charge smile_regular

I look forward to hearing from you in the near future.

Regards,

Darren Neimke
Readify - Resource Manager 

Suite 206 Nolan Tower | 29 Rakaia Way | Docklands | VIC 3008 | Australia
M: +61 439 855 046 | E: darren.neimke@readify.net | C: darren.neimke@readify.net | W: www.readify.net

posted on 12/28/2006 9:33:29 AM ( 2 Comments )


Creating interesting Gadgets - Getting data from a web service

If you are building a Sidebar Gadget you will nearly always need to get your hands on data of some type.  Some of the common data types that you will want to access are:

  • RSS Feeds from the web
  • RSS Feedstore
  • Web Services
  • Mail and Calendar data
  • Messenger Contacts
  • File and Folder information
  • Other LOB data

In this article I'm going to show how to get data from a web service.  Here's a web part that accesses the ProjectDistributor web services and uses the ListProjectsByLatest method to return a list of recently added projects:

PD Recent Projects Gadget

 

When accessing a web service you can either use a GET method or a POST method to make the web service call.  The simpler of these is a GET as you can simply use a URL with the arguments contained in the querystring to call the web service, here's the GET URL for the ListProjectsByLatest web method:

http://projectdistributor.net/WebServices/ProjectDistributor.asmx/ListProjectsByLatest?countOfItems=5

You can see that this method takes an argument named countOfItems which it uses to determine how many items to return - in this case I am returning 5 items.  By default, ASP.NET web services are configured to deny GET access and so if you are planning to make a GET call, you will need to add the following configuration entry in the web.config file for the applicaiton that is hosting the web service:

<webServices>
    <protocols>
        <add name="HttpGet"/>
    </protocols>
</webServices>

The next thing to do is to write some Javascript code that will call the web service and get the XML contained in the web service response so that we can begin working with that data.

function loadData() {
    gXMLHttp=null ;
    if (window.XMLHttpRequest) {
        gXMLHttp = new XMLHttpRequest()
    } else if (window.ActiveXObject) {
        gXMLHttp = new ActiveXObject("Microsoft.XMLHTTP")
    }

    if (gXMLHttp!=null) {
        gXMLHttp.onreadystatechange = state_Change
        gXMLHttp.open("GET", gWsUrl, true)
        gXMLHttp.send(null)
    } else {
        alert("Could not get an XMLHTTP instance.")
    }
}

function state_Change() {
    var xmlDoc = null ;
    if (gXMLHttp.readyState==4 && gXMLHttp.status==200) {
        xmlDoc = new ActiveXObject("Microsoft.XMLDom");
        xmlDoc.async="false"
        xmlDoc.loadXML(gXMLHttp.responseText);
        processData(xmlDoc);
    }
    xmlDoc = null ;
}

Here we see that an XMLHTTP instance is created and a event handler method named state_Change is wired up to the onreadystatechange event of that object.  When the web service call returns the state_Change method will be called and the readyState for XMLHTTP will be 4 and the status will be 200 (OK).  Once we have that return call we create an XML document instance and load the responseText of the XMLHTTP response into it using hte loadXML method of the XMLDom instance.  Finally, once we have our XML document we pass that instance off to a method that will create our UI - in this case the method is named processData.

The processData method will use XML DOM methods to grab the data from the XML document and then use string concatenation to embed the values into some user interface elements.  The following code displays the processData logic which loops through the nodes in the XML document and renders Project elements as a list of HTML DIV elements with a clickable project name:

function processData(doc) {
    var projects = doc.documentElement.selectNodes("//Project");
    projectItemHolder.innerHTML = "" ;
    var node = null ;
    gBuilder = new Array();

    for (var i=0; i<Math.min(projects.length, 5); i++) {
        buildProjectDiv(projects[i]) ;
    }

    projectItemHolder.innerHTML = gBuilder.join("");
    node = null ;
    projects = null ;
    gBuilder = null ;
}

function buildProjectDiv(node) {
    var idNode = node.selectSingleNode("Id") ;
    var displayNameNode = node.selectSingleNode("DisplayName") ;
    var purposeNode = node.selectSingleNode("PrimaryPurpose") ;
    var dateCreatedNode = node.selectSingleNode("DateCreated") ;

    var id = idNode.childNodes[0].nodeValue ;
    var projectName = displayNameNode.childNodes[0].nodeValue ;
    var purpose = purposeNode.childNodes[0].nodeValue ;
    var dateCreated = dateCreatedNode.childNodes[0].nodeValue.substr(0, 10) ;

    gBuilder.push("<div id=\"") ;
    gBuilder.push(id) ;
    gBuilder.push("\" class=\"ProjectItem\">") ;
    gBuilder.push(" <a class=\"ProjectItemLink\" href=\"http://projectdistributor.net/Projects/Project.aspx?projectId=") ;
    gBuilder.push(id) ;
    gBuilder.push("\" title=\"") ;
    gBuilder.push(projectName) ;
    gBuilder.push("\" onmouseover=\"toggleBack(this.parentElement, true);\" onmouseout=\"toggleBack(this.parentElement, false);\">") ;
    gBuilder.push(projectName) ;
    gBuilder.push("</a><div class=\"ProjectItemName\" style=\"float:left;text-align:left;\">") ;
    gBuilder.push(purpose) ;
    gBuilder.push("</div><div class=\"ProjectItemDate\" style=\"float:right;\">") ;
    gBuilder.push(dateCreated) ;
    gBuilder.push("</div></div>") ;
}

 As you can see, the processData method calls out to a helper method named buildProjectDiv which extracts the values from each XMLNode and places those values into a UI display.

posted on 12/20/2006 2:48:46 PM ( 21 Comments )


Creating interesting Gadgets - User Interface Elements

Vista Sidebar Gadgets are changing the way that we consume data.  Over the next few weeks I will be looking at some of the interesting behaviors that you can add to your gadgets to make them interesting and I'll be using different Gadgets that I find on MicrosoftGadgets.com to highlight various features along the way.  To get things started I'd like to talk about the various UI elements that you can use to present information to your users.

The default view

Below is an image of one of the core Windows Vista Gadgets (a gadget that ships with the core Vista operating system and therefore is located in your C:\Program Files\Windows Sidebar\Gadgets folder), the Notes Gadget.  Here we see the Notes Gadget in its standard docked state in the Sidebar:

Notes Gadget docked in Sidebar

 

This UI is a simple HTML file which displays an image as its default background that gives it an appearance of a stack of notes.  The default view (HTML file) for a Gadget is a configuration setting in the XML manifest file of the Gadget:

 

<gadget>
    <hosts>
        <host name="sidebar">
            <base type="HTML" apiVersion="1.0.0" src="TestGadget.html" />
        </host>
    </hosts>
</gadget>

 

Customizable Gadgets 

The Notes Gadget provides the user with the option of creating new notes or deleting an existing notes and they perform those interactions by mouse'ing over the Gadget and having additional UI elements displayed.  Here we see the additional UI elements that appear when we mouseover the Notes Gadget:

Mouseover the Notes Gadget displays additional UI options

The elements on the upper-left side of the Gadget are added by the Vista Gadget system and allow the user to perform different actions.  The [x] icon is standard for all Gadgets and allows the user to remove the Gadget from the Sidebar.  Underneath that we have a spanner icon that allows the user to manage the settings of the Gadget, this icon is only present when an HTML file has been associated with the System.Gadget.settingsUI property.  Setting this is done at runtime like so:

System.Gadget.settingsUI = "settings.html"

With the settingsUI property assigned, the Gadget will display the spanner and when the user clicks on that, the contents of the settings.html file will be displayed to allow the user to make configuration changes to their Gadget.

Settings UI displayed for the Notes Gadget

 

Here the settings UI for the Notes Gadget allows the user to choose their note color and change their font settings.  When the user has made their choices and pressed OK, the Gadget would use the Gadget.Settings API to persist that configuration information.  Reading and writing configuration settings is as simple as this:

 

var settingValue = System.Gadget.Settings.readString("SettingName");   // reading

System.Gadget.Settings.writeString("SettingName", mytextbox.value);  // writing

It's important to note that the Settings.html file in the above image did not contain the Title bar with the text "Notes" and nor did it contain the OK or Cancel buttons as these were all provided by the Gadget runtime.  The Title bar text was read by the runtime from the title that is supplied in the Gadget's manifest file.

Providing a detailed view

Another useful UI feature of Gadgets are Flyout's.  Flyout's are used when your Gadget contains some summary information and you want to allow the user to click on that summary data to see a more detailed view of that data.  One of the standard Gadget's which makes use of Flyout's is the Feed Headlines Gadget (another of the standard Vista Sidebar Gadgets).  By default the Feed Headlines Gadget displays a summary of recent feed items in a list.

The Feeds Summary Gadget

 

The user can then click on an item in the list to display a detailed view of that item.  Clicking on the item displays the following Flyout with the detailed content for the RSS item displayed:

 

The Feeds Summary Gadget with Flyout information displayed

 

Again, the Flyout is simply another HTML page which you set on the file property Flyout object.   When it comes time to display the Flyout you simply set the value of the show property of the Flyout to 'true':

System.Gadget.Flyout.file = "flyout.html"

System.Gadget.Flyout.show = true;

As with the Configuration Settings view, the Title bar and surrounding chrome for the Flyout view are provided by the Gadget infrastructure.  To populate data into the Flyout window the Feed Headlines Gadget makes use of the onShow event of the Flyout object to determine when the Flyout is available and then the document property of the Flyout to gain access to the DOM of the HTML document for the flyout view:

System.Gadget.Flyout.onShow = function() {
    addContentToFlyout();
}

function addContentToFlyout() {
    if(System.Gadget.Flyout.show) {
        var flyoutDiv = System.Gadget.Flyout.document;
        flyoutDiv.getElementById("flyoutTitleLink").innerHTML = tempTitle;
        flyoutDiv.getElementById("flyoutTitleLink").href = g_feedURL;

        ....
    }
}

posted on 12/19/2006 11:08:21 PM ( 0 Comments )