---
title: WWDC2003 Session 425
framework: wwdc
role: article
path: wwdc/wwdc2003-425
---

# WWDC2003 Session 425

## Transcript

Kind: captions Language: en that's me H I toolbox well H I view is probably the most important technology and the H I toolbox these days if you're going to deploy an application on Mac was 10 that is using a chai toolbox you need to know about HIV you over the past few years we've been laying the foundation carbon events was like the first big milestone and we had this nice messaging system on top of that now we have HIV you and in Panther we finished that transition so now that H I've use are pervasive for this reason everything we do going forward is going to involve a chive you in some form or another so it's important that you learn about it if you're not ready to adopt it right the second that's ok but please learn about it and understand it and try to figure out how it's going to work how you're going to end up adopting it into your applications in the future so what this session is going to be is quick overview of a chive you we're just going to slice through some of the basics we're going to learn how to use it how you turn it on what makes it go we'll also talk about how to write a custom view what does it take and it turns out it's pretty easy and along the way we'll touch on performance things ways you can make your views perform really well in the HIV model so H I view is a complete replacement for the control manager technically though we always throw around these terms a chive you controls what's the relation a chive use our controls controls rhi views by and large HIV was kind of a subset of the old control manager and it allows controls to work in this new mode which we call composited mode and it is quite honestly the best thing to hit the toolbox since I don't know OS types don't make itself up um so it's important that you really understand the relation between the two so if you were to look in HIV H you see that you know not everything that was in the control manager is in there well that's cause we know we haven't finished moving everything over there yet but it is perfectly legal to call control manager called on h-i views there are some exceptions and we're attempting to document those in the head and the controls about H right now also understand as i mentioned we're now pervasive with these views we use them everywhere so this is great for you guys because you can learn one system one way to write a few and you can deploy it in menus windows and as a control obviously this is a modern view system uses all the latest technology basically we draw using courts use floating point coordinates we could support overlapping views which is really cool and as a panther we support layout facilities which can kind of touch down in the H I toolbox session so first let's talk about composite drawing what does that mean what it means is you have a predictable way to draw that doesn't involve a racing behind oneself the old control manager would always erase behind itself before it reader the control this happened back you know since 1984 it's always been that way couldn't exactly change it until now now we have a composite of drawing system we draw everything back to front and we also obey all of the Z ordering among siblings which gives us the ability to overlap views as I mentioned since we don't do a race behind you don't have to worry about pattern alignment problems all that stuff is just gone not to worry about it and drawing always occurs at a very specific time and that's at event loop time so right before we would go and flush your windows contents we actually would repaint all invalid areas of the abuse system so speaking of and validation what is it so essentially as your views decide that they need to be redrawn they will mark themselves invalid the tool box we'll only Mark things invalid if you move of you if you resize of you or if you show of you other than that it's all up to you for resizing we do have a special event that we send out k event k ctrl + BK event control and validate for size change this event will as I meant will get send out during a resize operation so you might have a control that knows that well my top left area always kind of stays constant so if I'm growing I only need to paint like that inverse el area that's just been revealed and conversely as the thing is shrinking you might decide you don't need to draw redraw at all but it's really important to know that you have to invalidate if your views it's totally up to your view to invalidate when it's appropriate so and this means things even like value change activate deactivate highlight we don't know if that means anything to your control so it's up to you to tell us by invalidating an important note is that in validating a parent does not invalidate the children it may seem strange but it's that way for performance reasons and I won't go into the details I can bore you with that some other time but it's really important to keep that in mind while you're using this the two api's that use their HIV set needs display and HIV you to set nice display in region and the second call is to be a lot more specific about what you want to get me drawn if you have a very complex control this can this call will be a friend because essentially you just want to invalidate some small part of your complex control so in the realm of geometry we have new types eh I point H I wrecked eh I sighs and these are essentially just type depth of the CG types but we kind of renamed them to kind of fit into our namespace and also to imply something else which I'll get into a little bit all the api's that we have are in terms of these new types the only legacy quick-draw type that you'll ever see in our API of region handles right now and eventually those will be replaced by hrs there are two coordinate systems for every view frame and bounce the frame is where you live inside your parents expressing your parents local coordinate system your balance is your local coordinate system whenever you're moving or resizing your view it's always done in frame coordinates whenever you're doing stuff internal to your view hit testing drawing it's always in your balance coordinates and it's just important to always keep that in mind the great thing about having local coordinate system is obviously all of the rectangles are local to you if you get moved or resize or any of that stuff you can pretty much not have you recompute all these rectangles all the time so it allows you to cash things pretty cool so in a quick visual example you have a button inside a group box its bounds are 0 0 to 120 this is very different from the old control manager way we're always always lived in port coordinates which was not always fun so now you have your local coordinate system it's great its frame is where it lives in its parent as I mentioned so in this case it might be 30 pixels down into the right from the top left of the group box okay there are two ways to draw an H I've you court quick draw quartz is obviously the native drawing model for Mac os10 have we said that enough got all types of so I think it's one of the coolest features in Mac os10 myself it's got all types of cool things transparency anti-aliasing basye occurs really cool stuff and all of our drawing internally is actually done through quartz we also fully support quick-draw though if you have your code it's probably likely all in quick trial code you can migrate that very easily it's one issue though court has a lower left origin we don't we use top left origin and this is the other reasons for having a redefined type space so when you see an H I point or an H I wreck you know that this is in terms of top left coordinate system so it's a signal for you to know which kind of orientation worrying so ultimately we've caught we've transformed the context that we deal with in that we give to you whenever you draw we put 00 at the top left where it rightfully belongs and what you and where you're really used to we have an old joke I won't go into it I won't make friends ah so so this is a port because our windowing system has always been top left base and of course all your existing code is top left base and we don't want to throw that away or have you make you flip rectangle for the rest of your life we just want you to take your code and be able to migrate it initially it also saves us from things like window resize if we had a bottom left origin when you resize the window essentially all your frames are changing throughout the window and that's kind of a big pain in the neck so we want to avoid all that but you got to realize that you're basically drawing upside down and if you get a context from us and you call CG context drawimage you'll find it out quite quite apparently so to help you with that we have helper api's to deal with it first it's a chive you draw CG image that will take the image and render it in the appropriate way and we also have a chai theme draw text this is the Panther version of dropping text box which also will draw in the correct orientation only HIV and draw Texas much faster so use it so essentially these api is just take the context flip it draw and put it back and slipping is only a matter of a couple of lines of code I don't have an example of showing you that but it's really easy to do the next issue of the next solution really have is that of layout so one of the big pains we've always had is being able to lay out all of your controls and you always have to do that manually have a listen to balance changes advantage to move everything around and it's a lot of codes we wanted to eliminate that okay so we have layout facilities kind of show this in the H I toolbox session so what we have here is an automatic way to position or size any of your views in your window based on any other view in your window if they do not have to be next to it doesn't have to just be your parent it could be any view in the window theoretically we were talking this earlier theoretically you could base this across windows be crazy but hey have fun so there are multiple ways to do this you have binding physicians and scalings will touch on those as we go forward a little bit so as I mentioned you can do it any other view and the way you actually go about this mechanic are a couple of API a chive you get layout info and HIV set layout info so typically the code flow would be getting the layout info that's there you know twiddle your bits and reset it but just setting a layout doesn't actually make the layout reflow if you want that to happen immediately use a chive you apply layout what we would do otherwise is just wait for a bounce chance event to happen on the original view that you're relating to and then we would make everything go online this is kind of analogous to if you selected a whole bunch of objects in some drawing program and then said you know align left and everything was align left well the selection is like creating the bindings and then saying align left is like calling apply layout so a little code to show how to do this pretty simple again you just get the layout info set some settings and then you set it in this case what we're doing is a setting binding the bindings are kind of like the power plant bindings where you essentially bind an edge of your view to the edge of some other deal in this case we're binding the left and the right of our view to our parent and you can indicate parent by just passing know in the to view field of the structure and in this case what would happen is as the window resized horizontally your view would resize horizontally the next type of positioning we support is scaling in a specific example what we're doing is we're taking as we are scaling to fifty percent of our parent views horizontal distance so whatever with my parent is I'm going to be half that you can also use this in cool ways because often times you might have a view that embed a second view and the second view is actually exactly as big as the first view doing this the other week in fact and what you can do is you can just use this and just say I'm a hundred percent of my parent and you can do that in both axes x and y so width and height and it just automatically lays out on ya some things all right position is the next one position you can really think of as alignment in the specific example what we're going to do is we're going to position ourselves centered horizontally to some view that happens to be above me like literally above you and this is all great code and it's wonderful but why don't we take a look at what it actually does so you saw some of this in the on my own demo boy by the way ah you saw some of this in which machine am I on this one this one oh all right so you saw some of this in the H I toolbox session I'm just going to show you again because I'm that way so basically going to edit mode here and we have this crazy little control and what we want to do is pull these out of the way no bye-bye okay so what we want to do is just have this thing bind to this parent let's say so we can just find our right to the parents right and as we move but they move with it we can also bind the left the parents left and as we move it moves automatically and now the things are kind of stuck to the edges great thing about the way we have done the layout stuff is that you don't really it doesn't matter where it is it's just the bindings just work so you can just move stuff around and the bindings just work automatically think about it of course there are other things you can do I could take this view and instead of binding it this way I could instead just bind it to once again Oh point five of the width of the window and again no matter where it lives I could put it over here it will always be half the window no matter what you can do this in both axes and of course the last option that we mentioned was aligning to some other views so I have B and I have a thought don't you all see we knew that was going to happen haha can't stop me alright we really knew that that was going to happen oh-ho yeah you can't stop a chai toolbox alright we're from the department of redundancy department so do we really have everything here why is that not a app all right folder there's a folder ah don't you dare do this to me now what all right well you have fun with that I had the best demo ever but you'll never see it now of course now I'm building up your expectations all right well my crack team yes they do smoke crack are up there um we'll move on all right how do you use a chive you now we'll have one being demo at the end how do you use this stuff now that you saw how great it was it's easy first thing you want to do is turn on the compositing mode of a window as I mentioned we have this composite mode which we draw which all back to front no race behind it's really great so the way you turn it on is basically specify k window compositing attributes at creation time of your window this means you do have to call something like create new window to make that happen or you can just use a nib check the checkbox there's a checkbox to this and it's just magic we also say use the standard window handler you don't absolutely have to but you'd be crazy not to because just does so much stuff for you honestly you know time there are people who come to us and say hello i'm not using standard window handler how do i do this how do i do that and then we start to realize man we do a lot of stuff for people so really if you're going to call if you're going to use composite mode we really recommend you use the standard window hammer and a match made in heaven so we've always supported like a control hierarchy a Mac os10 but when composited modes on it's a little different it's actually a bit deeper in the past we've had this concept of the route control and route control essentially represented your windows content area but in a chive you the route is actually the structure so that means that although the window widgets that you see in mac OS can Panther they're all control just like anything else they never were before that really it was always just innovation so we've done a lot of work to really make all that stuff work so now you have this concept where we have this old route control which is really the content and now you have this new route control which is really the structure so it's according to keep that in mind when you're in this mode ignore the last point we're going to touch on in a second anyways what happens to something like create route control is that if you call it in a composited window you will get an error it will tell you the route already exists now if you call get route control what you'll get is the content view of the window and this is to allow you to have code that's compatible with the past and you might have called get route control and then embed control on that that code code will still continue to work as expected if you want the real root you call HIV you get root and pass the window rest so if you look at the two calls there they're equivalent get route control and a chive you find by ID using a control ID in this case khi view window content ID which is defined in a chive you HIV eh both of these calls will yield the exact same call both work the second is technically more correct in the simplest of all worlds you'd have a window that used all tool box controls and all would be blissful and in that case all you have to do is go in and turn on the causing attribute and things would just work I mean really it's just that transparent to you however there are some things that your code might be doing which might change it depends on how far you go so for example if you're calling stet and get control bounds these are actually frame coordinates when you're in composite mode despite the name bound okay so it's important to keep that in mind get insect control bounds frame coordinates in compositing mode so you have to look at every where you're using that for a specific window that you might be dealing with and say all right am i dealing with like moving and resizing then I should probably use a chive you set frame or get frame am i dealing with drawing his testing or anything that that's more local I should use a chive you get bounced and it can convert points from bound space or from view to view by using HIV convert point wrecked and even region another common problem that we find is that you take some existing code with some existing controls with some existing bounds and you just embed them and then half your stuff went away and you're wondering where it is well it's probably living way down below the bottom of your window and you can't see it has been clipped out by its parent and yes we do clip to parents nhi view all the time there's no sometimes anymore so this is caused by using basically drawn coordinate system you're using port coordinates everywhere and you're trying to now embed that all in an HIV space where again the parent relatives so if you had a group box and a push button in it which was supposed to be 20 pixels down you might find that it's you know way down now just because you know you're in the wrong coordinate system so these are things that keep in mind some more do's and don't if you ever call draw one controller update control gen in general don't instead just use HIV settings display if you really need to redraw something though in general you probably won't need to do this because it will be your your custom views or things like that that will invalidate themselves you've never I would say you almost never need to do that from an external point of view if you absolutely need to draw immediately you can use HIV render on Panther technically you could use draw one control on Jaguar but again we're really trying to emphasize the invalidation model over the direct draw model so really try to focus on that and if you can only use direct drawing it's absolutely have to because I mean in truth if you're going to use something like HIV render you're essentially rendering all the layers in the closet layer for the region that you're interested in so it can be a little pricey so you don't want to draw as much as maybe you used to let it happen at event loop time where everything can be aggregated and we have a better performance overall if you ever called draw control and current port and just don't it just doesn't work into positive mode just ain't gonna happen so what you want to do instead is if you might be able to use something like a chive you create off-screen image this is an API that allows you to just take any control in your hierarchy and just just create a CG image rest from it and now you have a perfect image of that might be able to use that for some of the cases that you were using draw one control I'm enjoy control and current port for and lastly if you've ever called auto-embed control it just isn't going to work as expected this was invented for the dialogue manager where we had a flattened it'll list and we didn't really have a hierarchy we were trying to build one from from from that flattened list so we kind of had to figure out where things went and automatically embed things in one another and it also assumes they're all import coordinates and all of this other things it just isn't really going to work at all in composited mode so just use you know HIV you I'd subview or even embed control directly might be asking yourself I have a dialogue manager dialog how do I make it support API view the answer uh-huh use a nib um yeah good answer huh I mean I don't really have a good answer this is the answer you should switch to using nibs because basically they're a lot better than the dialogue manager you don't have to worry about pascal strings I mean everything is unicode savvy it's a lot more localizable plus you don't have to deal with all of you can only deal with a certain subset of controls and when you can't deal with those then you need to create cntl resources then you have to put a proc ID in there and what is the value min and Max mean again I don't remember for the specific control it's really just a big mess so with the advent of nibs and carbon events even at the beginning of Maca was 10 we said dialogue manager you know start moving away from it and we're still saying that especially in that in the context of a chive you now we're going to talk about how you can write your own views essentially every view you do or any constant contact you have has to be wrapped in a chive you it's the law and the reason is we want to have a consistent behavior want to have one draw pipeline you know and everything goes through the same bottleneck this is important or else you can't do things like overlapping views because you can have people stomping on one another has to be all through the same pipeline let's talk about how you write one it's basically like you do anything else that's a chai object-based you register your view class via the API object mechanism so H I view nhi object register subclass and you can sub class H I view or one of our existing controls as a panther and Jaguar you couldn't really do that we didn't export the class IDs and pants that we do explore to class IDs and don't go getting fancy trying to use those class IDs on jaguar they might not work because we actually twiddle the names between those two releases so Panther forward you can actually subclass existing controls and then all you have to do is just create your view with H I object.create and you pass the event handler into your register so once you create your object then you're up and running and then what you need to do is just handle the carbon event pretty easy let's first talk about the draw event chances are if you're running an H I've you you want to draw so we sending the car payment so you can do that k event control draw takes two parameters alright receive two parameters first is a context dress this is where you draw your bit you should always draw in this context reps do not create a context of your own this is will be important as we move toward being able to print the view system which honestly we're not too far away from but it won't make pather the second parameter we give you as a draw region you are actually clipped to this region so once cured raw handler is called clipping is set up and so is the g state we save g state for you you can draw like crazy transform rotate types of crazy stuff and leave the G state trash we're going to restore it right after to draw them so it doesn't matter it actually to be faster overall if you don't save and restore the chief state yourself the other thing about the draw region that's important is you might want to use this if you have a complex control I mentioned earlier that you might want to use h i HEV you set nice display and region if you use that to just invalidate a portion of your control when you get called back you might be called back to just we draw that portion of the control and that will be reflected in your draw region so you can use that reason to kind of intersect it with the parts of your control and just draw the pieces of your control that intersect that next we want to talk about calculating regions we have a carbon event for that k event control gate region in general there are two regions that we really care about structure in opaque region there's a new one in pants they're called the clickable region this actually gets used for things like a sink dragging especially on metal window or you want to be able to click through things like text and other things like that reasons are always in HIV bounds coordinates never in frame coordinates structure region is essentially where you're going to draw and it can extend outside your bounds that's okay it's a little weird to some I agree but it's kind of the way out things have always been and it's also convenient in a way this we can do things like focus rings and have a dormant that draw outside of the natural view bound and this can be helpful because then the metrics of the actual view don't change even though we might change the metrics of hobby we adorn things so at for example as the edit text field gets and releases focus you might want to extend outside and then contract back in if you don't respond to this event will assume that your structure region is just your bounds that's fine you don't need to respond to the gate region event but if you do need to do things like focus rings and you are changing your shape that might happen like I set focus time so we'll call you with a set focus part event and you'll maybe set and say alright I'm focused now I know I'm going to be bigger so i'm going to call hig reshape structure and that just tells us Oh something's changed we need to wreak weary your structure region and recompute and Riaan validate everything and we just do it automatically for you and there's the API very easy to call at the bottom of the slide your cake region is used to help us determine what's basically a visible below you in the hierarchy so what's behind you and this is used to help us optimize drawing it also is used to determine what the windows opaque region basically we take the aggregate of all of the opaque regions of all of use in the window and we just kind of ship that off to the windows server so that it knows all right these regions of the windows are opaque and I can use that information to maybe do fast living for that section of the window and I know that nothing can show through if you don't handle our request to get give up this region we will assume you are transparent does not mean you do not draw that just means that you might have holes in yourself or maybe sometimes you are transparent or you're small enough that it doesn't matter in general if you have an opaque region you should well in general you should make views opaque that are rather large smaller views being opaque actually chop up the views behind it and that makes for a very complex clip region and what happens oftentimes is it ends up being more expensive to draw with the clip then without the clue so unless you have a really big region you know I mean big beautiful spamela for the window you might not want to do this but we will use it and we will know all right we don't need to draw like the metal background of the window metals very expensive the render so if you have like a data browser or something that's expanding it you know that you wrote we know that we don't have to draw that metal behind that big area and that's save some time if your opaque region changes on the fly and it can you can call either HIV reshaped structure which is available in Jaguar or in Panther you can call a newer API call HIV region change it's a much more specific API you're going to tell us my take region change and we'll go okay and we'll recompute everything and we'll know that next event loop time we're going to readjust the opaque region of the window but that API won't invalidate so you can do like multiple things including HIV region change and then maybe invalidate yourself if you really need to one thing about regions is that you generally want to be square for maximum performance the square or the better and how can you be more square than square so the idea here is you want to use alpha to define complex regions and not a complex region it's much easier and the graphic system is designed this way so really take advantage of alpha and just use square regions every window that we have has a square structure region we don't use complex shapes anymore we just use alpha to punch out the corners much easier to but you know for hit testing and things like that if you have a view that is essentially a circle in the corners where you would normally punch through you might want to click region that just represents the circle in those cases is perfectly fine to have a complex raishin to describe that because you know hit testing that view happens much less frequently than we rendering that do I want to touch on control features for a long time we've had this concept of features ever since a parent's 10 ultimately what they do is they advertise the abilities of a view so for example you would tell us so I support embedding I have I want focus on click things like that and we have some new features that we're introducing in Panther as well like the is opaque fit I'm going to cover in a little bit on Jaguar and prior the only way to specify these features was at K control k event control initialized time we would send you this thing this is kind of like the analogous the carbon event that's analogous that you'll control an it event or a message from the deaf proc days and in response to this initialize event you're expected to give us your your features and then we would hold on to that and they were immutable these days in Panther that's changed you can change your features on the fly you can say i'm going to better no I'm not if I am so you can have you can write your own schizophrenic views and the other thing that you can do is I mean this is comes in really handy because yeah you might want to say I'm opaque now or I'm not opaque I want clicks to go through me wait no i don't and we use this for example of consider document window so never document window and the content region is opaque and click hit it okay it's like a solid yeah thing when you specify the metal attribute do you see that area anymore no and that's because we actually take it doesn't go away it's still there but now we make it transparent it's no longer opaque and we allow clicks to go through and we do that on the fly via this mechanism so three interesting features that i want to touch on for various reasons are everyone khi view is opaque this marks your entire view is opaque and this is just kind of a clue to us that we don't have to ask you for it I mean asking you for the region basically involves us creating a carbon event stuffing some parameters and sending it off to you getting back to result in and okay it reaches great but if you know that your entire bounds are opaque or your entire structure region is ok just tell us that via the future bit and we save some time likewise khi view ignores clicks as I mention we have this clickable region this allows you to now specify that area of your control where you accept clicks anything that does any point that might hit outside that region will go through two views behind you this is never the case before but if you if you know that none of me is clickable you can specify khipu ignores clicks and again like the opaque region we won't ask you so like our text control specifies this rather than handling the event the last one is khi view does not draw now I did say before that chances are you have a view and he wants us to draw the answer as well sometimes you might have a view that's just a container of you and it doesn't draw it's not supposed to respond to click it's just there to group other items so that you can operate on them as a unit so the combination of things like ignores clicks and does not draw allows you to accomplish that and that's exactly what our content view does when it goes onto a metal window and we also save work because we know oh you don't draw so hmm I don't have to actually call you the draw anymore and I'll have set up a GPA for you or any of that sort of thing and we also know that we could be more efficient when we move you normally when we move your view we're going to invalidate the old area and the new area with this we say oh hey wait you don't draw so I'm just going to invalidate the areas that your sub views are which might be a lot smaller so we can make things more efficient that way can we do coding the demo I'm getting the thumbs up all right will anything explode everything what's in there swear to God hope to die stick a needle even re yeah we're good all right okay next all right I won't go through rebounder but I did want to go through some of the other things that I didn't was unable to go through a little earlier the first is this little app I think I showed this last year but basically what it is is just proof that I'm not lying to you and indeed the hierarchy of a window is deeper so what we're looking at here is the representation of the hierarchy of that window that the chasing arrows is running in there so basically we have our window frame here stop that all right there we have the window title and you'll notice that the highlight as I go through them it's a grow box which you can't see right now and then we have the window buttons up there they're all real views what does that mean well it means that I could just take it and put it right here maybe I want a bigger you know the best part is it still works so that I mean this is pretty cool so now you know everything's of you you can do really cool stuff with that yeah but basically you know realize that we do have you know a deeper hierarchy now and there are different you know you'll get root controls it's not mean the real root anymore that's the important thing to take away from that the other thing I wanted to show something we also showed last year about some of the things that we do with views these days there are some views that are compositing only one of them is in wish you the other scroll view on the text view image view we may try to make work and composite in on composite but some of them are a little more complex than that and our problems a little harder to solve so here's our image view it's pretty exciting hook and image okay well that was fun alright so now scroll view scroll view is a little more interesting because it manages all the stuff you need to deal with with scroll bars including things like auto hiding the scroll bars when the image is full size so we take care of all of that for you and we supplied this a protocol called the key event what does it call Kevin scrollable protocol and you scandal a carbon event a couple of carbon events that we will ask like a target view for how big are you what the available view sighs what's your line height things like that so that the scrollview knows how to operate on it we highly recommend that people use the scroll view because then as we make changes to the way things scroll and the interface everybody will get that stuff for free rather than everybody rolling their own one thing I just want to demonstrate just for grins is that last year I i had a BMW roundel in here and I got in trouble for that but anyways I won't get in trouble is here or maybe I will alright so the cool thing about this really is that that view is composited at the same it's a sibling of the scrollview you notice that it's actually drawing over the scroll who in fact over the scroll bars and that you know it even composites fine and I get great performance out of this so it's really fast that is one of the things you want to take away from this H I view is fast we've really optimized it especially in panther now let's look at some of the problems that can happen we have X good as we do so here's a little app we call character edit which apparently is building right now and while it builds others tell you that what it is is it's a visual description of what is wrong with the path okay and how the future is pretty bright eventually it will build okay I could to keep talking um did i mention that each of you with fast yes but more importantly in the past there were these problems with drawing order drawing order was always different than click order and we're going to actually see an example of this in about 10 years linking alright alright so here it is so we see guy here and but I can't click on any of these things nothing works and that is because in order to get the picture visually behind all of the other controls it also happens to grab the clicks first which really sucks so let's fix that so we're just going to run interface builder and here is the window and if I select the window and turn on compositing okay so anyways it works now and I can click and everything's great now notice that kind of lags doesn't it yeah it's not so great let's fix that too while we're in here so we'll go back to the nib and we'll look at this thing and what you see is that we have a picture control in here okay let's get rid of that and instead what we're going to do is we're going to drag in and image you stick that there hopefully I'll give it the right ID 45 or 40 and now just need to send this to the back take our user pain will be back into position save it close enough and run it again now as you can see i indeed use the wrong ID but we can fix that very easily thanks to interface builder ok think it's one save that build on oh I hate you now I have to look at code that makes things harder there's a couple of things that yeah image 1 if it doesn't work well then oh well let me just check reload image 1 yeah is that or something that's happened to my resources under skypein well Guys looks like homestar runner I don't know why here he is okay so the interesting thing is you know we have this running but now because that it sticks right to the mouth now in a powerbook show it show that I was afraid I couldn't show this demo because we're on this fast machine but on this power book on a slight slope our book I could do this this also happens to have it on my machine at work but anyways that's another story but the cool thing is is that image you is really optimized for HIV it's just much faster than using a picture or drawing a using CD image raft itself so we highly encourage you to use image image view wherever possible now the other thing that it didn't show is that you know hey we've actually embedded all the stuff into a scrollview we just didn't show you that that's pretty neat but I can also scroll everything right over the picture and you get full compositing beautiful everything is cool alright so that took longer than it should have one of the other thing i want to show you was just about the pervasiveness of the view system so you know we showed views and it was a great but we also touched on in the tool box session things about being able to draw in menus so let's take a look at some of those and this is a standard menu views example it's there it's on the website right now download it you can play with it but in case you haven't let's just take a quick look so menus can now be driven to a chive you you don't have to use em deftly anymore Oh hallelujah you're saying so here's a standard menu and that looks great right now you can do cool things like have pictures in the background you can have custom views like this I mean this is basically the basis for what the Finder is abusing just a simple custom menu woodson text color grid all types of neat stuff and the coolest of all the volume control right so here we have a menu that just has other views in it and yes it actually kind of sort of works and in fact I found out earlier that if I click the press button actually opens up sound panel that's cool so you know you can use these things there anywhere now that that was so views menus what about windows well we can show your window there you go that is a completely custom view written completely in a chive you with controls embedded within it ok I wrote this last night ok it only took me about I won't even tell you anyways but here's the other thing this is that same view embedded in a window it's the same view and whenever you would click on this view I have a handler in there so that when i get clicked I call drag window so if I click in this view I call drag window so it just kind of works but the important thing is it's just a view you can you can be deployed anywhere in any way and you learn at one model deploy everywhere ok I just watch them one thing don't open yes okay I mean I didn't speak that i ah ok there you go okay one of the things i want to show you about at this point so that would be before devil now it's the now demo what I wanted to do is go through some code here to exactly show you the steps involved in building a view so we're going to use the simplest case right here which is called a chai test view this is part of the sample code it's on the website is Stephen on you on all bills of Panther and all in the developer tool stuff I'm just going to have some fun font stuff here so you guys can all see I'm just going to increase this can I click it again of course oh all right now hopefully you'll be able to read this from way back there so basically i mentioned that what you want to do is you want to register your class and then you want to create your view and then you want to handle event so we're just going to show you an example of exactly how to do that in real code so first we have our registered function and this is kind of a one-shot function you know you register once you can call it ten times they'll only going to register once and what we do is we set up a list of events that we want to handle now this is an H I object like are all UI objects in the H I toolbox so we have to respond to at least two of these events can construct indeed struck technically we're also listening to initialize just for grins in this case so we have our H I object protocol I won't go too much into that but these are the important ones here's what we're actually handling everything that has to do with control so whenever you create an instance of this class that handler this handler right here is installed automatically and all your event handling set up automatic and I'm gonna say automatically all the time so we have activate deactivate highlight change and value field change the only reason we're handling those is to that we can call invalidate all right HIV set needs display as I mentioned you need to do that yourself you're going to have to handle these events if you want to actually get redrawn when these things happen but of course it depends on your view what you're doing etc go here we end up calling h object register subclass so we just passed our class ID which is just a string and we're subclassing the standard HIV base class we're installing h I test you handler which is just below in the bottom there and we're just installing it for all the events that we saw now once we've registered that you can create the view and we have a function to do that eh I test you create and first thing it does is just registered a subclass just in case it hasn't been registered already next thing it does is we we create an initialized event and I think what we do yeah if you pass it inbounds we will set the balance into that initialize event this is a way for you to get initialization parameters into your view so that you can do interesting things then all we do is we call a chai object.create and bang you get created your construct handlers call you build whatever instance data you want you give it back to us standard a chai object stuff you don't know a lot about H object I owed you to read documentation that's on the website I also wrote something for Mac tech last year or something end of last year which goes through this and you know insane detail so you might want to check either one of those things out and then if we get one will actually embed it into the into the window you don't need to pass a window to most of the HIV you api's will actually once the HIV way p is don't take a window rep at all and all of the older api's like create push button control and all those things have been modified to accept no at the window parameter you don't have to bind it to a window you can have detached views in the HIV system so once we've created this thing we're going to start getting events we're going to get them through our handler right there so first we're handling events of event class H I objects to just construct initialize and destruct and then we handle the control event so we get told the draw we draw we get told to do hit testing we do hit testing tracking with you tracking and here are those other events as I mentioned so when any one of these things happen we call hitsp change it ends up taking us here and all we do is call a chive you set nice display passing true meaning yes please and we'll get invalidated and redrawn in the next draw cycle we also have to get data set data just here mostly for example and get region which is also only here for example take a look at some of these I'm going to skip construct and destruct at standard stuff you really want to know about it just look more in the in the example initialized we get the bounds out that we had passed in and to create thing we set our bounds in here using a chive you set frame okay drawing first thing we do when we're going to draw is we get the context the context is only sent in the composited mode right now so we get that context and again we've been transformed top left is 0 0 and we're clipped accordingly and what this does is we call it red box blue box so it's a red box until you click on it then it's a blue box it's wild so it's just a simple example to show how you can do this and how you can tap into the to the standard tracking that exists in the control manager so you know if we're just sitting there and something's going on we're red we get clicked or blue and we also listen to these two part codes so we get our highlight essentially and we decide how to draw if that is 0 we know we're in a standard state if it is the neck part of the sable part we can draw in the disabled State an even better way to do that is to actually check to see which is to call is control active or is control enabled and generally don't like to overload the park toes these days and if it's any other part code that's nonzero will assume that we've been clicked and we draw blue ok hit testing in the hit test scenario we do is we just extract the mouse location we test to see whether that point is in our bounds and then we just give back the correct part code if it's in our bounds we return to part code of one the part code space is your space you can return anything you want the only thing you need to keep in mind is that if you pass 0 back to us we will assume you don't want to track at all and maybe that's what you want maybe it's not what you want let just be aware of that technically from a technical pure standpoint you don't have to even check your bound because we wouldn't have asked you in the first place unless somebody was calling just something like the old test control API you might get called that way but again for proper checking you might want to at least check your bounds so if the click is in us we're hit if it's not we're not hit and we report the answer back and again that answer tech ties into the standard tracking loop in the tool box doesn't it we click on a view we'll ask it with their part hit oh yes it's part one okay start tracking that part and then we'll do standard tracking for you and as we track in and out of your control we will set the highlights and that's how you draw you can also do custom tracking I don't think this specific example is set up to do it right now but instead of having the toolbox through the tracking you can do it it's even another level of tracking beyond this which the minute the cliq gets you you can do whatever you want once you get into it's kind of like two levels of tracking it and which i think i think we explained it in the carpet event dot H header but basically you can do anything you want in this case we're doing basically what the tool box does you know we did 70 we're we inside when we started what we probably work and then as you move out we said our variable you probably all written in this loop but the point is you can write it yourself if you want to you don't have to use the tool box and stuff and that's a great part about carbon events and the way it ties into HIV you can override just about anything you want again test you change we invalidate you already saw that get data set data I'm not going to go into those very exciting get region that's something I want to talk about so this is the get region handler and we extract the part code and a region handle and basically based on the part code we want to munch that region handle it's important that if you get a part code that you have no idea what it is return event not handle there you may trip us up we did experience a couple of applications that were not doing so and they were giving us empty regions and crazy things started to happen so we had to implement workarounds in the toolbox and generally try to avoid doing that because it there's a performance penalty in that regard so really try to be correct in how you handle these things in this case all we're going to do is if we get the content or the structure met apart we're just going to return our bounds like I said earlier you don't have to do this if it's just going to be your bounds don't even handle it that's an even simpler but it's just a simple example of what you would do so we just get our bounds we convert it into a quick draw rectangle because we need to call wrecked region as I said before we're trying to toward these new shape riffs that we have kind of introducing introduces a bad word because you couldn't use them but we put them in Jaguar but you can use them we're starting to use them now in the HIV API so you'll see a chai shape rescues there okay so if we were to run this you see a very exciting application red blue red blue red blue red Musa ok so that's cool now you notice there's one next to it and that's what I want to cover next that's okay all right c++ everybody's friend everybody's enemy but here it is we like C++ on the toolbox we use it internally all of our stuff follows this thing we have HIV you internally at the C++ class and we just export it to this H I object layer well what we also did when we were writing these sample codes if we came up with a sea view class which is kind of a mirror of our HR HIV class only it's a little more generic so what we do have is this thing called a chai and I don't wonder if it's a nice oh there it is beautiful we have this thing called a chai framework this is series of classes which allow you to write views really really easily and that's how I wrote even that sample app and homestar runner and all that very easy to write this stuff it's part of all of our sample code all of our sample relies on it we urge you to look at it it may grow into something bigger we're not sure right now the important thing is you might be able to use it directly you might not if you can use it directly great if you can't you might at least be able to borrow the ideas and the implementation strategies that we put in them and try to merge those into your own framework so we really urge you to look at it cuz I we figure that most people are actually programming in C++ pieces so it won't go too much into that suffice it to say that we have this t-test view that derives from RT view quest we can see just exactly the same basic control that we just looked at only in C++ so these lines are interesting I mentioned that if you if you change some aspect of your view like activate deactivate highlight and and like you'd have to invalidate yourself welcome you takes care of that for you so in this case all we need to do is just say on highlight and not activate we want to be Auto and validated we also do this internally in our HIV class and it's so helpful that we may end up exporting as real API in the future but basically this codes a lot simpler and you can actually look at the guts of the code so like create it's just register class create and then in bed just like you saw in the earlier example register class is even simpler because basically t view or an ultimately t object which tu derives from just takes care of it for you to just give you a class ID and give it your construct proc and construct it's like a static proc on your class it gets called whenever a chai of the creators call and all we do is create a new instance of ourselves and return it very easy draw it's pretty much the same code only we don't have to do all the carbon event stuff that's the beauty of doing it using the C++ stuff is that all the carbon of that mechanism is taken away and you just worry about you know what you're doing hit test a simpler we don't have to deal with taking the part out I mean taking the point out and returning apart it's just a method call like anything else and get region is simpler a lot simpler so we urge you to look at stuff like T view unfortunately running short on time so I'm going to cut back to slides okay I want to talk briefly about performance tips first off as i mentioned try to invalidate only those portions of your view that need to be redrawn if you have a small view you can probably just evaluate the whole thing it's not going to make a big deal but if you have really complex you a table view or some type of spreadsheet stuff we're only cells are changing you might want to just invalidate those portions obey the incoming limit region that draw region that I mentioned in your draw handler if you do have a complex control to limit the area that you draw this makes a huge difference in the performance of your views if you're moving or resizing views the best best solution and Panther if you use layout the next best solution is to watch content view bounce changed event not window bounced change event turns out the window bounced change events come too late the way that window mechanics are is that when you resize the window we reshape the whole frame view which reflows all of the window widgets and the like and then we paint it then after that you get called with a window bounced change event and then you go oh I have three flow and then you move everything around and then we paint it so just by listening to window bounced I mean the content view bounce change as opposed to window bounced change makes a big difference in your live resize speed you will definitely get a few frames per second than that and the best solution as I mentioned on Panther is to just use layouts but then you don't have to worry about that stuff well I should go back just so and those feature bits that i mentioned that help us to avoid having to call you for regions you know make sure you set them as appropriate so in summary want you to know that HIV is our focus and we're really concentrating all our efforts on making it perform great and it's changed our world seriously writing things like the sidebar in navs just took days I mean it's just it's amazingly quick you like a right demos and hours no that's just that's what's to know that's not a good example but seriously we've been able to just care to reviews these days I mean the amount of work that we can get done is amazing and I guarantee you that if you start to use this stuff you will realize that oh my god this really is different and you can throw away a lot of code application I kid you not so and at the same time that it makes everything better it's still familiar to do extensions of control manager okay and it still you know kind of like it's still home and that was funny hey I was serious so yeah and a dimension is pervasive so you don't have to have all of these different neo MFG dfw def just few and you're done and above all if when we make changes to the renderer and the compositing your stuff you'll all benefit from that so we're all going to share in this and this H I've you adventure or so and as I mentioned it's very fast this is the fast new system it is not the control manager trust me
