Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2007-201
$eventId
ID of event: wwdc2007
$eventContentId
ID of session without event part: 201
$eventShortId
Shortened ID of event: wwdc07
$year
Year of session: 2007
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC07 • Session 201

Effective Widget Creation with Dashcode

Leopard Innovations • 57:07

Discover the tools and technologies behind creating fantastic Dashboard widgets. Get an introduction to the use of HTML, CSS, and JavaScript to create a new desktop experience for your users. Apple experts walk you through the design process and show you how Dashcode, the new widget development tool in Mac OS X Leopard, makes it easy and fun to realize your vision.

Speaker: Christian Wagner

Unlisted on Apple Developer site

Transcript

This transcript has potential transcription errors. We are working on an improved version.

Good morning. My name is Christian Wagner and we're here this morning to talk about Dashboard widget development, Effective Widget Development using Dashcode. So first off thanks for coming here. It's a bright and early Tuesday morning. Hopefully your attention spans are still at a good rate. And we'll teach you a lot of widget design this morning.

So first and foremost, hopefully you're all familiar with Dashcode or Dashboard at this point. It's this layer that overlies your desktop, provides these miniature applications called widgets. And hopefully by now your Dashboard looks a little bit more like this, has a whole bunch of these little applications on there.

In Mac OS X Leopard, we're providing this new application called Dashcode that helps you make widgets. Widgets, you probably know are made with web technologies. A lot of times its very buzz word compliant, AJAX, Web 2.0 and all that brouhaha. So that's all there. Now Dashcode provides these wonderful templates that help jump start your widget development.

So for instance, it's very easy to make a widget that counts down to an upcoming event like WWDC. It also has this great daily feed template and helps you show like a comic or something that updates on a less regular frequency. Oops. There we go. So in case you like Dilbert, you can easily make a Dilbert widget.

And also now in Leopard we have two new, new, two new templates. We have the video podcast template which makes it really easy to make a video podcast widget. So if you have for instance a podcast like Ask a Ninja, you can make a widget very easily. And there's also this great new Google maps mash up template. So if you have any type of geographic data in an RSS feed or an XML file, this guy can handle it, display that on a map. It's really easy to use.

Now today's session is going to focus on when you should make a widget. So there's three cases. The first one is you have a great idea, OK? You have a fantastic idea and you think you know this really needs to be a widget. So that's the first case in which you would make a widget.

Second case is you have a website. You have some online property that you feel belongs on people's desktops. And this is great because it allows you to be on people's Dashboard even when they're not visiting your website. The final case for making a widget is when you have an application.

So you want to provide a hot new Mac OS X technology with your widget, or with your application to compliment it. Making a widget is a great way to pull out a single feature from your application, put it on people's Dashboards so they don't always have to launch your application to add that feature.

Along the way we're going to talk about some things like color and fonts and using those to the best of their advantage. And XML HTTP request and RSS feed parsing. And finally we're going to talk about some native technologies, how to use things like Automater and AppleScript within your widget.

So to get you in the mood for making a great idea, which I just got two what I like to think are great ideas. First one is what I like to call the business card widget. So this is a sales tool. If you're a salesman and you're giving people demos and your computer, you give them your demo and then afterwards you can just show Dashboard, already have your information here. And they can just type in their email address and hit send.

It does one thing. It does really well. It's a good model for a widget Another idea is the idea of an erase CD-RW widget. I don't know if you've ever erased a CD-RW in Mac OS X, but it's actually kinda tricky. You have to go to disk utility, pull up a dialog, it's, it's kinda convoluted. Here's a widget that just recognizes when there's a CD-RW inside of your drive and if so gives you the option to erase it. One thing really well. So on that note, I'd like to talk about staying on task.

A widget really needs to pick one thing and do it well. Up here you'll see a widget that is an iTunes controller. It does play, pause, forward, backwards, has a scrub bar on it. And it also has the name of the currently playing track. But underneath you're seeing that it also shows you some you know popular albums in iTunes right now. And the thing is, is that that's kind of, that's kind of a discrepancy. It doesn't quite fit. There's too many degrees of separation there. So instead of doing something that's kind of attenuated, do something that's more direct.

For instance, here's the cover art of the song that's playing right now. That's directly related to the song, you've just provided a value add, OK? Or show the lyrics of the song that's playing right now. Or my personal favorite, show me when this person's playing all over the United States or all over the world, show me their concert schedule. That's something that's directly related to the, to the main focus of the widget, playing back a song. So on that note, I'd like to go to demo please.

( Period of silence )

So one of the big feature requests, and this might surprise you, that we've had for Dashcode is for a template that does an analog clock, just good old minutes, seconds, and hours. And I'm here to tell you that it's actually really easy to do.

You don't even need a template. You can do it in about five minutes and we're going to build one right now. And what's cool about this is that normally when you make a clock, you have to deal with all the drawing on a canvas, on a JavaScript canvas element of the hands and all that stuff.

Well, Dashcode includes some handy parts that just make that all easy for you. You won't even have to do it. So let's go right into that. I'm going to bring up Dashcode here. And you'll see that we have the new templates here, maps and video cap podcasts that I mentioned. But we're just going to start with a basic custom template.

So now that we've got the window open here, you'll see we've got the canvas right here in the center and that's where you design your widget. Over here on the side you have all of the different elements that make up this widget and at the bottom here you have the steps that guide you through making a widget. We're going to hide that right now.

So I want this widget to be a square, so I'm going to go here and bring up the Inspector. The Inspector is where you can modify the elements for any element on the canvas, I'm sorry, the attributes for any element on the canvas. So what we're going to do is I'm going to select the widget itself here in the Navigator. And go over to the Metrics Inspector and just make this guy 300 by 300, there we go. So we've got a square one. And I don't need this Hello World text, so I'm going to get rid of that.

