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

WWDC00 • Session 146

High Level Toolbox: DataBrowser

Mac OS • 43:10

Learn how DataBrowser enables your application to present data as the Finder does, simplifying your application development and delivering a more consistent user experience. Implement views and highly customizable lists with variable row heights and cells that contain text, icons, checkboxes, and progress bars.

Speakers: Jim Rodden, Johnathon Suker

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it may have transcription errors.

Good morning, everyone. Please welcome John Galinzi, User Experience Technology Manager. Sorry. Well, good morning. It's a great day, and I've certainly realized that I haven't had nearly enough sleep this week, and that's probably true for many of you. But this is session 146, and it's High-Level Toolbox Data Browser. You know, as part of our renewed interest in user experience at Apple with Aqua and Mac OS X, we've been sort of stressing this message that if you want to have great user experience and you want to deliver the Aqua look and feel, you need to adopt system control. That sort of has come through this year and it's come through in past years. And it's particularly true with 10. And data browser is one of those things coming out of Apple that's sort of a hybrid, high-level, powerful, new type of control. And we're going to talk about that this morning. But data browser is going to allow you to deliver exactly the user experience that we are delivering in lists, in Finder, and in other components of the OS. And it's going to do the right thing on 9 under Platinum. It's going to do the right thing on 10 under Aqua. So even though it's early in the morning, you need to be paying close attention to what's going on here because Data Browser, I think, is going to allow you to deliver a really awesome and very consistent user experience within your application. So to get you the info on this stuff, I'd like to welcome Jim Rodden, who's the tech lead for the list manager replacement called Data Browser. Thanks. Thank you.

Good morning. Good morning. I want to make sure you're all awake and in the right room. So I want to ask you a couple questions before I get started. Now, stand up instead of show of hands. How many of you have ever used the List Manager before? Now stand up. Stand up. Come on. This is audience participation. OK. Now how many of you don't use it anymore?

OK, that's a fair number. Now I'm sure the reason for that is pretty consistent. It kind of doesn't present a really sophisticated interface. And it's not very robust, and it has some serious limitations. I'm sure you're using other solutions like power plants, table views, and things like that. Data Browser is going to take care of all of that stuff for you and present a new user interface-- well, an interface that's been around for a while, but hasn't been accessible to developers.

So with that, here's what I'm going to cover today. Basically, what is the Data Browser thing? Go over briefly the programming model that it uses and how you can incorporate that into your code and how it will help you factor your code. And then some simple usage examples get into the coding. What is this Data Browser thing? It's a control. I want to emphasize that because it's actually pretty fundamental. It acts just like a push button control or a pop-up menu control or any other control that's been around for a long time. You can send it size control messages, move control messages, et cetera.

It's a completely self-contained presentation of discrete elements. So anytime you're presenting, say, a set of file system objects, or database objects, or whatever your application does, you should seriously consider the data browser as a solution for presenting that information. It is not the list manager. List manager is effectively obsolete now. It's still in Carbon. It's not going away, because it's too important for backward compatibility. But the data browser is simply much, much, much better. It does what everyone wishes the list manager had done all along, and it does it in a much better way. It takes a totally new programming model. It does not store your data. That was one of the serious limitations of the list manager, because it tried to make assumptions about your data and how it should be stored.

And invariably, those assumptions were wrong in many cases. Data Browser only stores references to your data. So you can cache your data, you can store your data out on network, or file mapped, or whatever's appropriate for your application. The Data Browser only asks for the information that it needs to present those elements that are currently on screen.

and its standard equipment. It is a very fundamental part of PEN. The Finder uses it. The Finder ListView is a data browser. And it's also in CarbonLib on 9. So you can rely on it to present the standard list style interface to your users. You don't have to reinvent this wheel anymore.

And because it's part of the finder, and Sherlock, keychain access, and many other system components, you can rely on the fact that it is very robust, very fast, and very high performance. And now with that, Jonathan is going to give a quick demo of exactly what it does, so you have a visual image. JONATHAN CHAM: Thanks, Jim. So here we have a sample application with Data Browser. The Data Browser control is actually everything in this window that you see that is not the window frame itself. You'll notice it looks exactly like the finder. No big-- It's not an uncommon view. And we have some sample data showing here. So Data Browser does everything that the Finder does. disclosure triangles so you can show more data, hierarchical data. You can do column resizing. You can do column reordering. You can also, Data Browser also supports contextual menus, and it supports drag and drop all internally.

