Sunday, November 11, 2012

Creating EasyTooltip class: Part 10

In this tutorial we add the ability to set maxWidth and maxHeight properties for tooltips.

Go to TooltipStyle and add 4 new public properties there - maxWidth, minWidth, maxHeight and minHeight. We're only going to add real functionality to maxWidth and maxHeight today though.

package com.kircode.EasyTooltip 
{
import flash.text.TextFormat;
/**
 * Used for visually styling tooltips.
 * @author Kirill Poletaev
 */
public class TooltipStyle 
{
public var backgroundAlpha:Number;
public var backgroundColor:uint;
public var textAlpha:Number;
public var textFormat:TextFormat;
public var textPadding:TextPadding;
public var offsetX:int;
public var offsetY:int;
public var maxWidth:int;
public var minWidth:int;
public var maxHeight:int;
public var minHeight:int;

public function TooltipStyle() 
{
backgroundAlpha = 1;
backgroundColor = 0x000000;
textAlpha = 1;
textFormat = new TextFormat("Arial", 17, 0xffffff);
textPadding = new TextPadding(5, 5, 5, 5);
offsetX = 0;
offsetY = 0;
maxWidth = 0;
minWidth = 0;
maxHeight = 0;
minHeight = 0;
}

}

}

Now go to TooltipCursor.as class and find the updateSize() function.

We will need to add a few if...statements to the code, in multiple places. In the very beginning of the function, check if the max values are 0, and if so - set them to the size of the parent:

if (style.maxWidth == 0) style.maxWidth = parentW;
if (style.maxHeight == 0) style.maxHeight = parentH;

Then we set wordWrap property of the text field to true, and calculate width and height:

txt.wordWrap = true;
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;

Then, if width exceeds maxWidth, set it to maxWidth. Same with height:

if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;

The part that calculates direction remains unchanged:

// calculate best direction
if (this.y <= parentH * 0.5) { 
direction = "bottom"; 
actual_y = -style.offsetY;
} else
if (this.y > parentH * 0.5) { 
direction = "top";
actual_y = -h + style.offsetY;
}

if (this.x <= parentW * 0.5) { 
direction += "right"; 
actual_x = - style.offsetX;
} else
if (this.x > parentW * 0.5) { 
direction += "left";
actual_x = -w + style.offsetX;
}

In the next piece of code we limit the width and height right after setting values for w and h. We also check if width doesn't exceed maxWidth in the while loop conditional.

// If sticks out on the left:
if(direction == "topright" || direction == "bottomright"){
// if tooltip sticks out of border - calculate shortened width to fit the content
if (this.x + actual_x + w > parentW) {
txt.wordWrap = true;
w = parentW - this.x - actual_x;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;
if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;
} else {
// if doesn't stick out, keep adding 1 pixel to the width until as much text is seen as possible
while (this.x + actual_x + w < parentW && w < style.maxWidth) {
w += 1;
// try turning off wordwrap and see if it still fits (as one line)
txt.wordWrap = false;
if (w > txt.textWidth + 4 + style.textPadding.left + style.textPadding.right) {
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
break;
}
txt.wordWrap = true;
}
}
}

Do the same with the next piece of code:

// If sticks out on the right:
if(direction == "topleft" || direction == "bottomleft"){
if (this.x + actual_x <= 0) {
txt.wordWrap = true;
actual_x = -this.x;
w = this.x + style.offsetX;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;
if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;
} else {
// if doesn't stick out, keep adding 1 pixel to the width (and substracting it from actual_x) until as much text is seen as possible
while (this.x + actual_x > 0 && w < style.maxWidth) {
actual_x -= 1;
w += 1;
// try turning off wordwrap and see if it still fits (as one line)
txt.wordWrap = false;
if (w > txt.textWidth + 4 + style.textPadding.left + style.textPadding.right) {
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
break;
}
txt.wordWrap = true; 
}
}
}

Full function code:

private function updateSize():void {
if (style.maxWidth == 0) style.maxWidth = parentW;
if (style.maxHeight == 0) style.maxHeight = parentH;
txt.wordWrap = true;
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;
if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;

// calculate best direction
if (this.y <= parentH * 0.5) { 
direction = "bottom"; 
actual_y = -style.offsetY;
} else
if (this.y > parentH * 0.5) { 
direction = "top";
actual_y = -h + style.offsetY;
}

if (this.x <= parentW * 0.5) { 
direction += "right"; 
actual_x = - style.offsetX;
} else
if (this.x > parentW * 0.5) { 
direction += "left";
actual_x = -w + style.offsetX;
}

// If sticks out on the left:
if(direction == "topright" || direction == "bottomright"){
// if tooltip sticks out of border - calculate shortened width to fit the content
if (this.x + actual_x + w > parentW) {
txt.wordWrap = true;
w = parentW - this.x - actual_x;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;
if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;
} else {
// if doesn't stick out, keep adding 1 pixel to the width until as much text is seen as possible
while (this.x + actual_x + w < parentW && w < style.maxWidth) {
w += 1;
// try turning off wordwrap and see if it still fits (as one line)
txt.wordWrap = false;
if (w > txt.textWidth + 4 + style.textPadding.left + style.textPadding.right) {
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
break;
}
txt.wordWrap = true;
}
}
}

// If sticks out on the right:
if(direction == "topleft" || direction == "bottomleft"){
if (this.x + actual_x <= 0) {
txt.wordWrap = true;
actual_x = -this.x;
w = this.x + style.offsetX;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;
if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;
} else {
// if doesn't stick out, keep adding 1 pixel to the width (and substracting it from actual_x) until as much text is seen as possible
while (this.x + actual_x > 0 && w < style.maxWidth) {
actual_x -= 1;
w += 1;
// try turning off wordwrap and see if it still fits (as one line)
txt.wordWrap = false;
if (w > txt.textWidth + 4 + style.textPadding.left + style.textPadding.right) {
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
break;
}
txt.wordWrap = true; 
}
}
}

}

