WWDC2001 Session 119

Transcript

Kind: captions
Language: en
well good morning looks like a lot of
you stayed up but kind of late and
aren't here yet
so welcome to this session this session
is really just the if you think of the
session that I gave yesterday which was
session 111 talking about how to create
a great citizen on Mac OS 10 citizen
application on Mac OS 10 and I said in
that session that wouldn't talk about
API is talk about conceptual ideas this
session is all about talking through
that material but looking at it from the
Carbon API level and so I'd like to
bring on stage guy Fullerton from the
high level toolbox team at Apple and
he's going to talk through the specifics
of some of that material as it relates
to the to the API is guy thanks first
things first did anybody bring me any
donuts no okay I guess everybody who got
here early so my presentation last year
and knows how fast I talk how fast I'm
gonna get through this stuff that's me
so I want to tell you a little story
that you've probably all witnessed
firsthand and it's the story of a carbon
application most carbon applications
start off as an interface live
application on Mac OS 9 and you begin
the carbonization process and that's
fairly straightforward and it takes you
anywhere from a couple weeks to maybe a
couple months but finally you get
through the opacity issues and weaning
yourself off of some api's and starting
to use other api's and you get it so it
actually runs well on carbon lib and
usually part of the way through that
process you get your application running
well enough to try running it on Mac
os10 the first time you try running on
my Mac os10
usually crashes because Mac OS 10 is
really good at exposing bugs that were
sort of latent in your Mac OS 9 code
base well you end up fixing those those
usually don't take too long because
they're just typically writing to null
or other strange stuff like that you fix
them you finally get the app to launch
and it comes up and it looks kind of
good but what's all that stuff going
wrong in my apps interface so I'm going
to tell you how to fix most of those
problems today as well as certain
techniques to ease your adoption of aqua
and how to avoid certain user interface
pitfalls but before I go any further
what
like to do is show off some of the user
interface pitfalls you might call into
and let's bring this up
okay so what I have here is a small
application based on an earlier version
of power plant that shows up some of the
problems you might run into when you
bring your application up under aqua now
the first thing you probably noticed
when this this dialog comes up is that
it's got a progress bar animating in the
top left hand corner and initially you
might think okay that's right
but then you look down in the bottom
right hand corner and you see that well
your progress bar should really be
animating down there why is it animating
up in the top left hand corner you might
also see this phenomenon with the
pulsing default button as well one thing
that I hope shows up on the big screen
and I've got the magnifier unning on the
right to kind of show it off more are
though is the white halo problem if you
look closely at the magnify window you
can see that the pattern shows up on the
dialog but it doesn't show up properly
behind the text and speaking of text
that text doesn't exactly match the
proper aqua look it just looks too thin
doesn't have the right anti-aliasing so
you probably have that in your
application as well one other subtle
problems that you may not notice here
until you look really really closely is
a misalignment of patterns you take a
look at the magnify window you can sort
of see strange pattern alignment issues
going on on the check box clip there
it's almost as though the pattern
shifted down by a few pixels and
speaking of these tabs that the check
boxes are in the tab pane doesn't look
quite right the tab pane is supposed to
have a border around the outside and
it's supposed to have some shadowing
around the outside but it's just not
showing up you might also see this same
problem with shadows on push buttons or
other controls and another problem that
doesn't often expose itself until you
use the application for awhile is over
compositing of things like focus reins
and edit text frames if you take a look
in the magnify window as I tab back and
forth between these fields you can see
the edit text field borders start to get
darker and darker and darker and this is
something that you need to be aware of
and I'll show you how to fix this as
well so we can go back to slides they'll
be great
so the first thing I want to talk about
and show you how to solve is the white
halo problem now like I mentioned it's
basically when some other color seems to
surround your widgets your controls your
static text items in a dialog that
otherwise has the proper line background
now fundamentally this is because of two
things
controls erase their background before
they draw and we have and the reason we
have to do this is because a lot of aqua
widgets have shadows under platinum they
didn't often need to erase behind
themselves because they were fully
opaque but now we need to erase in a lot
of cases and so when a control is about
to draw you need to make sure that the
proper background color has been set up
for that control so that the control
knows the right thing to erase too the
best way to get the proper background
behind your control is to properly
explore exploit the control managers
embedding hierarchy support now Control
Manager embedding has been around since
Mac OS 8.0 and a lot of people haven't
yet been exposed to it so I'm going to
talk a little bit about it now
essentially what the embedding hierarchy
is is a view system in the control
manager you can take controls put them
into other controls move them around as
a group it's just a mini view system it
does hit testing properly drawing
properly things like that now when the
control managers embedding stuff is
working well and when you're utilizing
it properly it will draw backgrounds
properly based on parent controls that
contain other controls for instance you
might have a push button in a tab
control when that push button goes to a
race it traverses up the embedding
hierarchy finds its parent that's a tab
control and says hey tab control well
you set the background up properly for
me so I can erase now the tab control
does that and then the button can go
ahead and erase and draw its structure
and life's great if a control is
embedded in such a fact such a fashion
that it isn't in a parent control that
has some sort of a fake background
ultimately as the control traverses up
the embedding hierarchy to find the
right background it might reach the root
pane for the window and if it does reach
the root pane for the window it uses a
background that's been associated with
the window directly via
set themed window background API I'm
going to talk a little bit more about
set themed window background a bit later
but just quickly what this API lets you
do is associate a certain pattern or
brush with the window such that I
control that is in this situation can
erase to that brush and get the right
pattern so all the system CDF's support
control embedding properly they they do
the right thing when they're requested
to have background color setup and if
you have custom CDF's and you want to
start taking advantage of embedding you
can do the right thing here as well
the best way to do this on Mac OS 10 is
to listen to the Kay event control
applied background Carbon event we
talked a lot about Carbon event in
previous sessions and one of our main
points is that in order to adopt current
and future Mac OS 10 technologies you're
going to need to start leveraging Carbon
events a lot more what just so happens
that if you have a old-school message
base CF you don't need this particular
carbon event right now we do send out
old CF messages to your control
definition to set up the background you
just have to do a little bit more work
if your control has a special background
the first thing it needs to do is tell
the control manager hey I've got a
special background and the way you do
that is by reporting that you have the K
control has special background feature
bit you're going to receive a control
message requesting your features you
would set that bit on the way out of the
feature request and once you've
responded that you support a special
background when the control manager is
trying to draw your sub controls it will
send you a cake control message set up
background message and in this message
you can set up the current port with the
proper background so that your sub
controls can draw properly now not
everyone can take advantage of the
control embedding hierarchy fully a lot
of frameworks have their own view system
and we're working on making it such that
you can integrate the view system with
the control manager more directly in the
meantime however you might not be able
to fully exploit control embedding but
you still need to set up the right
background and the way you do that is
with set control color proc now simply
speaking set control color proc allows
you to associate a proc pointer with a
given control and that proc pointer will
be called to
the background or the text color for a
given control and this control color
proc can actually be used in conjunction
with an embedding hierarchy if there's a
color proc associated with the control
it will override the control managers
embedding hierarchy support for color so
you can hook in that way and I also
mentioned that say control color proc
allows you to customize the text and
this also goes back to custom control
definitions responding to either the
Carbon event or the CDF message if you
have a custom background let's say
that's totally opaque black and somebody
puts a static text control on top of
that complete opaque black control you
need to make sure that the text that
that static the text control draws is
visible and the way you would do that is
probably by saying hey draw your text in
white set control color proc will let
you set up a white text color as well
and like I mentioned you can handle the
proper Carbon events or the CDF message
to do the same sort of thing now
sometimes that control color proc may
not do exactly what you want or maybe a
little bit of a hassle to use so as a
latch just a last-ditch effort you can
always rely well not always
you can sometimes rely on the control
managers default behavior of erasing to
the current court if the control manager
does not have a color proc associated
with a given control and if the
embedding hierarchy doesn't have a color
associated with the given control and if
there's no theme brush associated with
the windows background we're just going
to erase to whatever color happens to be
in the current port so if you're careful
you can use api's like set theme
background I'm going to talk a little
bit more about that later
you can use api's like that to prepare
the current port before you call any
control manager API which might draw now
this is going to work in most cases
but if flat-out won't work for animating
controls and the reason it is that
animating controls animate behind your
back you won't have a chance to
preflight any color setup or port setup
before a control draws so you won't be
able to use this current port technique
for things like push buttons and
progress bars and the other animating
controls
now another obvious problem you'll
probably notice as soon as your
application comes up is shadow clipping
I showed it in that demo application in
the tab pane but this particular example
shows it happening on push buttons now
generally speaking this is caused by
applications clipping to a controls
bounds before asking that control to
draw in aqua however controls have
shadows that lie outside their control
bounds and some controls like pop up
buttons have traditionally drawn outside
their control bounds so in general
clipping to a controls bounding
rectangle isn't going to cut it you're
gonna end up cut end up cutting off
shadows or worse power plant is probably
the most obvious victim of this
particular problem I know they're in the
process of fixing that I think they
fixed it already in fact so the way you
fix this problem is don't clip to the
controls bounds but you might still have
clipping needs you might still want to
make sure that the control doesn't draw
willy-nilly all over the whole screen
but you still need to give the control
the flexibility to draw where it needs
to draw and the way you do that is by
asking to control for its drawable area
you can use the get control region API
along with the K control structure met
apart heart tag and this lets the
control tell you hey you know what I
draw all over this area of the screen
and this region is going to include not
only the sort of opaque structure but
it'll also include the shadow pixels and
things like that so if you make sure to
clip to this structure region you will
let the control draw as much as it needs
to draw now gate control region is not
just useful for finding out where to
clip various controls support certain
part codes depending on the type of
control and you can ask for instance a
tab control you can say hey what's the
region for your third tab and we also
have another meta part which is called
the Kay control content meta part that
many controls support and this allows
you to query a control for the region
that its sub controls should be embedded
into so you can do proper positioning of
your controls within a tab pane for
instance
so I actually should have changed the
title on the slide this is not just
focus ring issues but this is also edit
text frames as I showed you on the demo
as I was tabbing back and forth between
those edit text fields you could see the
edit text frame get darker and darker
and darker and darker and in some cases
you'll see the same phenomenon with the
focus ring and essentially what this
does is it to sort of wrecks the visual
appearance of your API sorry of your
interface it starts looking heavier and
heavier and heavier and it just doesn't
fit in with aqua and the reason this
happens is because certain appearance
primitives now draw with alpha whereas
in platinum they did not and the two
best examples are focus rings and the
Edit text frame if you're going to draw
either of these you see the reviews
primitives to draw your focus rings and
your frames you need to make sure you
erase before you draw now erase is a
little bit of a lie what you might
actually need to do is draw the
background or draw whatever happens to
lie behind your focus ring or frame
because it might not just be a simple
background so in the demo app I showed
you the progress bar was animating in
the total wrong location but probably a
worse instance of this is when your ok
button that should be down in the nice
bottom right hand corner of your screen
according to the proper UI guidelines
all of a sudden jumps up to the top left
and start starts pulsing and that's a
really quick indication that something's
wrong
fundamentally this is caused by a non 0
0 origin in the window that you're
dealing with and this non 0 0 origin can
also cause pattern misalignment like I
showed you in the check box but you
might be thinking to yourself well I've
been changed in the origin for years hey
power plant does it my framework does it
our custom application code does it was
working fine right well it was behaving
fine but it really wasn't working fine
if platinum if you tried to draw
controls on top of patterns or other
pictures under Mac OS 9 you would have
seen this same problem happen just so
happened that in most cases you end up
drawing with the solid color so you
didn't see the phenomenon and generally
speaking it's practically impossible to
do
willy-nilly origin changes to your
window on Mac os10 because you're gonna
run into these two problems but you have
good reasons for wanting to change the
origin I mean it's it's a valuable tool
right so there are safe ways to do that
the one thing you need to keep in mind
is that the Control Manager really
really really wants a 0 0 origin
associated with the window that it's
drawing its controls in and in fact
every controls bounding rectangle must
be relative to a 0 0 origin in order for
the control manager to work properly for
instance if you have a default button in
the bottom right hand corner of your
window and you want it at position
200-300 relative to the windows top left
you need to make sure the controls
bounding rectangle is 200 300 and if you
do need to change the origin you want to
make sure you save and restore it
properly the way to do so is very
straightforward in order to determine
what a ports current origin is
unfortunately we don't have an API for
that directly but what you do is you get
the ports bounding rectangle just save
off the top left corner of the bounding
rectangle that's its origin then you can
change the origin to whatever you need
it to be do your setup and other drawing
when you're done drawing restore the
origin to the way it was before and let
me go into a little bit more background
about why the pulsing buttons jump just
to give you a better feel of exactly why
this problem happens if you have your
control with a bounding rectangle whose
top-left is 0 0 and your framework or
your application would make sure to
adjust the origin such that it's
negative 200 300 before it draws the
control hoping that the control really
will draw down you know 200 pixels down
at 300 pixels to the right of the
windows origin that's going to work if
and only if you have explicit time to
set up the port before you ask that
control to draw however because controls
draw in timers you don't have that
pre-flight chance and in fact when it
controls timer fires it can't make any
assumptions about the current port and
this is also a general rule you'll need
to follow yourselves when using carbon
event timers a timer might be firing at
some totally odd time like when menus
are down or when you're tracking in
another
trol therefore the origin may have been
set up to do something totally different
and your timer needs to set the origin
and things like the clip to something
very predictable and the control manager
for predictability sake sets the origin
to zero zero therefore if your buttons
top left hand corner is zero zero well
your buttons going to draw at the top
left hand corner of the screen or out
the window
sorry pattern alignment is not the only
pattern issue you're going to run into
and I'll like with it sometimes you want
to draw with a pattern you got a color
instead other times you'll want to draw
the opposite direction you got a color
and you wanted a pattern other times
you'll just see strange grey backgrounds
which look great and platinum but why
are they coming up in my aqua interface
and worse yet is a system seven white
background that's probably been in your
application for about the last five
years the reason this happens is because
pattern or sorry backgrounds under aqua
can be either colors or patterns and
your application needs to be aware of
that needs to be expecting it quick
draws behavior when there is a pattern
in the current port is to draw using
that pattern not necessarily the color
you've set up so if you use an
appearance manager API to set up a
pattern for your window and then a
little while later you change the color
to white because you want to draw some
area white then you go to erase and all
of a sudden the pattern comes up but but
I just set the color to white why is
this pattern coming up well simply
speaking that's because the pattern is
still in the port and that's what
quick-draw is going to use so in order
to make sure that you don't have
unwanted patterns associated with the
current port you can call normalized
theme drawing state now this API was
introduced and I believe the Mac OS at
8:5 time frame and it was designed to
just do a quick wipe of the current port
settings such that it's in a very
predictable clean drawing state it will
make sure to eliminate any pattern
that's in the port it will set the
foreground color to black the background
color to white and tweak a few other
things to make it more predictable
now these theme drawing state API is
also have a saver and restore which are
very useful if you want to make sure you
don't disrupt the system's use of
patterns in some
all that or possibly in a carbon
eventhandler and you use the safe safe
theme drawing state and restore theme
drawing state to save and restore the
theme drawing state they will pass back
out and opaque reference to a whole
bunch of settings you hang on to these
settings you can do your own court
preparation often with normalizing
drawing state or other preparation do
your drawing and finally when you're
done you call restore a theme drawing
state and passing the opaque object and
it'll set things back up the way they
were before now if you happen to be
drawing grey backgrounds in your windows
just because well that's what you always
did and that's what looked right in
platinum and I didn't know we had to use
these appearance manager api's well you
know what you got to use these
appearance manager API is to draw the
aqua back on the Aqua patterns and in
fact these same appearance manager api's
will let you draw the right thing on
carbon live on mac OS 9 and the
appearance manager supports a whole
bunch of different backgrounds and
they're they're tagged sort of a high
level with the notion of theme brushes
and theme backgrounds and theme brushes
are like I said used in a high-level way
you tell the appearance manager what
sort of background for what case you're
drawing in you might say I'm drawing in
an active dialogue right now or I'm
drawing a toolbar background right now
or even I want to draw a bevel Button
Center Phil can you please set that up
for me so we've got several dozen sorry
several dozen theme brushes and beam
backgrounds in appearance H you can go
ahead and take a look there and see
which ones you want to start using in
general you want to use the dialog alert
utility window toolbar backgrounds
things like that that'll get you the
proper aqua lines on Mac os10 and I'm
platinum they'll draw the proper gray
now the way you use these is typically
through set theme background and set
theme pen set theme background takes a
theme brush and talks to the appearance
manager figures out what color or
pattern needs to be applied to the
current port and then applies it to the
current port set theme background
applies it to the background so you can
follow that up with an erase rect or any
other quick draw API that might erase
set theme pen applies it to the
foreground so you can follow that up
with any quick draw
that's going to paint now as I mentioned
before there's this set themed window
background API well how is this
different from set themed background you
might ask set themed window background
associates a theme brush with a window
on a kind of permanent basis you can
come in later and call set themed window
background again and set up a different
theme brush to that window but generally
speaking it's remembered until your next
call this a themed window background
whereas set themed background
transiently just applies this background
setting to the port and it can be get
stomped upon later now the other cool
aspect about set pane window background
is it lets the window manager be a lot
more efficient because there's this
brush constant permanently associated
with the window the window manager can
use it when it needs to paint a window
as it comes on screen for the first time
and this saves a lot of time and a lot
of your hassle because in a normal
situation the window might paint white
and then later you'll get an update
event and then you'll draw the lines and
you really don't want to be seeing that
sort of flicker on that go stand under
aqua that's kind of crummy so you should
start using the set theme window
background API to associate a theme
brush with your window there's one other
theme background API and that's called
apply theme background and it's a little
bit different it's essentially similar
to set theme background in that it takes
a theme background constant and shoves
it shoves the right color or pattern
into the current port but the difference
here is that apply theme background also
takes a rectangle to align that
background to the classic example of
this is tabs or group boxes the
background that fills a tabbed pane
doesn't want to align to the windows top
left-hand corner it wants to align to
the top left-hand corner of the tab pane
itself so that's why you need to pass in
a particular bounding rectangle and
we've got several theme backgrounds that
are useful for lighting background in
the right sorts of cases you can take a
look at a parent set H to find those as
well
so non aqua text is sort of a sticky
issue when you bring your app up you see
all these really wacky white halo
problems really ugly visual things you
fix all those and you go yeah I think
I'm done I think I got it ready but you
kind of glossed over the fact that your
text doesn't quite match up and you
might be really tempted to just leave
your application that way but please
don't it looks really really crummy
compared to the rest of the aqua text
and there's another downside in that the
ugly text is not only ugly but it's
totally Unicode on savy it's drawn with
mac and coding characters you can't have
mixed run strings you know that your
file system might have a file name that
has five different languages in it using
five different fonts to display it and
if you try to render it with the api's
are currently using you're going to get
to just get jumbled garbage and it's
going to look just horrible and the
reason it looks bad is because you're
using the old quick draw text drawing
api's now there's a number of ways you
can make your text look really good
under aqua the most straightforward way
is to adopt the system control
definitions window definitions and menu
definitions as much as possible the more
you adopt those the less work you have
to do in the first place
all of these def procs have been revved
to use aqua text where it makes sense
now there's actually a few exceptions to
this the most obvious one is the
old-school edit text control the
old-school edit text control is going to
forever draw with quick quick draw text
because it's forever associated with
TextEdit and we're not bringing TextEdit
forward so if you really want to do
proper aqua Savi text editing you should
use the Unicode edit text control and
like the rest of our aqua text story not
only does it look good but it also fully
supports Unicode multiple languages and
stuff like that and if you have certain
static text areas on your screen that
you're using quick draw text api's to
draw directly one easy way to make those
aqua savvy is to begin using the static
text CDF instead the static text CDF is
really good for simple needs when you
just want to draw a little caption or a
little label on top of something and
using the control managers embedding
support it'll let you draw on top of
most arbitrary backgrounds and if you
don't like the overhead of you
control or if you need a little bit of a
quicker solution you can always use the
theme text API I'm going to talk a
little about a little bit more about
that in a slide or two and if that
doesn't work out for you you can always
use atsui or M LTE now these are the
lowest level ways for a carbon app to
draw aqua Savi text it's a little more
complex to set up and use but it gives
you a heck of a lot more flexibility and
a little bit better performance
the downside of using these api's is
there is not currently a way to get the
proper theme fonts for given situations
to use them with at Hsu E and M LTE this
is something that we're going to add in
the future but for right now if you use
Atsui nm LTE you might see a few strange
misses when you try to render mix
language text so the quick and easy
solution to get this aqua text is use
via the theme text api's we've got api's
to do drawing and measuring and
truncation and essentially they're meant
to be very easy replacements for the
quick draw text routines you've already
been used to if you're using draw text
or draw string or te text box you'll
want to use draw theme text box likewise
if you're using text width or get theme
font info to determine widths and
Heights you can use get theme text
dimensions now certain theme text draws
shadow outside of it
- best examples are window title bars
and push button fonts and you can
determine the amount outside of your
text that the shadow will draw be it
again theme text shadow outside API this
returns a rectangle and each of the
coordinates of the each of the fields of
the rectangle tells you how far out each
of the sides the shadows will draw so
you can take that into account if you
need to clip or do some other stuff like
that and if you were using trunk string
or trunk text to do your truncation you
can easily switch over to truncate theme
text all of these theme text api's are
unicode savvy they take CF strings and
they're fairly easy to use I tried to
model them after the quick draw text
routines that they were placed so
they're pretty easy to just swap in and
out very easily and all of these theme
text API is also take the notion of a
theme font ID and theme font IDs have
actually been around for a while the
appearance manager supports a way of
asking what font will I draw and if I
want to draw on the system font
we had the support I believe in the Mac
OS 8 timeframe but we took these theme
font IDs forward added a whole bunch
more and what they essentially are is an
opaque way for you to say you know what
I want to draw a push-button font or I'm
going to draw on the system font or I
want to draw on the window title font
and the cool thing about the theme font
IDs is not only do they specify one font
they also specify that font size and
it's shadowing effects but even cooler
it will resolve to more than one font if
the string you are about to render has
more than one language in it you can
give us one C F string that contains
Roman text Japanese text in the future
Korean text and stuff like that and we
will render that one string in multiple
fonts as we see it's necessary and of
course if you call the measuring api's
we're going to return accurate
measurements for all the variety of
fonts that we're going to end up using
now the theme font IDs that we offer is
only a family of about a dozen of them
and you might have more custom needs if
you have custom needs you can use the K
themed current port meta font this meta
font lets you set up the current port
with whatever texts text font size style
and face you want and the appearance
manager routines will pull that
information out of the current port map
it into the right data structures for
Atsui
and end up rendering aqua text with it
unfortunately there's a few limitations
it doesn't support all styles we don't
support outline and shadow styles
because the underlying engine Atsui
doesn't support either of those and
likewise you don't get the proper aqua
shadowing effects the only way to get
aqua shadowing effects is to use the
theme font ID which maps to one of those
shadowing effects in the last downside
is that it's it's got suboptimal Unicode
support if you pass in a Unicode string
with multiple languages and languages in
it we're going to do our best to guess
the right fonts for that and we're going
to accurately render the glyphs but the
fonts we choose to render other text in
let's say Japanese text or Korean text
if you're in an otherwise Roman
application
those fonts may not match visually very
well with the one font you specified in
the current port so that's one of the
drawbacks using the the current port fun
and you want to stick with the
higher-level theme on API sorry
higher-level theme font constants as
much as you can now the theme text API
is don't actually do anything with the
color theme font IDs don't actually
imply a color we let you choose what
color you want to draw the text in
entirely on your own and the easiest way
to do this is via the set theme text
color API set theme text color like the
draw theme text API has a constant a
family of constants which lets you tell
us what sort of thing you're trying to
draw text on you can say I'm trying to
draw text on my active dialogue where
I'm trying to draw text on an inactive
dialogue and those two theme theme text
colors will resolve into different raw
colors to draw the font width in the
active case we're going to draw with
black in the United II case we're going
to draw with the proper gray we have a
whole bunch of these theme text colors
pretty much on a one-to-one
correspondence with the various theme
buttons and theme font IDs that you
might be used to from the appearance
manager now if you've had a chance to
use the theme text api's most of you
probably said yeah this works this is
pretty good but some of you might be
trying to draw a whole lot of text and
give it a window and well you know the
theme text API is are going to be a
little slow there are a couple ways to
deal with this and make the theme text
API is faster the best way is to take
advantage of the cg context ref
parameter that draw theme text box
allows you to pass in if you've had a
chance to attend any of the courts
drawing sessions you'll know that a cg
context ref is an opaque reference it's
kind of like a quartz graph port it
stores all your drawing settings that
you want to use if you don't pass one of
these into the dropping text box API
we're gonna create one for you and
that's okay and we're gonna even pull
certain settings out of the current
court and apply them to the context and
that's also okay problem is that takes a
little bit of time so if you have 50
calls to draw themed text box and you
pass a null context rich ref to each of
those we're going to end up creating a
contact syncing it with the current port
50 times
and that's just some performance issues
you don't want to run into and if you
want to bypass this the right thing to
do is create your context ahead of time
set it up the way you want it with the
proper color and the proper clipping and
stuff like that and then pass that one
context in to each of your 50 dropping
text box calls that's probably going to
solve a majority of your needs but one
thing I found when I was revving certain
parts of the system to use these theme
text
routines is that they use the measuring
and truncation routines multiple times
before each draw and the static text
control for instance might measure its
bounds twice once to figure out what
rectangle to clip and then it might
measure the text again to know what
rectangle to pass in to draw a theme
textbox well that's silly and if your
applications doing the same thing it
should really stop every call to the
measurement routine is actually fairly
expensive we're working on making that a
lot faster through things like caching
but in general if you have redundant
calls to the measuring routines or even
the drawing routines I found a few cases
in my own code where I have that you
want to eliminate them and cache the
measurement values if you can for
instance if you're drawing a static text
item you might calculate the bounds for
that static text item once store it off
in your object pointer that represents
that static text item and then use that
bounding rectangle every time you draw
you don't even need to measure every
time before you draw cuz you've already
done the measurement once one other
thing we're working on besides the
caching I want to make a way possible
such that you can use Atsui and M LTE in
a proper theme font fashion so it gives
you total low-level custom control as
well as the proper unicode font stuff
that's not available now but it's
something I'm looking at for the
relatively near future I've talked a lot
about the Control Manager in the session
so far but a lot of the same principles
apply to the appearance manager you can
draw virtually any widget that the
control manager draws with the
appearance manager primitives we've got
low level primitives for drawing buttons
for drawing edit text frames focus rings
tabs group boxes all sorts of stuff and
the important thing to realize is you're
going to run into the same sorts of
visual issues if you draw with the
appearance manager primitives if the
appearance manager draws with alpha
the appearance manager sometimes needs
to erase we need to be aware of both of
these things and some of the appearance
manager api's allow you to pass in a
theme erase proc this theme erase proc
gives you a chance to erase properly
before the appearance manager needs to
render and again that erase should be in
quotes because sometimes you're not
literally erasing you're drawing
something behind the new widget you're
trying to draw and likewise the
appearance manager will draw outside of
the bounding rectangles you give it if
you give the appearance manager a twenty
pixels tall bounding rectangle to draw a
button well the shadows gonna go outside
that bounding rectangle the way you
determine how far outside is to use an
API like get theme button background
bounce this particular API tells you how
far out at the extreme case a given
widget will draw and so you can do
clipping or whatever else you need to do
with that and lastly we offer a new API
as part of carbon and Mac os10 called
get theme metrics generally speaking
widgets under aqua are about the same
size under platinum but there are a few
exceptions I think the tabs and tab
panes are a few pixels taller the amount
that a focus ring draws outside the
input rectangle is a little bit wider
edit text frames actually don't draw as
far outside the bounding rectangle as
they did on platinum but they draw
inside the rectangle somewhat now too
and we offer themed metrics for you to
ask for this sort of information there's
probably five or six dozen themed
metrics and the headers you can find out
how to have tall the tabs are how much
an individual tab overlaps the tab pane
and stuff like that alright so talked
about the control manager I've talked
about the appearance manager and they're
pretty much equal but which one should
you use generally speaking you want to
use the control manager there are some
things that the appearance manager just
can't do for you right now in some cases
the control manager implements certain
things directly itself the best example
of this is the pulsing button there is
no way to draw properly pulsing button
on Mac OS 10 right now if you use the
appearance primitives you must draw with
the control manager if you want those
but in the rest of the cases the
appearance manager works very very well
all right so you heard about the
problems well what do you do now the
best thing is go out there and start
aqua fiying
if you got a chance to see John's
session yesterday on adopting aqua aqua
stoat aliy level the playing field a lot
of applications are just getting on
board now and this is your chance to go
out there and really polish your user
interface and really step over your
competition and show hey you know what
we've got this great interface and the
users will really like that a crummy
interface really taints the user
experience the first time you launch an
app you see all these funky visual
problems you're gonna go whoa well they
didn't spend much time working on the
interface I wonder how much time they
spent working on the code is this app
gonna crash and it just puts a bad taste
in your mouth so you want to make sure
your application is as aqua pretty as
possible take advantage of shadowing as
much as you can do the themed tech stuff
as much as you can and final word I want
to make is that the carbon high level
tool box is a perfect way to deliver
carbon applications yeah we've got a few
shortcomings but we're working on that
but I want to assure you that we're
bringing the high level tool box forward
you saw yesterday's window and menu
manager session we've added a lot of
features there we've added a bunch of
features in the control manager I'm
going to talk about it at the session
after this and we're going to continue
enriching the control window menu and
all the high-level tool box managers so
with that I would like to do some QA and
go through the roadmap and so I'll bring
up John Lindsay
all right thanks guys so the road map
just talks about some other sessions
that relate to this material and that
are really to the topic of user
experience on necklace 10 the second
session which is just right after this
one right here so you don't even need to
move is 120 controls appearance we're
guys just gonna keep talking about the
same sort of stuff doc animating doc
icons that sort of stuff and continue on
this track and then the feedback forum
for the high level toolbox it's a great
opportunity for you to come and give
your feedback as to things that you
think are missing in terms of controls
or functionality within the appearance
manager whatever relates to a high level
toolbox then session 112 which is today
at 2:00 p.m. I believe no that was
yesterday so watch it on DVD designing
and easy aqua icons I talked about that
one in at the end of my session 111
yesterday which is a great session to
come to to learn how to critique the
icons that are being designed for your
application then today Apple help
learning about how to do a good help
system and provide user assistance with
your product content and it's speech
recognition and synthesis fantastic
session to learn how to add speech
synthesis or recognition to your
application and really extend the user
experience on Tim and then yesterday is
114 which if you didn't get there watch
it on DVD and then some other sessions
that that were yesterday or the day
before so let's get into the QA this is
my contact information if you have any
comments about this session or if you
have feedback in terms of what's
supported within high level tool box or
within carbon in terms of user interface
please get in touch with me
you