Data Browser also supports several native data types, checkboxes, icon and text, text only. It also supports icon only, but we don't have any here. It supports date and time, supports relevance ranking, and it supports pop-up menus. One of the nice things, since Data Browser has native data types, is that when you do things like resize date and time, the date and time format can grow to match the size of the column. Data Browser not only does list view, but it also does column view. And in this case, it's something new to Mac OS 9, but it's not new to Mac OS X. So this presents a column view that is standard in Mac OS X. You can see that it is good for displaying hierarchical data. You get automatic traversal of aliases. And also, when you click on an end node, you get a custom preview pane. The content of this custom preview pane is entirely up-- the drawing of it is entirely up to you. However, you do receive events, so you can have something like a push button. And even though the control is taking up the entirety of this window, you do have certain control over the-- elements of Data Browser. So if you wanted to, say, have a placard in the bottom area of the scroll bar, much like Code Warrior or BBEdit have, you can also change the size of the scroll bar. So you can have some custom content showing there. And with that, Jim will show you how you can incorporate Data Browser into your code. JIM POPHAM: Thank you.

Can we get the slides back? Thank you, Jonathan. One thing I'd like to point out, that the code specific to the data browser in that sample app is very small. It's on the order of 50 lines to get the bare minimum. Now that demonstration does quite a bit more. It actually puts information in the drag and drops.

some of the contextual menu stuff. So it's a little bit bigger than a simple app. It's maybe 100 or so lines, but very little. A lot less than it would take to do the same thing with List Manager or any power plant type table view or any of the other solutions out there. And it insulates you from the details of the presentation.

So just to recap, here's a fairly exhaustive list of the features that you get mostly for free. I mean, you have to do a little bit of work. Some of them you have to turn on some bit flags, set some accessors, and provide some routines of your own. For instance, like contextual menu, you have to provide the menu to be displayed, and you have to handle the response to it. But that's pretty straightforward stuff. Some key points. It's designed to hold a lot of items. 2 to the 32. It uses 32-bit references. Because the finder uses it, and the finder has to display the contents of networks and file systems. Tens of thousands of items. That's what this is designed for. So no more 32k data limit or anything like that.

And again, it does a lot of the work for you. It has several native display types. The idea is you provide the data, the raw text, the raw icon, Data Browser takes care of the formatting. And that list there is not complete for the native types, but it's extensible. If there's a display type that you want, that you think it should support, let us know, and we'll see about adding it.

Also supports custom content, so if the view styles there are not sufficient for you, you can add your own content, have more complex information in the cells. and it'll store off the user state. So as the user resizes columns and reorders columns, for instance, you don't have to record that all yourself. There's a call to ask the data browser, what is that state? It'll flatten it out. You can store it off in a pref file and load it back in next time your application is run. Go into detail. And it's not just for Finder anymore. This is a screenshot from the 10 Finder. That is a data browser.

Some additional features that it supports that are not necessarily used by the finder are variable height rows. So you can have individual items have their own unique row height, and it tracks with the item. It is not table index based. So as you resort or you add items, that item stays that height that you set it to.

It'll take care of right to left support for you. So for instance, it doesn't at the moment, but at some point in the future, we may want to automatically invert the column ordering on right to left systems. You don't have to worry about that. It'll happen for free. And because everyone's using it, it'll happen across the system. Hierarchicalness is completely optional. If you want to present a flat file or a flat list, you can. You just don't turn on the hierarchicalness. And you can have it in whatever column you want.

There's two different highlight styles. There's the traditional finder style, where it just highlights the bare minimum around the text. Or you can have the band selection, like, say, in the chooser. And you can use whatever's appropriate for your interface. Under Platinum, it supports different theme backgrounds. So the default is the Finder style with the light gray background and the darker gray for the sort column. But it also supports the white style background like you find in the chooser. And you can mix and match that with the highlight style, so you can customize the look a little bit. Under Aqua, there really only is one theme background style white, so it doesn't really apply there. But the API works just the same. So you can call the API to turn off the gray background and doesn't make any difference on Aqua. Just a no-wop, basically. And one thing that is coming from Aqua back to Platinum is the per-column sort ordering.

