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: wwdc2006-313
$eventId
ID of event: wwdc2006
$eventContentId
ID of session without event part: 313
$eventShortId
Shortened ID of event: wwdc06
$year
Year of session: 2006
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC06 • Session 313

Introducing Dashcode

Development Tools • 1:11:15

Introducing Dashcode, the new Dashboard Widget development tool from Apple. Dashcode is the center of widget authoring, giving you one place to assemble a user interface, author code, and debug your widget. You'll also learn how to make your own Dashcode templates and work with existing Widgets.

Speakers: Tim Bumgarner, Max Drukman, Han-Ming Ong

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good morning. Welcome. We're very excited to be here this morning and welcome to our session 313, Introducing Dashcode. We have got a great hands-on session for you today. We hope that you've all got the sample code, the listing up there. Have that with you so you can follow through and you're going to learn a lot about Dashcode.

I'm Tim Bumgarner. I'm a senior software engineer at Apple and a member of the Dashcode team. Let's look and see what we're going to be doing today. So here's our agenda here this morning. We're going to take a minute and talk about why we built Dashcode. Why did we go ahead and create this application for building widgets? Then we're going to spend the bulk of our time this morning on a hands-on session. We're going to be creating a countdown widget from start to finish.

And part of that process is we're going to design the widget. We're going to take a template, start with that, adjust the look and feel of it to make it our own. And then we're going to add additional functionality that doesn't come with the template. We'll do that using some JavaScript.

So, and of course, whenever you start writing code, you're probably going to have to debug that code. So we're going to walk through a little process of the debugging. So make sure you have the sample code. Now, there are two ways to do a hands-on session. If you've got the sample code, you can follow along. We do have milestones. So if you get behind, you can always, we'll clue you in on when to start with the next milestone.

Or you can just sit here and watch up on the screen and follow along that way as well. Then we're also, at the end, we're going to show you that we can open up existing widgets. And we're hopeful we'll have some Q&A, but not terribly hopeful. So hopefully we don't run too long.

So why Dashcode? So why did we build this? Now, if you look at this set of steps, this workflow, this is how you've had to create widgets thus far. You had to, the images that you needed for your widget, the front and the back, you had to create those yourselves using something like Photoshop or a graphics editor of your choice. Well, I don't know about you, but Photoshop's not one of my skills.

And so the back is extremely challenging. It has some textures. But once you've got your images together, then you needed to use the HTML and CSS to provide the structure for your widget, defining all of your elements. And you would use your favorite text editor to do that as well. And then to add functionality to your widget, you needed to use some JavaScript code, and you had to write that. And then the fun begins.

And then it's the process of bundling it up into a bundle in the Finder, double-clicking it, and then you have to write it down. running it in dashboard and see that it doesn't work, go back, edit the stuff, and go through that whole process. And it's not very efficient, it's not very good. And you don't even have any debugging facilities. So let's see what DashCode brings to the table for us.

The images are created for you. So we actually create the front, the back. You can customize those images. All of the buttons and parts that we have come with our own images and you can customize those as well. So for by and large, you don't have to create those images. We do a good job for you. You still can use your custom images, however.

Now we auto-generate the HTML and CSS for you. So as you drag in parts, you're moving elements around in the Canvas, we're constantly writing those changes out to the HTML, the CSS, and the JavaScript. And we start out with some very nice templates. They come with lots of JavaScript code written for you already, so that reduces the amount of code that you have to write.

Instead of just testing in Dashboard, you actually get to run it inside of Dashcode itself. You can use the debugger to its full extent. That eliminates, in essence, this whole package. You don't need to package it up, run it from the Finder, run it in Dashboard. It's all just taken care of for you. You can also deploy your widget when you're ready to give that widget out for your own purposes.

So there's some additional things we bring to the table. We have project-wide search. So we have a spotlight view built into Dashcode. So it's very easy to find the variables and things that you're looking for. We also have parts. We have a whole library of parts. We have sliders, buttons, gauges, indicators, lots of different things that we've built to make your widgets much more beautiful and functional. We also have built most of those parts on top of the Apple Classes. So if you've seen the session yesterday, Christian talked about Apple Classes. We just built right on top of it. You don't even need to know how they work. You just drag them in.

and we have workflow steps. There's a little view in the bottom left-hand corner of Dashcode that actually walks you through the process of what's necessary to create your widget. And we'll finish up here with widget opening, opening up an existing widget. And we'll have a demo at the end for that as well. So would you rather use the old broken or new hotness? Yeah, so that's the question.

Now, what I'd like to do is bring up and invite Max. It's in the spec, Drukman. I don't know how many times he's told me it's in the spec, so he's our UI designer on the project. And he's going to give us a quick tour of Dashcode to give you a feel. Max, take it away. Thank you, Tim. Good morning, everybody. This is a hands-on session, but for now, we're going to start hands-off while I take you on a tour of Dashcode so we're all familiar with it when we start building our widget together.

So, sit back, relax, watch me do some work, let your coffee kick in a little bit, and I'm going to show you around Dashcode. Now, the first thing you'll notice when Dashcode launches is that it's template driven. As Tim mentioned, the templates give you a lot of power and really get your projects up and running very quickly. I'm going to dive right in here. You're going to want to check these out, but we're going to start with the Podcast Widget. And let's have a look at what the Podcast Widget does for us.

This template creates a widget that displays and plays a podcast episode. Well, it doesn't get a lot simpler than that. Let's check it out. I'm going to click the choose button, and Dashcode is going to create a new, untitled widget project based on that template for me. Now I'm going to show you around the Dashcode interface a little bit, and then take you through some workflow.

So front and center, right here, we have the Canvas. Now the Canvas is Dashcode's interactive visual editor, where I can do things like change the size of my widget, Select elements in my widget, move them around with guidelines to help me, and directly edit elements like this text.

Yay. Directly to the left of the canvas is the Navigator. The Navigator gives me a structural view of my widget and lets me select elements on both the front and the back. Moving on down in the Navigator, we have the Attributes view. Now the Attributes view is where you manage all of the meta information about your widget, such as its identity, its access and extensions, properties, localization. We'll get back to this in just a few minutes.

