WWDC2001 Session 106

Transcript

Kind: captions Language: en thank you welcome to session 106 you know the carbon Event Manager is one of the most important technologies that we've added to carbon because it can simplify your code make it easier to write Carbon applications improve your performance especially on Mac OS 10 and it's the foundation for most of the improvements that we are adding to the toolbox so here to tell you all about it is the manager of the high level toolbox team edy Bose that's me all right as Mark said carpet events is one of the most important technologies to learn about as an application developer the reason for this is that it permeates everything we do in the toolbox every one of the toolbox managers like the window manager menu manager etc deals with carve events at least in some respect it is the Alpha and the Omega so what you got to learn about here is you can learn a brief overview of current events we're gonna try to talk about basic fundamental principles how it works what makes it go I will also show you how easy it is to actually build a carbon event based application and we'll also show you some examples of how you can extend the toolbox via carbon events so what carbon events is is is a direct dispatching model events a dispatch directly to objects in your application this is in contrast to the wait next event model where it's up to you to pick up an event and decide what to do with it the tool box can do that for you and with that the tool box can also provide many many default behaviors all the things that make a Mac application behave like a Mac application but your applications can override those default behaviors and extend it in ways that make sense for your app and while we have a pure carbon event based model you can also use carbon events in your wait next event based applications this is to allow you to actually start installing handlers and eventually get to a point where you don't need to call wait next event anymore so why did we do this well first off if you remember the event record structure our friend it only has a possibility of 16 events and the reason for this is because there's only 16 bits in an event mask we wanted a system where we could send hundreds of events possibly thousands of events all different types if you were to look in Carbon events th right now you could see hundreds of events already existing we also wanted to unify different models that we had we had event records for receiving events by your application we also had deaf procs for Windows controls and menus and we also had different notification callbacks that you can install for whatever they were but each one of these was different and every time he did install a new callback or to find a new callback it had a different API he had to learn it and it was just mayhem so what we're trying to do with carbon events is unify all of that into one model that's easy to learn it's flexible and it assumes everything else that we've ever done this also makes it simple to write applications not only because it's a simple model learn it once you know it but also because as I mentioned the toolbox provides default behaviors so you get to write the code that matters for your application and lastly we want an API that would encourage good performance particularly on Mac OS 10 so I mentioned we're gonna show you how to build a carbon event based app it's really simple the easiest way to do that it's a project builder an interface builder if you were here for the last session before this one that was with interface builder that is really the star of this duo here and that's what allows you to throw together a nib file and just have it run via carbon events it's what I like to do is actually bring up somebody to show you how to do that so here's one of the engineers from high-level toolbox team guy pull it in so I'm gonna show you a little bit about what ed was talking about with respect to project builder an interface builder and how they make your life really easy when you want to make a carbon event based application project builder supports a whole bunch of different types of applications that you can make I'm going to start off with a nib based Carbon application there we go all right so you run the app and it just works well on a clean system all the basic handlers are all the basic event handling is taken care of for you you can click on the window title bar and drag your window around you can resize it you can select things from the menus and you know you can quit the application the best part though is the fact that this all happens with virtually no code this is just a page of code this is all that there is in the application all it does is it opens up the nib for the app sets up a menu bar creates a window cleans up after the nib shows the window and runs the application run runs the application event loop and everything else is taken care of by the carbon of that manager now let's see guess I'm playing with fire here I can open up the nib for this window or for this application and as you can see it's just a plain old normal blank window just like we got in the app and I can throw some interface elements into there with interface builder so that's really cool if you got to see the session right before this you got to see how much you can construct of a carbon app I'm gonna go ahead and throw some edit text fields in here you know make some a little bit bigger or maybe put some static text in there I've got a couple buttons you know maybe this is gonna be an OK button change the name to OK and make it the default button go up here let's say we want a button that actually quits the application I can change it to be quit and I can say you know what to have the quit command in you save this nib go back here and I guess if I'm lucky it'll rebuild and I can run and the interface just comes up and works I wrote no extra code this is all just working you can type into the text fields you can hit return to flashes the OK button I don't know if you can see that up above and the coolest bit since this quit button has the quick command associated with it if I click in it the quick command is propagated to the application and the default Carbon event handlers just quickly quit the application for you so that's just the very basics of what Carbon events and interface builder can do for you but this shows that there's a lot of power in the system that you can leverage and it's gonna give you some more details on how you can leverage that all right so back in 1984 I still in high school and this is the way an application worked essentially everything was done by the application and the toolbox was just there for support so the application was responsible for the event loop the application was responsible for dispatching events and of course the application did something with those events in the hint and their handlers this is the new model the toolbox is taking a much more active role in driving an application in this model the application calls that run application event loop API you saw and it takes care of dispatching the events and all your application needs to be responsible for is the handlers and that's where your application lives and that's where your value is added so as we saw we have a lot of standard behaviors that we support in the toolbox naturally obviously drag Windows around you can resize them if you had a proxy icon in the window title we would handle that automatically for you with regards to dragging it around we also will handle contextual menu interception for you so you don't have to worry about you know ctrl-click will just tell you a contextual menu do it and the other thing is with this model we could actually handle the contextual menu click ourselves if you didn't and at that point we could say well we what we always want to put up a connectional menu when this happens and maybe we'll implement something where we start putting up a potential menu and then we'll send you a carmen event saying alright we're doing a contextual menu please fill it in here's the menu so there's a lot of power here obviously with menus we deal with tracking the menu bar dealing with command keys we deal with updating the menu bar as necessary and what controls will automatically handle all the tracking will deal with focus issues and the like so before I get into the real details I want to talk in general about how events flow through the system or at least through an application with carpet events at the top of this diagram you see the event queue and as some event today below that we have a diagram representing what the toolbox considers to be its canonical containment hierarchy at the bottom we have the application it is the container of everything above that we have menus and windows so the owners of menus and windows are the application and each window can own controls and each control can actually have sub controls based on our standard control manager control hierarchy so what happens is an event comes off the queue and then the toolbox looks at it and says ok what kind of an event is it where should it go for this example we'll say it should go to the control that's right below it once it gets into the control and looks something like this each control has a target associated with it and this is the receptor for Anakin for a carbon event each target can have multiple event handlers installed on that target and they're installed in the form of a stack the last handler installed is topmost on the stack the last hander installed is the first handler to get the events that is how applications override toolbox behaviors so in this diagram essentially we have an application handler at the top called my handler below that we have a some handle that was installed by the toolbox possibly a standard Handler and then below that we have an object camera and this can be thought of as the actual def product that's driving this control so we're gonna go through a worst case scenario where nothing wants this event its unwanted I can feel bad about it so as this event goes through essentially we look at each handler see if it was registered for this event and if it wasn't we will bypass it or it might be that the handler receives the event but decides at this time it doesn't want to handle it so it basically reports I haven't handled it so if this happens for all the handlers it'll just fall through and out of the object at that point the toolbox decides where should it go next and again it uses the standard containment hierarchy to decide that so in this case that will go to the window next and then if it isn't handle there it will propagate out to the application and this is where all unhandled events will end up now if the application doesn't handle it it'll actually just get dropped if you happen to be a wait next event based app if an event is unhandled by any of your handles it will actually be returned through wait next event as long as it was an event that could be returned to way next event like a mouse click okay details the first thing you need to know is about the event rack the event ref is the replacement for the old event record structure and in grand toolbox tradition it's opaque you have to use accesses to get at it each event is identified by a class and a kind so a mousedown event would actually have a event class of kay event class mouse it's a mouse event and the kind is just some sub event of that class in this case Mouse down now Mouse down all by its lonesome just knowing that the mouse went down isn't very useful usually you want to know where it actually happened what the modifier keys were things like that maybe what button was pressed and the way we do that is we have an extensible parameter mechanism on an event so all of the things I just mentioned can actually added to the event as parameters each parameter can be accessed through some mnemonic name a constant each parameter can also have a type so the mouse location is actually stored as a quick-draw point so we would actually use a constant representing that type like type QT point the important thing about an event ref is it's not just one way event records were always something happened Mouse down window activated it's always past tense event refs can actually be using a much more active role you can actually send an event ref someplace to get information the recipient of the event can actually store information in the event ref so that after you send the event you can extract the information out of that one good example hit testing in a window as I mentioned we're trying to replace deaf procs with carbon events and in fact the native messaging model for windows and controls and Mac OS 10 is Carbon events we actually simulate the old proc pointer based stuff on top of that so when we're gonna do hit testing what happens is we get the point we actually send a hit test Carbon event so the window the window then turns around says okay this part was hit stores it in the carpet event so this way when the sender gets the event back you can actually see they can extract that parameter and find out where the mouse is hit and Carbon events are extensible extensible to the point that you can actually create your own you can use maybe your application signature or whatever you want as your event class and then have your own suite of events which you can send around in your application the event queue is a little different in Mac OS 10 under Mac OS 9 or traditional Mac OS the event queue is shared among all applications on 10 that's not the case each application gets its own event queue when events come into that application via the Windows Server they're queued up in that application event queue however within an application we take it one step further in that each MP task can get its own event queue if you're running an MP task and on that MP task you call get current event queue you will get a private event queue for that MP task you might hand the QRF for that queue to some other entity in the application and then you could start using that to actually post events between threads using carbon events now you might just use MP primitives to do messaging back and forth but you can also use carbon events as it adds a much more expressive method of of events and contrast all cooperative threads including the main thread of the application share one event queue and that's the main event queue and that is the queue that receives all the events from the Windows server as I mentioned whenever you're waiting on an event queue for an event this allows timers to fire what the heck's a timer well it's the replacement for the null event processing mechanism through wait next event and wait next event if you don't handle an event you get a null event I mean if there's no event for your application you get a null event and then you decide oh I guess I should spend some time doing something timers allow you to just request time explicitly and as I mentioned they only will actually execute while you're waiting on an event queue so these aren't asynchronous with respect to your application and not running at interrupt level or anything like that they're running a task level you can allocate memory you can draw you can call the tool box there at that level the advantage of a timer is that each object in your application can ask for its own share of periodic time if it needs it and the timers can be disabled so for example if you have an edit text control or something which needs to blink the cursor or perform some animation when that goes inactive you might want to disable that you can actually remove the timer and stop using up that time because obviously there's nothing to animate anymore timers can be set to fire at intervals every half second every second or they can be one-shot so you say call me back in 15 seconds timers can actually fire while the mouse is down and this is important to note because you know obviously if you had we're processing a null event and we're processing a click so it's a little different and so this means timers can actually fire while you're tracking controls and while you're tracking the menu bar so it's something to look out for and Mac os10 finally has a much more reliable heartbeat Mac OS 9 because it's cooperatively scheduled you know any one prot any one application can steal the processor for any amount of time so you can't be guarantee to get a half-second timer firing - much more reliable on necklace 10 so as we saw in the example you drive your application to run application event loop this is the pure carbon event based carbon event API whatever I'm trying to say this is how you've run a comet event based app once you entered this API you will not exit until somebody sometimes the tool box sometimes your own application calls quit application event loop and while you're in there that's what's driving your application the toolbox then starts pulling events off the event queue sending them to your handlers as appropriate alternatively you can continue to call wait next event and while you are inside wait next event events will be dispatched to any handlers that you have installed and again this allows you to start installing handlers even in your wait next event based application and start adopting carpet events without having to go and reconvert your I mean you know just redo your entire application over to be a pure carbon event based app so while we're in run application event loop or inside wait next event we end up dispatching events and where they go is event targets and we saw a picture of one each target can have a stack of handlers inside and they're typically attached the toolbox objects like menus windows controls we also have some special targets one of them is called use a focus target we're going to talk about that a little bit a little later the other one is the toolbox dispatcher whenever one application event loop pulls an event off the event queue it just sends it to the toolbox dispatcher you can actually use this fact to install a handler on the toolbox dispatcher to catch every event as it was being processed so it does have its uses here and there as I mentioned they have a stack of event handlers and of course the event handler is where your application lives this is where you receive events it's a simple callback where you get your events you will only receive the events that you register for we don't support wild carding and a conscious decision with performance in mind we don't want to start sending out events to any handler that could possibly deal with it when you're inside your event handler you can choose to actually handle the event meaning do something with it or not handle it meaning let it propagate to some other object which or handler which which does want it the way it tells the toolbox whether we handled it or not is by its result code if your event handler returns event not handled there that's a cue to the tool box to say all right nothing happened here nothing to see here please move along so it sends the event off to some other handler if you returned any other status code event propagation stops are dead and the event is discarded and once we leave a target we do propagation we saw the diagram of our containment hierarchy that's what we use to decide where event should go so if an entire target doesn't handle an event we decide which target to send it to next and we redirect it I mentioned that application target is where all at all unhandled events end up now that's not a complete rule there are events which we will not allowed to propagate between beyond the target which we send it and the best example of those are those events which replace the old def product messages there's no point sending a window hit test event to the application so we only send it to that window object and I also mentioned you know how your result code tells the toolbox how to if we should propagate or not we call that implicit propagation so you don't really need to do any action on yourself to make the event propagate other than control your result code however you can do what I term explicit propagation which is you can actually say alright I have this event but I want the toolbox to do its fault processing right now because I'm going to do something after it and you do that through an API called call next event handler so you would receive an event just call through toolbox might do some default behavior and then you can follow up so you can be implicit or explicit alright I touched on user focus the user focus is quite simply where keyboard events go and you can get the user focused target by calling get user focused target back of Maca was st. we introduced keyboard focus which is great so you have a window when you have some concept of what the focus control is in that window well from an event model standpoint you know that's all wonderful and all but when we get a keyboard event which window should we even start with so what we've done is we've created this concept of user focus which is the combination of the currently active document window and any focused control in that window if the currently active document window doesn't have a focus control that window is considered to be the user focus there are times however when you actually want to redirect it to some other window which isn't the currently active document window best example would be a floating palette which accepts some sort of keyboard input you might want to redirect it there and you can do so with an API called set user focus window if you're using pure carbon events you don't really have to even worry about that because the toolbox will manage that for you automatically user focus along with being the recipient of the keyboard events is also the recipient of h:i commands h:i commands are merely the extension of the old menu command concept we introduced in mac OS 8.0 so a menu command is just a position independent way of identifying a menu item traditionally so instead of knowing that you know when the user selects undo from the Edit menu it's you know menu ID 129 item 1 all you need all you need to know is that the command is on it doesn't matter where it isn't the minibar as long as you can undo you know what to do when we were doing all this carbon event work though we decided it would be really good if we could share this with controls as well and he saw an example of that where we hooked up the quick command to a control so the H I command structure is actually little struct is the encapsulation of that so inside these structures it has the command ID as well as information about where the command came from the propagation path is a little different based on whether the command was originated from a control or from a menu if from a control we just follow the standard control hierarchy starting with the actual control that originated the command for menus we send the command to the menu which originated the command and unhandled at that level we then send it to the user focus and that is probably what makes the best sense for example if you're going to select cut from the Edit menu the command should probably go right to that focus control in the currently active document window wherever the user focuses basically we also use h-i commands to deal with menu item enabling and disabling we talked about this a little bit more in the windows and menus talk tomorrow but essentially whenever menu is about to be displayed for each item in the menu we send out kay event command update status events this is your cue to actually do something with the command in the menu you might want to enable it or disable it if you want to add a check mark or change its text maybe undo changes from undo to undo typing it's completely up to you but we send this right to the user focus saying I'm about to show this how should it appear when the user selects one of these menu items or clicks the control we send out kay event command process and that's when you can deal with the command commands are actually really useful for doing simple inter target messaging so for example you can have a window with controls in it and the controls in the window can all have command IDs associated with it and the window can be listening to all the commands that the controls generate so every time you click a checkbox or drag a slider the window can actually pick that up and say oh check box and say that I gotta go do something it's also important to use the standard command IDs that we've defined in carbon events eh whenever possible we have a whole list of them in there right now and we're adding more as we speak but the reason for that is we want to be able to share the menu bar between the toolbox in the applications so if the toolbox has something you know up on screen at the time and we need to enable the disable certain menu commands such as the edit menu we need to be able to find those by command ID there comes a time in every applications life when you have to go modal and typically we've done that in the passage with modal dialogue so you called get your dialogue you bring up your dialogue and you call modal dialogue and you sit there until the user hits ok or cancel or whatever the way to do that in the carpet event model is to call run app modal loop for window so you can create any window you be a nib based resource base we don't care we just put it up on screen and you call run that motor loop for window now at some point somebody needs to call quit at modal look for Windows so that you can actually terminate from the call it's very much like run application event where you enter it and you will not exit it until somebody calls the appropriate quick call and this is probably good enough for most most uses especially if you pure carbon event-based but you might have an application which has a lot of legacy code and you can't necessarily do that you need to drive the event model yourself or drive to the event loop while this thing is modal so you can actually share our modality environment while driving the events yourself and you do that with begin and end at modal State for window and what I mean by our modal environment is that whenever we enter this modal state we automatically take care of display be disabling the menu bar and then dealing with the click situation so we don't allow clicks outside the window that happens to be modal so by using begin and end up the modal State for window you can actually use the toolboxes canonical modality stuff all right we talked about performance there are a couple ways that you can actually tune your app for Mac OS 10 and I mentioned that Carbon events help you do that first thing is timers as opposed to using wait next event timeouts ideally you should have your way next event sleep time set to the maximum it can be and install timers throughout your application that actually goes a long way to helping toward minimize unnecessary idle time another thing is tracking lose tracking loops written traditionally with while still down no get mouse are very very bad on 10 they make everything else go slow so what you need to do is instead use track mouse location we're actually going to show you an example of that in a few minutes another thing is to try to use notifications whenever possible as opposed to polling we've gone I mean we've done a lot of stuff in the carpet event model to try to send you Carbon events when certain things happen in your application or sometimes outside of your application for example one common polling situation is pulling the the process list i wouldnt know when the process comes and goes well we actually have carbon events to tell you when that happens so rather than you sit in there in some sort of loop or you know instead of installing a timer to do this every you know millisecond or something you can just say you know hey let me know when an app gets launched or let me know when an app quits and if you if you have cases in your application where you need to do polling and we don't have a solution please let us know because we're really trying to add as much in the in the realm of notifications or notification events as possible so we talked about how carbon events is the native kind of death proc model for Mac os10 and carbon in general toolbox objects is what allows us to do this toolbox objects are effectively an event handler that you can define and register with the tool box using register toolbox object with this you can then in the window and control managers call create custom window or create custom control passing one of these toolbox object reps that you register and then that handler that you associated with the toolbox object will get called to deal with all the events having to do with def procs and this is the recommended method for doing custom controls and windows these days and then the reason for that is quite simply this is where we're spending our time you know Carbon events is like our future and it's very flexible carpet event second we can add parameters and new events you know until we're blue in the face and the thing is when we start adding parameters on existing events you know we could kind of augment behaviors and things like that without affecting and the recipients of those events who maybe don't care about that parameter yet so you know we can actually start to send new parameters while not well and not breaking basically so that was a lot of stuff so what I'd like to do now is actually bring up guy again to show you a more detailed demo and show you about a lot more of the power that we have oh yeah all right cross your fingers for me so the first demo I want to show has to do with what ed mentioned about eliminating polling I've got a small application here which is based on that basic carbon app that I showed you before and I'm running another application it's on the system which is a CPU gauge this basic app has just a normal window in it with a couple of bevel buttons one of them's good one of them is bad and this app is almost as small as the one I showed you before I added one Carbon event handler to it to override Mouse tracking for the bad control and the reason I overrode it is because the system already does the good thing with respect to polling the system when it's about to track the mouse does not sit in a spin loop it calls track Mouse location which will block and which will make sure the CPU doesn't get used when it's not necessary so what I did is I overviewed sorry I overrode the click handling for the bad control and I have a a while still down loop in the bad control so if I click on it you can actually see the CPU just pin out I'm not even moving the mouse but the CPU is using up absolutely everything it possibly can if I was trying to download something in the background your download speed will be cut in half you don't want to be doing this what you really want to do is either let the toolbox do the default behavior for you which as you can see if I click and move around you know I get a little bit of CPU usage but if I click and hold it still I don't get any usage so use track mouse location if you're currently doing polling loops now we'll go back to magnify this time for real so magnify is an app you may have seen I think we've shown at previous years it is a simple application which magnifies the screen pixels that the mouse happens to be over and we do this with a timer magnify updates once every so often grabbing this the pixels from the screen and displaying it in the window and it also has a carbon event handler on the window to handle window resizing we always want the magnify window to be squared just because we're that way so if even if I move the mouse only horizontally the window still maintains its squareness so let me show you oh the one other thing I want to show you about magnifier is we also offer a modal preferences dialog that lets you configure various things you can change the zoom level turn off the little info that gets shown in there or make it float or not float let's make it not float for now so let me show you a little bit of the code and how we do all that it's the first thing I want to show you is how we did the timer timers very simply are just a croc pointer that you register with us tell us how often you want to do something and then when you're proc pointer is called you get to do whatever you want to do so here's our event timer we just called it magnify event loop timer it receives user data which is basically like a refcon so if you have some global state you need to reference or some per contact state you need to reference you can receive it there and our timer goes in there we do some various things we basically create a port so we can grab some screen pixels and we copy bits it to various things and end up painting it into our window so it's one thing to write this but you actually need to install the event oh you know what didn't want to hide me to do that the way you install an event loop timer is you create a upp around your proc pointer and you pass that upp in to install event loop timer you tell it which event loop you want to install the timer on and typically you're gonna want to install your timers on the current event loop and you tell it how often you want it to fire in this case I have this timer firing about once every 20 seconds and that's it the only thing you have to do after that is just run the event loop and your timer will automatically fire so next I want to show you I show you how to write a basic event handler like I mentioned before we have a window handler which makes sure that our window resizing always is square and just like an event timer this is a simple callback proc pointer you receive an event a refcon and when your callback is called you can extract parameters from this event in this case our window extracts the attributes from this particular event I know that this handler is only registered for one event so I can just dive right in to extracting parameters without looking at the actual event type but if I wrote a handler to handle multiple events you'd actually want to switch over the type of the type of event you're receiving so a window bounds change event actually contains some attributes which tells you how the bounds are changing when the window bounds changed the the window might be resizing or it might just be moving ie the origin is changing we only need to do work when the size is changing so I check the attributes to make sure we're only gonna do work when we need to one other thing I want to point out we have a result code that we're going to return eventually by default this result code is event not handled err so if our handler ends up doing no work that tells the event subsystem to just go and do whatever default processing you would have done so going back we know that we're changing size we get the current bounds out of the event that's the bounds that the window manager figures you want to really use but we take them out we don't really want to use them because we want to make the balance square so we go ahead and we do a little bit of effort to make the bounds square and then we stuff the current bounds back into the event and we set our result to no error no error is an indication that our handler handled the event don't call any default handlers just let this event finish now so our handler exits the window manager ends up getting the bounds that we've changed out of the event and it resizes our window to those bounds and as you might imagine installing one of these event handlers is also very simple you create a upp for that handler oh I keep hitting the wrong keys and you call install window event handler you pass it a window you pass it the UPP and you pass it the list of events that you're interested in for that handler and it just so happens that I am only interested in the k1k event window bounds change event once you do that your handler is installed and any time the window manager or whoever might need to call that handler whoever anytime someone needs to call the handler it will be called the last thing that I want to go into is handling commands from menus we just so happen to have the default preferences command associated with the Preferences item for our menu and we need to set up a handler to handle that preferences item and display the modal dialog so in my main first thing we do is we enable the Preferences command because we know we want to allow the user to select that and next after we do some more setup we install an application event handler now as Edie mentioned when you select a command from a menu the first place that command goes is the menu itself menus don't often handle commands and in this case our menu does not handle like commands specifically then the command will go to the user focus which would be the window well our window isn't particularly particularly interested in it so the event ends up propagating to the application and that's where we want to handle it and we have an application Handler oh you know I keep hitting that don't I just as you would expect we pull out the direct object out of the handle out of the process command event and it happens to be of type H I command we look to see if it's the Preferences command and if so we do the Preferences dialog and the Preferences dialog is an excellent excellent example of how you would do a modal dialog first we build the window via and then don't have to build at the end him you can build it programmatically or via resources or however you want to do it we set up a few controls and then we install a handler onto the window to handle commands that are going to be generated by the controls in that window and that's the pref handler then we position it on screen as appropriate and we call run app load a loop for window now when one app modal OOP for window eventually returns we disposed the window we dispose of the event handler and then we returned from the Preferences function so most of this work actually happens inside the toolbox until our pref handler gets called and our prep handler is going to get called for commands associated with controls in the window and just like handling menu commands we extract the direct object out of the command event take a look at the command ID and we do various things one of the interesting things is if we see a magnification change command we change our magnification factor and tell the the actual magnify window to update itself if it needs to and there's a couple standard commands for dialogs and those are khi command ok and khi command cancel and those have been associated with the ok and cancel buttons in that dialogue when we see the OK button we write out our current settings to the Preferences and we call quit app mode a looper window that way run app mode we'll exit we can ultimately get out of due preferences and back into the normal application processing so this magnify sample code will be released a sample code on the website very shortly as soon as we can get it up there now those are just the basic concepts for how you'd implement sort of Carbon event handlers and Carbon event timers but I want to show you the true power of Carbon events we have another application on here called live buttons now live buttons looks a lot like one of the earlier apps I built it's just very simple kind of an ugly dialogue you know we've got some text fields in here you know we've got some buttons you can pretend that this was I don't know some kind of find dialog so you click search and it goes off and does something I mean we're not really doing anything here we're just animating for fun we've got an OK button bevel button a little disclosable area stuff like that and this is all being run by the toolbox now the cool thing is live buttons is set up such that we've installed Carbon event handlers on all the controls in this window to intercept clicking and drawing I can put it into this edit mode and our handlers that we've installed know to intercept drawing by drawing blue frames around each individual control and intercept clicking by giving you handles that you can actually resize the controls and repositions things sort of live and move my button over here resize it's the H I designers won't like it and I move my bevel button around and do whatever I want and as soon as you're done fiddling with it it's live button sample lets you turn off edit mode and you're back to normal that's interesting but I can't there we go [Applause] now on previous systems this sort of functionality would only be possible if you wrote lots of extra code or patch the toolbox but with carbon events we allow you to do things like this in a clean legal way but Carbon events certainly aren't limited to just demo apps if you've got a larger document based application we can serve your needs too now this is simpler text this is sort of a new version of simple text that we're writing you know as you would expect thoughts kind of small but you can type into simpler text and change the font change the size and things of that nature but what we also did is we wired up a font window now the main simpler text window is is pretty unintelligent about the rest of the application it just edits some text and it happens to process a few events a few special events the simpler text window can handle a change font event and they change font size event a change font style event so that we can create another totally independent separate part of the application to drive this font palette and wire up functionality into the font palette that just sends Carbon events to the main window so I can change the size over there I don't know or change it with a pop-up or maybe change it to bold and let's bring it back to sixty point and do stuff like that now one other kind of cool thing that we did in this sample is handling some window events this font palette we set it up to handle the bounds change Carbon event to automatically snap it to the edge of the window I don't know if you can see that jumping on the big screen but as I get close it sort of automatically snaps it there a lot of applications like to group their palettes together and you can override certain Carbon events that way but that's not the only thing you can you can do with the balance change event now balance change events are also good for handling live resize well we decided to wire that up too but then you can get really strange and what if we only wanted this window to be displayed on a single monitor and as the user moved it off you could actually scrunch it up in very weird ways so you can do that too there's all kinds of cool things you can do with Carbon events and a scale very well I mean they're great for demos obviously but you can fit them into large-scale applications you can wire up a little bits of new functionality to take advantage of new toolbox features in such a way that it doesn't disrupt your your existing application so it's really cool I'm gonna hand it back over to Edie for a couple more words that was pretty cool stuff now what well item one start memorizing carpet events th there will be a test at the end of the conference there's a lot of stuff in there we have a lot of documentation in the header itself to help you along and get you started the learning carbon book has some examples of how to write a carbon event based application I've submitted an article to Mac tech which goes into the stuff in way more detail than we can talk you know in an hour though and just start playing with the you know interface build a project builder start building carbon event based apps it's really easy to start you can just create you know default app is start installing handles and see what you can do I mean the little demo where you you know drag the window to the corner of the screen and kind of scrunches you know that took about you know 10 minutes to write so I mean this stuff is really easy to do and like I said there's just a lot of powerful things you can do with not much code and that means there's much more time for you to spend doing the stuff that makes your applications great and with that I like to bring out mark Turner again let me just through the roadmap and QA thanks [Applause] Thank You Eddie Wow those were some kick-ass demos huh Thank You guy okay so here we are six o'clock Tuesday the next session you should attend is tomorrow carbon windows and menus ed will be back share with you great stuff about windows and menus obviously and as you can see the next two controls and appearance wanted to a good pair of sessions to catch and finally I really recommend the carbon performance tuning session coming up on Thursday if you attended the keynote or obvious presentation basically every presentation on Monday we talked a lot about performance and how the characteristics of your apps performance vary whether you're running on eight or nine and/or Mac OS 10 and so this carbon performance tuning session will give you a lot of useful information on how to tune your app for Mac OS 10