WWDC2003 Session 425

Transcript

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