going to hide the Inspector. I'm going to bring up the Library is a handy place to get all these different parts that we include. These are common controls and views, things you want to use when making a widget and they really save you a lot of time. If you're already familiar with widget development, a lot of these wrap around the existing Apple classes that we provide. These are JavaScript classes that provide buttons and sliders. So you don't have to implement these yourself.

So I'm going to look for one of the new Dashcode-specific ones called a Gauge. Now the Gauge is literally like a radial display, right? It's just got a circle and a hand on it. They have it by default set up to be kind of like a speedometer, but a clock is just a round circle with a pointer on it. So we're just going to use this for our clock. So I'm going to take this guy up here.

And I'm going to resize it and see how it's not doing it, it's not doing it proportionally? If I hold down the shift key, it'll make that proportional. So that's just a handy little, little tip. So now that I've got the Gauge here on my, my canvas, I'm going to pull up the Inspector and I'm going to go to the Attributes Inspector. This is where I can set various attributes on how this Gauge works. I'm going to set some values here. First thing I'm going to do is I'm going to call this guy minutes. I'm going to turn off my caps lock and type that again.

OK, so now this is our, going to be our minutes hand, OK? And then down here on the bottom there's the different values that this, that this control corresponds to. So right now its range is 0 to 100. We're going to change that to be 0 to 60, because there's 60 minutes in an hour. And then there's also different Thresholds where it'll change this display. We don't worry about that right now. We're just going to get rid of that altogether. We're going to set its Warning value off to 80, out of range.

And now for Geometry, by default, this guy kind of goes from 45 to 315. So we're going to change that so it goes from 0 all the way around to 360. So if I type in 0, you'll see that the Gauge, by default actually points straight down. So we want that to go up 180 degrees. So we're actually going to have it start at angle B, 180 degrees and we're going to have it go one revolution around from that. We're going to have it to 540 degrees.

And the last thing I'm going to do is I'm going to take this guy's background image which is right now kind of this Gauge style, we're just going to but a clear PNG there so that there's no background at all. So I'm going to click Choose here. Or actually I'll show you something else you can do.

If we go here to the Files view, these are all the files that make this widget and there's an Images directory right here in the bottom that house all the images for this widget. So I've got this clear PNG right here, I'm just going to drop that into the Images directory and you'll see that now we've got that there. That's how easy it is to add an image or any type of supporting file to a widget. So back to our Inspector, I'm going to choose the picture here and I'm going to just choose within, actually I'll just choose the clear PNG off the desktop.

OK, and then I'll do the same for the on value that way when we change a value, it'll also be clear. OK, now that'll update on the canvas in a second. But, so we've got the minutes hand all set up. I'm going to duplicate this guy and I'm going to use this one to be my hours hand. So I've got it right on top of the minutes and I'm going to go back here to the values. Now hours go from 0 to 12 instead of 0 to 60, so I'm going to choose 60.

And then one other thing the hours hand on a watch is usually a little bit smaller than your minutes hand. So in the Geometry here, instead of being 85 of the...85% of the radius of the, the Gauge, I'm going to make it be 60%. OK, so that's our minutes hand, or the hours hand. I'm going to change this ID to be hours.

And now we've got hours. So the last thing I need to do is add a seconds hand. So I'm going to take the minutes and I'm going to duplicate it one more time. And to duplicate it, I'm just using command-D, or File > Duplicate. And I'm going to go and change its ID to be seconds.

going to move it, lets see, lets move everything out of the way here. going to move it so it's on top of the minutes too. And then I want it to be underneath the minutes hand, so if you just got into the Navigator on the side, and you just move the seconds below the minutes there, which is above, below, it's just how the Dom ordering is.

And we are going to make the second hands be 95%. And that's it. We've just pretty much designed a widget. Now this is obviously not the most gorgeous widget you're ever going to see. But the rest is just art at this point. Except for the code to actually make the hands move. Let's do that. So if I go to the View menu and I show the Source Code, you'll see the Source Code editor pops up underneath.

I'm going to just double click on the separator that brings the code all the way up to the top and I'm going to click on our green dot here to make it fill screen. Now I have one function here that I wrote already, just going to drag it in right here at the top that changes the time. And so what this does, this has seven lines of code.

OK? It gets a new JavaScript data object, pulls out the hours, minutes, and seconds and then it uses the Dom to go and get the Gauges individually and just set their values to the respective hours, minutes, and seconds. That's all this does. OK? So I'm going to run this widget. If you just click on the Run button here, the widget launches and nothing happens, because I have never called this function.

So I could quit the widget right now, but I'm going to be lazy and use Dashcode Evaluator. If you go to View and EWvaluator here, the Evaluator is a JavaScript console that lets me run in, individual JavaScript commands in one, in real time in the run time one at a time. So I'm just going to call the setClock() function right here and you'll see that we now have the time set. So that's works pretty well.

Let's hook it up so that this, this clock now refreshes every second. To do that, we're going to bring up the source code again and the shortcut for getting the source code is just clicking this button in the, the bottom bar here. And there's two, two events that we care about here. On widget show and on widget hide. So when the widget is shown we want this clock to start updating.

So we're going to go here in the function pop up and look for the show function. And what I'm going to do is I'm going to use an interval and I'm going to set that interval to update every second. So I'm going to say setInterval, whoops, I'm actually going to say myInterval, I'm going to use a global variable to hold this, then say setInterval.

(SetClock)

Every 1000 seconds, and again since I have a global variable, I should declare it globally. myInterval = null and I'll put a var in front of that. And that also in the hide function, I should clean that up, OK? And the idea behind this is when a widget, when Dashboard is not showing, you shouldn't take up any CPUs. So it should turn off any timers intervals that you're using. OK? So I'm going to do clearInterval here. I'm going to say go ahead and get rid of myInterval.

And just for bookkeeping purposes, I'm going to set it to null. OK, so this, fingers crossed, should work. I'm going to hit the Run button here. And there we go, every second we got this second hand sweeping about. So that is pretty much it. Like I said, the rest of this widget is just design. So just to give you a taste of what can be done here, here's a version, and I just got some art from Dashcodes Archive Max.