Now Dashcode also gives you access to previewing and editing important images in your widget, such as the default image, which is the image that splashes in Dashboard while your widget is loading, and the widget icon, which is the iconic representation of your widget in the Dashboard widget bar.

So that's the Navigator. Now directly below that is the Workflow Steps view. As Tim mentioned, this is a built-in help system that's template-based, so the help is different with each template. And it walks you through the process of taking your project from basic template to finished product. The steps are really handy. They really help you along the way, show you what's going on. They help keep you on track in the process and even show you around the interface to tell you where to set certain important properties.

In fact, I'm going to use the steps to build a widget while I show you the Dashcode workflow. So let's have a quick look here. We can see that there are five steps in this template. Two are marked as required. I'm just going to do the required steps today to keep it quick. Let's see what the steps want us to do. So step one, set the source podcast for your widget. Seems simple enough. Looks like I've got to set a podcast property.

Well, I want to know where to do that and I'm going to let the step tell me. If you'll notice, there's a little button next to the label. That's called the go-to button. And whenever you see that in Dashcode, you can click it and it will take you to the place in the interface that it's referring to. I'm going to click on it and it's going to take me back to the attributes view. And not only that, it actually focused in on the field that I need to enter the data in.

And that's the podcast URL. So it just so happens I have a podcast right here. And how do I set it? It's pretty simple. I'm going to drag it out of Safari and drop it in there. So I've now just set the feed. So basically, I'm done with one of my steps. I'm going to mark it as done and close it. I'm essentially halfway through the required steps of turning this template into my widget. Let's see what the next step is.

It's provide an identifier and version number for your widget. This is very important because it's the thing that uniquely identifies your widget as being yours. Let's see where we set that. I'm going to click the Go To button again. And you can see that we stayed in the attributes view, but now we're focused on a different field, and that is the widget identifier field. So I'm going to enter a unique identifier for my widget. It's in reverse notation. So com.company.widget.name of your widget.

whatever you want to call it. And the version number, I'm going to leave at version one since this is the first time this widget has seen the light of day. I've set the attribute now, so I'm going to mark it as done. That's basically it. I'm done. This widget is now ready to roll.

But of course, I don't want to stop there because I really want to make this widget look like it's my widget. We don't want hundreds of widgets out there that look exactly like our templates anyway. Here's where you want to get into customizing the look and feel of your widget.

Nice, but I may want to change the color of something, like the background. Now, the background element is, you can see over here in the Navigator, which has opened up to show me what I have selected. It's an element called Front Image. So that's the image that represents the background of the widget. And I can change its look by going to the Inspector. Just click the Inspector button and it brings up the Inspector, which lets me set all the important attributes of of a selected object.

[Transcript missing]

I'm going to show you how I do that in just a second. So I've added a button now, but what does it do? Well, it doesn't do much of anything because I haven't told it what to do yet. But I can do that very simply using the Inspector again. So with this element selected, I can go back to the Inspector to the last tab, which is the Behaviors Inspector. Now the Behaviors Inspector is where I wire up functionality to the elements of my widget.

So I can turn this into a button by simply setting a handler on the onClick event. I'm going to do that just by double-clicking, which turns it into an autofill field and also a pop-up. So I happen to know already that there's a function called Subscribe that will do exactly what I want, and that is pass off the URL of the feed I've given it to iTunes so it can be subscribed to. So all I need to do is say Subscribe. So now I've wired up my event.

This is now a button that my users can use to subscribe to the podcast. And you'll notice also that once I wired up this event, I got a Go To button again. So the Go To buttons, again, wherever you see them, they will take you to the related part of the interface. So I'm going to click on that, and it'll take me right to the source code. So here in the Embedded Source Code Editor, I have this function that I've just wired up.

So I can go in and start editing right away. Or check it out and see what exactly it does. This is obviously a pretty simple one. Now the source code editor gives me access to obviously the JavaScript file, but in addition the CSS and the HTML as well. So I can go in and edit by hand if I want to.

But I probably don't want to. I certainly don't want to. For those of you who have built Widgets yourself, you know that there are more files than that. Don't worry, we're not hiding those from you either. I can bring up a files view, which replaces the steps view and gives me access to all of the files, including the Apple classes, an English project, all the images.

It's all there for me. Now, what have I done? I've taken a template, I've given it a feed, I've given it a unique ID, I've customized its look a little, and I've added some functionality. So now the next thing I want to do is see if it works.

All I need to do in Dashcode is hit the run button. And it launches in Dashcode's run environment, exactly like it would in Dashboard without the hassle of having to package it up and install it. And it runs exactly like it would in Dashboard. It's a full working widget. everything Here are my episodes of my podcast. Let's go ahead and see if I did my work right. Ah, here we go. How drunk was Mel Gibson? Let's find out.

How drunk was Mel Gibson? Hi, I'm June Thomas with the Slate Explainer podcast for Tuesday, August 1st. All right, well, we don't have time for that. You'll have to find out how drunk Mel Gibson was on your own. But let's say, so what else did I do? I stuck a button on there. Let's see if that works, too. Subscribe to podcast. What does it do? Hey! Look at that.

It's a whole demo that worked. All right. That's my demo. Back to you, Tim. TIM BUMGARDNER: Thanks, Max. Awesome. Back to slides. All right, this is where it gets fun. We're going to start our hands-on section. So hopefully you've all got your sample code. And we're going to go through this, in essence, a very similar process, creating a countdown timer.

So this is what we're going to do in our hands-on section of today in the session. We're going to take a template, and we're going to customize its appearance. Just as Matt showed, we don't want 1,000 widgets out there that look exactly like our templates. You should take something, create it, and make it uniquely yours. And then we're going to add some custom code to this widget that will add additional functionality that's not built into the template. And then we're also going to take advantage of the parts.

And then we'll go through the process of testing the widget. And then we'll finally show you how to deploy the widget. So that's what we're going to cover in our hands-on section today. So we'll start off with the first part, which is designing a widget. And these are where we're going to get started creating our templates. We're going to choose a template. It'll be a countdown template. We're going to set up the specific options for that template.

