Create a Resizable AS3 ToolTip with OOP

In this tutorial we will create a ToolTip that automatically resizes itself. Our ToolTip will update its contents according to its position on stage, so that they are always visible. As part of this task, we'll also create our own code to handle 9-slice scaling.


Preview

Let's first take a quick look at our tooltip in action:


Step 1: Set Up FLA file

Let's begin by creating a new folder called "ToolTip". Inside the ToolTip folder, create an ActionScript 3.0 FLA.


Step 2: Creating the DisplayOjects (Sprites):

Now, create a rounded square of 150x77px with the following properties:

Select the rounded square and press F8 key to convert the square into a Sprite. Apply the config below:

Draw a picture (17x17px) similar to the figure below:

Select the second drawing, press F8 key and apply the config below:

Save your FLA file.


Step 3: Set Up FlashDevelop

FlashDevelop is an ActionScript editor with many resources. You can download FlashDevelop at http://www.flashdevelop.org/community/viewforum.php?f=11.

FlashDevelop documentation can be found at: http://www.flashdevelop.org/wikidocs/index.php?title=Main_Page

Open FlashDevelop, then select: Project > New Project, to create a new project.

In the dialog box, set the options as in the next image.


Step 4: Creating the ToolTip Class

First, select the Project tab (if the Project tab is not visible, select: view > Project Manager).

In this tab you can see all files and folders of the project. Right-click the ToolTip folder, then select: Add > New Folder and create a folder called tooltip (lowercase).

Now, right-click the tooltip folder and choose: Add > New Folder and create a folder called display. Right-click the display folder and select: Add > New class.

In the dialog box, insert ToolTip as the class name and browse to flash.display.Sprite in Base class field.

Now, our project has the following structure:

And this is our ToolTip class (generated automatically):


Step 5: Creating the Utils Package

The utils package will help us in features related to Bitmap, Sprite and TextField. The idea is to follow OOP practices, making this package reusable.

So, let's create the utils package. Right-click the tooltip folder, then select: Add > New Folder and create a folder called utils.

Create the BitmapUtils class inside this folder:

Create too, the SpriteUtils class:

Finally, create the TextFieldUtils class:


Step 6: BitmapUtils Class

The BitmapUtils have a single static method that take a snapshot of a IBitmapDrawable instance.

Here is the code:


Step 7: SpriteUtils Class

This class adds a Sprite to the display list:


Step 8: TextFieldUtils Class

This class easily creates a TextField instance.

I highly recommend reading the TextField class description to understand all the properties used.


Step 9: Resizable Background Concept

To create a resizable background, we will be using the concept of 9-slice, similar to the 9-slice scaling built into Flash. Sadly, the native 9-slice within Flash does not meet our needs.

The idea is to slice the source (Sprite) in 9 parts (see the image:)

When the width of background is altered, the parts 2, 5 and 8 are stretched horizontally, while the other parts stay the same.

Likewise, when the height of the background is altered, parts 4, 5 and 6 are stretched vertically, while the others don't change.


Step 10: The Matrix Class

The Matrix class creates a points map to be used in many forms. For more information, please read the documentation of the Matrix class from Adobe's site.

We will use the Matrix class to translate the source of background and so, draw the parts. In fact, the Matrix class does not affect the movement of translation in the object automatically, it only stores the values that the object would have if the motion was carried. This enables you to use an instance of Matrix in various ways without being locked into a DisplayObject.

For example, to draw the second image, we must take into account the position (x = 0 y = 0) and size (10 x 10px) of the image 1. It will apply the translation (without affecting the source) and only after that draw the second part. Example:

The identity() method can be used to reset the Matrix. If we do not reset, it will perform new calculations based on values previously stored.


Step 11: The CustomBg Class

To create the CustomBg class, create a new package called bg inside the display package. Create new class inside this folder called CustomBg. This class must extend Sprite.

Here is the class:


Step 12: The Constructor

Let's now deal with the Constructor parameters, class properties and imports. We need to import all the classes below to complete our class:

Now, create two properties:

The constructor must contain the following parameters:

In the constructor, we will slice the image.

First, we declare the variables. With the "Instance" and "source" vars, we attach our background (Sprite) to the CustomBg class. In the "parts" variable, we store the drawn parts of the background. Finally, with the "m" variable, we get the translation values and use them to draw the parts of our CustomBg.

Here is the code:


Step 13: Update the Parts' Positions

Every time the background is resized, the position of the parts must be updated. Let's create the arrange() method, to update the position of all the parts of background:


Step 14: Width and Height

Finally, we override the width and height methods of Sprite class, to resize and update the positions of the parts:

Now, we have a resizable background that does not suffer distortion when it is resized. See the preview:


Step 15: The Singleton Design Pattern

Design patterns are programming methodologies that offer solutions to common problems in software design.

We will create a ToolTip class under the aspects of the Singleton design pattern, which gives us a class that has just one global instance across the entire project. Think: you want to use the ToolTip in a menu with several buttons. It would be unnecessary and impractical to create an instance of the ToolTip class for each menu button, since we can only display one ToolTip at a time. The best approach in this case would create a global instance for the entire project and use methods show() and hide() to control the display.

The Singleton design pattern will prevent calling the class constructor; it creates an instance of the class within itself, and always returns via a specific method. Please note our Singleton implementation:

In the example above, we can see the declaration of a static instance. It will always be returned by the getInstance() method.

In the constructor, we require a parameter that can only be declared within this class, since this parameter is of type Singleton and this data type only exists inside the class. Thus, if we try to instantiate the class through the constructor, an error is generated.

The getInstance() method checks whether the variable was declared; if it has not been declared, the method getInstance() declares the instance and then returns it. If the instance has already been declared, the getInstance() just returns the instance.


Step 16: TweenMax Class

Jack Doyle's TweenMax is a tween engine which is often mentioned on Activetuts+. It allows you make tween animation easily.

The TweenMax library and its documentation can be found on GreenSock.com.

In our case, we will use the TweenMax class to add shadow and also to display and hide our ToolTip. Here's a brief example of the syntax of the class TweenMax:

Now look at a simple use of the class TweenMax:

See the example code used to achieve this:


Step 17: Adding Instances to Stage

We will add the objects on stage with the aid of our previously created classes and two methods. We must add a listener for the event Event.ADDED_TO_STAGE to avoid null references to the stage.

Update the constructor and add the two methods below:


Step 18: Event.ENTER_FRAME listener

Our ToolTip will always appear near the mouse cursor.

In order to know which aspect the ToolTip should appear, I divided the stage into a grid of nine squares (using calculations; I have not used DisplayObjects). Only six squares would be enough, but I created nine squares so that you can change the behavior of square 3, 4 and 5. In this case the count is zero-based.

The mouse cursor will always be in touch with one of these squares. Based on this, I know how I should draw the ToolTip. Roll the mouse in the squares below:

In the onFrame() method, I check which square your mouse cursor is in and then make a call to arrange(style:int), passing as parameter the number of the imaginary square, so that it draws the ToolTip as I wish it to. I used one-line statements because they are faster.


Step 19: Arrange Function

The arrange() method updates all elements of the ToolTip based on the value received in the parameter.


Step 20: Show Function

The method below does not need much explanation; it's self explanatory.


Step 21: Hide Function

I created the onCompleteHide() method which will be executed after the end of instruction TweenMax (this is done through the following statement: onComplete: this.onCompleteHide). It will remove all elements from the stage.


Step 22: Instantiation and Use

To use our ToolTip, I suggest you add it to the DisplayObject that is at the highest level (eg DocumentClass). Having done this, simply call the methods show() and hide() when needed. Here are two simple examples of using the ToolTip:

Alternatively:


Conclusion

I Hope you liked this; I created this tool using best object-oriented programming practices with the objective of processing speed, reusing classes and low system consumption. See you in the next tutorial! Thanks!

Tags:

Comments

Related Articles