And he put that in the background here. And I also added a little bit of animation. There's this Apple animator JavaScript class which will let you iterate between values over a period of time. And so what I do is every time the second hand moves, I don't just move it, I actually animate it to move. So let's run that. You'll see when it first loads, it's going to move the hands about. And now every second, it's actually moving the hand, using animation, so. Slides, please.

( Period of silence )

So now that I've shown you how easy it is to use Dashcode to just, you know, make your great idea into a functioning widget, let's talk a little bit about design. So the great thing about Dashcode has been that it's been really easy for a lot of users to make widgets.

One thing that we've seen a lot of is people taking our templates and just kind of changing one color. And we think that there's a little bit more that you can do to really make your widget stand out. So for instance, here's a Podcast and the person has added, you know, a little bit of yellow in the gradient and the purple kinda goes against the grain of the yellow and its, there's some things we could do to clean this guy up.

So first thing we're going to do is I'm going to talk about Color Schemer Studio. This is an application, third party, that makes it easy to make color schemes. And so I'm a big fan, if you provide a color of using the analogous colors, so those are nearby ones for different, for different buttons and objects on the widget canvas.

And the monochromatic one is good for glass and gradient effects. They also have this suggested colors feature which will give you an entire scheme, an entire layout which is really handy if you're not good at picking out colors. It'll just give you an entire scheme for your, for your widget.

So using just the colors that you find in Color Schemer Studio, you can make a widget that looks, originally would look like this, and then use a little bit of glass and kind of transition it to be something, fits more in with this yellow theme that the person chose.

Another thing you can use to your advantage are fonts. This here is a list of standard fonts that are included on every Mac OS X machine. And they're really clear, easy to read and they're good for use on a widget. There's more fonts that are available in Mac OS X but this is a good subset to work with. They're very versatile, they work well on widget interfaces.

So for instance, if you have a widget that does command-line output like this one, you might want to use a monospaced font like Monaco. This makes all your tabs and spaces look the same. It's kind of what people except. And that's the point I want to make here is that use fonts that kind of reinforce what people inspect, expect. So if they're expecting a headline, use a nice serif font. If they're expecting something command line, use a nice monospace Monaco font.

And just in case you didn't quite jot down that list, it's essentially the widgets that you, the, the fonts you can use with the Stickies widgets. So if you flip the Stickies widgets over backwards, all of those fonts are very safe to use and Monaco. It's not there, but Monaco is a good one to use too.

So the next thing I want to talk about were Preferences on your widget and making sure you put the preferences on the back of a widget. So here is a website, superconcerts.com that I made up that shows you the upcoming concerts in your metropolitan area. And they put this pop-up on the bottom of the widget that lets you choose what city of the concerts you'd like to see.

So the thing is that how often do you move in your lifetime? A dozen times at most, right? So this is information that really doesn't need to changed nearly as frequently as you use this widget. So if you flip this widget on to the back and move that menu onto the back, that's where this type of stuff belongs. Things that don't get changed, updated as frequently, go on to the back of the widget.

In addition to any preferences, you might want to also put About information on the back. So your website again, most people know your widget belongs to you. That's why they put it there in the first place. So go ahead and put your About information on the back. So if I flip this guy back around, you'll see that now I've saved myself a whole bunch of pixels on the bottom, making the widget smaller, making it more likely that someone's going to want to keep this widget on their Dashboard.

And you'll notice that I still have the superconcerts.com banner on the top. I can get rid of that, now that I've put it on the back and replace it with a control that lets me change which day is being displayed. And now the widget is infinitely more useful.

I can you know go backwards, forwards in time and see what concerts are playing on what day. So that's really handy. New in Leopard are syncing preferences. This is something you should be aware of. People can sync their Dashboards over .Mac and Leopard. And so you probably want to be aware of this if you're saving preferences at any point.

There's a new JavaScript handler called widget.onsync. And onsync is called whenever sync is completed and new preferences, and it gives you a chance, sorry, to read your preferences and compare those preferences to your state. So if there's new preference, just update your state accordingly and you're in good shape. Now if you have any preferences that you would not like to have synced using .Mac, use the SyncExclusions info plist key. Basically in this array you provide all of the keys that you would like to not have synced and we'll respect that.

I mentioned before in my last demo that the Dashcode parts are really handy and I, and when you're making your great idea a widget, go ahead and take a look, see if any of these parts suit your needs. There's a whole slew of them from QuickTime all the way through to QC and some Dashcode-specific ones like the Gauge and the Indicator. So go ahead, browse through there, they've got descriptions and all that stuff. They're really handy and they might help you bring your widget just that much quicker to market.

And finally, Web Kit in Leopard has some new features that might also be of use to you. First is -webkit-border-radius. So if you've ever used a rounded rectangle on your widget, you've probably had to do that in, in Illustrator or Photoshop. Well, now in Leopard, you'll just be able to take a div, put it on your widget, and then just use this CSS property to round off its corners. And that allows you to change it on the fly without having the round trip back and forth between a graphics app and Dashcode.

So that's a really easy one. Another one that's in the same vein is -webkit-box-shadow. This puts drop shadows underneath any element on a widget's UI, on a webpage too. And so what's great about this guy is again, you don't have to round trip between Illustrator, or Photoshop and Dashcode. You'll just be able to apply this property, tweak it on the fly, you got drop shadows. So using some of the things I just told you, I'd like to go to demo and give a widget a makeover.

So I have this widget here on my Dashboard and this widget is a secure notepad. And they did do some things that I liked. I'm glad they made a widget and I'm glad they made it this orange color because it's unique, it makes it stand out a bit. And so, but they did some things that I'd like to now show you and tweak a little bit. So I've got the widget here on my desktop and all I'm going to do is I'm going to drag the widget on to Dashcode.