And then we're going to change up the graphics a bit, jazz it up. And then we're going to add a custom image to show that not only do we have built-in images, but you can still use all of your custom images. So in order to do that, I'm going to bring Max right back up.

Yeah, don't go away. Come on. He's going to walk you through this first section of our hands-on session. And again, if you don't have the sample code, just watch us. And if you get behind, we do have milestones in the next section. All right, Max? Hi, it's me again.

I was just getting comfortable down there. All right, so here's where we're going to go hands on. So anybody who wants to follow along in the studio audience, let's get going. So before we dive in though, I want to show you what it is we're building. So I have a widget running here in Dashboard. This is what we're building. This guy right here. And what this widget is going to do is it's going to count down to the Dashcode lab time.

Because for some reason the lab isn't right after our session, and you know, you've got a lot on your mind. So we want to remind you. So what we're going to do is build a countdown. It's a pretty simple kind of widget, but I'm going to show you how easy it is to do it. So as you can tell, it's got a big piece of custom art on it, but the rest of it is really straight out of the template.

So let's dive in. So for those of you who-- hey, I don't want you. I want you. So if you haven't already got Dashcode running, it's where you might imagine. It's in Developer, Applications, a folder you should all be familiar with, certainly by now. Let's go ahead and launch Dashcode.

So, you should be seeing what I'm seeing. It's the template chooser. This time, we're going to start with a countdown template. It's the second one from the left. Go ahead and choose it. Click the Choose button. Is everybody with me? Yeah? Good. Okay, so not much to tell you about this. It's a countdown template. It counts down days, hours, minutes, and seconds to a target time that you can set.

Now, I'm going to bring back my finished widget. I'm going to show you, well, it's a little bit different. So you'll notice that the built widget is taller and narrower. The colors have been changed, and of course that custom art is there. Also, we're only counting down hours, minutes, and seconds since our target is today. We don't need any days.

So let's go back and see if we can build that together. Now the first thing we're going to do is change the size of our widget. And the way you do that, very simply, in the canvas, you grab this resize grabber on the lower right side of the widget and start pulling on it. Now if you'll notice, there's a HUD that shows us the value. So as we're changing the size of the widget, the numbers are reflecting what size we're going for. And I want to get about 300 by 240.

That's about what I'm going for, but it doesn't have to be perfectly exact, because we're all designers here, not engineers, right? So, 301 by 240, that's good enough for me. So, has everybody got their widget looking pretty much like this? Again, we're all designing, so it can be pretty close, but it doesn't have to be exact. So now one thing you'll notice is that the background image, the front image it's called, resized when I resized the widget. Now the reason it did that is because it's set to do that. Let's open up the inspector and see where that gets set.

So if you go to the Metrics Inspector tab, that's the one in the middle that looks like it has a little ruler on it. You'll notice that about two-thirds of the way down, there's a section called Auto Resize. And I've lost my selection, so I'm going to go re-select it again. And you'll see springs. So anybody familiar with the Interface Builder should know more or less what these things do. They tell this element to resize along with its parent.

We don't want it to do that, because if you remember from the widget, we want it kind of smaller than the widget. So we're going to turn those off. Now the way we do that is just click on them. You'll notice that they're in pairs, horizontal and vertical. So you just click on each pair until you've got no springs set at all. Is everybody with me? You seeing what I see? So now, when I resize my widget, if I cared to, the front image would not resize with it.

So one other thing I want to tell you about the front image is that in all of our templates, it comes locked. That means you can't resize it directly in the canvas. And the reason for that is because you usually want to treat this element sort of as like a background object. So I can do things like drag select starting on top of it. And the way you can tell that it's locked, which is perhaps a little subtle, but the resize handles are gray instead of blue.

But we're going to unlock this. So I want you to make sure you have it selected. Click on it in the canvas. And we're going to go up to the menu. Arrange. Unlock. Is everybody following along? Who cares to? So we're going to unlock it. And now that means that I can grab it and start messing with it.

And that's exactly what we're going to do. So let's grab the bottom left corner and resize it. And I want to get this to about 100 tall. And, oh, I don't know, 230 wide. Again, you know, this is design. Hey, that looks pretty good. Everybody with me on that? Is anybody following along? Or can I just like, you know, okay.

So now we've got this thing pretty much sized the way we want. If you'll remember, there were a few things we want to get rid of because we don't need them. For instance, the days countdown. So let's go ahead and delete those. I'm just going to click on them in the canvas. So this first zero on the left, that's the days counter. And you can see in the navigator, it's telling me what I have selected. I'm just going to hit the delete key to get rid of it.

Pretty simple. The same with the days label. We don't need that. Delete key. And here's where the hand-eye coordination comes in. This separator. There we go. Hey, I got it. Does anybody else have it? Okay. Delete. There you go. Pretty simple. So now we have, we're only counting down hours, minutes, and seconds. That's exactly what we wanted.

This event label, we don't need that either. Let's go ahead and delete that. So basically we're tearing our template apart. I don't know if you noticed that. But we're going to start building it again soon. So now the last thing I want to do is take this whole element and move it down. Because if you'll remember from our built widget, it's not at the very top. It's about three quarters of the way down.

So I'm going to drag select it. So I'm going to start a marquee select outside of the widget until I have it all encompassed. Let go. So now I've selected the whole thing. So that's got the front image, the counter, all of those elements are now selected. And I'm going to drag them down. Now here's a little gotcha. Make sure if you're going to drag this down now, make sure you click on what appears to be the front image because there can be some reselection goofiness if you don't. So I'm going to just drag this down. Hey, look at that.

If I hold down the shift key, I can constrain it to an axis, which is pretty much what I want to do. So I just sort of keep it pinned to the right side. And I want to get this down so that the Y value, if you'll see in the HUD there, is about 100. 100 is a very popular number today, I think. At least with me.

So there, I've just moved it down. It's about where I want it. Again, it's design, whatever you want. Everybody with me? Yeah? All right. So now we'll notice that the info button is kind of hanging out by itself. I want to bring it up now to match the rest. So just grab it and move it up. And on this one, you know, I don't even care what the numbers are. I'm just going to do this by eye. It just should be, you know, sort of largely in the lower right corner of this group of elements.