This is something that a lot of the third-party implementations of this style of interface have done, where instead of having one sort ordering, ascending, descending, that applies regardless of what column is the sort column, it's tracked per column. So you can have the first column ascending, second column descending, and as you switch back and forth, it remembers those sort orderings.

Here's an example of the list view under Platinum-- or the column view, excuse me. Column view supports some additional features, the most prominent one being alias traversal. Because the column view is designed for navigating through a hierarchy, particularly file system hierarchy. File systems have aliases to other containers, and it doesn't work to be navigating, burrowing down into it, and all of a sudden get blocked because you hit an alias. It supports traversing down those. And it's smart about it. It doesn't ask for more data. It just already has that information. Or if it already has that container open, it just replicates it.

It supports custom preview. So for instance, in the finder, how it does the QuickTime preview or the picture preview in the last column, that's supported. Of course, you have to provide the code that actually renders in there and does the tracking in there. But it's completely-- screen space is up to you. Again, you can have variable heights. The two highlight styles works there as well. This defaults to band selection, but you can turn that off and have the minimal highlight style. And again, you can have custom content in your items.

I don't want to go into too much detail on the performance, but I know some of you are concerned about that. Just again, remember the finder uses it, and NAV services uses it, so it has to be very high performance. Throw up some numbers here to give you an example. It's very lightweight, very scalable memory usage. It only uses as much memory based on how many items you've added to be displayed. And as containers are opened, of course, those take a little bit more memory, but we've kept it to a minimum. And over the next few months, I'll be working on performance and may get that down even more.

How many of you remember your algorithms class? Again, you don't need to worry about details. Just remember it's fast. Basic idea here is it does binary searches internally. Now this is really just when your code is calling in to get information about items. For instance, is this item selected? Is this container opened? That's your code querying the data browser state. Internally, data browser is optimized to basically order one. So interactions with the user and rendering is as fast as a can be.

So this is all you really need to remember. It's fast. And it's optimized for bulk operations. So if you want to do, say, threading, retrieval of your items, whether they be file system items or from a database, you can spawn that off in a thread. And whenever you get a large enough chunk, insert it in one step into the data browser. And that will give you the best performance. So now I want to talk about the programming model a little bit and how you can use it to help factor your code.

Excuse me. This is not a new paradigm. It's not unique to the data browser. It's very common in various frameworks-- Power Plant, Mac App, Think Class Library, for those that remember that. And the Cocoa frameworks are all oriented around model view controller paradigm. The basic idea is the controller code is your framework code. It's your initialization. It's where you throw up your windows. You create your menus. And it's your event dispatching, where you take the raw events-- this is a mouse click-- and you figure out which subview it belongs to, and you route it into that.

Data Browser takes on the role of the view. It's in charge of presenting your information to the user, putting things on screen. And it takes those raw events, a mouse click, for instance, and turns it into a semantic event, a double click or a drag on a particular item. And it talks to your application data, which is the really value add of your application. What makes your application unique?

And it stores the items you want to present to the user. Again, you're in charge of the data storage, the management, the caching, and whatever you need to take care of there. Now how do you get those items into the data browser so they're displayed? There's a routine called add items, where you add the references, unique item IDs, into the data browser such that there's a one-to-one mapping between those item IDs and the data they represent. Data browsers use callbacks to query information about those items as it needs it. So if an item isn't on screen, it's not going to ask for its text string, because it doesn't need it. So you can take advantage of that in your caching scheme.

Once again, to summarize, controller code creates the Windows, creates the Data Browser, passes events into the various views, including the Data Browser. Data Browser queries your application data as it needs it, and your application data sends messages back to the Data Browser for adding items or changing the state.

Now, a data browser needs to assume certain things about your data model and how the items relate to each other. It's a very minimal set of assumptions, but it basically defines the structure of the data. The most important of those is that each item has some set of properties. These are defined, again, by unique IDs. There are some that are predefined in the header.

such as, is this item active? Can this item be selected? Is this item a container? Can this container be opened? That gives you control over some of the behaviors. And it lets the data browser communicate in a known language. You can define additional properties. For instance, the list view is very free form.