And when I do that Dashcode opens this widget in place. This is one of the features we've added. And we do this because sometimes you don't want to use the code generation features that Dashcode offers. You just want to use the debugging features and write all the code yourself. This mode gives you that. so you'll be able to just write the code and test it, using the debugging features we're going to demonstrate tomorrow for you and you know that's going to work great.

But the down side to this is that it makes giving this widget a makeover kinda hard. You'll see I can't move any of the elements here on the canvas. So what I'm going to do is if I go to the View menu here, I can start the Code Generator. So that means importing this widget into a widget project, not just opening it on disk, but actually making a new project out of it.

So I'm going to click Start, Import. And I'm just going to save the new file on my desktop. And here we are. You'll notice that there was a stripe along the bottom that had a lock on it. That meant that the code generation was off. Now that stripe with the lock is gone.

We can do anything we want with this guy. So the first thing I want to do, and if you look at this widget, there's this lock on the top corner here. And there's this big stripe of nothing to the side of it. So that's just kind of not the wisest use of space.

So I'm going to take this lock and I'm going to just move it straight down to the bottom. And I'm going to resize it a little bit, even a little bit bigger. And so now by doing that I've got this huge stripe of just orange up there that I can get rid of. So I'm going to select all of the items on my canvas here.

And one trick when you import a widget is that the Info button doesn't show up, but it's there. So make sure you grab that too. And I'm just going to move it straight up. So now I've reclaimed all of this space. Now you'll see that the front image doesn't resize with me. And that's because I've imported this widget.

Dashcode doesn't know to redraw this. So I'm going to add a front image part to the, to the widget here so that we can redesign it and add some effects to it. So if I bring up the Library here, I'm just going to search for Front Image. I'm just going to drag it onto the widget right now.

And by default it's locked, so I'm going to just go right away and unlock it. That lets me freely move it. And I'm just going to move it so that it fits here on the widget. And right now it's this gray gradient, which isn't terribly exciting, so I'm going to bring up the Inspector here. And there's the Fill in Stroke Inspector. This lets me adjust the style, the color, the stroke of any object. I'm just going to take this guy and right now make it solid.

And I'm going to click this color chip. That brings up the Color Inspector, going to use the magnifying glass to just grab this orange color. Like I said, I'm actually glad that this person used a unique color, so we're just going to grab that and close out this. And get rid of the original image here.

So I'm going to select this guy and one thing I'm going to do is I'm going to turn Autoresize on the inside on. And so that means that when I resize this widget on the canvas, it's going to automatically, automagically resize this front image for me. So I'm going to shrink it again.

( Period of silence )

OK, so now we're doing better. So I'm going to go back here and solid color is okay, but Dashboard gives me a little bit of glitz and glamour here. So I'm going to make this guy a gradient. And I don't like the orange to white so I'm just going to take the orange color here, you can just grab it like any other NS color well. Drop it up here.

And then if I put this guy, I'm going to make it lighter. So now I've got a nice light gradient. And, of course, Dashcode makes it easy to put glass onto a, a front image, so I'm just going to take this guy and just play with it. And this is where you get to be the artist. You can, you can change these values however you see fit. I'm going to make it a little bit curved, move it up.

But you see that, you know, I've done all this stuff. You really can't see it, right? We've got this big, white box just blocking up our UI right now. So I am just going to get rid of it. There, it's gone. How are you going to use this widget though? So I'm going to get rid of the Inspector and bring up the Library and I am going to just use a box. OK? Now a box is just Dashcode's word for a div. So I'm just going to drop this guy on here.

( Period of silence )

And I'm going to give it a new name in the Inspector. I'm going to call it inputbox. Now by default, you can't just type into any old div. We're going to use Web Kit's content editable support to add this as a text field that you edit in.

So I'm going to close off the Inspector here and I'm going to use Dashcode's search feature to show me, to reveal the HTML for this element. Because I, I don't want to search through HTML. It's a pain in the neck. So I'm just going to put in inputbox the name that I just gave this one.

And you'll see here on the side, we now have the object logically on the canvas. We have the style for this. And we also have the HTML. And so right here is the div that makes this box. So I've got a code snippet right here. I'm just going to drop it right in there. And you'll see what I've done is I've just made this contenteditable="true".

That means that this div I'll be able to type into it and select in it. Do all the stuff that you normally expect from a text area. So that's step one. Step two, let's make it actually look like something. So I'm going to pop open this guy's CSS here.

And you'll see that inputbox is right here. Actually let me double click on the separator and bring us our code. So by default, there's all ready all of this CSS here. I'm going to add a couple of lines right here. And we're going to format that. So I'm going to use a couple things. First off, I'm going to use the -webkit-border-radius, what I showed you before to give it some rounded corners. I'm also going to make it an -apple-dashboard-region. This is a subtle thing that some people miss. By default, a widget's UI can be grabbed anywhere and moved around.

But if you're within a text area, some place where someone's adding text, you actually don't want that behavior. You want them to be able to select the text, not move the widget. You use the -apple-dashboard-region CSS property to make that happen. So there we go, we've added that. I've also just added some font information, given it a Helvetica Neue Bold. We've made it 14 point. And I've also given it some padding by having the rounded corners on there now.

The text would normally just squish right all the way to the edge and show up underneath the, the rounded corner, that's nice. That's not so nice. By giving it a padding, we're just making sure everything fits nicely within our rounded, rounded rectangle. So I've added this code, let's go back to the canvas, and see what it looks like.

So now that we've refreshed, you'll see that now I've got a rounded rectangle, we're almost there. Adding the padding changed the dimensions of the div a little bit. So let's move that back. And I'm going to go here to the Inspector and I'm going to tweak it a little bit. I don't like the back line around it, so we're going to get rid of that.

But I am going to fill it with a solid color. Instead of black, we're going to go to white. OK, so now we're almost to where we were before. We've got a big white box. Let's add some opacity, knock that down a little bit. We're going to move it down to 60 some odd one`s here.