Everybody got that? It's pretty simple. All right. So now we've got the template aspect of our widget is done. But what about that big old graphic? Well, that's why we wanted you to download the source code, the sample code. So if you've downloaded the sample code, there's a folder called Milestone 1.

So go find that. And inside it, there are two PNG files. There's a Dashcode Lab icon and Dashcode Lab logo. Everybody got that? Who cares to? So all we need to do now to add our custom graphic is grab it. We're going to grab the logo and just drag it onto our widget. And I'm just going to drop it in the empty space of our widget.

There we go. I've added my custom art. So all I need to do now is make sure it's placed in the right place. I want it to be aligned with the upper left corner, and I want it to be the full height of my widget. So I'm going to just drag it until I get it into the upper left corner, and I know I've gotten there because the position HUD tells me it's at 0, 0, which seems like the sensible number for the upper left corner.

And so now it's positioned. All I need to do now is resize it, and I'm going to do that by dragging the lower right corner. So I start dragging, and I hold down the Shift key to keep it constrained so that I'm not stretching it out, and I'm going to make it 240 tall, which is the height of my widget. Once I get it placed, boom, there we go. Is everybody with me? All right, so now we've added our art.

We're getting pretty good at this. It was pretty darn close, but now the blue of the background of the countdown doesn't quite look exactly like I want it. I want it to harmonize a little better with my art. So let's go ahead and change the color of that object. So select it. You can select it in the canvas or in the navigator. Remember, it's called Front Image. And let's go back to the inspector.

Now this time we're going to go to the Fill and Stroke Inspector, just like I did in the tour earlier on. We see that it's got a glass texture and a blue fill. Let's change its texture. Glass is nice, but I like rounded glass, which is a glass, but it has this nice rounded horizon line. Makes it look a little sexier.

And let's make sure that the color harmonizes with our placed art. So click on the color chip right below there to bring up the standard color picker. And we're going to use the magnifying glass to pick a color out of our placed art. It's a pretty common little design technique. I'm going to grab the sort of darker blue of the Dashcode logo that's embedded in our beaker and just click on there to pick that color.

So now I'm getting some more color harmony, and I'm digging that. So the next thing I want to do is just change the black background of the counter. And I'm going to do that by selecting it, this time in the Navigator. So if we look in the Navigator, we see here's the structure of our widget. There's a group of elements called Timer. And that's all this group here, the background plus all of the digits.

I'm going to select Timer BG, which is the background, as you might imagine. I still like it in black, but let's turn it to solid. So we just pick solid, right? And let's give it some opacity. So right down here towards the bottom, you see there's an opacity slider. I'm going to shoot for 50%. Let's see how good I am at this.

Hey! That's hand-eye coordination for you. So now I've got that, and I lost my selection, but that's no big deal because I'm all done with that. So now, if you're following along, we've done all of the, just about everything we need to do to the front. There's one little thing left over, it's a detail, but it's a pretty important one, and that is that the close box is kind of hanging off in space.

And I know Christian would be upset if we left it there, because he's a stickler for that. And what I want to do now is just, I'm just going to drag it so it's touching the edge of the beaker. And again, I'm just going to do this by eye.

There, hey, that was pretty simple. Much easier than going and setting values in an Info.plist, certainly. So now our front is all done. We've got the close box where we want, we've got a custom art, we've got our timer all whiz banged. So let's have a look at the back and see what's going on there.

Well, there's not much to it. It's pretty close to being done. The one thing that sort of stands out is now the close box is sort of not in the left corner. So I actually want to fix that. Now the background image on the back is called back image, which maybe you could have guessed because the one on the front is called front image. But the back image is the one I want to adjust and just like the front image, it's locked.

So, and it also has spring set. So just like we did on the front, we're going to undo all of that. So we're going to go back to the metrics inspector, the one in the middle that looks like a ruler, and turn off the springs. So that it looks like this, no springs in this thing. Great. Everybody with me? Good.

So, the next thing we need to, who remembers what you need to do next? Unlock it. Thank you. I wish I had a prize. The prize will be you get to keep this widget. Go back to the Arrange menu and unlock. Now we can move this object around.

All I want to do now is just move the left side of this thing in so that it's aligned with the close box. I'm just going to use the close box as an alignment guide. If I wanted a custom alignment guide, I could of course drag one out of the ruler and put it in place. But I'm just going to use the close box as my guide.

There, pretty simple. And, you know, if I'm feeling extra fussy, I might take the "developed with Dashcode" logo and stick it in the middle, which I get nice guidelines for. You can do that too, if you like. But I won't make you. So now we've got our front and our back all laid out. Hey, that's cool. So what's left to do? Almost nothing, except, of course, we have to tell this to count down to the right thing. And the place we do that is in the attributes.

And there's actually one thing I sort of forgot to mention. In the quick tour I showed you, we needed to set a widget identifier. And let's all do that here, too. So, The identifier comes on your machine, com.probably your username.widget.untitled. So whatever your particular naming convention is, this should probably be your company name. Let's rename this thing. I'm going to call it Dashcode Lab.

and Daaah. There we go. So is everybody following along? Yeah? You sleeping? Okay. Me too. So now I've set the identifier, just like in the tour, version one is good. This is the first one we've got going. Now we're going to skip right down to the properties area. Now on the countdown template, it's pretty cool. There's a number of ways we can set what the countdown target is.

Now the countdown target is what we're counting down to. And we can set it by date and time, that is specifically entering a date and a time. An iCal event, so we can just drag an iCal event out of iCal into the widget. Or a shared calendar, so we can publish a calendar like on .Mac and we can point to it with the widget so it can constantly update. We're going to go with date and time because we know what we're counting down to.

And so with that selected, now all we need to do is set what the actual target is. So it's today, right? 8. Let's see if I remember what the date is. 10, right? Am I right? And we want to give you a few minutes to get there. The lab is at 12 noon, but let's make it for 11:55.

So, for those of you playing along, you should be seeing the same thing, set for date and time, 8/10/2006, 11:55 AM. Right? We're all there? So when the target is reached, the widget is going to stop at zero. We can tell it to do different things, and you're going to see a little bit of that soon. But we're just going to go with that for now.