And data browser doesn't know what kind of columns you want to present. That's up to you. So each time you create a column in the list view, you're defining a new property. So there's a one-to-one mapping between columns and properties. And those are properties you've defined and that you are telling the data browser, here's some additional information that I have on this item that I want you to know about. And here's how to query details on it. But these are all optional. If you don't respond to the property request, Data Browser assumes default values. Now, you really should respond to the properties that you define, or else nothing's going to be put on screen.

Now one of those important predefined properties is, is an item a container? This is how you get the nested look and the hierarchicalness. And you use the container of a given item when you're adding it. So when you add items to the data browser, you say, put these items inside this parent container. And that's how it creates the internal tree.

Just to summarize, data browser stores references, not data. Very fundamental design decision. And it queries information about the items as it needs it, based on the unique item IDs and the property IDs. And everything is optional. If you don't install a callback, you don't respond to a property, Data Browser will assume and perform for you a default behavior.

Moving on to the API, that's a big number, 112 API calls. But don't let that intimidate you. I did a breakdown here. Most of those calls are just get set accessors. And if you're not interested in some of those, you can ignore them. These just allow you to customize the behavior and appearance. It's a very flexible, very rich API.

Now a trend in the control manager in general, since this is a control, is to move away from type unsafe structures that you turn into a void star pointer and pass in via send control message or set get control data. So these are really just wrappers, literally, they are wrappers in the implementation around get set data calls. But they're type safe, which makes your code more cleaner, more maintainable, less error prone, and the same for on our side. This is over and above the standard control manager calls. For instance, size control, move control, set control visibility. Those work just the same because it is a control.

But when you get right down to it, only six calls are really, really needed to do a bare bones implementation to just throw some information on screen. So most of those calls, you don't need. Some of, for instance, the configuration and manipulation calls, some apply to all view styles, whether it be list view or column view. For instance, turn on the scroll bar, turn off the scroll bar.

And some are view style specific. For instance, the list view has a notion of a disclosure column, so you can specify the disclosure column. Whereas that doesn't mean anything to the column view. Conversely, the column view has a notion of a path, but the list view does not.

Plus there are two sets of callbacks broken into two pieces. There's the high level ones that deal with the standard behaviors, and the low level ones that apply to the custom content. I'll go into those in a moment. plus your standard control manager callbacks, key filter, input validation proc. Those work as well.

Now the standard callbacks, the high level callbacks, these are what you're mostly interested in for the standard native display types. Most important of these is the get set item data. This is how the data browser queries your application for text strings, icons, date values to present on screen. Again, you just provide raw data. Data browser takes care of the formatting. And it's called get set because this is also how the data browser tells you that the user has completed an edit operation. For instance, the user has clicked a check box or clicked a pop-up menu or done a text edit. This is how the data browser provides that information back to you so you can store it off in your data.

There's item comparison for sorting. You're in charge of the sort operations. It just gives you two item IDs and asks for their relative ordering. So if you want to do secondary, tertiary sort orderings, that's up to you. If you want to have case-sensitive or case-insensitive sorting, that's up to you. If you don't install a comparison callback, it presents information in insertion order. So if you're providing a list of stack elements, then you get that for free. You don't even need to install a comparison routine.

Data Browser will notify you of semantic events on items. For instance, double click, container opened, things like item selected, and does that via notification routine. There's some drag and drop handlers for adding data into a drag. Again, the Data Browser sets up the drag, but you need to provide meaningful information into it, the drag flavors.

You are in charge of specifying whether a given item is interested in a drag. If you respond yes, you are interested, Data Browser will take care of highlighting that item appropriately to give the user feedback. And when the drag ultimately is dropped, again, it's your call to handle that, because Data Browser doesn't know what the data is. It just knows something was dropped on something else. And there's a cleanup operator. There's also help tags is the follow-on replacement to balloon help. When help is going away under Carbon, help tags gives a tool tips kind of appearance. and interaction, and Data Browser supports that natively. And you need to provide the content, but the Data Browser will take care of putting it up on screen and determining which item it goes with. So you can give help tags on an item by item basis. And same is true with contextual menu. You need to provide the menu, and you need to handle the user's response with just a couple of routines.