OK, so now we've got this more orange theme. There's one thing that I can think of left to do for this widget. And that's the three controls at the bottom. Right now, they're good old fashion H refs. And I need to tell you that a widget isn't a webpage. It may technically be a webpage, but from a user perspective, it's an application. So instead of using hyperlinks in the sort, use buttons.

So Dashcode's Library includes buttons that make this really easy to do. So I'm going to actually mimic the good old segmented controller that you're used to seeing and I'll go, I'm going to give it a design that fits in with this widget. So what I'm going to do is I'm going to grab the, the left rounded part. I'm going to grab the right rounded part. And then in the middle we're going to put just a square button.

And there we go. There's our segmented controller. Let's shrink that to fit. And another thing is that the, the links here are using you know greater than and less than. That's not so nice. Let's use English language. We'll do Previous.

( Period of silence )

We'll get rid of these.

( Period of silence )

OK and then we'll have an Add button to replace the plus. And then here on the end we'll have a Next.

( Period of silence )

One of the new features that was added in Dashcode for Leopard was the support for multiple selection. So this is actually a big deal.

I can select these three elements at once. Bring up the Inspector here. And now I can modify the design of all three of them at once. So instead of being a gradient, we're going to make them solid, but we're going to leave the glass effect on them and the font we're going to bump it down a notch.

Whoops, instead of adding a notch, we'll go down a notch. So a little bit smaller. Oh, and the stroke is gray on these. That's not so nice. Let's tweak that too. And again, I'm just going to grab the color from the body and put it down here. And let's make him a little darker.

( Period of silence )

OK, now they'll stand out a little bit. So I think at this point, our widget makeover is just about done. Let's go ahead, take this widget, and deploy it onto our Dashboard. We'll install it. And keep it. And so here we've got our before and after. We've got a kind of a chunky widget, now we got this one glossy, shiny, rounded rectangle widget ready to go. Did that in about five to ten minutes. Let's go back to slides, please.

( Period of silence )

So now that we spent a good while talking about taking your great idea and making it work and look good, let's talk a little bit about the next portion of our presentation. And that's making a widget for your website. If you have a website today, there's probably a lot of things on your website that you can use to make a widget, web properties you can kind of utilize for a widget.

This is a webpage you're probably all familiar with. This is the Apple hot news page. And this page is a gold mine for making widgets right here. So we're going to play a game that I like to call, Where's the widget? And it's basically identifying the widget opportunity on this page.

So the first place where I can see a widget on this page is in the top corner, there's an events list, OK? So you could very easily take this list and make it into a widget that looks a little bit like this. And again the real benefit to doing this is that people now don't have to go to your webpage to see what's happening.

Every time they show Dashboard, they're just going to see that events that are happening sponsored by Apple. And again, we've taken this design and done something a little bit different than what's normally on the webpage. Instead of just a boring list, we've given it this purple style and made it nice and long, given it some colors.

It's a little bit more fun. Next on the list is the top stories here. Dashcode has a template called the Daily Feed template which makes this really easy to use. If you do press releases and you want to give a widget to people who work in PR firms, this would be really helpful.

And finally in the bottom corner here, you'll see there's this widget for the iTunes Top 10. This would also work well as a widget, something like this where you list all of the artists and click on it, it'll bring it up in iTunes. That would work really well.

Now all of you were at the keynote yesterday and you saw Web Clip. And Web Clip is a great user feature. Lets users make widgets out of whatever they want. But you as developers can kind of do a little bit better. You can, you can one up this and really kind of make Dashboard and your widget your own by making, by shipping your own widget.

The first reason why you want to do that is because you don't want to have to put a message like this on your website that says if you want a widget of my website, go ahead and load up Safari, because not everyone uses Safari. Click on the add to Dashboard button and then kind of wrap this, this is a bad user experience. If you provide your own widget, it's a much better experience.

And the second reason why you might want to provide your own widget over just relying on Web Clip is if a user goes offline, this happens. All the sudden the widget isn't replaced with the content, it's replaced with this kind of we can't open this page kind of a, a feel. And that's not so nice. So if you provide your own widget, you can handle this case a lot more elegantly.

So what we're going to do is we're going to take the iTunes Top 10 that I just showed you and we are going to model it after this. If you're all familiar with pop music, there's the Billboard Hot 100 Singles list. And this is about what it looks like. And so what we're going to do is we're going to just learn things from this particular design and apply them to a widget that, that mimics it.

So here's our, here's where we start. Here's our Web Clip. So the first step is just to break it out of Web Clip and make it a widget. So what we've done now is we've used an iframe in a widget to show our content. And that's really not much better because if a user goes offline, well the iframe is going to do the same thing. It's just going to be a white box instead of your content. So I know people like to do that because it's kind of the cheap, dirty, easy way of making a widget. But I'm going to have to ask you not to.

Instead, what you really want to do is extract the text from a feed somewhere and put it on your widget. Like this. And how are you going to do that? Well, you're going to do that using XMLHttpRequest. So this is a JavaScript object that lets you make HTTP calls, then parse the data and put it on a widget.

So there's a code snippet in Dashcode which is a feature where we provide a whole bunch of shrink-wrapped code ready to go that provides this all for you. And this is that snippet right now. So the first two lines are basically things that you provide. The URL that you want to get the feed from and the handler that you want called when the feed is loaded. And in that handler you're going to do some type of Dom operation to pull the information out and put it on your widget's UI. Usually not too hard, take a look at our code to see how that works.

The second half of this particular snippet really is just ready to go. All it does is it sets up the handlers, sets up the request object. It's also going to then send the feed off. And it also turns off cache controls, that way you don't get stale data. That's an important thing.

So, OK, we've got our XHR working, now we've got this widget that gives us our text on a widget UI. What's the next step? Well, we're going to pull in some fonts into this whole thing. So here's the Hot 100 list, and I'm going to pull up that list of fonts from before and have you guys look at it. And can anyone guess what the font that's being used in the Hot 100 list is? Takers? Anyone? What was that?

  • (Unclear).
  • It's Helvetica, is that, yeah, sorry. It is Helvetica, but it's a specific brand of Helvetica. So you're right. It's Helvetica Neue Condensed. You get a prize later, come see me. So we're going to use Helvetica Neue Condensed to make this widget happen. So here's our original widget with the text on it.

