Mac OS • 52:13
This session describes changes and enhancements to the High Level Toolbox for Carbon. This session is an absolute must if you are Carbonizing your application. We discuss better control creation, dynamic menus, and new APIs such as Help Tags, as well as basic window layering, control embedding, and flavored scrap support. Omit final sentence.
Speakers: Pete Gontier, Guy Fullerton
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Ladies and gentlemen, please welcome Carbon Technology Manager, David Wright. Thank you. Welcome to session 143, high level Toolbox Carbon Enhancements 1. So Carbon, Mac OS X, the theme of this week. We cannot wait to get your applications onto Mac OS X. There have already been a number of sessions this week letting you know about some of the-- in my session, I called them closed roads and detours. There will be a few more in this session.
But we're also adding a lot of functionality to Carbon to make your development lives easier. Again, there have already been sessions about that this week, Carbon events being one of them. And so I was thinking about the title of this, High Level Toolbox. What does that mean, high level? And I think another cool theme of this week is that the high level toolbox is beginning to do more and more on behalf of your application, thus making it even higher. So anyway, to talk more about that, I'd like to introduce Pete Gontier from the high level toolbox team. Please welcome Pete.
You've been hearing a lot about Aqua this week. And it's certainly the case that the High Level Toolbox is enhancing, growing and being enhanced in order to make your jobs easier in implementing Aqua. But it's also Growing and enhancing just because it needs to grow and enhance in order to stay a living thing. So we've added lots of features, some of which have to do with Aqua, some of which don't, and that's what we'll be talking about in this session.
I want to approach this topic from a couple of different directions. The first one we're calling architectural changes. And the architectural changes have to do with stuff that you pretty much need to do in order to adopt Carbon, in order to Carbonize your application. And those things include such things as the fact that window layering is now enforced. It's no longer optional. You can't choose to use it or not. You've pretty much got to live with it. Root controls are always created for any window that has controls.
MenuRef is now opaque, which shouldn't be any surprise to anybody who's been hearing about Carbon all this time. We've been creating more opacity in the Toolbox. But with respect to MenuRef, it's a matter of some interesting semantic changes that have more to do with, or have less to do with, accessors and more to do with your application code.
And the Scrap Manager needed a change for Carbon, and particularly for Mac OS X, which means that CarbonLib also had to change. So we'll be talking a little bit about that. The second category of things I want to talk about are the cool new features we've been adding that you aren't obligated to adopt, but once you learn about them, you'll realize you want to adopt them.
The first big category, or the first big subcategory there, is the Menu Manager. We've been adding a lot of stuff in recent versions of the OS to Control Manager and Window Manager. And Menu Manager has sort of been a little bit neglected. We've added a few features here and there, but in Carbon, Menu Manager is really catching up in terms of feature list.
We've also added a whole new manager called the Help Tag Manager. And this is basically the replacement for Balloon Help, and we'll be talking a little bit about that. We've added some new control creation APIs. They're more intuitive, they make more sense, you don't have to worry about overridden parameters. And there are some whole new standard controls that we've added, mostly to support Aqua, but partly to support you.
I said something about window layering earlier. Window layering, of course, is done according to class, the way it always has been. So when you create windows, you need to be very conscious of the class that you're creating, because that will basically imply the layer the window will fall into.
In addition to that, we've also changed some existing Window Manager APIs so that they operate within the layer of the window that you pass to those APIs. So when you call Select Window or Send Behind, you'll find that the window is only changed within its own layer. So if you have a document window and you pass it to Select Window, it's not going to jump in front of your floating palette windows. It's just going to become the frontmost document window.
The other API that's changing is Front Window. Well, excuse me, the API that's not changing is Front Window, and you have to watch out for that, because when you call Front Window, you will get the Front Window, even if it's a floating palette, irrespective of layer. So if you need to be aware of the Front Window of the layer, you need to actually use the specific call Get Front Window of Class instead of Front Window.
In Mac OS X, because we need to plan for future enhancements we want to do to the Control Manager, we pretty much need to require that your windows, which have any controls, have root controls. And basically what happens is when you create your first control, we check to see if there's already a root control in that window. And if there isn't, then we create one for you.
I said just now that this is a Mac OS X feature. This might cause you trouble if you're thinking, "Oh, no, now I have to write conditional code to figure out, am I on Mac OS X? Is there a root control?" Well, the simple solution is, as part of your Carbonization process, Just add a call to create root control, and always create a root control for all of your windows that have controls.
It's a simple thing to do, and it will simplify your life in the long run. You'll always have a root control on 9 and on 10. The one part of this is not automatic is the root control pretty much sticks around. Once it's been created, even if it's created automatically, it doesn't go away just because you deleted all the child controls.
Now this new mandatory root control has some implications for the Dialog Manager. Basically, the moral equivalent of creating a root control in a dialog is setting the use control hierarchy bit in your dialog resource, in your DLGX resource, I should say. But that bit really controls two things. One, it ensures that you have a control hierarchy in your dialog. But the other thing is that it makes all of your items into controls. And once they've become controlled, you need to be careful about how you access your dialog items.
And specifically, you need to be careful with setDialogItemText because it expects a control now. And that's done because of compatibility. setDialogItemText needs to search all of the dialog item lists in all the dialogs in your application because the API is not defined so as to allow us to do anything else. So it needs to find that control handle in the dialog item, in the dialog that you care about, and the only way it can do that is by taking a control wrath.
Now, the really clean thing for you to do is not do this tricky typecasting thing to make set dialog item text work. The cleaner thing to do is to just use set control data and pass it the tag for the text of the item. And the last sort of implication for dialogs and the mandatory root control is, um, You basically want to set this bit not only to make your life easier, but also because it's the only way you can get aqua-savvy text in your edit text items.
So I mentioned menu refs are now opaque, which should be no surprise. But it's not just a matter of calling some new accessor function instead of directly accessing the menu record. The way Get Menu used to work is that it used to hand you back a resource handle that came from a menu resource. And it would post-process the resource handle a little bit, but pretty much it was a resource handle.
And if you called Get Menu over and over and over again, you'd get the same handle over and over and over again. That's no longer true. Get Menu now returns you a menu ref which is based on the menu resource, so it's not as if you had to throw out your menu resources. But that is basically a unique copy of that resource used as a template.
So not only can you not assume that you've got a resource handle and you'll get the same one every time, but you should also, instead of calling Release Resource, which some documentation tells you to do, not many people do it, but that's what the recommendation used to be. Now we're telling you, go ahead and call Dispose Menu, forget about Release Resource because the menu is not a resource.
So of course there are some accessor functions as a result of menu ref opacity. One of them is called Duplicate Menu and it replaces the ability you used to have to use the memory manager, say you might call hand to hand to duplicate a menu. Well you can't do that anymore because menu refs aren't handles anymore.
And then of course Copy Menu Items provides you with the functionality you need to reach into a menu and pull out specific items and copy them into some other menu. And of course you used to be able to do that by simple pointer arithmetic, or actually it was complicated pointer arithmetic. In any case we've given you an API now so that you can reach in and do that same stuff.
The Scrap Manager is, I hesitate to say it's a new API, pretty much what it is, is an old API with a lot of new names and a few changes. Pretty much, you still get things from the scrap, you still put things on the scrap, you still zero the scrap, or as we say in the new terminology, you clear the scrap.
Basically, we had to make some changes to the Scrap Manager in order to support the way events work on Mac OS X. On 9, your app would get a suspend event, and if you were maintaining a private scrap that the Scrap Manager didn't know about yet, you would take the suspend event as your clue that it was time to export your private scrap to the public scrap.
On 10, suspend events work significantly differently. By the time you've received a suspend event, it's very likely that your application has already been pushed towards the background because of preemptive multitasking. And so if you, at that point, try to export your scrap, it won't work because background applications can't put things on the scrap.
While we were in there making these architectural changes to the Scrap Manager, we decided it was a good time to add some features as well, so we added flavor flags. Flight reflects are pretty much like the Drag Manager. Let me step back for a moment. I didn't explain the whole promise thing. So to replace the suspend event process, we added a promise feature, which is much like the drag manager. You basically supply a callback. You associate it with a scrap.
And when some other application requests the data that you promised, you get called back and you provide the data on the fly. Now, when you make these promises is pretty critical. You want to make these promises when the user performs a copy operation or cut operation. You don't have to supply any data up front, but you do have to say, I have data of a certain type.
And you may optionally, if you know, supply the size of the data as well, but that's optional. And the reason you want to do this at this time is that there's really no better time to do it because otherwise you'll just be sitting in your event loop waiting for an event to come in and by the time you receive your suspend event, it's too late. So you really do need to do the promising when the user issues a command.
So now let's go back to Flavor Flags. Flavor Flags are also like, work very similarly to the Flavor Flags in Drag Manager. You can specify a sender only flavor, you can spec, excuse me, and you can test for whether a flavor that you are pulling in from the scrap has been translated. And, The previous session we talked about Translation Manager, and that's what that bit is intended to be used for.
We also added some APIs for introspection. You used to be able to look in low memory, grab the scrap handle out of low memory, and then walk around inside the scrap handle in order to determine what flavors were on the scrap, how big they were, and maybe even peek at their data. Now you need to use some clean APIs that basically tell you all the same things in a way that we can support into the future.
So I said that the menu manager was catching up. And the menu manager is catching up so much that we cannot cover all of the things that have been added to the menu manager in this session. You see there's a long list there, and we'll cover most of those things.
But the last item is almost the most important one because there are probably six or seven important things that we just don't have time to cover. And you can learn more by looking in the headers and experimenting with the new APIs and then maybe sending us feedback to get the documentation finished sooner.
But that's a really important part that I wish I could cover but just don't have time for. So before I go into too much detail about the Menu Manager, I want to bring out Guy Fullerton to show us a demo of some of these new capabilities. Guy? So it looks like all my dark little obsessions are coming out of the conference. Let me steal the water.
So as Pete mentioned, we've got an awful lot of new features in the Menu Manager. I'm only going to touch on a few of them, but they're kind of the cooler ones. Got a simple little application here. I showed this off in the Aqua Overview demo. It takes advantage of a few of the new Menu Manager features.
First one I want to touch on is the inclusion of this font menu. This font menu is actually implemented by the system. Your application can have any given menu and it can call an API to tell the system, "Please put all the standard font commands in this menu for me." We even offer a mechanism, it's actually an option bit that Pete will talk about, that lets us hang submenus off of each of the fonts that has the different types of fonts available. So in this case, Oh, I don't know. Lucida has a bold and a regular version.
And those are both automatically hung off the menu. And the system will keep track of the submenu management for you automatically. We also provide some APIs that allow you to take a given menu selection and ask the menu manager, "Hey, what kind of font was this?" So you can take that font and run with it.
[Transcript missing]
You can put different menu manager command IDs between each item so that you can find out what the user selected on a command ID basis. The next thing I want to do is actually show you how I implemented that. It's actually really, really straightforward.
The first step is done just in your menu resource, or if you're using Interface Builder, you can do it straight in the Nib resource. This is the menu that did not have any dynamic menu commands in it. Your dynamic menu resource, or Nib, looks basically the same. In a dynamic menu, if you have one item that has three variants, there are really three menu items behind that one item. So your menu resource simply has each of those three items.
I'll take the Amplify case, for instance. Each of the items which is ultimately going to show up as just one visible item must have the same base command key, but you can specify different modifiers. So, for instance, the Amplify item itself just has the command key, Amplify All is Shift Command, and Amplify Selection is Option Command. So you build up your menu, you save that off, and then you need to do one step in the code.
actually. So it's a very small application, uses Carbon events to do most of the work. And one of my subroutines is a routine that just builds up my menu bar. One thing I happen to do in here that Pete will talk about as well is get the root menu. This is a really convenient way to be able to get your menu bar, treat it as a menu and iterate through things in a quick easy way.
So I get my root menu and the first thing I do is I pull the sixth menu out of it which happens to be my dynamic menu. There's a number of other ways I could have done this but for speed I just knew it was the sixth menu and grabbed it.
And then I happen to iterate over each of the items in the menu and change an attribute, just turn on the dynamic bit for that item. And that's really all it takes for the dynamic stuff to work. As soon as you run, the menu manager just does the rest of the work.
So, calling this API is a little inconvenient, and we're going to look at getting that integrated directly into Interface Builder so that Interface Builder will let you click a checkbox and mark an individual menu item as dynamic, and it'll just do it all, and you won't have to do any work. You just build your menu and run it, and it's all dynamic. And so now, Pete, I think he's going to talk a little bit more about these APIs I've shown you and some more stuff as well. Great. Thanks a lot, Guy.
So now we're going to talk about some APIs as sort of a backgrounder and we're going to build up towards the exact APIs that Guy showed just now in that demo. The first ones that we're going to talk about are the menu attribute APIs. A set of menu attributes is just a 32-bit quantity, a bunch of flags, that Control the behavior of an individual menu. Right now we define two attributes. One of them is to exclude the mark column.
The mark column, of course, is that column down the left-hand side of the menu with the check mark or the diamond or whatever other symbol you need to put in there to tell the user that a certain mode is in effect or some item has been selected as the current item.
Basically, the reason you would want to exclude that column, the best example we have is the Path pop-up menu that Windows supports now. There's no reason to mark any of those items, and it's much nicer if the width of the item is very close to the width of the title in the window. So we turn off the Mark column for that menu. And you may encounter situations like that in your app as well.
The other bit that you can set in the menu attributes is the auto-disable bit. This bit basically, we hope, replaces a lot of code in your application in which you attempt to determine whether all the items in your menu are disabled. If they are, go ahead and disable the title. Well, if you set this bit on a menu, the menu manager will figure all that out for you and disable the title on the fly on an as-needed basis.
So there are a couple of APIs for accessing these bits. The first one is pretty simple. You pass it the menu you care about and it gives you back the attributes for that menu. The second one is a little more interesting. It has an idiom that we are probably going to use a lot of in the future for the toolbox. And basically where you would expect one parameter, there are two.
And the first one is the attributes that the menu manager is supposed to set. And the second one is the attributes that the menu manager is supposed to clear. And this replaces the code in your application where you would get the attributes and then do some bitwise operation on those attributes and then set them back onto the menu. And of course, that's not nearly an atomic operation. So since thread safety is the sort of thing we try to consider when we're designing new APIs for Carbon, that's what this sort of dual parameter strategy is all about.
Now of course there are attributes for menu items as well, and these are the attributes that Guy was talking about when he showed you how the dynamic menu support is implemented in his app. The first menu item attribute is the disabled attribute. Of course, this is an attribute that's used by disable menu item and enable menu item.
There's no sort of recommendation that you use the attribute version of this capability. The old APIs work fine. It's just that it's nice to have all of these attributes in a single place. The second attribute is the dynamic attribute, which Guy talked about. You turn that on and you get that dynamic menu support.
The third is A hidden attribute allows you to hide and show individual menu items in a menu without deleting them. They are still there, but the menu manager simply chooses not to display them. We'll get to how that can be useful in a very specific example in a few slides. The last attribute is the separator attribute.
And the separator attribute compensates for the fact that we still have one metacharacter in menu items, and that is a leading hyphen. And the leading hyphen, of course, causes the item to become a separator line instead of a chunk of text. With this attribute, you can turn that off and have a leading hyphen in your menu items. And this would be useful if you don't want to know what kind of data you're putting into the menu.
Say it comes from the file system or it comes from a list of resources or some database or something. And you don't want to have to process, does this thing have a hyphen in it and do I need to do a special hack in order to make it work? You can just put text in the item as long as that attribute is set, you won't get items turning into separators unintentionally. Now, there are lots of other menu item attributes, probably as many as a half dozen more.
There are lots of other menu item attributes, probably as many as a half dozen more. They're a little more obscure, but they're worth looking at if you have some time. Take a look at them and see if they apply to your application. They're all commented. The APIs are much like the menu attribute APIs, and of course, you specify a menu item, but otherwise they're pretty much the same.
So now let's talk about that dynamic menu item attribute. Guy explained a little bit of this, but basically you create the same old resources or you use Interface Builder to create your menu and X menu resources. And in your XMenu resources, of course, you specify all the modifier keys that you care about.
Basically, what you do is you specify multiple "redundant" items in your resources. They're not redundant because obviously they have different modifiers, but they sort of look redundant. They have the same base command character associated with them. That's how the menu manager figures out which items to merge and which items to leave alone.
And then once you've got your menus instantiated in your application, when you set the dynamic attribute bit on the items, that tells the menu manager, "Okay, you should look to see if this item should be merged with another one above or below it." And of course, you saw only the current set of modifier keys is displayed in the menu.
I guess I should also point out the items that aren't displayed are still in the menu. So the menu manager knows to return you the index of those items according to which modifier keys are down. So you don't have to worry about, well, I should say, the menu manager tells you, if you've got three items in a sequence and they're dynamic menu items, say they're items 4, 5, and 6, if the user holds down the modifier keys associated with item 5, menu manager tells you that the user selected item 5, and you don't have to worry about all the fact that menu manager hides all those other ones for you.
So we did some work with hierarchical menus as well. A while back we added some functions to allow you to get away from overloading the semantics of existing APIs like set item mark and set item command. You used to have to pass all sorts of goofy stuff according to all sorts of rules that nobody wanted to remember and everybody had to look up every time.
But in the latest release of Carbon, we are also finally eliminating pretty much, I think, the last weird case of overloaded parameters, and that is insert menu and passing negative 1 for the after ID. You can now basically create a menu, decide which item to make it a hierarchical menu of, and pass the menu handle to the menu manager and let the menu manager worry about the rest. You don't have to worry about what ID the menu has. You don't have to worry about doing something special. You have a name that actually does what it says it does.
And the only time that you really have to worry about the menu ID is if you don't take advantage of the APIs on the following slide. We've also had menu command IDs for a while. We had a sort of a sparse set of APIs, but I think we are pretty much rounding out the API set for menu command IDs in Carbon. The first interesting one is enable menu command.
And what this does is if you associate a 32-bit command ID with an item, You can enable that item or disable it according to its command ID without worrying about where it is in the menu hierarchy. Basically, this allows you to not be concerned about searching or having a list of constants in your application that relates command IDs to items or anything like that.
And we've added a couple of other APIs that allow you to sort of query your existing menu bar to figure out where command IDs appear in your item hierarchy. And this is going to be useful for situations like when you have your font menu and you want to associate the same command with all the items in your font menu. Yet you still need to look up the text of the item of the menu that was selected because that's the font name and you need that to obtain a font ID and use that.
Speaking of the font menu, we've added some calls to create a standard font menu. And of course you saw the demo where you had the option of creating sort of an old style font menu with just font names in it. Or you can create a menu with font names and their variants hanging off the side as a hierarchical menu. And of course you make that decision by choosing whether to pass the K-Hierarchical Font Menu option flag to Create Standard Font Menu.
Some of the other interesting parameters to this function are the first hierarchical menu ID. If you care about where your font variant hierarchical menus start in the ID list, this is where you can specify where they should start. You would use this if, say for example, you had menus starting at 128, say, and going to 150. You're pretty sure you're not going to use 50 more menus in this application, so you could tell Menu Manager, "Okay, start my font variant IDs at 200," and I'm pretty sure there aren't going to be any collisions.
Let's see. So yes, and the other API will allow you to, instead of getting the string out of the menu and having to figure out what that corresponds to, just ask directly for the font family and font style in font manager terms instead of you having to do that yourself.
So one of the other standard font menus that we're supporting in Carbon is a standard Apple menu, or on 10 you'd call it the application menu. You no longer need to call append REST menu and pass DRVR to build an Apple menu. And you also obviously no longer need to call Open Desk Accessory because that's not supported, so you better not need it. Under CarbonLib, we build the Apple menu and we handle selections in it, and pretty much it just works. You don't have to worry about it. You still need to worry about your About item, but other than that, everything just works.
Under Mac OS X, we still build the menu for you, but we add a couple items that you need to respond to, one of which you're probably already responding to. Basically, the QUIT application, pretty much everybody supports it. If you don't support it, you really can't even shut down the Mac properly. So, you're definitely already there.
You need to add a new Apple Event Handler to handle the Preferences event that will send your application when the user selects the Preferences item from the menu. This is pretty easy because if you have a Preferences dialog, all you have to do is call the existing code that brings up that dialog and you're done.
If you don't have a preferences dialog, it's perfectly reasonable for you to pass the preferences command ID to some of those APIs I mentioned earlier to either hide the preferences menu item or disable it as necessary. And of course, if your application is in a state where it can't quit, it's perfectly reasonable to disable the quit menu item for a while. And that sort of seems counterintuitive because we built the menu, but that's sort of also why we built that whole command ID support into the enable and disable mechanism, because we knew that you were going to run into that problem. So go ahead and do that.
So, I'm about to explain these APIs and you're going to be wondering at the end, why did they add those APIs? And then I'll tell you. You can now clone menus. And cloning really is just terminology for reference counting. So if you explicitly clone a menu, you increment its reference count.
If you insert a menu into a menu bar, that implicitly increments that menu's reference count. And if you delete a menu from a menu bar, that implicitly decrements the reference count. And of course, when you dispose the menu, the reference count, hopefully if you've stayed balanced all this time, the The reference count goes to zero, and the menu goes away.
Why would you need this? Well, one use is: The enhancements we've made to Get Menu Bar. Get Menu Bar still returns the handle that you expect, that weird packed array of strange stuff that's kind of documented inside Mac 1, I think. You can still walk around in that handle and extract information out of it, but at the same time you want to use some new APIs that we've added. The Dispose Menu Bar will do the right thing with all the menus that happen to be in that Menu Bar.
Once you've gotten the Menu Bar and all of those menu refs have their reference count incremented, and then you dispose the Menu Bar, those menu refs will have their reference count decremented. Duplicate Menu Bar, of course, will increment all the reference counts of the menu refs in that Menu Bar so that you can keep everything balanced.
The thing that you want to avoid is that you want to have a menu bar that's not a reference count. The thing that you want to avoid is passing a Menu Bar handle to a Dispose handle because that obviously won't give us the chance to do all of that reference count maintenance. Same goes for Hand-to-Hand. Equally, it's a similar problem in that Memory Manager has no idea that it needs to do anything with menu refs.
Another way, though, to access the Menu Bar is Get Root Menu. And it returns to you what I think of as sort of a virtual menu ref. The Root Menu behaves as if it's a menu, and you can pass it to all the menu-- well, yes, you can pass it to pretty much all the menu manager APIs.
But the most important ones are Count Menu Items, which immediately tells you how many items there are in the Menu Bar, so you don't have to-- Declare your own data type and do tricky things to get that simple information. And the other thing it will do is it will allow you to get the menus that are in the menu bar, their menu refs, really easily simply by calling a new API instead of, again, walking around in that weird handle.
When you're done with the root menu, you can just call dispose menu just like you would with any other menu ref. So what we're hoping is that if you're in your code looking at all that weird menu bar code, Instead of changing it to use Dispose Menu Bar or Duplicate Menu Bar, which is perfectly acceptable to do, we're hoping that you have the alternative to simply rip that out, use Get Root Menu and the other menu manager APIs, and then make your maintenance life simpler over time. So it's been 15 years. 15 years and we still didn't add a way to set the menu title. In Carbon, we finally did it.
So, the Help Tag Manager. There's good news and bad news about the Help Tag Manager. The good news is it's the replacement for Balloon Help. The bad news is you have to give up all of those alternate names for balloon help you've made up to express to the world what you think of it.
So the Help Tag Manager is, we think, a big improvement on Balloon Help. The first improvement is that it's object oriented. And what that means is you can associate a Help Tag with a Toolbox object, like a control or a window or a menu item. The second big improvement is the human interface. Instead of having those big cartoony balloons, what you've got is small yellow rectangles, just like you've seen for I don't know how many years. But what's great about ours is that it has that slick aqua-translucence that you see everywhere else.
The content is a little different for Help Tags. Basically what we're expecting Help Tags to be used for is three or four words, a phrase. So suppose for example you had... You had a button with an icon with a label, and the button was supposed to send an email message.
The button might say, on the caption, it might say "Send" because after all it's in the context of an email message window and so "Send" is pretty clear. If the user for some reason needs to know what the "Send" button does, and hovered over that button waiting for the balloon help to appear, the balloon help might have said something like, Open a TCP/IP connection to the SMTP server and squirt an RFC 822 message over the link. That's not what we expect in a Help Tag. What we expect in a Help Tag is something like, "Send the current message." Now, we've added facilities for you to leverage your existing Balloon Help content because we know that's important.
But we think that as you experiment with that, you'll find that the content really doesn't fit the Help Tag idiom. It's sort of a stopgap measure. You can get your help system back up and running with Help Tags. But the more you use it, we think the more you'll be motivated to rev your content over time.
So here are some of the APIs that you use to specify Help Tag content. I'll just talk about the first one. You pass it a control ref, and you pass it this new data structure called HM Help Content Rack. Basically, HM Help Content Rack is a data structure that specifies an expanding number of data types for your content. By expanding, what I mean is we hope to add lots of data types that Help Tags support over time.
Right now, the one that absolutely works flawlessly and the one that we fully intend to keep forever is str255, the standard Pascal string that you're used to. In the header, you may find other types, but we recommend that you stick with str255 for now because that's the one that's going to stay around. Some of the other interesting fields in the HM Help Content Rack are the tag display side, and that of course is left, right, bottom, top. So you can specify where you expect the tag to appear relative to the object you've specified.
And then the other interesting field is the hot rack field. Now I said earlier that this API is object oriented in the sense that it talks to Toolbox objects. And why would you need a hot rack that could just ask the Toolbox object? Well, The relevant example is a window. If you attach a Help Tag to a window, you may have multiple hot-wrecked areas within that window. And we'll see why that's relevant in a few seconds.
Well actually, we'll see how you can customize that in a few seconds. It may be relevant even if you don't customize. For example, if you've got a window up and you're not using Control Manager for some reason, I mean, I'm in love with Control Manager and I can't see why anyone would avoid it. But, Some people need to. So if you're in that situation, that's where the hot rack comes in.
So I mentioned customization. These APIs are APIs you can use to customize your help tags. Basically, you use these APIs to sort of do lazy content, to provide lazy content. You can do two main things. You can decide, oh, I don't want to use string A. I want to use string B. And that may have to do with what state the window's in or what state the control's in or something along those lines.
The other thing you can do is specify the hot rack on the fly so that So for example, if you've got the scenario I mentioned with the window with multiple possible hot racks, if things are moving around, you still want to inform the Help Tag Manager when to take down the Help Tag. And so if you're in that situation, you need to turn to these customization APIs.
So I mentioned balloon help compatibility, and these are the APIs that you would use to specify your existing balloon help resources as Help Tag content resources. And it does preserve your investment in content, but It's really up to you to evaluate whether you want to keep that content for your Help Tag implementation or not. It's really sort of the honor system, and we hope you do the right thing.
I also mentioned some new control functions that we've added. We're going to be talking a lot more about controls in the second session for Carbon Toolbox Enhancements tomorrow at 9 a.m. I believe that's in A1, A2. Well, we'll find out later in the roadmap. But basically, we wanted to cover a couple of things in this session.
It used to be when you wanted to create a pop-up menu, you would have to basically crack open the documentation and read a short paragraph on just about every parameter to figure out what it really meant. It wasn't really the control. It wasn't really the refcon. It was really something else.
So what we've done is for each control, or each standard control, I should say, we've added individual creation functions so that you can pretty much look at the prototype, figure out the data you need to provide, and provide it. Instead. of spending a half an hour every time you need to create a pop-up button.
The other change we've made is we've made these control creation functions return OS status. It used to be you'd call new control, you'd get back a nil control ref, and then it would just be a big mystery as to why it failed. Now that we return OS status, you can at least maybe figure out, "Okay, I need to do this other thing instead," or maybe tell the user what went wrong or something like that. It's no longer just this big mystery.
I mentioned that we're going to have some new standard controls in Mac OS X. And in fact, in Carbon in general. The first example is there was a session this morning, and I hope you saw it, on the data browser control. It's a really whizzy new hierarchical list control. It has excellent user experience.
It supports all sorts of features basically for free. You get drag and drop support. You get the little disclosure triangle support. You get the column headers and the movable columns and the whole nine yards. Basically, we're making finder level functionality available to your application with respect to list management.
Some of the other controls are pretty cool in their own right, but I've got to admit the data browser is great. The Relevance Indicator is a new control that's basically the result of the fact that the Progress Indicator is very different in Aqua and it no longer works as a relevance control.
So we've created a new control, and for example this is used by Sherlock to display search results to tell you how relevant each hit is to your search. The round button is basically intended as a navigational aid. We expect you to use it for things like back and forward and home.
The Disclosure button is something that you will see in Navigation Services. It's basically for expanding and contracting dialogue windows. If you have expert users who need access to more settings than your main customer base and you don't want to burden your main customer base with too many controls, the Disclosure button is a way to give your expert users the opportunity they need to twiddle the settings that they want to twiddle without distracting your mainline customers.
And then of course, in Aqua we really, really, really want you to use the standard progress bar. And the one barrier left to that really was we didn't have a vertical variant for it. We really want you to get away from drawing progress bars with Quick Draw. It's never going to look good under Aqua. So, if you've got a vertical progress bar now, now's the time.
So, we've talked about things you have to do, and we've talked about things that you're going to want to do. The things you have to do are: you have to watch out for mandatory window layers and mandatory root controls. And the window layering shouldn't be too onerous, but it is a little bit of work. And as long as you understand it, I think you'll be OK.
The root controls stuff is even easier to deal with because all you really need to know is be aware of it for debugging. And for the most part, you shouldn't have to make too many changes because your code will create controls, and they'll become child controls of the root control, and everything will pretty much work the same. Watch out for get menu returning copies.
Don't assume that it always returns the same handle over and over again. Check out the Scrap Manager if you have some private scrap code where you export your private scrap during a suspend event. Look out for that. Stuff to look forward to is all the new Menu Manager APIs.
They basically enable you to eliminate code, support Aqua without too much effort, and then We'll keep working on them as well, but we're pretty happy with them. Help Tags is something that is basically really the help system of the future. It's basically the way balloon help should have worked in the first place. And we think you'll want to check that out as well.
And then of course there are some control manager improvements that you'll want to keep in mind. And again, if you're interested in control manager, the Carbon Toolbox Enhancement Session 2 tomorrow morning at 9:00 is the place to be. So with that, I'd like to bring out Dave Wright again, and he'll wrap things up for us.
Thanks, Pete. So just to take a look at where to take feedback about this, for Carbon APIs and ways that the Toolbox could better help you with your programming efforts, please feel free to contact me at [email protected]. And for user interface type issues, please contact our User Experience Technology Manager, John Galenzi, at [email protected].
And for the roadmap, as you can see, these Carbon Enhancement sessions are very useful. These are issues that are going to affect you as you're Carbonizing your applications. So don't miss tomorrow's second session about this stuff. It's in A2 at 9:00. I don't know about you, but engineering at 9:00 AM is really early, but it's really important, so be sure to be there. Also, be sure to go to Navigation Services, since that's the only standard way to open and save files in a Carbon application now. And for feedback, again, that you'd be sending to John, please contact us at gmail.com. Thank you.
And if you have any questions about John during this conference, please be sure to attend the Aqua feedback forum, because that's where user interface type feedback should go during this conference. And again, for programmatic type stuff, ways that the Toolbox could help you get your Carbon application going faster and better and concerns that you have, please attend the feedback forum for the high-level Toolbox. So this time, I'd like to invite the panelists to come up for Q&A, and we'll move into that.