Full class so far:

package com.kircode.EasyTooltip 
{
import flash.display.MovieClip;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFormat;
/**
 * The cursor that follows the mouse (if not set otherwise) and displays each tooltip.
 * @author Kirill Poletaev
 */
public class TooltipCursor extends MovieClip
{

public var txt:TextField;
private var style:TooltipStyle;
private var background:Shape;
private var w:int;
private var h:int;
private var actual_x:int;
private var actual_y:int;
private var parentW:int;
private var parentH:int;
private var direction:String = "";

public function TooltipCursor(pW:int, pH:int) 
{
parentW = pW;
parentH = pH;
txt = new TextField();
txt.multiline = true;
background = new Shape();
addChild(background);
addChild(txt);
}

/**
 * Set style of the tooltips.
 * @paramst TooltipStyle object to apply.
 */

public function setStyle(st:TooltipStyle):void {
style = st;
}

/**
 * Change the text value of the tooltip.
 * @parammessage The new text value.
 */

public function setText(message:String):void {
txt.text = message;
txt.setTextFormat(style.textFormat);
updateSize();
updateDisplay();
}

private function updateDisplay():void {
background.graphics.clear();
background.graphics.beginFill(style.backgroundColor, style.backgroundAlpha);
background.graphics.drawRect(actual_x, actual_y, w, h);
background.graphics.endFill();

txt.width = w - style.textPadding.left - style.textPadding.right;
txt.height = h - style.textPadding.top - style.textPadding.bottom;
txt.x = actual_x + style.textPadding.left;
txt.y = actual_y + style.textPadding.top;
}

private function updateSize():void {
if (style.maxWidth == 0) style.maxWidth = parentW;
if (style.maxHeight == 0) style.maxHeight = parentH;
txt.wordWrap = true;
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;
if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;

// calculate best direction
if (this.y <= parentH * 0.5) { 
direction = "bottom"; 
actual_y = -style.offsetY;
} else
if (this.y > parentH * 0.5) { 
direction = "top";
actual_y = -h + style.offsetY;
}

if (this.x <= parentW * 0.5) { 
direction += "right"; 
actual_x = - style.offsetX;
} else
if (this.x > parentW * 0.5) { 
direction += "left";
actual_x = -w + style.offsetX;
}

// If sticks out on the left:
if(direction == "topright" || direction == "bottomright"){
// if tooltip sticks out of border - calculate shortened width to fit the content
if (this.x + actual_x + w > parentW) {
txt.wordWrap = true;
w = parentW - this.x - actual_x;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;
if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;
} else {
// if doesn't stick out, keep adding 1 pixel to the width until as much text is seen as possible
while (this.x + actual_x + w < parentW && w < style.maxWidth) {
w += 1;
// try turning off wordwrap and see if it still fits (as one line)
txt.wordWrap = false;
if (w > txt.textWidth + 4 + style.textPadding.left + style.textPadding.right) {
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
break;
}
txt.wordWrap = true;
}
}
}

// If sticks out on the right:
if(direction == "topleft" || direction == "bottomleft"){
if (this.x + actual_x <= 0) {
txt.wordWrap = true;
actual_x = -this.x;
w = this.x + style.offsetX;
h = txt.textHeight + 4 + style.textPadding.top + style.textPadding.bottom;
if (w > style.maxWidth) w = style.maxWidth;
if (h > style.maxHeight) h = style.maxHeight;
} else {
// if doesn't stick out, keep adding 1 pixel to the width (and substracting it from actual_x) until as much text is seen as possible
while (this.x + actual_x > 0 && w < style.maxWidth) {
actual_x -= 1;
w += 1;
// try turning off wordwrap and see if it still fits (as one line)
txt.wordWrap = false;
if (w > txt.textWidth + 4 + style.textPadding.left + style.textPadding.right) {
w = txt.textWidth + 4 + style.textPadding.left + style.textPadding.right;
break;
}
txt.wordWrap = true; 
}
}
}

}

}

}

You can now go to main.as and set max width and height values using the style object:

var myStyle:TooltipStyle = new TooltipStyle();
myStyle.maxWidth = 200;
myStyle.maxHeight = 100;

tooltip = new EasyTooltip(stage, stage.stageWidth, stage.stageHeight);
tooltip.setStyle(myStyle);
tooltip.addListener(object1, "This is a piece of a longer text. It should fit in the visible area.");
tooltip.addListener(object2, "This is a piece of a longer text. It should fit in the visible area.");

That's all for today!

Thanks for reading!

No comments:

Post a Comment