Keilly: May 2007

Monday, May 28, 2007

Aqua Button Image Templates


Warning, drawing images takes ages!
Bizarrely writing the code for widgets always seems to be the quickest bit, drawing graphics and wrestling with Dashcode sucks up most of the time.

To help with drawing I followed an online guide to creating Aqua buttons and created long and round versions.
Here are the saved template files for Gimp to save all the bother. It's easy to change size, colour and put an icon inside.

(The icons are deliberately rotated above for maximum shock value when viewing the page, hold your laptop sideways for a more realistic view of what to expect)

Round Template
Long Horizontal Template

Sunday, May 27, 2007

Listen Again v2.0


I've just uploaded a new version of the ListenAgain widget. This version adds the much needed, and much requested, ability to skip forward and back through playing programmes. Rather than fast forward the skip jumps ahead in convenient increments.

Funnily enough the thing that took the longest time was drawing the new image for the control buttons.

Requires RealPlayer

Mac OS X 10.4 Tiger is required. If you're using Safari, click the download link. When the widget download is complete, Show Dashboard, click the Plus sign to display the Widget Bar and click the widget's icon in the Widget Bar to open it. If you're using a browser other than Safari, click the download link. When the widget download is complete, unarchive it and place it in /Library/Widgets/ in your home folder. Show Dashboard, click the Plus sign to display the Widget Bar and click the widget's icon in the Widget Bar to open it.

Troubleshooting: If you cannot play radio streams, and also cannot play streams directly from the BBC web site in Safari then RealPlayer is probbaly not installed or configured properly.

Friday, May 25, 2007

Resizable Background

The better widgets resize. The apple guidelines here do a nice job of describing how to add the resize corner and code, but to get it to look nice at any size is tricky.

By default Dashcode will create a widget with a nice background image that can have rounded corners, gradient fills, and glass effects. This image does not dynamically resize.

One super simple way to get these effects plus enable resizing is to replace the background image with a canvas, and render draw the background on the fly. It's pretty simple. This code will render a black rounded rectangle at any size...


var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

context.clearRect(0, 0, canvas.width, canvas.height);

var x = 0;
var y = 0;
var x1 = window.innerWidth - 20;
var y1 = window.innerHeight - 28;
var round = 10; // The roundness of the corners

context.lineJoin = "round";
context.fillStyle = '#000000'; // background color

context.arc(x1-round,y+round, round, -Math.PI/2,
0, 0);
context.arc(x1-round,y1-round, round, 0,
Math.PI/2, 0);
context.arc(x+round,y1-round, round, Math.PI/2,
Math.PI, 0);
context.arc(x+round,y+round, round, Math.PI,
3*Math.PI/2, 0);

context.fill();
The steps to add this to a widget are

- Replace the background image with a canvas
- Size the canvas component to it's largest possible size
- Call size and the rendering code when the widget is shown.

Sizing is canvas is the tricky thing. Dashboard initializes the canvas drawing area to a fixed size when the component is first created - so sizing the canvas later does not increase the available area for drawing - leading to possible clipping. The workaround is to initially size the canvas as large as your widgets maximum size, and to add some code to resize the canvas down to the desired size after creation - but just before the widget is shown (i.e. call it in function show()).

The canvas is quite powerful at drawing, and nice effects can be quickly achieved with its API. This image of an unreleased widget is all drawn on canvases, with some text and and buttons added..


Take a look at the code of the ZX Spectrum widget for a working example of a widget with a resizable canvas

Tuesday, May 22, 2007

Full Screen Widgets

It is possible to have widgets that can enter a full screen mode. This would be useful for my ZX Spectrum widget where the user might want to quickly step back in time and pretend for a while that their $1000 Macbook is a humble 48K ZX Spectrum.

The only catch is that your useful widget code must be written in Java.

Java has the immensely useful Java full screen mode. The catch here is that an applet by default doesn't have enough permissions to use it. We can work around this by running as a application and starting Java from the command line rather than embedded in a web page. For full screen mode the rendering must be done to the contents of a Frame or Window.
So if you'd like to work in two modes: one as the contents of a small widget area in Dashboard and also as optionally full screen: write your code so it can be started as an applet and as an application.

Invoking full screen is easy ('this' is a JFrame containing our UI):

GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
setUndecorated(true);
gs[0].setFullScreenWindow(this);
setVisible(true);

We also want to exit full screen when the user hits 'Escape', I added this to the JFrame:

protected void processKeyEvent(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
{
System.exit(0);
}
}

To run this from a Dashboard widget, use the widget.system command to run the application. Ensure that 'allow command line access' and 'allow java execution' is turned on in the widget preferences.

widget.system("/usr/bin/java -jar
FullScreenTest.jar fullscreentest.Main", null);

Boom! and that's it.

I've bundled this up into a test widget to demo the experience:

Widget: Full Screen Test
Java source: fullscreentest.Main

Monday, May 21, 2007

Spectrum Version 3

I've completed work on a new version of my ZX Spectrum Widget:


Relive the glory days of the 80’s guiding Miner Willy through the ‘Solar Power Generator’, defeating Doomdark near the ‘Mountains of the Moon’, or just programming your next BASIC masterpiece.

Important upgrade instructions:
The widget update will copy over the game file directory, so if you’ve added new games to an earlier version: Save the game files, then upgrade, then copy the games back.

Download v3

Older Versions are here

New in version 3.0
- Custom resizing - drag the widget to your preferred size, up to 1000x800 (larger sizes require faster machines)
- Basic (10 PRINT "Neil Rules! "; 20 GOTO 10)

New in version 2.2
- Sizing bug fix
- New games

New in version 2.1
- Compact size when not in use

New in version 2.0
- Sound
- .TAP file support
- Faster and smaller emulator
- Kempston joystick support (use arrows and ctrl)

Pull those bedroom curtains even tighter together and ignore your mother calling you for dinner.

Mac OS X 10.4 Tiger is required. If you're using Safari, click the download link. When the widget download is complete, Show Dashboard, click the Plus sign to display the Widget Bar and click the widget's icon in the Widget Bar to open it. If you're using a browser other than Safari, click the download link. When the widget download is complete, unarchive it and place it in /Library/Widgets/ in your home folder. Show Dashboard, click the Plus sign to display the Widget Bar and click the widget's icon in the Widget Bar to open it.

Legal
The widget comes with a few legally provided games (see below).
You can add more games by flipping over the widget, pressing ‘Open Game Snapshot Folder’ and adding your own games to that folder.

Only add files that you are legally allowed to - e.g. In some countries these can be games you have purchased. Copyright laws vary from country to county, so check them if you are unsure.
Don't pirate games!

I believe the owners of the supplied games allow their games to be freely distributed (according to the web-site World of Spectrum). If you are the copyright owner of one of these games and you would like it removed from the widget distribution contact me and I will be happy to remove it.

The widget is based on the Qaop Java emulator - which has it’s own page here

Troubleshooting:
Requires Java v5.0. If you are seeing a red 'X' in the corner, then Java isn't set up correctly. This is most probably fixed by:
- Open Finder
- Navigate to Applications->Utilities->Java->J2SE 5.0
- Open Java Preferences
- Ensure version is set to J2SE 5.0

Monday, May 7, 2007

Widget Resize Bug

Looks like there's a bug in Dashboard where if you resize a widget vertically only the widget gets clipped rather than resized. This is really annoying because once the resize corner itself is clipped out it's no longer possible to get it back and the widget is left permanently in the clipped state. Removing and re-adding is the user's only option.



Here's a hack to the resize code that prevents this. Add something similar around the window.resizeTo(x,y) statement in Apple's standard code to do resizing. The code contains some size limiting code too as this also interacts

function sizeWidget(x,y)
{
if (x == window.innerWidth && y == window.innerHeight)
return;

// size limiting code
if (x<=200)
x = 200;
if (x>=440)
x = 440;
if (y<=130)
y = 130;
if (y>=340)
y = 340;

// prevent vertical resize bug
if (y>130 && y<340 && y != window.innerHeight &&
x == window.innerWidth)
window.resizeTo(x+1,y);

// finally the original resize
window.resizeTo(x,y);
}


All that's happening is that if our condition is met (height changed, width unchanged) then the widget is resized horizontally by one pixel, before being immediately resized to the desired size.

It's not perfect - a slight wobble is barely noticeable on my machine when resizing vertically, but it's nicer than the widget being chopped.