WWDC2001 Session 120

Transcript

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