So now we're just about done. Let's check out the default image and see how that looks. Hey, it looks pretty good. Not only does it look pretty good, it looks a whole lot like our widget. And the reason it does is because the default image is actually being updated for me while I edit the front of my widget.

And you'll notice that the time isn't in there because those are set not to show. I could turn those on if I wanted, but this is generally how you do a default image where you have the basics of the interface but not the content show up first. So we don't need to do anything here. I like it.

So let's have a look at the widget icon. Well, that's pretty bland. It's not a great icon. So let's jazz it up a little bit. Let's go back to our sample code and that other PNG file, Dashcode Lab icon. So as you can imagine, How do you do it? You drag it in.

Pretty darn simple. So now our icon's done too. So we've got our front, we've got our back, we've got our default image, we've set our attributes, we've got our widget icon. Is that it? I think it is. Let's run our widget. So everybody who's following along, on the count of three, let's run our widget. One, two, three. Click run and voila. You should be seeing what I'm seeing. There we go.

Everybody? Yeah? All right, cool. Back All right, thanks, awesome. Very cool. Hopefully you're all following along and got the same results. And Max has shown you how easy it is to start with a template, add some custom art to it, change up the appearance, and create something that's really your own widget.

Let's look on to our second part, which will be part two, and that's working with the code. Now, if you're not in Dashboard at the moment that the countdown timer hits zero, you're not going to realize it hit zero, unless you happen to be living in Dashboard, which really is not the intent and purpose of Dashboard. It's something that moves in and out. So we'd actually like to take and add some additional functionality, so it'll actually give us some visible notification that our Dashcode lab is just about to begin.

So we're going to do that by adding some code to the target event when it runs. And we're going to use Quartz Composer to actually add some cool graphic effects to this as well. And then, of course, any time you're working with code, you're probably going to have to test and debug.

And so to do that, I would like to invite another coworker, another member of the Dashcode team, Han-Ming Ong, and he's going to walk you through part two. Hi, my name is Han-Minng Ong, an engineer in the Dashcode team. So, in this part of the hands-on, we're going to take what Max has done visually, add more customizations to it, coding, to see if we can make it more interesting. Let's get started.

To do that actually, we're going to open up milestone two. This is because the project we're going to give you has additional resources in there and some code that we've added in is currently commented out. So essentially, you can save away what Max has done or I'm just going to throw it away.

All right. So let's go to your sample code. Now, I'm going to go slow because there are people following. And just for the benefit, I want to be clear. So, close milestone one, twiddle open milestone two, and you should see Dashcode Lab Widget Proj. Double click on it.

Okay, visually this is what Max has done. For those who are following, are you with me? Good. Thank you. So first thing I want to do is, and this is important, like Christian has said, when you have a new widget, you want to customize the widget identifier. Now, this is not really a new widget, but I want to do it because I can. So go to your Attributes view by clicking Attributes in the Navigator, and go to your widget identifier, okay? Give me a second. Everyone uses the Borac, right? Right, I'm going to change it to Dashcode Lab Part Deux.

For those who learn English from the 90 movies, you know Pad Deux, especially in English, means second version. So I'm going to change it to version two. So with that out of the way, what's important now is I want your eyes to scroll down to the middle part of the Attributes view, where it says "Properties slice". Now Max has already set the target to be five minutes before lab hour, and he has left the rest as default, which means it's going to stop at zero, the timer. If you scroll your eyes to the right of it, you'll see a little checkbox that says "Do Action". We're going to check that.

When you check that, what that means is besides stopping at zero, the widget is going to do something. And that something is the JavaScript expression in the text field. Right now it says it's an alert. So let's do it together. I'm going to zoom in for you. Check that.

Click in to select that. Now as part of this sample code here, we have given you some codes in there. And one of the codes is a function called GoLab. So let's type it in together. Lowercase g, O, uppercase L, A, B, open parenthesis, close parenthesis. Those who are following? Say return.

Okay, so let's look at what the function does. And to do that, we're gonna go to the View toolbar item. Now, we are always going to the ViewTubar item here in this hands-on, but those who know what Keyboard shortcut is, you can just do it by yourself. So, this View toolbar item, select files, and I want you to select the main JavaScript file, which is DashcodeLab.js.

Okay, so the source code view is now showing. Just like Xcode, we have a function pop up for you, which is the second pop up. I want you to click on it. Okay? Now, you should be able to find GoLab at the bottom of it. If you option click on it, you'll be sorted in alphabetical order. The default is the positional order in the file. So I'm going to go to GoLab. I'm going to resize it so I can show it to you on the screen because the font size is obviously bigger here. And please uncomment the first chunk of the code.

While I briefly explain what this does, what it is doing is looking for the additional resources that we added to this project, which is invite.html, and once it finds it, it uses the widget.openURL function to open it. And I left a little comment in there to remind all of us who are following that when you open an external file, you need to turn on the file access. Okay? So, it's a meta information, so we do it in the attributes view. Let's go back to the attributes view by selecting attributes in the navigator.

Now this time go to the Network/Disk Access Slides and see the checkbox. Allow external file access. Now this is important. If you don't check that, you will not see the HTML coming up as a reminder. So let's go ahead and I'll check that. Oops. There we go. Okay, we're all set actually. But if you were to run it now, nothing will probably happen because the lab is an hour and a half from now.

You can set the target date to test it. You can set the target date to be 10 seconds from now, run it, and then wait 10 seconds for something to happen. But we're going to do it in another way that's probably easier in your development cycle. Okay, let's do it together. To do that, let's go back to the front.

Let's resize it a little. We're going to add a test button in there. Okay, now where do we get the button from? The library. So go to your toolbar, open up library, Max has already explained what this is about, so I'm just going to dive right in. Make sure the front is twiddled open and select the buttons subcategory. See a series of buttons here. I'm just going to select the front. Losange here. Drag it over to the canvas and drop it into any open space. So this is good.

Because this is just a test button, so I'm just going to leave the appearance as it is. But I'm going to change the label to test. Those who are following, are you with me at this point? Excellent. So we have a test button. We have a GoLab function. What do we do? We hook the behavior up. And to do that, Let's go to the Inspector Behavior. Behavior Inspector.

