| Download
the Open Source Here
CUBIC stub MIAW
Tool
Provided by Jorge
Rodriguez
The first thing you need
to do when you want to
create a tool is to define
the main points. What
the main points are? Well
the objectives of the
tool and the functions
it will have. Not the
interface, for now. Also
if it should be updateable
or not.
It should be able to run
any Director project just
for test the window appearance.
It will not have updates
( this limit the design
of the interface and also
the programming).
The program will have
this functions:
An open button ( to open
the MIAW).
As many buttons as windows
type are, including the
mask.
An info panel to display
the info for the type
of window selected.
An special add only when
you set the mask type.
This add should have:
An open, invert
and apply button to work
with the mask.
A preview window
to display the current
mask.
Info panels with
the MIAW size and the
mask size to check if
both have the same size.
A drag bar and close button.
Once you have defined
the main points you can
start to planning how
the interface should look.
Go to your deign or painting
program and create the
main look including the
states for the buttons.
You can include the states
of the buttons in the
main points if you want
if you are working in
a big project, but in
this case this is not
really important. So the
interface look like this:

Then you need to slice
the interface. At this
point you need to think
in the functionality because
you need to break apart
the pieces into “interactive
pieces” like buttons,
drag bar, scroll bar,
etc. and “background
pieces”.
Why you need to do this.
Well, because the you
can attach different behaviors
in Director that will
assign to the different
images different functions.
You also can create a
big image (including all
of the states buttons)
and then use Lingo to
draw specific parts at
specific points but this
is a more complex task
and also a more time consumer.
So we will break apart
the different image like
this:

Now we need to import
all the pieces into Director.
To do this I prefer to
create a separate castlib
just to keep the things
clear. It will let you
find things more ease.
So, is a good practice
to create different castlib
for different type of
resource. For example
if you have to many different
buttons create a separated
castlib just for the buttons,
also if you have to many
sounds, fx, videos and
so on. Keep in mind that
if you use different castlib
then you will need to
call the member by their
names or by their position
in the specific castlib.
Then create the text members
for the info and array
them in the stage (see
the source file)
This script first clear
the list of the windows
in case there are a window
opened and also remove
it from the memory. Then
create a new window which
name is an empty string
(“”) and assign
a type with the ”windowType
= WinTape”.
WinTape is a global with
the value for the current
window. Also assign a
title to the window (“MIAW”)
and finally open it. The
command SendAllSprites
is used to actualize the
text member with the size
info ( you can see this
text member only if the
window type is mask).
global
WinTape
on mouseUp
the windowList = []
window("").forget()
window("").windowType
= WinTape
window("").title
= "MIAW"
window("").open()
SendAllSprites #GetSizes
(the stage).moveToFront()
end
This handler is
attached to the buttons
that select the windows
type. It case the names
of the member to apply
the correct number for
windowtype and also to
update the text member
with the info about this
type. Note that “W
01 – 1”, “W
02 – 1”, etc
are the names of the buttons
members. Because all of
this buttons have the
same behavior, we need
to know which member was
pressed to set the correct
windowtype.
The handler is incomplete
here. See the source file
for a complete behavior.
on
ApplyWindow
case my.member.name of
"W 01 - 1":
WinTape = -1
member("Description").text
= "Movable, sizable
window without zoom box.
Default window"
"W 02 - 1":
WinTape = 1
member("Description").text
= "Alert box or modal
dialog box"
end case
end
Also this behavior have
handlers to set the correct
state of the buttons.
The myOn and myOff properties
store the members of the
buttons ( both states).
Note that the member are
arrange in order in the
castlib so member 14 is
the state off of the first
button and member 15 is
the state on of the same
button and so on.
On mouseUp the command
“sendAllSprites
#MyWindowOff”
sets the states of all
buttons that have this
behavior attached to off
state and then change
the member for itself
to the on state. Then
call the handler “ApplyWindow”
wich was explained before.
The mask button is a bit
different from the rest
because it will expand
the stage rect to display
the mask options.
on
beginSprite me
my = sprite(me.spritenum)
myOn = (my.member).membernum
+ 1
myOff = (my.member).membernum
my.cursor = 280
if my.member.name = "W
01 - 0" then my.member
= member(myOn,2)
end
on mouseUp
sendAllSprites #MyWindowOff
my.member = member(myOn,2)
ApplyWindow
end
on MyWindowOff
my.member = member(myOff,2)
end
This button will
not apply the mask immediately.
When you press it the
movie advance to next
mark. At this point there
are an score script that
will expand the stage
to display the mask info.
After that the mask will
be displayed. This is
just to make sure that
the stage is completely
expanded before the mask
is applied because some
masks can take a few seconds
in redraw the MIAW.
This is the score script
that will enlarge the
stage. First it store
the stage rect in the
variable A. The rect of
the stage (or a MIAW)
is a list with two points
(upper-left and bottom-right)
to draw the rectangle
of the stage, so changing
this points you can alter
the stage position and
also it size. So this
list have 4 values ( remember
that each point have 2
values x,y) and for short
syntax you could know
this values with rect[1],
rect[2], rect[3], rect[4].
The script also move the
sprite(1) which is the
background of the mask
info. This is to give
the idea that a panel
is moving behind the stage.
Once the stage is complete
opened check if there
is a MIAW opened (if
the windowList <>
[] ) and then assign
the mask to the MIAW and
move to another frame
just to not repeat the
exit frame handler.
global
WinTape
on exitframe
A = (the activeWindow).rect
if (the activeWindow).rect[4]
< ((the activeWindow).rect[2]
+ 300) then
(the activeWindow).rect
= rect(A[1], A[2], A[3],
A[4]+28)
if Sprite(1).locV <
230 then Sprite(1).locV
= Sprite(1).locV + 28
else
WinTape = member("MASK")
if the windowList <>
[] then window("").windowType
= WinTape
go the frame + 1
end if
go the frame
end