Very good. The low-level callbacks are for custom content. If you don't have custom content, you don't need to worry about these callbacks. If you do have custom content, you are telling the data browser, I want to be in charge of all rendering and tracking and hit testing for this item, wherever it may be on screen, when it's on screen. Data browser will give you the bounds at any given moment when you need to draw or hit test. And the custom content is used for the preview column. That is a custom content space. So if you don't want a preview column, don't install custom contents. You just get a blank column. But if you do want to present preview information in the preview column, you need to install custom callbacks and handle them.

Now with a quick code demonstration of getting a bare-bones implementation up and running, Jonathan's going to show that. Okay, so here we have an application that's basically the minimalist data browser. It's a single column with seven elements. You can select them. You can click on the column and reorder them. As Jim said, we have no sort routine in here, so they're in insertion order. So this is your most basic application. Let's see what code was needed to create it.

Very little code was needed to create it. If you look at it, it's in total about 220 lines. Only about half of those are actually needed for the data browser itself. And so we're just going to go quickly touch on what is actually needed for the data browser. This is a Carbon event application, so it is a lot smaller because we don't have to do a lot of the event handling ourselves. It's taken care of automatically.

So the first thing we do is we create a window to put the data browser in. We then create the data browser to fill the entirety of that window. We'll then configure the data browser, install the callbacks that are needed by data browser to communicate with our application, and we'll populate the data browser with our item references or item IDs, which will be given to the callback to request the information to be displayed. The rest of the application is basically just showing the window and running it. So the first thing to do is to configure Data Browser. Since Data Browser is taking up the entirety of the window, we don't want to have a focus frame. Data Browser will manage the focus frame for you if you want one, if you have, say, two Data Browsers in a window and you want to change the focus between them. So in ours, since we have a single window and it's taking up the entire contents, we turn it off. The second way that we configure it is, Data Browser installs columns by filling out a parameter block. Jim will be going into detail about this parameter block, but it's not very hard to fill out. Doesn't take very much. Once you fill out the parameter block with the details about your column, you then add that column to the Data Browser. And here we're setting the sort property to be the first column. If you have multiple columns, you can specify which of those columns you want to be the sort column initially. If you don't set it, nothing will be highlighted at the very beginning, but as soon as you click on a header button, it will then highlight. Once you've installed the column into the data browser, you then need to install your callback. Callbacks are also filled out or installed via parameter block. It's very simple. We only have one callback in this application, which is to actually get the data from our data model and return them to the data browser. So we fill out the parameter block and install it into the data browser.

Now that that's done, we need to populate the data browser with our item IDs. Item IDs are entered into data browser by using an array. So here we have a simple array of seven elements. These are actually indices into a simple string array. They can be anything you want. They're just numbers or IDs that are one-to-one mapping to your data model. So we create the array with our seven elements, and we store them into data browser. And that's basically all you need to actually configure Data Browser itself. We do, of course, have our one callback, which is for requesting the information from our data model. In this case, when Data Browser needs to display its information, it will request via callback from our application or our data model using the item IDs, passing in an item ID into our callback. In this case, like I said, we have an array of strings with seven elements. So each time the callback is called, it gives an item ID. We return a string, and Data Browser displays it. That's basically it for the application. There's not much to adding Data Browser to your application. We do have a bit more code here.

One of the interesting things is you can resize Data Browser by a simple size control call. Basically, as our window resizes, we just resize the control to follow the bounds of the window. And that's it. Very easy to add. you get a lot of features with very little code. Anyway, here's Jim to describe the APIs and the callbacks more. JIM DICARLO: Thank you, Jonathan.

All right, here's the sequence that Jonathan just demonstrated to you to create and display a data browser. It's pretty straightforward. You create it, one call. You configure it. There's a couple of steps there. You set up the format. In case of the list view, you need to add your columns. You install your callbacks, and you populate with your initial set of items. And the last step is just handling the runtime, handling the callbacks as the data browser dispatches them, and routing the raw events into the data browser. I'll walk you through that.

Here's how you create a data browser. Now you notice it's not using new control. Control Manager is moving away from that model because, again, it's not type safe. And it's based on the notion of code resources, which are not supported in 10. So instead, we're moving towards unique type safe routines for everything you want to do. So it means we have more APIs, but it's no different than all the different structures that were introduced with the Appearance Manager. The arguments to this are a window ref, the bounds that you want, the initial view style, create either list view or column view. Here we're creating a list view. And you get out a control ref. Pretty straightforward. So there, we've done step one.