The movies taught me that. Let's see. All right, this is the last button right here. And the onclick event is selected by default, so we're going to double click into that to set the handler. Let's do that. And we know that function is Golab, so it auto completes.

So just type GO and you should see Golab. Hit return. You know that it successfully hooked up when you know, unclick the event, name becomes bold. Okay, so we are actually ready to test it. Let's run it. I'm going to close this, make more space. Go to your toolbar item, hit run.

Excellent. Those who are following, please hit run test with me. And there you go. So you say, "Dashcode Lab, the new hotness, please come and see us and ask us questions." Alright, so the first part of the hands-on is done. Let's see if we can add more pizzazz to it, okay? Now, you see the bubbles in the HTML? Let's see if we can add that to our widget when it's running. Okay, I'm going to close that, Safari. We don't need that anymore. Stop the widget.

Okay, now to do that we're going to make use of Quotes Composition, that gives out the bubble. To have a nicer effect, I'm going to make the widget taller. Okay, so that's what I'm going to do now. So go to your front, sorry, go to your widget, by selecting it in the Navigator. Open up the inspector. And this time, select the matrix tab, which is the one in the middle. I do want some precise measurements as opposed to Max who is dragging it, because I want to have some effect coming out right. So let's make the height to 320.

Excellent. Okay, now I'm going to drag select from the bottom right so I can select everything and bring everything down. It gets a bit tricky here, like Max said. Make sure you select the bottom of the beaker. Okay, and just drag it down. and just make sure it's flushed with the bottom of the widget. Now the close box is a bit off. Simply select it.

and align it to the top left of the beaker. Okay, those who are following, you got your front set? Okay, great. Now let's look at the back to make sure it looks okay. Oh, it's a bit off. No problem with that. This time I'm going to select from the top right. Okay? Because it's easier. And again, I'm just going to using the closed box as a guideline, just drag it down.

Let's go to the front. OK, now that the widget dimension is ready for us to drag in the Quartz composition bubbles, go to your sample Quartz. And you should see in Milestone 2, a QTZ, which is the extension for the Quartz composition, called More Bubbles. Drag it and drop it into an empty area on the canvas.

Now at this point you can drag and position it, but again I want some precise measurements, so I'll go to the inspector by clicking on the inspector toolbar item. The metrics pane should be up there. All right, so please enter these numbers with me. The width should be 163. and the height, 250. Okay, now I want it to be anchored to the top left, so make it zero top, zero left.

Okay, now as you can see from the screen up here, the course composition is not opaque, but it's currently opaque. But we don't want that because we want the beaker to show through. Now, to customize some of these attributes, you go to the Attributes Inspector. Depending on the part that you drag in, This part here could be different. Okay? Right now it is a Quartz composition, so it's showing the customizable attributes for the composition. I want you to uncheck isOpake.

Everybody got that? All right. So this is what we're going to do. When you run the widget, or when the widget is running in Dashboard, we don't want the bubbles to show up because, you know, it's not the time yet. So we actually want to use a CSS key called visibility to first hide it. And then when the time is up, we will use JavaScript to set the visibility of that element to be visible. Okay? So let's go to the files view and bring up DashcodeLab.css to set that attribute.

All right, select dashcodelab.css in the files view. Now just like DashcodeLab.js, we also have a pop-up to help you navigate this file. But it is a selector pop-up. So I want you to click on the pop-up, second one, at the top of the source code view, and you'll see a bunch of selectors.

CSS selectors. I want you to navigate to the bottom of it, which says "Pound Composition." So another piece of code we left in there, which is currently commented out, is visibility. Those who are familiar with CSS, probably the majority of you, you can just type in visibility hidden into the composition selector. I'm just going to cut and paste, copy and paste.

Make sure your cursor is in between the braces. Okay, this is important. Everyone got that? Those who are following? Good. All right. Now we will go back to the JS file, the JavaScript file, so that we can unhide the course composition when time is up. So again, in your files view, go to JS.

Google Apps is selected. Now, uncomment out the second chunk. Now, I'm going to comment out the first chunk because I've already tested that and during testing I don't need to keep coming up. You can do that too. So we're actually ready to test. So I'm going to run it now. Go to the run toolbar item.

is a widget. I'm going to hit test and see what happens. So, now is a great time to introduce one of the great features of Dashcode, which is the integrated JavaScript debugger. You have seen it in Ted Goldstein's demo. This JavaScript debugger is in Dashcode, so you can use it in real time when you are running to debug your software. So let's see what's going on.

At the bottom right, There's a status toolbar message that says there's a null value exception somewhere. Okay? Now there are various ways to find out what happened. I'm going to go through a couple of ways. First, I'm going to go bring up Run Log. There are usually messages in the Run Log that tells you what's going on. Okay, go to Run Log. Again, you go to the View toolbar item. Select Run Log.

And there you go. There's a message there that says there's a null value exception somewhere in line 416. So if you select that now, He'll bring up that line. It's kind of hard to see, but it's a gray line up there. OK, from code inspection, we're kind of expecting that QC might be now. So how do we verify that? One way is to use the Evaluator. The Evaluator is a JavaScript console that let you evaluate the JavaScript runtime. And also, it is able to evaluate any JavaScript expression that you type in. Let's take a look at that.

View menu item, toolbar item, select Code Evaluator. Now because the Code Evaluator shares a space with the source code view, so it takes over. But we actually wanted to open in a separate window so that we can look at both at the same time. I want you to click on the Open in Separate Window button at the bottom left.

Okay, so you should see Code Evaluator up here. Now I'm going to enter, type in QC just to see what it is. QC. So indeed it is null. So something is not initialized correctly. And what happens if I say qc.style? We see we get the same exception back.

Okay? You probably perceive by now that my acting is really bad, so we actually planted the exception right there. So, what we are doing is, in this line right here, We're trying to get the HTML element by ID. And we probably misspelled that. Okay, the composition name, the name, the ID name is called Dash1 right here, composition Dash1. But, From the Navigator, one way you can find out what the name of the ID is from the Navigator. Select it now.

