WWDC2001 Session 119

Transcript

Kind: captions Language: en well good morning looks like a lot of you stayed up but kind of late and aren't here yet so welcome to this session this session is really just the if you think of the session that I gave yesterday which was session 111 talking about how to create a great citizen on Mac OS 10 citizen application on Mac OS 10 and I said in that session that wouldn't talk about API is talk about conceptual ideas this session is all about talking through that material but looking at it from the Carbon API level and so I'd like to bring on stage guy Fullerton from the high level toolbox team at Apple and he's going to talk through the specifics of some of that material as it relates to the to the API is guy thanks first things first did anybody bring me any donuts no okay I guess everybody who got here early so my presentation last year and knows how fast I talk how fast I'm gonna get through this stuff that's me so I want to tell you a little story that you've probably all witnessed firsthand and it's the story of a carbon application most carbon applications start off as an interface live application on Mac OS 9 and you begin the carbonization process and that's fairly straightforward and it takes you anywhere from a couple weeks to maybe a couple months but finally you get through the opacity issues and weaning yourself off of some api's and starting to use other api's and you get it so it actually runs well on carbon lib and usually part of the way through that process you get your application running well enough to try running it on Mac os10 the first time you try running on my Mac os10 usually crashes because Mac OS 10 is really good at exposing bugs that were sort of latent in your Mac OS 9 code base well you end up fixing those those usually don't take too long because they're just typically writing to null or other strange stuff like that you fix them you finally get the app to launch and it comes up and it looks kind of good but what's all that stuff going wrong in my apps interface so I'm going to tell you how to fix most of those problems today as well as certain techniques to ease your adoption of aqua and how to avoid certain user interface pitfalls but before I go any further what like to do is show off some of the user interface pitfalls you might call into and let's bring this up okay so what I have here is a small application based on an earlier version of power plant that shows up some of the problems you might run into when you bring your application up under aqua now the first thing you probably noticed when this this dialog comes up is that it's got a progress bar animating in the top left hand corner and initially you might think okay that's right but then you look down in the bottom right hand corner and you see that well your progress bar should really be animating down there why is it animating up in the top left hand corner you might also see this phenomenon with the pulsing default button as well one thing that I hope shows up on the big screen and I've got the magnifier unning on the right to kind of show it off more are though is the white halo problem if you look closely at the magnify window you can see that the pattern shows up on the dialog but it doesn't show up properly behind the text and speaking of text that text doesn't exactly match the proper aqua look it just looks too thin doesn't have the right anti-aliasing so you probably have that in your application as well one other subtle problems that you may not notice here until you look really really closely is a misalignment of patterns you take a look at the magnify window you can sort of see strange pattern alignment issues going on on the check box clip there it's almost as though the pattern shifted down by a few pixels and speaking of these tabs that the check boxes are in the tab pane doesn't look quite right the tab pane is supposed to have a border around the outside and it's supposed to have some shadowing around the outside but it's just not showing up you might also see this same problem with shadows on push buttons or other controls and another problem that doesn't often expose itself until you use the application for awhile is over compositing of things like focus reins and edit text frames if you take a look in the magnify window as I tab back and forth between these fields you can see the edit text field borders start to get darker and darker and darker and this is something that you need to be aware of and I'll show you how to fix this as well so we can go back to slides they'll be great so the first thing I want to talk about and show you how to solve is the white halo problem now like I mentioned it's basically when some other color seems to surround your widgets your controls your static text items in a dialog that otherwise has the proper line background now fundamentally this is because of two things controls erase their background before they draw and we have and the reason we have to do this is because a lot of aqua widgets have shadows under platinum they didn't often need to erase behind themselves because they were fully opaque but now we need to erase in a lot of cases and so when a control is about to draw you need to make sure that the proper background color has been set up for that control so that the control knows the right thing to erase too the best way to get the proper background behind your control is to properly explore exploit the control managers embedding hierarchy support now Control Manager embedding has been around since Mac OS 8.0 and a lot of people haven't yet been exposed to it so I'm going to talk a little bit about it now essentially what the embedding hierarchy is is a view system in the control manager you can take controls put them into other controls move them around as a group it's just a mini view system it does hit testing properly drawing properly things like that now when the control managers embedding stuff is working well and when you're utilizing it properly it will draw backgrounds properly based on parent controls that contain other controls for instance you might have a push button in a tab control when that push button goes to a race it traverses up the embedding hierarchy finds its parent that's a tab control and says hey tab control well you set the background up properly for me so I can erase now the tab control does that and then the button can go ahead and erase and draw its structure and life's great if a control is embedded in such a fact such a fashion that it isn't in a parent control that has some sort of a fake background ultimately as the control traverses up the embedding hierarchy to find the right background it might reach the root pane for the window and if it does reach the root pane for the window it uses a background that's been associated with the window directly via set themed window background API I'm going to talk a little bit more about set themed window background a bit later but just quickly what this API lets you do is associate a certain pattern or brush with the window such that I control that is in this situation can erase to that brush and get the right pattern so all the system CDF's support control embedding properly they they do the right thing when they're requested to have background color setup and if you have custom CDF's and you want to start taking advantage of embedding you can do the right thing here as well the best way to do this on Mac OS 10 is to listen to the Kay event control applied background Carbon event we talked a lot about Carbon event in previous sessions and one of our main points is that in order to adopt current and future Mac OS 10 technologies you're going to need to start leveraging Carbon events a lot more what just so happens that if you have a old-school message base CF you don't need this particular carbon event right now we do send out old CF messages to your control definition to set up the background you just have to do a little bit more work if your control has a special background the first thing it needs to do is tell the control manager hey I've got a special background and the way you do that is by reporting that you have the K control has special background feature bit you're going to receive a control message requesting your features you would set that bit on the way out of the feature request and once you've responded that you support a special background when the control manager is trying to draw your sub controls it will send you a cake control message set up background message and in this message you can set up the current port with the proper background so that your sub controls can draw properly now not everyone can take advantage of the control embedding hierarchy fully a lot of frameworks have their own view system and we're working on making it such that you can integrate the view system with the control manager more directly in the meantime however you might not be able to fully exploit control embedding but you still need to set up the right background and the way you do that is with set control color proc now simply speaking set control color proc allows you to associate a proc pointer with a given control and that proc pointer will be called to the background or the text color for a given control and this control color proc can actually be used in conjunction with an embedding hierarchy if there's a color proc associated with the control it will override the control managers embedding hierarchy support for color so you can hook in that way and I also mentioned that say control color proc allows you to customize the text and this also goes back to custom control definitions responding to either the Carbon event or the CDF message if you have a custom background let's say that's totally opaque black and somebody puts a static text control on top of that complete opaque black control you need to make sure that the text that that static the text control draws is visible and the way you would do that is probably by saying hey draw your text in white set control color proc will let you set up a white text color as well and like I mentioned you can handle the proper Carbon events or the CDF message to do the same sort of thing now sometimes that control color proc may not do exactly what you want or maybe a little bit of a hassle to use so as a latch just a last-ditch effort you can always rely well not always you can sometimes rely on the control managers default behavior of erasing to the current court if the control manager does not have a color proc associated with a given control and if the embedding hierarchy doesn't have a color associated with the given control and if there's no theme brush associated with the windows background we're just going to erase to whatever color happens to be in the current port so if you're careful you can use api's like set theme background I'm going to talk a little bit more about that later you can use api's like that to prepare the current port before you call any control manager API which might draw now this is going to work in most cases but if flat-out won't work for animating controls and the reason it is that animating controls animate behind your back you won't have a chance to preflight any color setup or port setup before a control draws so you won't be able to use this current port technique for things like push buttons and progress bars and the other animating controls now another obvious problem you'll probably notice as soon as your application comes up is shadow clipping I showed it in that demo application in the tab pane but this particular example shows it happening on push buttons now generally speaking this is caused by applications clipping to a controls bounds before asking that control to draw in aqua however controls have shadows that lie outside their control bounds and some controls like pop up buttons have traditionally drawn outside their control bounds so in general clipping to a controls bounding rectangle isn't going to cut it you're gonna end up cut end up cutting off shadows or worse power plant is probably the most obvious victim of this particular problem I know they're in the process of fixing that I think they fixed it already in fact so the way you fix this problem is don't clip to the controls bounds but you might still have clipping needs you might still want to make sure that the control doesn't draw willy-nilly all over the whole screen but you still need to give the control the flexibility to draw where it needs to draw and the way you do that is by asking to control for its drawable area you can use the get control region API along with the K control structure met apart heart tag and this lets the control tell you hey you know what I draw all over this area of the screen and this region is going to include not only the sort of opaque structure but it'll also include the shadow pixels and things like that so if you make sure to clip to this structure region you will let the control draw as much as it needs to draw now gate control region is not just useful for finding out where to clip various controls support certain part codes depending on the type of control and you can ask for instance a tab control you can say hey what's the region for your third tab and we also have another meta part which is called the Kay control content meta part that many controls support and this allows you to query a control for the region that its sub controls should be embedded into so you can do proper positioning of your controls within a tab pane for instance so I actually should have changed the title on the slide this is not just focus ring issues but this is also edit text frames as I showed you on the demo as I was tabbing back and forth between those edit text fields you could see the edit text frame get darker and darker and darker and darker and in some cases you'll see the same phenomenon with the focus ring and essentially what this does is it to sort of wrecks the visual appearance of your API sorry of your interface it starts looking heavier and heavier and heavier and it just doesn't fit in with aqua and the reason this happens is because certain appearance primitives now draw with alpha whereas in platinum they did not and the two best examples are focus rings and the Edit text frame if you're going to draw either of these you see the reviews primitives to draw your focus rings and your frames you need to make sure you erase before you draw now erase is a little bit of a lie what you might actually need to do is draw the background or draw whatever happens to lie behind your focus ring or frame because it might not just be a simple background so in the demo app I showed you the progress bar was animating in the total wrong location but probably a worse instance of this is when your ok button that should be down in the nice bottom right hand corner of your screen according to the proper UI guidelines all of a sudden jumps up to the top left and start starts pulsing and that's a really quick indication that something's wrong fundamentally this is caused by a non 0 0 origin in the window that you're dealing with and this non 0 0 origin can also cause pattern misalignment like I showed you in the check box but you might be thinking to yourself well I've been changed in the origin for years hey power plant does it my framework does it our custom application code does it was working fine right well it was behaving fine but it really wasn't working fine if platinum if you tried to draw controls on top of patterns or other pictures under Mac OS 9 you would have seen this same problem happen just so happened that in most cases you end up drawing with the solid color so you didn't see the phenomenon and generally speaking it's practically impossible to do willy-nilly origin changes to your window on Mac os10 because you're gonna run into these two problems but you have good reasons for wanting to change the origin I mean it's it's a valuable tool right so there are safe ways to do that the one thing you need to keep in mind is that the Control Manager really really really wants a 0 0 origin associated with the window that it's drawing its controls in and in fact every controls bounding rectangle must be relative to a 0 0 origin in order for the control manager to work properly for instance if you have a default button in the bottom right hand corner of your window and you want it at position 200-300 relative to the windows top left you need to make sure the controls bounding rectangle is 200 300 and if you do need to change the origin you want to make sure you save and restore it properly the way to do so is very straightforward in order to determine what a ports current origin is unfortunately we don't have an API for that directly but what you do is you get the ports bounding rectangle just save off the top left corner of the bounding rectangle that's its origin then you can change the origin to whatever you need it to be do your setup and other drawing when you're done drawing restore the origin to the way it was before and let me go into a little bit more background about why the pulsing buttons jump just to give you a better feel of exactly why this problem happens if you have your control with a bounding rectangle whose top-left is 0 0 and your framework or your application would make sure to adjust the origin such that it's negative 200 300 before it draws the control hoping that the control really will draw down you know 200 pixels down at 300 pixels to the right of the windows origin that's going to work if and only if you have explicit time to set up the port before you ask that control to draw however because controls draw in timers you don't have that pre-flight chance and in fact when it controls timer fires it can't make any assumptions about the current port and this is also a general rule you'll need to follow yourselves when using carbon event timers a timer might be firing at some totally odd time like when menus are down or when you're tracking in another trol therefore the origin may have been set up to do something totally different and your timer needs to set the origin and things like the clip to something very predictable and the control manager for predictability sake sets the origin to zero zero therefore if your buttons top left hand corner is zero zero well your buttons going to draw at the top left hand corner of the screen or out the window sorry pattern alignment is not the only pattern issue you're going to run into and I'll like with it sometimes you want to draw with a pattern you got a color instead other times you'll want to draw the opposite direction you got a color and you wanted a pattern other times you'll just see strange grey backgrounds which look great and platinum but why are they coming up in my aqua interface and worse yet is a system seven white background that's probably been in your application for about the last five years the reason this happens is because pattern or sorry backgrounds under aqua can be either colors or patterns and your application needs to be aware of that needs to be expecting it quick draws behavior when there is a pattern in the current port is to draw using that pattern not necessarily the color you've set up so if you use an appearance manager API to set up a pattern for your window and then a little while later you change the color to white because you want to draw some area white then you go to erase and all of a sudden the pattern comes up but but I just set the color to white why is this pattern coming up well simply speaking that's because the pattern is still in the port and that's what quick-draw is going to use so in order to make sure that you don't have unwanted patterns associated with the current port you can call normalized theme drawing state now this API was introduced and I believe the Mac OS at 8:5 time frame and it was designed to just do a quick wipe of the current port settings such that it's in a very predictable clean drawing state it will make sure to eliminate any pattern that's in the port it will set the foreground color to black the background color to white and tweak a few other things to make it more predictable now these theme drawing state API is also have a saver and restore which are very useful if you want to make sure you don't disrupt the system's use of patterns in some all that or possibly in a carbon eventhandler and you use the safe safe theme drawing state and restore theme drawing state to save and restore the theme drawing state they will pass back out and opaque reference to a whole bunch of settings you hang on to these settings you can do your own court preparation often with normalizing drawing state or other preparation do your drawing and finally when you're done you call restore a theme drawing state and passing the opaque object and it'll set things back up the way they were before now if you happen to be drawing grey backgrounds in your windows just because well that's what you always did and that's what looked right in platinum and I didn't know we had to use these appearance manager api's well you know what you got to use these appearance manager API is to draw the aqua back on the Aqua patterns and in fact these same appearance manager api's will let you draw the right thing on carbon live on mac OS 9 and the appearance manager supports a whole bunch of different backgrounds and they're they're tagged sort of a high level with the notion of theme brushes and theme backgrounds and theme brushes are like I said used in a high-level way you tell the appearance manager what sort of background for what case you're drawing in you might say I'm drawing in an active dialogue right now or I'm drawing a toolbar background right now or even I want to draw a bevel Button Center Phil can you please set that up for me so we've got several dozen sorry several dozen theme brushes and beam backgrounds in appearance H you can go ahead and take a look there and see which ones you want to start using in general you want to use the dialog alert utility window toolbar backgrounds things like that that'll get you the proper aqua lines on Mac os10 and I'm platinum they'll draw the proper gray now the way you use these is typically through set theme background and set theme pen set theme background takes a theme brush and talks to the appearance manager figures out what color or pattern needs to be applied to the current port and then applies it to the current port set theme background applies it to the background so you can follow that up with an erase rect or any other quick draw API that might erase set theme pen applies it to the foreground so you can follow that up with any quick draw that's going to paint now as I mentioned before there's this set themed window background API well how is this different from set themed background you might ask set themed window background associates a theme brush with a window on a kind of permanent basis you can come in later and call set themed window background again and set up a different theme brush to that window but generally speaking it's remembered until your next call this a themed window background whereas set themed background transiently just applies this background setting to the port and it can be get stomped upon later now the other cool aspect about set pane window background is it lets the window manager be a lot more efficient because there's this brush constant permanently associated with the window the window manager can use it when it needs to paint a window as it comes on screen for the first time and this saves a lot of time and a lot of your hassle because in a normal situation the window might paint white and then later you'll get an update event and then you'll draw the lines and you really don't want to be seeing that sort of flicker on that go stand under aqua that's kind of crummy so you should start using the set theme window background API to associate a theme brush with your window there's one other theme background API and that's called apply theme background and it's a little bit different it's essentially similar to set theme background in that it takes a theme background constant and shoves it shoves the right color or pattern into the current port but the difference here is that apply theme background also takes a rectangle to align that background to the classic example of this is tabs or group boxes the background that fills a tabbed pane doesn't want to align to the windows top left-hand corner it wants to align to the top left-hand corner of the tab pane itself so that's why you need to pass in a particular bounding rectangle and we've got several theme backgrounds that are useful for lighting background in the right sorts of cases you can take a look at a parent set H to find those as well so non aqua text is sort of a sticky issue when you bring your app up you see all these really wacky white halo problems really ugly visual things you fix all those and you go yeah I think I'm done I think I got it ready but you kind of glossed over the fact that your text doesn't quite match up and you might be really tempted to just leave your application that way but please don't it looks really really crummy compared to the rest of the aqua text and there's another downside in that the ugly text is not only ugly but it's totally Unicode on savy it's drawn with mac and coding characters you can't have mixed run strings you know that your file system might have a file name that has five different languages in it using five different fonts to display it and if you try to render it with the api's are currently using you're going to get to just get jumbled garbage and it's going to look just horrible and the reason it looks bad is because you're using the old quick draw text drawing api's now there's a number of ways you can make your text look really good under aqua the most straightforward way is to adopt the system control definitions window definitions and menu definitions as much as possible the more you adopt those the less work you have to do in the first place all of these def procs have been revved to use aqua text where it makes sense now there's actually a few exceptions to this the most obvious one is the old-school edit text control the old-school edit text control is going to forever draw with quick quick draw text because it's forever associated with TextEdit and we're not bringing TextEdit forward so if you really want to do proper aqua Savi text editing you should use the Unicode edit text control and like the rest of our aqua text story not only does it look good but it also fully supports Unicode multiple languages and stuff like that and if you have certain static text areas on your screen that you're using quick draw text api's to draw directly one easy way to make those aqua savvy is to begin using the static text CDF instead the static text CDF is really good for simple needs when you just want to draw a little caption or a little label on top of something and using the control managers embedding support it'll let you draw on top of most arbitrary backgrounds and if you don't like the overhead of you control or if you need a little bit of a quicker solution you can always use the theme text API I'm going to talk a little about a little bit more about that in a slide or two and if that doesn't work out for you you can always use atsui or M LTE now these are the lowest level ways for a carbon app to draw aqua Savi text it's a little more complex to set up and use but it gives you a heck of a lot more flexibility and a little bit better performance the downside of using these api's is there is not currently a way to get the proper theme fonts for given situations to use them with at Hsu E and M LTE this is something that we're going to add in the future but for right now if you use Atsui nm LTE you might see a few strange misses when you try to render mix language text so the quick and easy solution to get this aqua text is use via the theme text api's we've got api's to do drawing and measuring and truncation and essentially they're meant to be very easy replacements for the quick draw text routines you've already been used to if you're using draw text or draw string or te text box you'll want to use draw theme text box likewise if you're using text width or get theme font info to determine widths and Heights you can use get theme text dimensions now certain theme text draws shadow outside of it

  • best examples are window title bars