This section is
divided in:
The “Load Mask”
button
The “Invert Mask”
button and “Preview
Mask” window
The “Apply Mask”
button
The panels with the mask
and MIAW size info
To preview the mask you
need to create an image
member. This member must
be a 1 bit image because
the mask only use a 1
bit images. If you want
you can use another bit
depth for this member
because is just for preview
but maybe youl’ll
not previewing the same
as the mask is.
This member will be used
as a buffer member just
to replace the preview
member when you was loading
mask and want to load
another mask. This part
is a bit complicated to
explain so pay attention
and use the source file
as reference.
- Create an image member
with the same size as
the preview window and
name it “MASK_T
Buffer”
- Set the bit depth of
it to 1 bit in the Director
image editor (see the
image)
- Duplicate the member
- Place the duplicated
member in the right place
into the stage (note that
at start the stage size
is smaller so the sprite
will be out of the rect
of the stage)
-Once you place the duplicated
member delete it from
the cast, but NOT delete
the sprite so the sprite
will maintain the position.
We will use it later.
- Open the member “MASK_T
Buffer” in the image
editor and erase it with
the eraser tool. Now you
have an empty member but
it still have the properties
of the image, so the member
is a 0x0 pixel image with
1 bit depth :).
Note than when the movie
start the member “MASK_T
Buffer” is duplicated
and also the name of the
duplicated is changed
to "MASK_T"
(Mask Thumbnail).
member("MASK_T
Buffer").duplicate
(2)
member(2).name = "MASK_T"
Now you have no more empty
sprite, is was filled
with the "MASK_T"
member. You’ll not
be able to see it but
it’s there. Also
at start this sprite is
out of screen but it will
appear when you press
the mask button.
This behavior use
an extra called “FileXtra3“
witch is a very useful
and free xtra to manage
files. You can download
at http://www.kblab.net/xtras
. In this case you also
can use FileIO xtra.
This xtra is just to create
a dialog box and to return
the path of the file.
It will NOT open the file,
just return the path and
assign it to a variable
NewImage.
Once you know the path
then the image is imported
into Director with the
importFileInto
command and renamed as
"MASK_S" ( mask
source).
This image is duplicated
to a new castlib position
and renamed to "MASK".
Note that the member "MASK"
is changed to a 1 bit
depth image with the image
command because we will
use it as a mask for the
MIAW and remember that
Director only support
1 bit image for mask.
There are some xtras to
create an 8 bit mask (witch
means that the window
could be transparent)
like AnyShape at http://www.starsoftmultimedia.com.
Finally it create the
preview image with the
handler SendAllSprites
#CreateMaskAndThumb.
We’ll see it in
the “Invert mask
button” section.
on
OpenImageFile
ThePath = the moviepath
TheImageType = "All
Formats/*.bmp;*.gif;*.jpg/BMP
(*.BMP;*.RLE;*.DIB)/*.bmp;*.rle;*.dib/CompuServe
GIF (*.GIF)/*.gif/JPEG
(*.JPG;*.JPEG;*.JPE)/*.jpg;*.jpeg;*.jpe"
fxObj = new(xtra "FileXtra3")
NewImage = fxObj.fx_FileOpenDialog("ThePath",TheImageType,"Choose
a image file", True,
True)
if NewImage <> empty
then
importFileInto member(3),
NewImage
member(3).name = "MASK_S"
member("MASK_S").duplicate(1)
member(1).name = "MASK"
Rsource = member("MASK_S").rect
NewMask = image(Rsource[3],
Rsource[4], 1)
member("MASK").image
= NewMask
SendAllSprites #CreateMaskAndThumb
end if
fxObj = 0
end
This behavior have
2 parts. The first one
create the mask and the
second one create the
preview image (also called
thumbnail)
To create the mask it
use the same syntax than
the OpenImageFile with
the different that it
use an opened image. If
there are no opened image
for mask it will show
an alert dialog box. Also
replace the actual preview
image with the member
"MASK_T Buffer".
This is because if you
use a different bit depth
image the preview may
be corrupted. Also is
used to be sure that we
are creating a preview
image by coping pixels
into a blank image. Just
to make sure. Then call
the handler CreateThumbnail
to create the preview.
Rsource
= member("MASK_S").rect
NewMask = image(Rsource[3],
Rsource[4], 1)
member("MASK").image
= NewMask
member("MASK_T Buffer").duplicate
(2)
member(2).name = "MASK_T"
CreateThumbnail
The CreateThumbnail handler
creates an proportional
image using the maximum
size as possible. Suppose
you have a mask of 300
x 200 pixels then the
Rsource[3] = 300 and Rsource[4]
= 200 witch means that
the image have more pixels
in width. If we know this
we will need to fit those
300 pixels into the maximum
space available for the
preview window and the
height to the proportional
size.
The concept should be:
If 300 = 100 then 200
= ? then
? = 200 * 100 / 300 then
? = Rsource[4] * 100 /
Rsource[3]
So the new image should
be 100 pixels width and
? pixels height. Replace
the ? by B and you’ll
get
NewThumbnail
= image(100, B, bits)
It should explain
by itself
This behavior just
get the size of the MIAW
and the mask image and
put this info into the
text members.
The window width is stored
in the variable W_x and
the height in W_y
W_x
= window("").rect[3]
- window("").rect[1]
W_y = window("").rect[4]
- window("").rect[2]
You can use this as well
W_x
= window("").rect.width
W_y = window("").rect.height
The mask width is stored
in the variable M_x and
the height in M_y
M_x
= member("MASK").width
M_y = member("MASK").height
Then assign this values
to the text members converting
the values to strings
and if the MIAW width
is different to the mask
width then change the
color of the text (for
the mask info text) to
alert there are differences.
Same for the height.
my.member.text
= M_x.string
if W_x <> M_x and
M_x > 0 then my.member.forecolor
= 35
else my.member.backcolor
= 255
If there are no values
if because there are no
MIAW or mask loaded and
fill the text member with
------
my.member.text
= "----"
The dragbar and double
click behavior
Well, they use the same
principle as the “Expand
Window” behavior
used to enlarge the stage
(see The mask button section)
. It just work whit the
rect of the stage. The
only difference is that
the dragbar use the mouseLoc
and the clickLoc
to calculate the rect
of the stage by adding
or subtracting the difference
between the points of
the mouseLoc
(witch is the current
position of the mouse)
and the clickLoc
( this point is stored
in memory when you make
a click, so it will be
the same value until you
release the mouse and
make another click).
repeat
while the mouseDown
A = (the activeWindow).rect
N = the mouseLoc - the
clickLoc
(the activeWindow).rect
= rect(A[1]+N[1], A[2]+N[2],
A[3]+N[1], A[4]+N[2])
end repeat
Well, this button just
do what it says. So if
we are here, I think is
time to close this tutorial
:)
Have fane and keep learning
:)
|