Course composition gets selected. And you'll see that the ID name, most probably, is composition. I say most probably because the navigator tries his best. If there's an ID name, it will show you. So let's test our hypothesis is if Composition name is really called Composition, so I'm going to try it here. Document. Dot, Get, Element. Those who are following, please type in with me. And you will see that it actually auto-completes as well. So hit the escape key. Get element by ID. There you go. And we'll just enter composition.

So it allows me to play with it, to play with the runtime to see whether I'm doing things correctly or not. If I hit return now, indeed it is a valid JavaScript runtime object. Okay. So I'm going to close the evaluator, stop the widget, and change the name to Composition. Okay, now we are really ready. So, let's hit run in the toolbar. Widget comes up. Again, on the count of 1, 2, 3, we'll hit test together. 1, 2, 3. Wait for it. Bubbles.

We're almost done. We're almost done with this hands-on. Right now, I just want you to clean up with me so that we can deploy it. So go to your GoLab function, uncomment out the first chunk so that it can have both effects. Save it. At this point, I'd like to invite Tim up here again to finish up with the deployment. Thank you.

Awesome. Great job, Han-Min. Thank you. Very cool. So he showed you how easy it was to add a little bit of JavaScript code to add some additional functionality, took advantage of the great technology which is Quartz Composer and show some very cool graphics in our widget. So let's finish up on our hands-on portion, which is deploying a widget. So we've got this widget, looks great, it's awesome, but it won't do you much good if you want to give it out to somebody.

Or it won't do you much good if you quit Dashcode because the widget goes away. So we actually have built-in functionality to deploy your widget. And there are really in essence two choices when it comes to deploying a widget. Whether it's going to be something I'm going to build for myself or whether it's going to be something I want to give out to my friends or maybe even submit it to Apple to put up on the Dashboard's download site. So we're going to go and we're going to walk through the hands-on deploying a widget. Let's back up one. And let's go over to the demo machine. A demo, please.

All right, great. So I'm going to clean up one last thing. I'm going to delete, and this is all hands-on, so follow along. We're going to delete the test button. We don't want that in our widget. And then we're going to go ahead and save the widget, so I can go to the File menu and choose Save.

Now, you'll also notice under the File menu, there are two deploy choices here. Now, remember, I mentioned that there's two choices to make, that you have a choice to make. And the first one is if I want to deploy this widget to give out to somebody else or to submit up to Apple, I would choose Deploy Widget. And it would give me a simple Save As panel, and I can name my widget and decide where I want to save it.

It creates a stripped out, simplified widget for you. As you notice, we're actually editing a document. It's not really a widget per se. Until we deploy it. And when we deploy it, it takes out all of the metadata, removes all the additional code we put into it while we're designing it, and saves out a copy for you. And the one we're going to do today, though, is we just want to build this widget for ourselves, deploy it. So we're going to go ahead and choose. So go with me. We'll choose Deploy Widget to Dashboard.

and when we do that you see that we get to name our widget. I'll go ahead with a Dashcode lab.widget, that's fine. And you'll notice that there's a little bit of text here. And what it's telling me is that we actually look through your widget and we look to see what technology you're using. And we know that there are some minimum versions that are necessary for that technology to run.

So for instance, we added a Quartz Composer part. Now Quartz Composer actually shipped with 10.4.7 as a web plugin. So you can't run this widget on anything earlier than Tiger. And that's a key point here is that you can actually build widgets that run earlier than Leopard. And if it didn't have the Quartz Composer, I probably would have got a pop-up here that would let me choose between 10.4.0 or 10.4.3 depending on the technology.

So we can build in some backwards compatibility into our widget. Let's go ahead and click deploy. And what you're going to see is we're going to actually switch into our install process that would happen as if you double-clicked it in the finder. And it's asking me, do you want to install that? I'm going to go ahead and click install.

It's going to take me into Dashboard and it's brought up my little sandbox. I can say, yeah, I want to keep this. I'm going to click keep. And there you have it. You have your finished widget should be running. Has everybody got their widget? All right, well done. Cool. So there is your widget. Let's go ahead and leave that. And back to slides, please.

Okay. Now, what we've shown you is terrific for starting out with new projects. Well, no one's had Dashcode until this session. So you've obviously been writing your own widgets. What can we bring to the table for you with your existing widgets? And I'm going to give you a quick demo about this in just a minute. But it's great for non-Dashcode widgets, for something that you've already started. It allows you to take advantage of much of Dashcode. So you can write your source code.

You can debug the widget, change all the settings that are not graphically related. And we'll talk about that in a minute. And there's no automatic code generation. So we're not changing your code. It's your code. It's your HTML. It's your CSS. It's your JavaScript. It's up to you to change. And to do that, I'd like to go ahead and give you a demo. So this is hands-off. It's just a follow-along up here. And I may move this. I threw this fairly quickly. So let's go ahead. Back to the demo machine, please.

Oh, I knew I do. I do not speak Dvorak, so my keys won't work for me, so I'll have to switch it back to US. I was wondering why Command-W was bringing up the wrong thing. All right, I'm going to drag in my demo here. I'm going to simply take a Voices widget, and this is a shipping Dashboard sample. And I'm going to drag that right on top of Dashcode. And you'll notice that it opens up. I've got the widgets showing here. And I'm just going to go ahead and run this widget to see what it does.

So let's go ahead and run. Welcome to Voices. Okay, it simply speaks a voice. It's got a little text area here for me to type something in, so I can type in hello. I can pick another voice and, oh, I always liked the hysterical, it's kind of funny. Let's pick this one.

All right, then I can speak whatever I've typed in. There you go. So it's just an exercise of the various voices. Now, when I look at the list of voices, I notice that it's missing a voice. Leopardchips with a very cool voice in his name's Alex. So let's go ahead and add that voice to this widget. So I'm going to stop. And I'm going to take advantage of our search, our project-wide search, our spotlight functionality inside of Dashcode. And I know that that element that pops that up is a select element. So I'm going to go ahead and just type select.

And you'll see that the view changes out over here. And it shows us the objects that match that select. So it finds that for me. And it also shows me that it's in my HTML. And sure enough, in my HTML is the list of voices here. So I'm going to copy the second one. And let's paste it down here.