And here's our widget with Helvetica Neue Condensed. You'll see that it has already a lot more of the feeling of that Top 100 list. So OK, what's the next we want to do? We want to a little bit of good old elbow grease spit and polish. So there's a design element here in this Hot 100 list that's kind of unique and that is all these lines that kind of separate the data, because everything's in tight confines.

We want to kind of mimic that look in our widget. So I'm going to take those lines, I'm going to put them into our widget. And I'm going to do one more thing. And this is kinda when you hit the top and you know you've done the right thing.

We're going to make it look like someone ripped this widget right out of the newspaper. We're going to give it a folded corner. We're going to give it a crinkly edge along the side. And now we've got a fun widget here that people are more likely to keep on their Dashboard.

So we've started off with a web clip which you know is great for a webpage and we've gone to this fun widget that people are actually going to be willing to use. So one that note, I'd like to go to demo and show you another kind of makeover for a widget for a Podcaster.

( Period of silence )

So there's a podcast that I like to listen to, which I made up back in Chicago, my hometown, called the ChicagoCast. And these guys do different walking tours of Chicago. And they've got this great website and they decided, hey, we're going to make a widget.

And here is the widget right here. And it's actually you know they've taken a lot of the design elements from their website, imported it to a widget. And that's really cool. But the problem with this widget is that it's not terribly unique. They use a lot of white. They're not using color to, to their advantage. And they, they need to really kind of embrace the idea of making an application instead of just taking a webpage and putting it into a widget. So they were kind enough to provide their widget project for me.

( Period of silence )

And so now we're going to go about getting, making this a more bonafide, beautiful Dashboard widget. And the first thing I'm going to do is I'm going to get rid of this banner on the top, because that's a lot of dead space. They can just put that on the back of the widget.

And they got this gray gradient underneath, we're going to get rid of that too. So already we've saved this huge stripe. We can now take some things, all the elements on our widget's interface here and move that all up. OK, so that's an improvement and we can resize the widget accordingly. Now another thing, ah, wait, hold on for a second.

You'll see that the info button is moving along with the bottom. We don't want that. So let's go ahead and click the info button here. And you'll see if you bring up the Metrics Inspector that its Autoresize properties are set so that it basically is anchored to the bottom right hand corner.

Well, we actually don't want that. We want it anchored to the bottom, to the top and to the right hand side. So I'm going to move the springs here so that that's, that's the case. And now when I resize it, now it just moves over with the, with the right edge.

OK, so that's just one bit of trivia for you. So there's two things here. An Episode Date and an Episode Description. Now I can tell you that these guys don't care about the date. They update regularly once a week. So feel free with any of our templates to just get rid of it. OK? If it's not something that people care about, get rid of it. The widget, the templates can handle that.

They're resilient, you're not going to hurt their feelings. So let's see. Now the next thing we can do here is we can move it so that the Episode Description and the Episode Name pop-up are above each other and move the play button right next to it. And resize this accordingly. And we've got ourselves much more of a, a lozenge-style widget. So that's pretty good.

But the thing about that is now we've got a white widget. And that's not terribly exciting. And we've lost our branding. There's no way for people to know. So here's a trick. If you take a look at the webpage here, they happen to have this nice round logo in the corner here. And that's going to fit really well into the lengthwise orientation of this widget. So I've got that badge right here as a PNG. And so I'm just going to literally drag and drop this onto the canvas.

That's how easy it is to take custom artwork and put it into your widget. So I'm going to resize all of these elements across a little bit.

( Period of silence )

And put the logo here on the side and I'm going to shrink it so that it fits in the body. All right, so we'll make it a little bit bigger. And this is the usual fiddling you're going to have to do when you make a widget, but that's okay.

OK, so now we've got a white widget with a logo. We're half way there. I'm going to take, I'm going to look at there logo. And if you look at the logo, they've got this red star and that's a very distinctive red. And that's a good thing to pull out in a widget. If you take a color that your website uses, pull that out, make the body that color, it'll help people remember that that's your widget.

So I'm going to go here, I have the front image already selected. I'm going to go in the Inspector. And I'm going to make it a solid color right now. And again, I'm going to use the Color Inspector and just use the magnifying glass to just pick up that color right there. Let's go for the darker side. Whoops! Slippery fingers.

( Period of silence )

OK, so now we've got a red, a red widget. OK, so let's have it so that the widget wraps around the logo. That would probably be a little bit nicer. So let's keep bumping up the corner roundness of the front image. That's looks about right. OK, so the next thing that's kind of disruptive here is this pop-up menu. Let's make that also fit in with this design. Let's make it also red. So I'm just going to pick up this red right here.

And you'll see that it kept the glass property, that's good. But the shine is a little bit much. That's, tone that down a bit. And I just realized that it also has a white stroke. So let's get rid of, actually let's just get rid of that altogether. And the background is kind of boring. It's a solid color. Let's actually give that some glass.

( Period of silence )

Tone that, tone it down a little bit, some curvature, move up the horizon a little bit. OK, that's starting to look a lot better. Now the text on the pop up menu is gray. So red on, gray on red doesn't look so nice. So let's actually flip that around. If I go to the Text Inspector here, I can change this. And actually, I want to change the description of the text and the pop-up. So what I'm going to do is I'm going to make them white.

And here's a trick for you. A lot of widgets like to have this embossed look, like the text is pushed into the widget. So what we're going to do is the trick to do that is you take a shadow of a darker color, we're going to say gray and you just move its Y Offset to negative one and now the text looks like, looks like it has the subtle indented feel to it. So that's just a handy little trick.

