Previous post: Widget Anatomy – The Manifest
This is part two of my “Widget Anatomy” series which will explain the ins and outs of the Widget Framework that is shipping as part of Windows Mobile 6.5. In this Article we will discuss the major challenges of creating a great user experience that not only looks great, but it integrates nicely with the phone and it’s snappy and fun to use.
The dark side of choice… dealing with screen DPIness
One of the coolest things about the Windows Mobile® ecosystem is that there are many different devices with all shapes and forms for me to pick up the one that matches my lifestyle best. All those choices do have a dark side though, there is a variety of screen resolution/sizes we need to make sure our Widgets work and look great on.
The table bellow shows all the supported Resolution/DPIs Windows Mobile 6.5 supports and as you can see it is a big table.
Thankfully for widget writing, there really are only two options, one that we will call HiDPI (for 192) and then LoDPI for the rest. The reason is that, in practice, a document designed for 96 DPI (Internet Explorer on the desktop at 100%) will look fine on 96 DPI, 131 DPI and 128 DPI but it will look way too small on a 192 DPI screen.
Now that we have reduced the supported DPIs to only two, then the best (and easiest) way to handle this in your widget is as follows:
1) Generate two CSS Style Sheets for your widget. You can call them something like HiDPI.css and LoDPI.css, and the basic rule is, for HiDPI, things should be about twice as big to look the same way as they do on the desktop.
2) Detect the screen resolution at runtime to determine which CSS to load. Here is an example:
1: function applyCSSStyle() {
2: var width = document.documentElement.clientWidth;
3: var cssFile = "css/LoDPI.css";
4: if (width >= 480) {
5: // The document is wider than 480 pixels
6: // it must be a High DPI device
7: cssFile = "css/HiDPI.css";
8: }
9:
10: // Add the correct CSS style sheet to the document
11: var headID = document.getElementsByTagName("head")[0];
12: var cssNode = document.createElement('link');
13: cssNode.type = 'text/css';
14: cssNode.rel = 'stylesheet';
15: cssNode.href = cssFile;
16: cssNode.media = 'screen';
17: headID.appendChild(cssNode);
18: }
19:
20: function onLoad() {
21: applyCSSStyle();
22: }
How to best utilize those SoftKeys
The Widget API gives you full control over the soft key menu bar, but since we want our widgets to behave as native applications do there are a few guidelines we should try follow:
1. The left soft key should always represent the default action and it should be context sensitive to what the user is supposed to do at that particular step in the User Scenario.
2. The right soft key can be either a menu or a button, when there only are two possible actions you should save the user one click and make it a button… that said, if you do this there should be a way for the user to exit the widget somewhere on your UI.
Just as a quick reminder, calling widget.menu.append(menuItem) Adds a menu item to the right SoftKey, if it was a button it will turn into a menu with the non configurable label “Menu”, also, the “Exit” menu item is added automatically and can’t be renamed nor removed. calling widget.menu.setSoftKey(menuItem, widget.menu.rightSoftKeyIndex) removes all menu items from the right SoftKey and turns it into a button.
Best practices
The following are some of the best practices we have found really help greatly widgets be the best they can be:
- When possible, integrate with the phone “skin” by using theme able colors like “highlight” (details)
- Use art assets that match the screen DPINess, or, just provide a high resolution set (shrinking is always better than expanding)
- Minimize scrolling, vertical scrolling is ok on some cases, horizontal scrolling in almost all cases is a general NO NO
- Handle the screen rotation event, remember that this must be fast
- Load fast, generate all dynamic content after the widget is loaded.
- Give visual feedback to all user actions.