---
title: WWDC2001 Session 120
framework: wwdc
role: article
path: wwdc/wwdc2001-120
---

# WWDC2001 Session 120

## Transcript

Kind: captions Language: en all right so this session and we're going to carry on with the topics that we were or nothing with the topics we're going to carry on then the track that we're talking about earlier which is how do you make a great application on Mecca Stan and if you remember in session 111 yesterday I had at the beginning the good better best scenarios for adopting aqua and in the best scenario or even in the better we started to talk about things like help tags and doing lists making lists appear properly on Mac os10 doing the right thing with the doc so one of the very basic things that every application should do is respect the docs position right and not size windows behind that we're going to talk about that in this session some of the other things you might do some applications might do with the doc is animate the doc icon or the application icon and we're gonna talk about some of that material here so it's a go in-depth on this stuff I'd like to bring guy Fullerton back on stage from the high level toolbox team a guy go for it all right well thankfully I'm not given the demo for this one so I can't screw another one up that's me John mentioned I'm gonna talk about a lot of things yesterday at Ed's session we talked about new features in the window and many manager and I'm gonna talk about a bunch of new features in the control manager as well as sort of a toolbox potpourri we're gonna touch on dock issues data browser help tags and a few other things so dive right in like I said the control manager is moving forward we've added a bunch of new functionality to it and the most obvious piece of functionality is aqua widget animation when you create a push button control it flashes when you create a progress bar control the fill moves to let the user know that the progress is really happening some other controls that we've had on previous systems that animate are the chasing arrow control sorry chasing arrows control in the edit text control those animated on previous systems they animate today on Mac OS 10 but the difference is that all of these controls animate via a carbon event timer what this means is the controls will animate automatically behind your back whenever you're sort of in the event loop sleeping if you got a chance to see Ed's carbon event session the other day you know what I'm talking about if you didn't get a chance to see it it's important that you try to track down the video for that later it's got some key concepts with respect to use of timers but fundamentally what this means is that you no longer need to call idle controls for the system controls under aqua on Mac OS 10 they're going to do their animation automatically via timer so you don't need to be calling wait next event with some small timeout just so you can call idle controls in fact that's going to be bad because your app is going to be using up a lot of the CPU and you don't want to do that now all of the controls will begin to animate as soon as they've drawn once we do this so that we can get the proper look as soon as the window appears we don't it we don't want to begin animating a push button for instance right after the window appears before you get the update event because you'll see the buttons show up before the rest of the window paints so what we do is we actually delay the beginning of the animation until after the control draws normally once and for some of the controls particularly the progress bar and the chasing arrows we offer a way to start and stop the animation if that's useful to your users you know you might want to say that a downloads paused for some reason or the there's a network lag and so you want to stop spinning the arrows for that reason and you can do that via the set control data API so that control data takes a control and a tag for the type of data you want to set and in these particular cases you pass in the Kay control progress bar animating tag or Kay control chasing arrows animating tag as well as a boolean value for whether or not you want it to animate so you can start and stop it that way now push buttons the way you start and stop them from animating is by marking them as default there's a bunch of different ways you can do that the preferred way is set window default button this is a new API for carbon essentially what it does for you is it marks a particular control as the default control for a given window and the coolest thing about this is if that default control is a push button the push button will begin animating the other benefit of set window default button is that it also tells the carbon event manager which control to hit when the user presses the return or Enter key so if you can use set window default button by all means go ahead and do it it's going to get you the most free functionality now in the future now an API that you're probably familiar with already is set dialogue default item if you use the dialogue manager a lot you use this API to tell the dialogue manager what which the default button is and of course when you call this API we will start the default button animating appropriately and if neither of those really serve your needs if you want more fine-grained control over whether or not a button is animating you can use set control data to toggle on or off the animation as you wish with the K control push button default tag we've added a number of new widgets for aqua and you can see all of them up on the screen I'll go through them sort of one by one and tell you what they're useful for we have a rounded bevel button you can see those down at the bottom of the window snapshot there it's just a different look for a bevel button by default your bevel buttons will come up with the square look that you're used to and that's so you can continue using the same sort of grouped bevel button api's where they're real close together but you might have some needs where you really want to draw a rounded bevel button and the way you go about that is by using a cool feature we added to the Mac os10 bevel button whereby you can change the appearance of the bevel button and essentially tell it which appearance manager theme button to draw itself as so you can create a bevel button control and say draw in a rounded fashion or draw in a normal push-button fashion or draw in some other fashion so the bevel button is sort of visually polymorphic in that way we also offer a round button that you can see up on the top left hand corner of the screen shot this is used for a number of reasons most prominently it's the new help button that we want in our aqua user interface guidelines I'm going to talk specifically about how to get that a little bit later in some gotchas with respect to Mac OS 10 and Mac OS 9 we also use that for the back button and the home button in things like Sherlock and the help viewer we have a relevance of a relevance bar as well which is essentially just a variant of the progress bar control let you do relevance ranking Sherlock uses this if you were using the progress bar control and mac os9 and carbon to do a relevance rank that's not going to give you the right appearance under Aqua on Mac os10 Sochi you should really begin using the relevance bar under Mac os10 we also have a disclosure button which is not on the screenshot that's most prominently used in a navigation services dialog and it's useful for controlling whether a window resizes or shrinks back to show you more details something that's not exactly new for aqua but that I wanted to point out is the fact that we still have four-sided tabs Platinum is supported four-sided tabs you can have tabs on the top right bottom left of your control but earlier releases of Mac os10 didn't support the full functionality I think we only supported top tabs for a while well they're all back into the GM release of Mac OS 10 so you can continue using them on all four sides of course we have appearance primitives to draw all of these widgets so if you don't feel comfortable using the controls or you have very specialized needs you can call the appearance manager to draw any of these for you another request we got when we came out with the aqua user interface guidelines was we need smaller controls or differently size controls now the normal controls are basically platinum sized but there are certain cases in your user interface where you've got a small pallet or some other tiny piece of screen real estate where you need to draw a bunch of small checkboxes or small push buttons or something like that and the Aqua widgets are just too big for those cases so what we did is we implemented some small versions of various system controls so that you could get the right look under aqua and a lot of applications out there had small controls already on mac os9 that's because they implemented them themselves they wrote custom CD f's or maybe they weren't CD f's they just wrote custom code to draw these things and of course those are going to look really ugly under aqua so if you're using your own hand rolled small controls you want to begin using the system supported smaller controls there are four basic sizes of controls now like I mentioned before the Platinum metrics are the normal sizes this allows you to have a window that's laid out and have it looked just fine on platinum and just fine on Mac os10 some controls like the checkbox and the radio button support a smaller size others like the progress bar support a larger size the progress bar is an interesting case actually because the default progress bar size being the same size as it was in platinum is good for your layout purposes but unfortunately the default size for the progress bar does not match the Aqua user interface guidelines the guidelines say you should use a larger one so in order to match the guidelines you to set the size of your progress bar control to be the large size the forth size we support is actually an automatic size and we've actually supported this for a while just not explicitly certain controls like the scroll bar to vary how they draw depending on how wide or narrow you make the the control rectangle themselves if your scroll bar is about 15 or 16 pixels wide we're gonna draw the normal size scroll bar but as soon as you drop it below a certain threshold which i think is about 12 pixels we begin drawing a narrower small scroll bar so the scroll bar is one of the ones that can support an automatic size now if you don't like the automatic sizing for scroll bars you can recruit explicitly request either the normal or small size if you wish but in general you need to make sure that you don't just use these because they're available you need to have good reasons for them the larger size controls are much more reasonable reasonable and if you can fit them into your interface please do so even if it means making your windows a little bit larger but if you do have specialized needs like to fit a whole bunch of widgets on a pallet or you know some other small bit of screen real estate go ahead and use the small controls that we provide now to change the size of a control it's really straightforward you can use the set control data API I mentioned it this session previous session you pass it a control you pass it the tag for the data type you want to change in this case you say change the control size kay control size tag and then you pass the size that you're interested in kay control size normal small large or Auto not all controls support all sizes so be ready to handle errors I believe we have comments in the header which say which controls support which sizes but in general if you're good about handling errors you'll be just fine the other important thing to note is right now these are only available on Mac OS 10 carbonyl a of 1:3 does not support any big control sizing stuff we're investigating what we would need to do to bring that into carbon Lim but I can't make any promises about it so this got brought up last session and the QA s but it bears repeating the control manager supports the notion of an embedding hierarchy and we've done that since Mac OS 8.0 it's been optional on the traditional operating system including carbon live but now on Mac OS 10 embedding is always on and this has certain interaction side effects for your application essentially hit testing and draw order might not be exactly what you expect on Mac os10 if your application does not use the embedding hierarchy on Mac OS 9 so my suggestion to everyone is always explicitly request the embedding hierarchy you do it online just so you can get the embedding hierarchy when you do it on 10 it's effectively and no up because the embedding hierarchies already there and it's still totally legal to do that but make sure you explicitly request the embedding hierarchy and run your app on 9 and get your behavior straightened out on there and you should be able to take that app then and put it on 10 and see good behavior create route control is generally the way you turn on embedding creating a route control for a window switches on the embedding hierarchy that's not the only way you necessarily can turn on the embedding hierarchy if you use the dialog manager you can specify a dlg X resource which corresponds to your DL og resource and there is a feature bit in that dlg X resource it says please turn on the embedding hierarchy for me you can do the same thing with alert resources now the reason we turn this on automatically on Mac OS 10 is that it not only allows us to really simplify the Mac OS 10 codebase and we basically had divergent code on the traditional OS we got rid of one whole side of the divergent code and diverted behaviors so that makes our maintenance life a lot easier but it also allows us to add a whole bunch of future enhancements yesterday at the windows and menu session we talked about how transparent sheets for carbon we're going to be coming in a future release we wouldn't even be able to do that unless the control embedding was mandatory so future control management's are also going to be sort of dependent on the embedding hierarchy now carbon removed access to a Windows control list the way controls were maintained in a window on traditional OS was that there was literally just a link list that hung off a window where we kept each control we eliminated that for carbon in favor of people just embedding the controls where they wanted them to unfortunately we heard a lot of feedback from developers when they said you know what we need the control list because we're doing cool things with it you know we have an interface that we literally want to move on the fly from one window to another maybe be a drag and drop and it's it's got great performance impact for us if you make us create both hierarchies at once you know as we destroy window and put destroy one window and put up another and we'd really like a way to move a control between windows so we gave it to you essentially we don't allow you to hack the control list anymore but we allow an existing API the embed control API to take a control out of one window and just embed it someplace else the only gotcha with respect to all this is that you cannot actually move the route control the route control once it's associated with the window it's always stuck to that window but you can go ahead and move any sub control so you're interested in we've mentioned this a ton of times again Carbon events permeate the toolbox the controls themselves are actually implemented in terms of Carbon events right now in fact the the the messaging model for control definitions is inherently carbon event-based now we obviously still support message based def procs but we do this through a compatibility layer where we intercept a Carbon event coming towards a particular death proc we see it doesn't handle it we turn it into a control rest message and route it off to the DEF proc but we don't necessarily handle direct messaging in the old-school way to the system controls what that means is if you have any application code which is calling send control message and trying to make the system controls do things they probably won't work on Mac os10 you might get lucky for the short term because I know we still support a few messages this way but ultimately we plan on removing all support for can send control message to the system control definitions now generally speaking you shouldn't even need send control message anyway we have high-level Control Manager api's that let you do things like drawing and hit testing and whatever at a very high level so you could probably just eliminate your use of send control message in favor of these other api's now if you have custom controls you may not be planning on revving them to support Carbon events anytime soon and you're using send control message with them obviously now you can continue to do so we're not going to eliminate the same control message API we're just going to prevent it from working with the system control definitions but your custom CSS will still work just fine so I want to go into a few of the future enhancements we're adding to the control manager for performance reasons drawing with quick-draw right now in the tool box is a little bit slow because ultimately when we render a particular widget we're going to draw with courts and drawing with courts means we need to build the proper courts port equivalent which is a CG context ref building one of these is a little time consuming in a little memory intensive and ideally what we'd like to do for a given draw cycle we would like to just create one context and pass it to all the controls when they draw such that each control now no longer needs to create its own context this will save us a lot on time and memory overhead drawing with courts will also allow you to get around one major missing feature in the appearance manager right now the appearance manager does not let you draw pulsing default buttons there's no way to do it via via the api's ultimately when we allow drawing through courts you will be able to draw pulsing default buttons through the appearance manager now yesterday we gave you a little taste of what control drawing modes were essentially we want to build some functionality into the control manager that makes it a lot more reasonable to work with right now when you call a control manager API you don't necessarily know whether or not it's gonna draw off the controls visible it draws for some api's and on Mac OS 10 you notice that it draws if you call set control bounds but on carbon live it doesn't draw and there's all sorts of weird little nuances like that and that we've had historically and we want to offer a way that lets you have more explicit control and exactly want to control draws in fact we want to get to a point where controls don't really draw by default you can go configure a control 5 times with 5 control manager api's and and not draw until you've done all that configuration and finally at some later point the control manager should be able to say well you know what I know what controls are dirty so why don't I just go and redraw them and this was all done initially to allow us to support transparent sheets which will be coming up in the future but it gave us a whole bunch of these cool side effects and in the future we're gonna allow you to turn this stuff on for your windows and get all kinds of cool performance benefits I'm going to switch gears a little bit and start talking about the dock a lot of applications need a new icon right now your icons are probably 32 by 32 and they look pretty miserable and with the dock being so prominent in the interface and the fact that the dock can display 128 by 128 icons you need to spend a lot of time making your dock icon look great but it may not be enough to just put a great-looking icon in the dock some applications need to put status in the dock they need to the best example is mail application mail puts a little marker in the dock that says how many messages you've got unread it's a really cool feature but at the same time you don't want to overdo it you shouldn't just animate your application icon or badge something on your application icon just because the api's are there you need to not be intrusive into the user's visual space unless it's going to be meaningful to them if you find an instance in your application where animating your icon would be useful there's a number of different ways you can do it probably the most straightforward way you're used to programming for traditional Mac OS is to use quick-draw and the way we allow this is through the use of the beginning and QT context for application doc tile api's these api's give you a color graph pointer that you can draw into and when you call end it ends up putting the the image onto the dock for you now quick-draw as you know does not support transparently in the Alpha Channel properly and if you want your application icon to have transparency you need to draw it with quartz and you do that with a similarly named beginning in CG context for application ductile we call those you draw with quartz you end the context it draws to the screen you can also do badging which is what mail does and there's only unfortunately a quartz way of doing that but in order for badging to work properly it needs to use alpha so that's why it's quartz only we've got a couple api's for that as well now all of these api's have pretty good documentation in the header itself they're in mac application h we show you some ways you use them some of the pitfalls in there so I suggest you take check those out your minimize windows also show up in the doc and therefore you might want to change the icon that's used to represent them when a window is first minimized and put into the doc the window manager automatically takes a snapshot of the entire window its structure its content and everything scales it down to 128 by 128 and puts that in the doc if your application has fairly simple needs and you just want to update the image in a doc based on your windows new image contents while it's minimized you can do that with the update collapse window doc tile so if your application has a minimized window and it's busy processing and you put some more status in your window or you change some image slightly and you want it to be reflected in the doc just call update collapse window doc tile on your window and the window manager will just do the right thing for you automatically if you need more custom control we offer api's for those as well create and release QT context for collapse window doc tile and these api's are all documented in mac windows h and we're working with the documentation people to get other forms of documentation available but right now I took a look at these these headers the other day and they're they're really really good they explain a lot of what you need to know now to give you a more concrete example of all this I would like to bring up David and you can show you some of the details David thanks morning I wrote a small demo application if you could bring up right that shows the use of just those few api's that guy mentioned and I have an example of each one that's a little demo application called Tyler and keep an eye on this guy down here that's the guy that's gonna get animated first I'm going to draw on it with quick-draw I'm not a graphic artist or anything I didn't have anybody make fancy art for me you can see that I had to erase behind the image otherwise I would have left behind some remnants of the other icon that was already there unfortunately when you erase with quick-draw any drawing it all with quick-draw just stomps your alpha and it's completely opaque and not transparent at all so the API is there but I really wouldn't recommend using quick-draw go to the court stuff it's fairly easy to use next I'll show courts you can see it's the same drawing if you can see really up close on it it's all anti aliased and stuff because quartz is really nice that way you get it all for free there's also a transparency on here you can't really see it unless I drag a window behind it you can see that that all that drawing is transparent you can see right through it see the window up there the next thing I'll show you here is I'm going to add a tile to the badge I'm going to add a badge to the tile excuse me it's just my WD WWDC badge again I think that might break some h:i guidelines I just made it myself and it's fairly simply you just make an image with an alpha Channel and you blast it on there with an API call one gotcha here though is that you need to clean the tile before you draw on it because if you don't the badge will just over composite on top of itself and I'll just do that a few times and draw and you can see that its shadow has just over composited over and over and it's not much of a shadow anymore it's kind of a black blob which is ugly the second last thing I'll show you is a restore tile just bring it back to what the application sets the IKE when the application sets the icon in there and the last thing that I'm going to show you is something I talked about with the collapse window tile animation so I have a little demo window here I've got a beautiful picture of someone it's a little dark though so we have some processing that can happen to it to lighten it so we can see his pretty mug got him going up there we can actually minimize this into the dock and you can see that the the tile continues to update itself so you can see how far along the processing is let's do it one more time just for fun let's do a whole bunch of them good thing my head's not really that big yeah he's so pretty so you can see they're all down there animating and you can also see that there's a whole bunch of things down there animating and it's a little ugly so don't get crazy doing the animating it's just fun sometimes next I'll just show you just some of the code I used it was all very simple and straightforward to do first you saw me do the quick-draw animation you call in and you get a Judy contacts context for the application doc Kyle you keep a hold of the port you get to use it for a while I happen to do some erasing here you really do have to erase you can get the same overcome compositing problems with courts and if you don't erase with the quick-draw you'll you'll end up with remnants of your previous tile drawing on there I do a little bit of drawing using quick-draw everybody knows how to do that probably better than I do and here's a gotcha when you have when you request a context you always have to flush the context before you finish with it because the drawing won't the tile won't update until you get to get some other update cue later on so don't forget to flush it's really important and lastly you got to tell tell the doc that you're finished with that context and you're not going to be drawing in there anymore that's the quick draw way and you saw how it made everything opaque and it just killed the transparency that's just no fun very similar code to do the courts I begin the cg context right here I clear it out this particular clear though maintains the transparency so I start out with something completely transparent I can start drawing on that I do the happy face drawing again and I happen to do a little bit of transparent yellow in there and that's how you can see through it CG contexts are just like the QT context you get in the first one don't forget to flush or else it won't update properly can't forget to flush and lastly you gotta tell it me hey I'm finished with the context the badge is a little bit more complicated and you you require a CG image you say I have a CG image and I'm gonna be blasting it on to the the tile you're gonna blade it on there there's a bit of a pitfall like I mentioned earlier where I showed you where the badge over composited on itself in its shadow was darkened so I actually restore the tile just before I draw on it so I have a nice nice clean tile to start with I make some I make some picks Maps and there's a really nice call available called create CG image from pix maps so you can take a pics Maps pics map that is an image that you want to put on there another picks map that is the Alpha mask that you want to use it makes a nice CG image for you to use very convenient and lastly you just want to overlay that image on top of the tile it's really straightforward the next part is restoring the dock tile it's very complicated so guy wanted me to go through the code line by line for you here it is here the one line restore application dock tile image very straightforward no parameters I think we can all manage to cut and paste that one out of the header and the last one was the collapse ductile animation it was very straightforward all I did is I ate at the window so that you can see the processing happening and you just have to tell you just have to call the API update collapse window dock tile with a window pointer and it does all the work for you it just takes the image of the window and sticks it into the tile so I do some image processing before and after and just make that one call and it does the animation for you and we gotcha there is you might want to make sure you update it one final time when you're finished so there's some tricky code hiding up here where I updated one last time but that's that's about it it was really easy to do tile animation oh one last thing this code is going to be up on the website it's just gonna be sample source code for everybody to try up Thanks so that was cool one final note about the doc staff again I know probably heard this about a dozen times just because you can do this doesn't mean you should do this make sure that your application and window icon animation is subtle and use it only when necessary I the last thing I want to see personally is about 10 applications each spinning some little random animation just because they can not only is it visually distracting but it's just gonna wreck performance for the machine so do it only when it's necessary so another note about the doc is that well you know it takes up space down there at the bottom of the screen how do I deal with that well simply speaking you can call an API called get available window positioning bounds this API receives a graphics device for a monitor that you're interested in and then we pass out a rectangle saying where the valid area of the screen is that you can position your windows on to and this makes sure to take care of the doc obviously and to take care of the menubar and you know if we add things in the future or change where the doc is or change things around this API will insulate you from those changes it will always accurately reflect reflect where the valid area of the screen for you to put your windows is now one last note about the doc that unfortunately I don't know a slide about but that's the importance of responding to clicks on your icon in the dock now I'm sure you're all aware of the basic for Apple events that your application needs to support and one of those is the open application apple event and the way you handle this is by putting up a default document window you know the first window that your user sees well when the user actually clicks on your doc tile icon after your application is launched we send you a reopen application apple event and you want to handle this apple event by putting up another blank window now this is only for applications that have a document centric interface for applications that are more like control panels or only have a fixed set of windows you don't need to worry about that oh but you might what you might actually want to do when I reopen is bring all of your windows forward and I believe you can do that with set front process that should bring all of your windows forward all right so switching gears back to the control manager Control Manager supports a lot of carve events they're all documented in carbon events on H we tell you what they're used for we tell you when they're sent we tell you what parameters come along with them we tell you what the responsibilities of someone who handles them is and this is a great way to write custom def procs now this is only available on Mac os10 right now but we're looking at making carbonate rocks available in a future version of carbon live and the best part about control carbon events is it also allows application clients of controls whether they be custom controls that you wrote or system controls that Apple wrote it allows those application clients to sort of override or augment the behavior of a particular control definition and all of the control carbon events except for two that I'm going to be mentioning today are of the hey event class control just take a look at carbon event stage and it'll tell you all the details there now let's say you want to write a carbon event based control definition it's your first time you're doing this I'm gonna take you through step by step in order to do a carbon event based toolbox object you need to register your toolbox object class on a toolbox object class is just an opaque wrapper around the notion of a def product you can think of it that way and the way you create an object class is by calling register toolbox object class you give it a name and you give it the carbon event handler for that def proc and you give it the list of events that you're interested in handling the API hands you back a toolbox object class ref now when you call create custom control you can pass in that toolbox object class ref actually pass it in as part of a control def spec structure but you pass that in to create custom control and therefore the control manager says oh you know what I know what Def brought to create now I'm gonna go create it when you call create custom control you can also pass in an initialization collection with all sorts of initialization information that your control definition might want totally free farm totally up to you what you want to put in there the control manager does support some default things in this initialization collection it will look for things like a starting value of starting minimum whether or not the control visible things like that that's all documented in the header as well let's say however that you do all of your control creation either via new control or get new control or perhaps you have you want to write a shared library version of a control that needs to be used by third-party applications and all they use are new control and get new control in order to support new control and get new control you need to use the register control definition API I should probably go into a little bit of background to make this more to have to give this make this make more sense when you call create custom control you're essentially saying create this control with this entry point I already know what the entry point is new control and get new control operate off this proc IDE model if you've done any toolbox programming in the past you know what a proc ID is essentially it's just sort of a mangled resource ID of where a def proc would have lived on the traditional OS and what register control definition lets you do is it lets you take a proc pointer based def proc whether it's a toolbox object type or whether it's just a raw proc pointer and say associate it with this sort of virtual resource ID so now your clients can call new control and get new control and actually instantiate versions of your carbon event based def Rock there's a couple basic Carbon events that just about every def proc is going to want to support and of course those has to do with initialization and disposal we send two different Carbon events cake event control initialize this is the one where you initialize it in the Carbon event has the initialization collection that you passed in to create custom control so you can extract that out start digging through there looking for your bits of information that are important to you your only responsibility for K event control it for handling of K event control initialize is to make sure you report your controls features back out in the K event per amp control features you do this so the control manager knows what kind of things you support like whether or not you're in embed or various other things and of course also while handling initialization you want to allocate any instance data or do any prep work that your control definition might need and you can imagine how the disposed work you get the dispose event you dispose your stuff and you're done it's pretty easy right now if you want to be a full-featured controlled definition you want to allow your clients to make use of certain control manager api's for instance if your clients want to determine what the proper size of your control is given its current settings like let's say I can let's say application creates a static text control and they start out creating one that's just ten pixels wide and ten pixels long just because it's the easiest way for them to do it and then they show some text in there then they want to ask the control manager hey how big should you really be to display all your text you would use the get control best direct API to do so in order for a control definition to report the right thing it needs to listen to the key event control get optimal bounds Carbon event you handle this Carbon event by examining your current state figuring out how big you should be and you can even include a baseline offset the space line offset allows your clients to do things like line up the text baselines for two totally different widgets make things look right according to the Aqua human interface guidelines now another API that you might want to allow your clients to support is get control region yet control region allows your clients to ask for any region relative to a particular part code of your control as well as a couple sort of meta part codes like the structure in the content part when the application calls get control region we send your control definition a kay event control get part region and well guess what has the part in it that the client is interested in and it's your responsibility to figure out what the region is stuff that in the carbon event and say you handled it and then you're done you'll probably want to handle the K control structure meta part and the K control content meta part in addition to all the sort of unique parts of your control and these will allow your clients to determine the total draw area of your control as well as the sort of embeddable area of your control and likewise getting set control data is a free-form way that clients can ask your control for a certain piece of information it basically enables you to provide information to clients that the control manager does not already have explicit support for for instance the disclosure triangle that's a bad example of the static text control the static text control supports a one line mode or a two line mode well it doesn't really make sense to add a control manager API that's called set control one line mode with a boolean right you can just use set control data to say hey static text I want you to be one line or I want you to be two line so this is a very powerful thing for configuration of complex custom controls and if you want to allow your clients to use it you listen to the key event control get set data a carbon events any control worth its salts probably going to draw right to do that you listen to the cave and control draw Carbon event and normally for message-based CDF's you always draw in the current port but for this carbon event we actually pass you the port that we want you to draw into and in fact we only optionally pass you this port if you see a port inside the que event control draw Carbon event draw into that court if you don't go ahead and draw in to the current port and likewise if your control supports a sort of opaque background that you need to sub controls to be rendered on top of properly you want to listen to the que event control apply background and que event control apply text color Carbon events these give you a chance to set up the background properly so your sub controls can erase most controls track the mouse how do you do that well it's actually really simple if you have a simple control if your control is something like a push button where it pretty much just has two visual states you know the users tracking on it the users tracking off of it all you need to support is K event control hit test became this Carbon event is sent by the control manager in a number of situations a client might be asking hey what part of the control am i over right now well we'll send you the carbon event for that so you can tell the client but if you're tracking needs are simple this hit test Carbon event allows the control manager to do the majority of work for you you simply respond with the part code the mouse currently is over and if you have simple needs the control manager will just highlight and unhighlight you withdraw Carbon events as appropriate and if you have more complex drawing the sorry tracking needs you should listen to the K event control track Carbon event this is sort of the one-stop shopping high-level Carbon event where you can do anything you need to do it's this carbon event is sent to you almost immediately after a client calls handle control click or track control you've got full rein you can do custom tracking weird scrollbar behavior or anything you want now there's actually about a half a dozen more tracking related Carbon events and they're honestly fairly complex and I'm not going to go into the details here but I doubt you'll really need to use them if you do if you are a widget like a scroll bar and you want the control managers sort of do its default thumb behaviors and weird things like that you can actually take advantage of about the half-dozen other carbon events those are all documented in the header pretty well so take a look there if you want to support keyboard input the first thing you must do is support the notion of focusing we talked about focusing before it basically says you know what my control is ready for keyboard input I'm where the keyboard input should go it's in order to support that you need to listen to the key event control set focus part carbon event there's a lot of information on the slide when it's really all important when you get sent this event you're going to be told which part to focus now sometimes you might be told to focus no part that means clear the focus if you have it already other times you might be told a specific part to focus so you should go ahead and focus that specific part other times like when the user hits the tab key or Shift key shift tab key as they're tabbing through your user interface we say focus the next part or focus the previous part so you want to handle those as appropriate of course if you're not currently focused and you receive the carbon of emphasis focus the next part should focus to your first part and as you keep receiving next parts next part Carbon events keep focusing next parts until you get to the end and finally when you're at the last available focusable part and you receive another request to focus the next part just turn your focus off of course you do the reverse if the user is asking for the previous part now your one responsibility on exit from this carbon event is to tell the control manager what part is really focused this is though the Control Manager can do certain smart things just store your currently focused part in the key event per am controlled part of the carbon event and that's all I really need to do you might optionally want to support the key event control get focused part carbon event in fact this is probably most of you will not need to support this if you return the proper part in cabin moran control part but if you have very special needs you might want to take advantage of this carbon event it allows the Control Manager to request sort of lazily what part is focused Oh actually let's go back one more thing this becomes especially important in the future one thing we want to do with Mac os10 is allow keyboard navigability across all the user interface and it's a little ways off but the only way to make that happen for your custom controls is to support these carbon events you will not be able to make it happen for controls that are message based now the cool thing is you can actually have a message based control that just in star elsif is sorry it just installs a few carbon event handlers and this might be one of them you want to take advantage of so it's just checking the stuff out learning how it works because it'll become very important in the future if you want to have a totally keyboard navigable UI so once you've got the focus you want to accept keyboard input the best way to do that is to listen to a carbon event that's not part of the control class this is actually part of the text input class and it's of class K event class text input the carbon event specifically is K event text input Unicode for ki event a little cumbersome for an of a name but you know it's documented well in the header and essentially the Unicode character stream is stored in a parameter of that Carbon event you extract it you slap it into your control and you're pretty much all set now they even cooler bit is that keyboard events are routed directly to the user focus once you're focused if you're doing carbon emit Savi deaf procs you don't need to worry about the client calling handle control key and I'll just get sent there automatically now there's several more events you might or may not want to handle depending on how complex your control is the first news cave and control activate and deactivate these are sent when a client calls activate or deactivate control now generally speaking most widgets will not need to respond to these Carbon events these are only useful if you need to change your controls internal state as a result of activating or deactivating you don't need to worry about handling this event if you only change your visual state on activate deactivating I guess the best example of this is the Edit text control when it receives this carbon event it calls te activate right because it needs to disable the look of the Edit field and it doesn't just do that to get the visual look it needs to do that so that the text services manager can make sure to deactivate any TSM documents and stuff of that nature but in general other controls like the push button they don't worry about it because after this carbon event is under your control the control manager will request is raw anyway so you'll be redrawn in the proper visual state now a lot of controls are becoming more complex these days case in point the data browser we talk more about the data browser a little bit later but as controls become more complex it becomes important to display a proper cursor when you're over control we're no longer at the point where we know all right well we want an arrow over buttons and just about everything oh except for the end of Tech's control which needs an insertion point no now we're at the situation where alright if I'm over one of the column headers in data browser I needed to display the little Expando arrow cursor unless I'm all the way expanded to one direction and then I want to show the expandable cursor that only points the other direction so we have a handle control set cursor API which was introduced relatively recently and in order to take advantage of that you just listen to the kay event control set cursor Carbon event we tell you where the mouse location is as well as what modify your keys are down and then you can look at your controls internal data structures and figure out what cursor to put up likewise contextual menus are becoming more important in the user interface we offer a handle control contextual menu click API and when the client calls this we send you a key event control contextual menu good Carbon event now the cool bit is these Carbon events will be sent to your app your control definition automatically if the default window handler is installed on your window it means if you're a very carbon event savvy your control definition can just handle these carbon events you don't need to worry about the right API calls because the toolbox is going to call them for you now so far most of the carbon events I've been talking about have been very concentrated in the def proc space right these are things that the definition themselves are going to want to handle so it can display the proper user interface or do the right functionality but some applications may actually be interested in listening to certain changes in the controls so we have these sort of state change Carbon events that gets sent out applications can listen to these just by installing a handler for the appropriate Carbon events on a controls target and in fact applications can even listen to all the previous carbon events I've talked about by using the same technique if you really want you can override the way a control activates or deactivates just by putting that handler on so these state change notifications particularly the first one the value field changed this carbon event gets sent out anytime the minimum the maximum value or view size changes on a control and we send you a sort of before and after snapshot so you can determine what changed and how to react appropriately likewise when a control is embedded into a parent control we send that parent a cave and control added sub control Carbon event so that it can react properly maybe position it in the right place or you know do something whatever it needs to do and we also send a removing sub control carbon event when we're about to remove it from the window and a really cool one actually is the K vent controlled bounds changed carbon event we send this out any time the controls balance changes as a result of size control move control site control bounds in fact it even gets sent out recursively if you have a parent control with a bunch of sub controls in it and you move the parent control all the sub controls do move so they also get a K event control bounds change the carbon event now the reason I think this particular one is so cool is because it will let us fix certain performance problems in some of the larger CDF's if you're if you have a large complex visually complex EDF and you resize right now the control manager says draw everything and if you're if it's particularly expensive for you to draw they can take a lot of time you see the lag maybe a flash on that glass nine and it just really isn't a good thing what we're gonna start doing in the future is passing allowing you to tell us what region to update as a result of one of these state changes so what will happen is someone will call size control on your control and you will be able to put a region into the into a parameter of the K event control bounds change Carbon event that tells the control manager look just redraw this particular area that way it's not very expensive now this stuff isn't in yet but it's one of the things that we're sort of throwing in the control compositing bucket that we've been talking about a little bit and finally if you're using the embed control API to move controls from one window to another we send a key event control owning window change Department event so you might want to react to that appropriately it's a few others and these actually def proxy won't want to handle these are these are pretty much reserved for the client of the control the first is K event control hit after the user clicks on a control and the application calls track controller handle control click and the click did successfully end on that control we send out a key event control hit carbon event this will give your application a chance to react to the control as appropriate if that control has a command ID associated with it and the K event control hit carbon event was not handled we will send out a key event command processed Carbon event first to the control and then ultimately through it's embedding hierarchy down to the window now the really cool thing about this is you can build up an entire user interface with a window and a whole bunch of controls in it and let the default Carbon event handlers track all the clicks on your controls and then let all the default processing happen and then at the window level you can install a KA event control hit or a key event command process Carbon event handler that listens to all the control hits and command processes for controls in that window so it sort of lets you encapsulate all your logic code into one place in a clean way now I've mentioned complex controls and right now there is no more complex control than the data browser the data browser is our list manager replacement essentially and we figured well if we're gonna replace the list manager we're gonna need a new API well we don't want to make any way P I so let's just leverage an existing API well the control manager API was really rich so we decided to turn the data browser into a control and essentially data browser is the ListView that you see in the finder and it's the column view that you see in a navigation services dialog it's totally customizable we support resizable columns you can change what's displayed in a given column you get to control the text that's display the icon that's displayed it supports text editing drag and drop all kinds of stuff like that like I said it's a system supplied control definition you create it with create data browser control gives you back a normal control rep you can use all the normal control manager API you can size control it you can move control it you can hide it you can make it active inactive but of course a complex list needs a whole new suite of api's that you can give it the right data configure it properly so there's a bunch of new api's and control definitions H to configure the data browser so we're not planning on leaving the data browser alone we need to improve it in several ways it's the the version we shipped in Mac OS 10 is pretty good there are some bugs in it yeah granted the version and carbon Lib is lagging behind a little bit so there's definitely some enhancements we want to make to it first office speed we plan on speeding up the data browser for one through the control compositing stuff I've been talking about and specifically by handling a key event control bounds change carbon event that way when you're live resizing a Finder window we don't repaint the entire data browser control and in fact that's why I live resizing a Finder window is so darn slow so we're gonna make that a little bit faster I have fixed several critical crashing bugs lately and they will show up in a future operating system release there's still a bunch of other bugs we know about we plan on fixing the major ones and I want to get as many of those bug fixes into the version of data browser that ships with carbon-14 as possible and finally data browser supports most of its customization through proc pointers proc pointers are a little bit limiting in that you can't change the parameter list they receive you know once you're stuck with once you've got a four parameter proc pointer you're pretty much always stuck with a four parameter proc pointer well Carbon events are sort of our prop plane replacements so we're going to integrate them more with data browser so you'll be able to do more customization through carbene events so if you're going to support help properly in your application there's several steps you need to take and probably the most basic one is including the proper help button in your application if you display standard alerts from you know create standard alert standard alert or create standard sheet we're gonna put the right button in there for you but if you have custom needs either in a larger window or in a dialog that you roll yourself you want to display the proper Help button and unfortunately you have to conditional eyes your code to make this work on both Mac OS 9 and 10 on aqua we want you to use the round button control and unfortunately you can only create a round button control Mac os10 I'm knockin was 10 just call create round button control on Mac OS 9 however we don't have support for the round button control in fact the Mac OS 9 look is just a plain bebel button control so call create Babel button control when you're running on carbon level enough to get the right help icon you just use icon services both of these control types support totally custom behavior via icon refs so you call get icon ref to get the help icon associate it with the control and that's pretty much all you have to worry about another step for supporting to help is of course help tags I'm showing on the screen showed it on the last slide help tags you can think of those as a balloon help replacement if you used to the traditional but really they're just context-sensitive tooltips the cool part about help tags is that they remain very brief for most cases as you hover over a particular button and it should give you just a very brief indication of what that button is gonna do but if you hold down the control key the help tag actually expands to give you a little bit more information that way you can get that information if you want it but it doesn't stand in your way and block out rest of the rest of the interface help tags also allow customizable positioning relative to the UI element that you're planning on putting help up about and we have content guidelines in the aqua user interface guidelines I believe I believe there's a section in the back that talks expressly about what sort of help content is good help content and how much is too much and what is just the right amount so take a look at that you can implement health tags in a number of ways the most straightforward way is to use interface builder and it's nib support any nib that you build from interface builder for a carbon application will allow you to specify help information directly in that nib so not only can you position everything but you can give it all the help content and then when you run that interface with the Carbon Event Manager the help tags just come up automatically so that's the most straightforward way we also offer a programmatic interface and we even added a few api's to let you leverage existing balloon help content that you might have for your dialogues now while these api's are available to let you use the balloon and help content I don't recommend you not for any sort of performance or technical issue but just because the guidelines for balloon content did not match up the guidelines for health tag content in general health tag content is a little bit more concise than the balloon content but if you need a crutch for the short term you can go ahead and use the compatibility api's so if you want to use the programmatic interface there's actually three different ways you can do it you can associate static help content with an individual control window or menu by using these hm set control window or menu help content api's you can go back and change the help content later but essentially once you've said it the carbon event subsystem which actually will run for your weight next event based application will put up the help content automatically based on the controls current position now if you need a little bit more control over when your content is displayed you can use a certain callback mechanism we allow a callback to be associated for controls and windows and menu items so this you can display the help tag or you can generate the help tags information dynamically on the fly this might be useful for a lot of frameworks out there and finally if that doesn't even serve your needs you can just put up any arbitrary help tag in any position you want by calling hmm display tag you provide the right hot rectangle on the right help data and you just put it up on screen and there you go now unfortunately tearing down the help tags is a little cumbersome we forgot the remove tag API so right now what you have to do yeah I know we're lame sometimes right now what you have to do is turn off help tags to make the help tag go away and then turn help tags back on kind of a crummy workaround but it'll do the trick now in the drag manager front most of the stuffs the same although there's a few gotchas the drag highlight color is changed under aqua it's no longer the I think it was a blue for platinum we now have a theme brush to allow you to draw the to draw the proper aqua Savi drag highlight and of course if we ever decide to change the drag highlight and you continue using the set theme background API with the right brush you'll keep getting the right look in fact we might even change the drag highlight depending on whether you're an aqua or graphite so use this use these api's to get the right color and you always have the right look as was pointed out yesterday in one of the sessions drop rocks for Dragon Editor don't work anymore on Mac os10 the way you do this on Mac os10 is actually through the set drag image API and set drag image is actually callable repeatedly during the drag so you can alter your drag image as the drag is moving along the screen if you want to so we actually get questions about cursors quite a bit and the h-i guidelines talk about it quite a bit but there's sort of one main gotcha that you need to worry about essentially the guidelines say this if you're going to be busy for less than two seconds just put up a watch cursor if you're going to be busy for more than 10 seconds put up some kind of progress dialogue or spinning arrow or there's something to let that user know you're gonna be busy but unfortunately there's this weird window of opportunity between 2 seconds and 10 seconds and the reason it's a weird window is because the system will automatically put up the spinning weight cursor for your application if your application is not responsive to events for 2 seconds so if you get into some long processing loop that goes beyond the two-second threshold up comes the spinning cursor which we like to call the spinning cursor of death you don't want to rely on this cursor for your busy needs because of why we call it the spinning cursor of death generally speaking this cursor should be interpreted by the user as wow this app is really hung maybe I want to force quit it or you know this app is really in a bad state so if you start relying on the system spinning wait cursor for your busy needs the users going to think your applications actually hung and might force quit you prematurely so what I would suggest doing is if you're gonna do any busy processing that's gonna take more than two seconds make sure you put up some kind of modeless dialogue or spinning arrows to let the user know it's gonna take a while and continue processing events as normal to allow the user to get the access to the rest of your interface so get out there go ship your applications I'm sticky using classic axe come on come on Carbon events are the way to do this Carbon events permeate the entire tool box you can take advantage of all sorts of new toolbox functionality we've talked about it in four different sessions you can use carbon events to adapt sheets Carbon events to do cool things with your controls Carbon events to do cool things with the windows you can use this as the sort of patching for Mac os10 to alter the tool box behavior take advantage of the dock when it makes sense for your applications don't go overboard with it but make sure if you've got a really great way to give the user a little bit more information by changing your docks icon great do it and as John Lindsay said in his session yesterday aqua gives you the chance to go and stand out the playing fields leveled a lot of applications are trying to make the most out of aqua this is your chance to go and beat all your competitors and get a great looking aqua interface and make your application best of class so with that to go through some roadmap and QA I'd like to bring back up John Lindsay thanks let's see the roadmap the first one 119 we just had that earlier this morning so if you weren't here you gotta watch it on DVD designing aqua aqua icons go to that one on friday tomorrow morning here in this hall 10:30 it's gonna be a great session Apple help again we've talked through all of these so I won't go into great detail anything new here though all this stuff happened yeah okay Friday tomorrow oh yes feedback on the high-level toolbox correct give us our feet your feedback as to what you want added to the high level toolbox or carbon functionality to get a really great user experience with your product on 10 there's my contact info if you need anything added to the system or you think we're missing something or something's not working the way you want it to work please contact me or if you have questions about creating a great application on 10 feel free to send an email and and work with me to get your app revised for Mac OS 10 you