So we are almost there. One last thing which I want to do is I want to visually group the pop-up menu, the description, and the play button since those three things kind of go together. I'm going to use a Dashcode part to do that. So in addition to functioning parts that do different controls, that act as controls and views, there's also just some straight up design elements you can use here. So if I look for rounded, there's a rounded, rounded rectangle shape that I can use. So I'm just going to grab this guy and drop him in here.

And so right now it's on top of everything. If I go here to the Inspector, I can just move it underneath everything, except for the front image. And I am going to resize it to be under all of these controls. And right now it's not sticking out very much, so let me close the Library and bring up the Inspector again. And in the fill in Stroke Inspector, I'm going to just turn off the glass.

And I'm going to bump up the corner roundness a little bit on that. And you'll see it's subtle, but now all of the play controls are kind of grouped together in one. So I think this widget is just about graphically made over. One last touch I would like to add and that's the idea of opening the website when you click on the logo. So what we're going to do is this is the only place we're going to write code in this particular demo.

I'm going to select the, the logo here and I'm going to go to the Behaviors Inspector. This is how you add a like basically a click behavior to anything. We're going to go over here to the onclick event, double click in the Handler column. I'm just going to do showWebsite.

And when I do that, the canvas is replaced with a Code Editor and a new function has been inserted into my code here. And it says Insert Code Here. Now I don't remember off the top of my head the code that it takes to open a website. But Dashcode provides this code for you. So I'm going to just go back to the Library and there's this Code tab here.

And if I just do a search for web, you'll see that I've got Show website here. So I'm just going to grab this code snippet, drop it right into here and you'll see that this code let's me just put in a URL and then opens that URL in a browser for you. So I didn't even have to write any of the code today.

So I'm going to save this widget. And then run it on Dashboard. Woo, I don't want to replace. And you'll see that we've gone from this kind of website inspired widget to this more colorful, more at home on Dashboard widget right there. And it'll load, trust me. Let's go back to slides.

( Period of silence )

So the last thing that I wanted to talk about in depth today is making a widget to compliment your existing application. So this here is a new application called Calorific by Wagnerian Software, it's my new software company. And what this does it is allows you to plan your diet. You can put in all the food that you like and basically plan a diet for your calories. And then shows you your history and all sorts of stuff like that.

And I've decided that I want to make a widget or maybe even a set of widgets to compliment this application. So the first widget that's really would be useful to my users is a widget that's shows my history, my caloric history, which is normally shown in the bottom corner of the app. So that widget could look something like this. You know has the chart on it, they can always just show Dashboard, see how they're doing.

The next widget that would be really handy for this one is basically my upcoming meals, my menu. So you could easily make a widget that just shows you what you should be eating in a day and that way you don't have to show Dashboard every time you're curious or launch your application, I mean, every time you're curious about what you should be eating today.

And the final widget for this application is the input. So if you have a new meal that you've got, a new recommendation, a new recipe, you could easily make a widget that just lets people put that in so they don't have to launch your application. And the point behind all of these widgets are this.

If you have one discrete area of functionality in your application that people use often, consider making a widget out of that. Pull that out, make a widget so people don't always have to launch your application. And another point to make is that you're not limited to having just one widget for your application.

You can have many, as many as you like, as long as they're useful for your users, you should provide them. And there's some great developers that have done this too. The folks at iSale, actually I think its Equal, Equinux, I forget the company name, but they, they're perennial ADA favorite.

They made a widget to compliment their application. And what this widget shows you, it shows you all of your eBay auctions. So that way you don't always have to launch the application, click within the app, find your auctions. There's one widget, keeps track of it all, you can get rid of it when you don't want it.

The folks at Panic also have a very handy widget for their Transmit application. This guy works as a bookmark, so if you ever have one place that you upload a lot of files to, a drop box of some sort, you can just make a widget out of it, drag your files into that widget. Just happens, everything happens like magic.

So I want to talk a minute about the tools of the trade to make this happen. We provide you the widget.system API. And this let's you take any command-line option and run it from within a widget. In addition to widget.system, there's also widget plug-ins which lets you tie in Objective-C code into your widget.

Now I want to side bar for a second and look at Dashboard's architecture in Leopard. And something is different from Tiger. You'll notice that for performance, Leopard is a lot snappier when it comes to running widgets. And that's because all widgets now by default run in one process instead of every widget getting its own process. So this process grouping, the gentleman to thank is sitting down here. You can thank him afterwards.

The, having all these widgets together in one process makes things much faster, OK? But if you happen to be using a widget plug-in, we're going to have to put you into your own process. That's to avoid main space collisions. OK? And so now we've got a whole other process just for this one widget.

And we'll even group widgets of the same, of the same class, but either way, now we've got three processes just for these two widgets and all the other widgets running in this one process. So you've just kind of, you kinda circumvented some of the work we did to help make things snappy. So when possible, please avoid using widget plug-ins.

That's why I wanted to bring up widget.system again. This particular guy makes it really easy to tap into your AppleScript and Automator investment. If you've already got a scripting dictionary or Automator actions, you can very easily use the osascript command with the -e that's for an expression or the automator-i to, to pass in and run a workflow.

One thing I want to bring up, actually back up a slide here. One thing I want to point out with widget.system is that widget.system actually has two modes of operation. Synchronous and asynchronous. And in Leopard you really, really, really want to avoid synchronous operation because since you're all running in one process now, if you do anything synchronously, you're not just blocking your operation, you're blocking everybody in your process.

And so whenever possible, make sure you use asynchronous operation. In widget.system, you run asynchronous by providing a handler function for that second parameter that you're seeing up there. That makes you run asynchronously. That makes sure you don't block, block every widget in your process. I really need to emphasize that. That's really important.

So now we're going to fast forward through these, AppleScript, Automator, go ahead and use these. They're wonderful. All right, some other things that are really helpful for you to use when you're trying to display data is Quartz Composer. Lets you do motion graphic and the canvas tag, lets you do CG-style rendering using JavaScript.

And these are actually very, very powerful. If you were thinking of using a Web Kit plug-in to draw a Cocoa view into a widget, try these instead. They're much lighter weight and again you won't be stuck in your own process. It's a lot, a lot cleaner this way.