Step two is formatting it. Now for the ListView, it's a little bit involved. But the basic idea is you create a param block, you fill out the values of the param block, and you add your column. So the details are really in that param block. First step is to create a property. You're defining a new property, telling the data browser, here's a new property I know about and I want you to know about, too. That involves defining a property ID. That's a unique identifier. It's how the data browser communicates and queries information about that property. You say what visual information you want displayed for that property. This is where the native types come in. In this case, we're displaying icon and text. There's other constants for checkbox, popup menu, et cetera. Then you define some behaviors for the property.

Excuse me. In this case, we want this column to reflect the selection state. So if you want certain columns not to be highlighted when a given item is highlighted, you don't set this flag for those columns that you do. If you want all columns to-- say you want a band selection to go all the way across, you need to set this bit flag for each column.

And here we're using the default column flags. They break down into other constants. They control, is this column sortable? So say you don't want sort property. You're just presenting a list, and you don't want the user to be able to change the sort ordering. And sort is meaningless. Say you're presenting a stack of information, and so sort doesn't have any meaning there. So you wouldn't set that flag, but that's included in the default constant here. Also controls whether a column is movable. So if you want a column to be glued always to the left, for instance, the finder always has the name column glued to the left, you can't move it over to the right, they don't have that flag set.

Next step is to define some behaviors and appearances of the ListView header. First part is the sort order. Again, sort order is on a per column basis. Need to provide an initial sort order. Provide the minimum and maximum width. This is for column resizing. If you don't want a column to be resized, just set these two values to be the same. And then the alignment. These are the standard TE flush default, TE center, left align, right align. And this also affects the appearance of the contents of that column. So the column content and the header text are aligned.

Next, we put these all together into a column descriptor. Again, the steps are column is a property, contains some header information, some formatting information, and a CFStringRef that is the text to put in the header button. Now, CFStringRefs are the way to communicate textual information with the control manager now. Doing away with Pascal strings because they're difficult to localize. They're script-dependent. CFStringRefs, it's basically a Unicode. string, so Data Browser's Unicode capable off the block.

And you need to go to some of the core foundation sessions to learn more details about how to use CFStrings. And then you create the column. The last argument here is the ordinal position within it. So as you're adding columns, you can specify what position you want to be in. In this case, we set a very large value. If you choose a value that's more than the number of columns currently in there, it just tacks it on the end. So we've set up the format. Now we're going to install the callbacks. Again, another param block.

Now the KDataBrowserLatestCallbacks constant may seem a little odd, but that's a versioning scheme we came up with so that we can provide backward compatibility In the future, if we need to add to this structure, change its formatting, maybe change the callbacks themselves, add new callbacks, replace callbacks, change argument signatures, we don't want to break your apps that you work on now as we need to make these changes in the future. Using this versioning scheme will allow us. So the version number maps directly to the structure of this param block. If we need to augment this param block in the future, will increment that constant value. And next time you recompile with the new headers that have that new structure, you'll get the new constant. And you may need to do a little bit of work to adjust to the new callbacks, new layout. If you don't want to, you can just revert to the previous constant value. And you'll maintain binary compatibility. I love it.

We initialize the structure. For now, this just sets all the values to null. The UPPs just sets them to null. But at some point, we may want to provide some default callbacks for you. And this is how you can get them. Basically, initialize it to a safe default value. Then you set each element within the structure to your UPPs that you create. And you install them. OK, we're done with step two. But there is a step three.

We populate. We create an array of references. Now again, the references are whatever's meaningful to your application. They can be raw object pointers, C++ object pointers. They can be indices into an array that you maintain. They can be some hash table value, whatever's appropriate. The only thing is they need to always map one to one consistently to the same piece of data.

The arguments to the routine here, the data browser reference, the control ref. The parent item, as I mentioned, this is how you get the hierarchicalness. If you want it in the root level of the list, or you're displaying a flat list, you just say there is no parent. The parent is the root item.

You say how many items are in the array and the array itself. Last argument is a performance opportunity. You create your array in some order that maps to one of your sort orderings. You can tell the data browser. And if the current sort property happens to match, data browser can save on some sort operations. So it'll make it add a little bit faster. OK, we're almost done.