And I'm going to call it Alex. That's the name of the voice. And it's just as simple as that. I'm going to go ahead and hit Run. Now listen to the quality of the voice. Welcome to voices. Well, not yet. When we switch it, we'll hear the voice. So I'm going to switch to Alex. Hi.

I'm Alex. That's a much higher quality voice. Now, I could go ahead and type in some text here and hit speak, but that would be way too simple. So let's do it the geek way. I'm going to go and actually use the evaluator as well. And I'm going to talk to this widget as it's running.

And I'm going to go in here and type document, get element, and hit my code completion. And I know that it's text input is the name of that text area. And I'm going to simply change the inner text. It's equal to, boy, I hope this works. Okay. And now you'll notice when I hit enter, watch this area right here.

I just inserted that text by talking directly to that DOM element and changing its inner text. Now, I could click the speak button, but again, that wouldn't be any fun. So let's go ahead and type in the function. I happen to know that there is a function in here in the widget called speak. And when I hit speak. Boy, I hope this works. Okay. Okay. So I spoke that easily enough. Now, let's actually go back to the source of this and look at that speak function. And I'll find it here.

And I'll put a breakpoint. Now, I don't need to go back and say, let's debug this widget. In essence, we're always debugging the widget. We can take a look at its runtime, we can set breakpoints, and go from there. So I'm going to go ahead and go back here and click on the speak.

And you see it breaks. And it stops on our function here, a speak. Up here in the top portion is our stack frames and variables. If we were in a stack frame of multiple, in essence, stack frame, we'd actually have additional slices. So I can see the variables for each stack.

I can also step across this for a minute. Let's step over, step over, and we'll get right down to the code that's actually going to try to speak. And what it's actually executing is I'm an AppleScript guy for quite a while, so we're going to run a little bit of AppleScript here. And it's going to call and pass in this tech to speak.

So if I actually stop and hold there, we've got data tips. So it will show you the value of that variable. And we can also go up here and find the variable there. But if I don't know exactly where it's located in this frame, I like to go up here and find the variable there.

So I'll actually go ahead and just type text. And we'll search through your variables. And we'll find the variable that you're interested in. And if you double click it, it'll actually go find where it's in the outline for me and select it. So then I can just simply change the value by clicking here.

Actually, I think spell. Did it work? All right. And let's go ahead and hit enter on that. And you'll see that it changed the value. As a matter of fact, if I go back down here and wait, you can see that it actually changed the value of that variable. And I'll go ahead and continue on this. Wow. It actually did work. There you go. So it just was able to change the runtime of that object and execute it.

All right. So that's pretty cool. So I've shown you how you can take your existing widget and just using the source code editor and the debugger and the evaluator, you can work with your widget and continue working on it. And you'll notice that I am editing a widget. Now, what if I would like to take this widget and actually add some additional functionality to it? So let's go ahead and hide the source code for a minute. I'm going to bring up the library.

and you'll notice that what I want to do is I want to add a volume slider to this. And I'll drag it down and well, it's not letting me drop. Well, there's a very good reason why it's not letting me drop. You'll notice maybe at the bottom of this view, there's a gray bar with a little lock icon. And you'll also notice that I can't drag anything.

I can select it, but everything's locked. That's because the Canvas became a preview in this mode. And behind the scenes, there's been this functionality that we call the code generator. And I'm going to customize the toolbar. And I'm going to add the code generator up here so you can actually see it in action.

Now, when we open up a widget as we're editing existing widget, you'll see that the code generator is off. We're not changing any of the sources on view. So I'm going to go ahead and say, all right, now it's time for me to turn the code generator on so I can enable some of this functionality.

I'll click the start code generator. It notices that I have an existing widget. And what it's going to ask me to do is import that widget into a project so that I can work with it. So it'll leave your existing widget alone. But it'll copy it into a project and start working with it.

So I'm going to click start import. And we'll just call it voices. That's fine. And you'll notice that it switched over to voices. The bar went away. And now we're back working as if we were started from a new project. So now I can actually drag in that slider.

I can select this existing button. Let's move it out of the way so I have some room. I'm going to drag this over. And let's add an event to this, tie up the functionality. I'm going to actually create a new one. I'm going to show you a different way, a shortcut. If you contextually click on this button, or the slider, you'll notice there's an event. So I can choose on change and say I'm going to change volume. That's the name of the function that I want to create.

And what it will do is when I click add, it'll actually add the function for me. It takes me right to there, ready to type the code. So I'm going to delete that little bit. Go here, drag in my code. And again, it's a little bit of AppleScript that's going to execute. It's going to set the volume output when we run this. So let's go ahead and run.

Sometimes there's a little display. I've got my breakpoint, so let's take that out and run it. And here's our widget. Now you'll notice up here in the top right that the volume is now set to zero, or it's off. And watch as I move the slider. You'll see that the volume is going to change, and the volume went up.

So I'm actually using AppleScript to change the system volume. So now if I type in something, like hello, and speak at a softer volume. Let's do it right here. Hello. If I turn it up louder. Hello. Alright, there you go. It's just that simple. So I've shown you how easy it is to take your existing widget, work with it as that, or import it and start adding some additional functionality. Come back to slides please.

We might actually have Q&A. We've got five minutes. We're close. Get ready, Alan. All right. So what did you learn? We learned why you would want to use Dashcode. There's some obvious benefits. I don't think if you stop and think about it, adding that part, what it did.

When I drug in that slider, it added a div to the HTML, it set up the JavaScript function, I didn't have to worry about going to the CSS and placing it where I wanted it, which is a trial and error process. It just really does a lot of work for you.

We showed you in our hands-on how to design a widget, make it your own, customize its UI, we added some additional functionality to that widget, and then we showed you the process of how to debug that widget. And of course, we show you that Dashcode works and plays nicely with your existing widgets.

Who to contact? Well, Alan Samuel is your contact at [email protected]. We recommend if you like to, there's also other resources and samples that you can find at this URL. And there's a related session, which of course you now have a countdown timer. It's going to tell you when it is, today at noon, so please come and ask any questions or give us any feedback.