Another thing that you want to consider is using a drop cell. So if you're widget wants to know files, wants to have files dropped on it, instead of trying to mimic a file dialog or something like that, just use drag and drop. People can be moving a file, show Dashboard, drop it on the widget, it just works.

Can I see a show of hands here who downloaded our head start for this session?

( Period of silence )

Hey, that's pretty good. Thanks, guys. So if you've downloaded our head start, you already know a little bit about drag and drop. And in a minute, our demo I'm going to go into that a bit more.

Again, use our Dashcode Library, the parts here are really helpful when you're making a widget. And finally, one thing which I do have to kind of advise against is key combinations. Widgets don't have the idea of focus, OK. So it's hard for a user to know when something has focus. And then if you want to like have them hit keys, it doesn't work so well. Try buttons instead. It's much more straightforward. It's much more visual. People will get that a lot better. So with that in mind, let's go to demo.

( Period of silence )

So this is the coding head start that we asked you guys to download before, before today's session. And if you did it, you'll realize that it's a widget that does drag and drop. And when you drop an image onto it, it just previews that image, shrinks it down, fades it in, right? So we're going to take this widget and we're going to gut it.

And instead of having it show an image, we're going to have it take whatever gets dropped on the widget and feed it to an Automator workflow. And again, the idea behind this is that if you have an investment in Automator for your application today, you can very easily wrap up a set of default actions or something like that into a widget, brand it accordingly and ship it as a widget.

So what, what I've got here is I've got a workflow that just takes whatever is dropped onto the widget, puts it in new email and changes the subject to be files from and then my name. So I'm going to just take this workflow and drag it right here into my Files list. So now the workflow is being included inside of the widget.

The next thing we're going to do is I know this particular widget has a drop handler. So this means that when a file is dropped onto the widget, this function is called. And I know that that's called dwDragDrop. So I'm just going to go here in the Function pop-up list and go to that and just like before, I'm going to hide the canvas for the time being. So in here is all this code to handle the, the image side of this widget, which I'm just going to delete. We're going to get rid of that right now. And I'm going to put in this one if statement right here.

And what this if statement say is if I've gotten a string from the drop event, I want you to clean it up because normally strings are URIs. I want them to be actually UNIX paths. So I'm going to have that clear that up. I've got a preparePath function. Then I want it to run the workflow. So let's actually add those two functions here. Add some space here.

And first thing I'm going to do is I'm going to add the preparePath. And there's not too much to really worry about here. This just decodes the URA, URI, takes care of some edge cases and cleans up the path. And the second thing, and this is the real, the real good stuff here is the runWorkflow. So what I've done is I've got the workflow name here. So by default, it's Default.workflow. And then I assemble a command. Now how the Automator command line works is if I want to feed it any information, I use the -i flag.

That means I'm in interactive mode. Then I throw another dash on the end of that. That means just read from standard input. So then I'm piping in something from echo before hand. And in this case I'm echoing in the path. So that way when once the Automator command line loads, it'll just read that path in there and then feed it to the workflow.

Notice then that I'm then calling widget.system. I'm calling command and again, I want to make sure this widget runs asynchronously. So I provided an empty function here. OK, and you can do that. And JavaScript functions can very easily just be variables. So by doing this, I've just provided an empty function and this will run asynchronously. So you don't always have to just provide some function and do something in it if you don't have to. But still it's important to do this. So that's pretty much it. That's our entire widget right there. So I'm going to run.

And you'll see I'm going to hide this guy and I'm just going to drag this image on top of it. And, uh oh. It didn't work. Well, that's not good. This is a common gotcha. A lot of time, whenever you're using command-line operations. If you go to the widget attributes, it turns out that you have to turn on command line access. And this happens to even seasoned widget builders. It happens to me all the time.

So make sure if you're going to use the command line, you go in here and click Allow Command Line Access. Notice that there's other check boxes here. If you're going to use XML HTTP requests, you're going to have to turn that on. If you're going to use a plug-in of some sort, you have to turn that on. So make sure that's your first thing to check if something goes wrong. Make sure you got the right check boxes on. OK, so let's stop that.

Let's run it again. All right, if I did everything right, it should work great. We're going to drop this on here. And Automator is running in the menu bar. Mail is loading and come on Leopard. And there it is. There's my new email that has the image, that has a whole bunch of other stuff in there. And so you can obviously imagine any Automator workflow, this is the one I've chosen to show you today. So let's go back to slides, please.

( Period of silence )

So as we wrap up our session, there's a few things that I'd like you to take home from today's session. And I just want to note, this is the first bullet list you'll be seeing all day. Everything else has been graphics. So if I'm using bullet list, I really, really mean it.

It's easy to make your ideas into a widget using Dashcode. Dashcode provides a lot of parts, code in there. It makes it really easy to prototype your widget, get it working. Make your widgets gorgeous, just make them pretty, pretty the heck out of them. Because that way people will remember them, they'll like to use them, they'll look forward to using them.

Colors and fonts are the key to doing that. Make sure your widget has unique design with a lot of great colors. Make sure to use some imaginative fonts. If you're making a widget to compliment your website, remember that you're widget is not a website. It is a presence, an opportunity for presence on the desktop. OK. So it's something that people will also see whenever they use Dashboard. And that's a great opportunity. And finally, if you have an application, tie into your application, leverage your Automator and AppleScript investment. If you've got it, easily wrap it into a widget and ship it.

We have two labs this week. Tonight at 5:00pm in Mac OS X Lab D and on Friday 3:30pm in Lab B. So please come and visit us, let us know if you have any questions. If you have any questions about my demos, feel free to come by and I'll gladly answer them.

If you have any questions that you want outside of the conference here, contact Matt Drance, he's the Sharing Technology Evangelist which sharing, widgets are a sharing technology in case you were curious. So Matt's the guy to talk to about widgets and about developer tools as a whole, talk to Matt Formica.