Excuse me. All right. There we are. All right. I'm only going to go over one of the callbacks, the most fundamental one, the get set data. As I said, this is used both for retrieving data from your data model and passing it to at the completion of an edit. That's what the last argument is for. Most of the time, it'll be set to false. That just means the data browser says, what's the text string you want me to display? When it's set to true, it's saying, here's the text string the user just entered, or the new checkbox value the user just entered. You need to update your data store. If you don't want to accept the value, that's fine. You can put up a dialogue to tell the user, sorry, that's an invalid new name, or you can't check this check box right now, and just ignore it.

But the main bulk of this is just a switch statement on the property that's being requested. You have a case entry for each property that you are interested in. If you don't want to respond to a property, Data Browser assumes a default value. You need to check on whether the data browser is giving you information or asking for information. But then you just install the information into an item data reference. That's a reference to the data that's going to be displayed. Now if you don't respond to a property, it's important that you return this error code, because that tells the data browser, give me the default value.

We're almost there. One last easy step. This is your standard control manager calls. Draw one control, handle control click, et cetera. There's some new ones that I'm not going to go into detail here. If you're interested in them, go to the Carbon enhancement sessions. They'll go over them. But basically, they allow the data browser to set the cursor, for instance, as a user drags over a resizable column, it'll change the arrow cursor into the bi-directional resize cursor. Some routines for doing drag and drop handling and contextual menu. Again, go to the Carbon enhancement session if you're interested in those. There's an easier way. These Carbon events, and you install the standard event handlers on your window, you get all this for free. That's what the sample application Jenna Johnson did.

So there, we're done. Pretty straightforward. You create a data browser, you configure it. That's the most involved step, but it's pretty straightforward, too. You populate with initial items, and you handle the runtime. Now, the Data Browser API is quite stable. It's actually been used by the finder in 10 since PR2.

And there are a couple of components in Mac OS 9 that use it. So we're pretty confident that it suits everyone's needs. But the data browser does a lot more than those core services, Finder, Sherlock, et cetera, need. For instance, the variable row heights, custom content. And so we had to make some best guesses of what reasonable behavior is there since we don't have any clients that are really using it. So that's where we need your help.

Please use them and give us feedback. If something doesn't work the way you think it should, let us know. The goal of the data browser is to do the right thing as much as possible and save you from work and do work for you. So let us know if Data Browser can do something additional to make your life even easier.

It's available right now. The Mac OS X CD you got on Monday, Data Browser's part of Carbon. When you use the finder list view, you're using a Data Browser. It's in CarbonLib 1.1 for 9 only. It went through-- it's in the D9 release, which I don't think has been posted just yet. I think it was built last week, going through Quick Looks this week. So it should be posted on the web next week. Or maybe it might be there now. I haven't looked. And you can get it through your Apple Developer Connection account.

The APIs are defined in control definitions.h. Again, it hasn't made it into the universal releases, universal headers releases, but the headers that come with the developer previews or the Carbon lib seeds, it's in there. And here's some contact information. I'm going to bring John back up to go over the rest.

So first of all, if you're working with Data Browser and need to get some feedback through to Jim or the team, probably the best contact would be to go through myself with John Glennzy, the first email address there. And there's also the high-level toolbox feedback email, toolbox at apple.com. And the Carbon mailing list is a great place to basically live and discuss and keep conversations live with other Carbon developers who are using Data Browser. Documentation address is there.

So some related sessions that you need to think about or consider attending. And some of them relate specifically to Data Browser or some of the APIs that have been discussed here. Others relate to the Aqua interface and doing the right thing, and that's where Data Browser fits in a little bit as well. And most of these are pretty self-explanatory. But a couple that I want to call out is just the Carbon Event Model sessions, which happened on Tuesday. Hopefully you went to those. And if not, hopefully get you some information post the conference.

Carbon enhancements in Carbon one and two, talk about some of the APIs that Jim referred to in the last few slides, and you can get some info there. And then the feedback forums. Please come to the high-level toolbox feedback forums in terms of getting us feedback on high-level toolbox or the Aqua forum in terms of feedback on developer adoption of aqua-related issues. So I'd like to invite the team up on stage for a Q&A. If you have any questions, there's a few mics in the aisle.