| Download
the Open Source Here
Smoothing windows...
make them glide
:)
(Odd Shape
(or Transparent) Window
Development PART
2)
Provided by Jorge
Rodrigues
The main idea is to create
a window similar to the
masked 1 bit windows but
with soft borders.
This windows have slower
performance than the masked
windows, as Director doesn’t
support alpha channel
for windows mask we will
need to trick it using
an screen capture of the
desktop. To do this we’ll
need an xtra that lets
us to capture the entire
screen.
I’ll use the
“ScrnXtra”
v2 witch is useful
and free from the same
creator of “FileXtra”
Kent Kersten.
You can download this
Xtra from:
http://kblab.net/xtras/
NOTE:
Inorder for the download
to work you will have
to do 2 things:
#1 Download the xtra (and
put it in the Xtra forlder)
#2 Create a projector
out of the "start.dir"
The "start.dir"
opens the the file named
"miaw.dir"
and that is in a folder
named "assets".
Look at the "start.dir"
and notice how it opens
the "miaw.dir"
as a Movie In A Window.
This is what allows you
to get rid of the 1 pixel
border around the standard
window.
The first thing we’ll
need to do is to create
the main interface.
This interface should
have an alpha channel
so this will let we give
the illusion of smooth
borders (in this case
it will be smooth shadow).
Then we need to make the
1 bit bitmap for mask
of the MIAW. This mask
will be based in the alpha
channel of our interface.
Once we have the interface
finished we need to crop
it using the alpha information
so we can be sure that
there are no empty pixels
out of the alpha channel
and this will also lets
us make the 1 bit bitmap
mask for the MIAW easily
because this mask will
never exceed the limits
of the alpha channel so
in Director both of them
( the interface and the
1 bit mask ) will have
the same size, and also
the movie should be of
the same size so everything
fits.
To create the 1 bit bitmap
you can apply a threshold
of 245 – 255 to
the interface in your
painting software. I prefer
to make this mask a bit
smaller than the alpha
channel as nobody will
see an alpha of level
254 in most cases. I recommend
you to make this 1 bit
mask as small as possible
because this way to create
soft borders have some
disadvantages and one
of them is that you will
see some kind of distortion
when drag the MIAW so
making the mask small
will reduce the possibilities
to see this distortion.

Remember when you import
the images into Director
to make sure that the
mask image is 1 bit. If
you didn’t save
it as 1 bit bitmap you
can convert it using the
Director image editor.
Double click in the “color
depth” and then
change the color depth
to 1 bit.

The first thing to do
is to make the size on
the movie fits with the
size of our interface.
In this case our interface
and our mask are 335 x
335 pixels so the movie
size is 335 x 335 pixels.
Now we have all the pieces
we need to arrange them
into Director. Create
a new bitmap of the same
size of the stage and
put it in the lower sprite
channel ( sprite 1 ).
We’ll use this bitmap
to copy part of our screen
capture into it. Then
add the interface image
to the sprite channel
2.

As we want to capture
an screen without our
own window we’ll
need to hide it before
the screen capture occur
so lets add some lines
to a movie script.
In the preparemovie
we are setting up the
mask for the current window
from the member “I_mask”
which is our 1 bit member
and then hiding the MIAW
( for better performance
you should set up this
in the projector before
open the MIAW ).
on
prepareMovie
(the
activeWindow).windowType
= member
("i_mask")
(the
activeWindow).visible
= false
end
In the movie script we
also have two more handlers:
As we’ll be capturing
the screen from an score
script the on
activateApplication
handler will lets us capture
a new screen every we
activated the application.
This is because the user
could change the background
that we captured before,
for example change to
another application. So
every time the user active
our application we’ll
capture a new screen.
on
activateApplication
go
to
1
end
And when we change to
another application just
hide the MIAW so it will
not appear in the next
screen capture.
on
deactivateApplication
(the
activeWindow).visible
= false
end
Because the ScrnXtra
needs a member to put
the captured image we
first need to create a
bitmap and give it a name.
NewBitmap = new(#bitmap)
NewBitmap.name
= "myScreen"
Now we have created the
bitmap member we’ll
proceed to capture the
screen. As this xtra doesn’t
required to be initialized
we just call the ScreenToMember()
function. We need to pass
the rect we want to capture
and the the destination
member.
To determine the rect
of the screen we use the
desktopRectList,
as we know that screen
coordinates always start
at point 0,0 the data
we need is the lower right
point.
ScreenToMember (0,
0,
(the
desktopRectList)[1][3],
(the
desktopRectList)[1][4],
"myScreen")
Then we’ll store
the image of this bitmap
member in a global called
myScreenPicture using
the duplicated()
function. Then just erase
the member ( not really
necessary but in authoring
it will not create a new
member every time we play
the movie ).
myScreenPicture = NewBitmap.image.duplicate()
NewBitmap.erase()
To end the screen capture
script we just update
the window content with
the information we got
from the screen of the
user ( the updateWindow()
handler is stored in another
script attached to the
background image ) and
then make the MIAW visible.
sendAllSprites
#updateWindow(
point
(0,
0)
)
(the
activeWindow).visible
= true
To drag the MIAW and
update the content of
it to create the illusion
of the smooth borders
we need to create another
script. This time the
script should be attached
to the background sprite
( you can modify this
script to have a separated
image to use as dragger
)
So, on mouseDown we just
call a separated handler
“updateWindow”
( the same we called from
the score script before
). This handler is a new
version of the script
I made for the dragBar
tutorial so take a look
at the other tutorial
to see how it works (
is really simply )
on
updateWindow (me,
Np)
Aw = the
activeWindow
M = Aw.rect.offset(Np[1],Np[2])
my.member.image.copypixels
(myScreenPicture, my.member.rect,
M)
sendAllSprites
#updateEffect
(my.member)
updatestage
(the
activeWindow).rect
= M
end
The main difference with
the previous script is
that this time I’m
using the offset function
instead of a large list
of points :)
As the screen capture
and the monitor have the
same coordinates we just
need to calculate the
new rect for the MIAW
and the background image
once. Then we just copy
the pixels we get from
this rect into our background
bitmap. Remember we are
coping pixels from a global
called “myScreenPicture”
which was created in the
screen capture script.
my.member.image.copypixels
(myScreenPicture, my.member.rect,
M)
The next line just call
another script to create
the lens effects. Really
simple, you can see it
in the source code.
sendAllSprites
#updateEffect
(my.member)
Then we’ll send
an updatestage command
before move the window.
At this point I need to
say that I couldn’t
find a better way to do
this but it’s still
slow :(, so here is where
you’ll see a little
delay when drag the window.
Biggest windows largest
delays. This is the reason
why we need to create
a 1 bit bitmap to mask
the MIAW so we reduce
the area where this delay
is visible as much as
we can.
In this movie I’m
using a big area in the
center where you can see
it clearly, but not all
of the MIAW’s needs
to have this big dirty
glass. So for common MIAW’s
where you only want to
have smooth borders or
shadows it should work
fine.
Finally we move the window.
As I guess that the rect
of the window redraw faster
than anything else, remember
to send the updatestage
before move it. Also try
to move the updatestage
after move the window
and then you’ll
see a really big delay.
(the
activeWindow).rect
= M
Coming soon we’ll
see other things we can
do with smooth windows
and it’s rect.
|