and push button fonts and you can determine the amount outside of your text that the shadow will draw be it again theme text shadow outside API this returns a rectangle and each of the coordinates of the each of the fields of the rectangle tells you how far out each of the sides the shadows will draw so you can take that into account if you need to clip or do some other stuff like that and if you were using trunk string or trunk text to do your truncation you can easily switch over to truncate theme text all of these theme text api's are unicode savvy they take CF strings and they're fairly easy to use I tried to model them after the quick draw text routines that they were placed so they're pretty easy to just swap in and out very easily and all of these theme text API is also take the notion of a theme font ID and theme font IDs have actually been around for a while the appearance manager supports a way of asking what font will I draw and if I want to draw on the system font we had the support I believe in the Mac OS 8 timeframe but we took these theme font IDs forward added a whole bunch more and what they essentially are is an opaque way for you to say you know what I want to draw a push-button font or I'm going to draw on the system font or I want to draw on the window title font and the cool thing about the theme font IDs is not only do they specify one font they also specify that font size and it's shadowing effects but even cooler it will resolve to more than one font if the string you are about to render has more than one language in it you can give us one C F string that contains Roman text Japanese text in the future Korean text and stuff like that and we will render that one string in multiple fonts as we see it's necessary and of course if you call the measuring api's we're going to return accurate measurements for all the variety of fonts that we're going to end up using now the theme font IDs that we offer is only a family of about a dozen of them and you might have more custom needs if you have custom needs you can use the K themed current port meta font this meta font lets you set up the current port with whatever texts text font size style and face you want and the appearance manager routines will pull that information out of the current port map it into the right data structures for Atsui and end up rendering aqua text with it unfortunately there's a few limitations it doesn't support all styles we don't support outline and shadow styles because the underlying engine Atsui doesn't support either of those and likewise you don't get the proper aqua shadowing effects the only way to get aqua shadowing effects is to use the theme font ID which maps to one of those shadowing effects in the last downside is that it's it's got suboptimal Unicode support if you pass in a Unicode string with multiple languages and languages in it we're going to do our best to guess the right fonts for that and we're going to accurately render the glyphs but the fonts we choose to render other text in let's say Japanese text or Korean text if you're in an otherwise Roman application those fonts may not match visually very well with the one font you specified in the current port so that's one of the drawbacks using the the current port fun and you want to stick with the higher-level theme on API sorry higher-level theme font constants as much as you can now the theme text API is don't actually do anything with the color theme font IDs don't actually imply a color we let you choose what color you want to draw the text in entirely on your own and the easiest way to do this is via the set theme text color API set theme text color like the draw theme text API has a constant a family of constants which lets you tell us what sort of thing you're trying to draw text on you can say I'm trying to draw text on my active dialogue where I'm trying to draw text on an inactive dialogue and those two theme theme text colors will resolve into different raw colors to draw the font width in the active case we're going to draw with black in the United II case we're going to draw with the proper gray we have a whole bunch of these theme text colors pretty much on a one-to-one correspondence with the various theme buttons and theme font IDs that you might be used to from the appearance manager now if you've had a chance to use the theme text api's most of you probably said yeah this works this is pretty good but some of you might be trying to draw a whole lot of text and give it a window and well you know the theme text API is are going to be a little slow there are a couple ways to deal with this and make the theme text API is faster the best way is to take advantage of the cg context ref parameter that draw theme text box allows you to pass in if you've had a chance to attend any of the courts drawing sessions you'll know that a cg context ref is an opaque reference it's kind of like a quartz graph port it stores all your drawing settings that you want to use if you don't pass one of these into the dropping text box API we're gonna create one for you and that's okay and we're gonna even pull certain settings out of the current court and apply them to the context and that's also okay problem is that takes a little bit of time so if you have 50 calls to draw themed text box and you pass a null context rich ref to each of those we're going to end up creating a contact syncing it with the current port 50 times and that's just some performance issues you don't want to run into and if you want to bypass this the right thing to do is create your context ahead of time set it up the way you want it with the proper color and the proper clipping and stuff like that and then pass that one context in to each of your 50 dropping text box calls that's probably going to solve a majority of your needs but one thing I found when I was revving certain parts of the system to use these theme text routines is that they use the measuring and truncation routines multiple times before each draw and the static text control for instance might measure its bounds twice once to figure out what rectangle to clip and then it might measure the text again to know what rectangle to pass in to draw a theme textbox well that's silly and if your applications doing the same thing it should really stop every call to the measurement routine is actually fairly expensive we're working on making that a lot faster through things like caching but in general if you have redundant calls to the measuring routines or even the drawing routines I found a few cases in my own code where I have that you want to eliminate them and cache the measurement values if you can for instance if you're drawing a static text item you might calculate the bounds for that static text item once store it off in your object pointer that represents that static text item and then use that bounding rectangle every time you draw you don't even need to measure every time before you draw cuz you've already done the measurement once one other thing we're working on besides the caching I want to make a way possible such that you can use Atsui and M LTE in a proper theme font fashion so it gives you total low-level custom control as well as the proper unicode font stuff that's not available now but it's something I'm looking at for the relatively near future I've talked a lot about the Control Manager in the session so far but a lot of the same principles apply to the appearance manager you can draw virtually any widget that the control manager draws with the appearance manager primitives we've got low level primitives for drawing buttons for drawing edit text frames focus rings tabs group boxes all sorts of stuff and the important thing to realize is you're going to run into the same sorts of visual issues if you draw with the appearance manager primitives if the appearance manager draws with alpha the appearance manager sometimes needs to erase we need to be aware of both of these things and some of the appearance manager api's allow you to pass in a theme erase proc this theme erase proc gives you a chance to erase properly before the appearance manager needs to render and again that erase should be in quotes because sometimes you're not literally erasing you're drawing something behind the new widget you're trying to draw and likewise the appearance manager will draw outside of the bounding rectangles you give it if you give the appearance manager a twenty pixels tall bounding rectangle to draw a button well the shadows gonna go outside that bounding rectangle the way you determine how far outside is to use an API like get theme button background bounce this particular API tells you how far out at the extreme case a given widget will draw and so you can do clipping or whatever else you need to do with that and lastly we offer a new API as part of carbon and Mac os10 called get theme metrics generally speaking widgets under aqua are about the same size under platinum but there are a few exceptions I think the tabs and tab panes are a few pixels taller the amount that a focus ring draws outside the input rectangle is a little bit wider edit text frames actually don't draw as far outside the bounding rectangle as they did on platinum but they draw inside the rectangle somewhat now too and we offer themed metrics for you to ask for this sort of information there's probably five or six dozen themed metrics and the headers you can find out how to have tall the tabs are how much an individual tab overlaps the tab pane and stuff like that alright so talked about the control manager I've talked about the appearance manager and they're pretty much equal but which one should you use generally speaking you want to use the control manager there are some things that the appearance manager just can't do for you right now in some cases the control manager implements certain things directly itself the best example of this is the pulsing button there is no way to draw properly pulsing button on Mac OS 10 right now if you use the appearance primitives you must draw with the control manager if you want those but in the rest of the cases the appearance manager works very very well all right so you heard about the problems well what do you do now the best thing is go out there and start aqua fiying if you got a chance to see John's session yesterday on adopting aqua aqua stoat aliy level the playing field a lot of applications are just getting on board now and this is your chance to go out there and really polish your user interface and really step over your competition and show hey you know what we've got this great interface and the users will really like that a crummy interface really taints the user experience the first time you launch an app you see all these funky visual problems you're gonna go whoa well they didn't spend much time working on the interface I wonder how much time they spent working on the code is this app gonna crash and it just puts a bad taste in your mouth so you want to make sure your application is as aqua pretty as possible take advantage of shadowing as much as you can do the themed tech stuff as much as you can and final word I want to make is that the carbon high level tool box is a perfect way to deliver carbon applications yeah we've got a few shortcomings but we're working on that but I want to assure you that we're bringing the high level tool box forward you saw yesterday's window and menu manager session we've added a lot of features there we've added a bunch of features in the control manager I'm going to talk about it at the session after this and we're going to continue enriching the control window menu and all the high-level tool box managers so with that I would like to do some QA and go through the roadmap and so I'll bring up John Lindsay all right thanks guys so the road map just talks about some other sessions that relate to this material and that are really to the topic of user experience on necklace 10 the second session which is just right after this one right here so you don't even need to move is 120 controls appearance we're guys just gonna keep talking about the same sort of stuff doc animating doc icons that sort of stuff and continue on this track and then the feedback forum for the high level toolbox it's a great opportunity for you to come and give your feedback as to things that you think are missing in terms of controls or functionality within the appearance manager whatever relates to a high level toolbox then session 112 which is today at 2:00 p.m. I believe no that was yesterday so watch it on DVD designing and easy aqua icons I talked about that one in at the end of my session 111 yesterday which is a great session to come to to learn how to critique the icons that are being designed for your application then today Apple help learning about how to do a good help system and provide user assistance with your product content and it's speech recognition and synthesis fantastic session to learn how to add speech synthesis or recognition to your application and really extend the user experience on Tim and then yesterday is 114 which if you didn't get there watch it on DVD and then some other sessions that that were yesterday or the day before so let's get into the QA this is my contact information if you have any comments about this session or if you have feedback in terms of what's supported within high level tool box or within carbon in terms of user interface please get in touch with me you