Adding images inside a Tooltip in Flex 4 - actionscript-3

I am trying to insert images and other html content inside a Tooltip in Flex 4 by making the text htmlText similar to this:
http://blogagic.com/190/easy-flex-tooltip-customization-using-html-tags
My HTMLToolTip class:
package custom
{
import mx.controls.ToolTip;
public class HTMLToolTip extends ToolTip
{
public function HTMLToolTip()
{
super();
}
override protected function commitProperties():void{
super.commitProperties();
textField.htmlText = text;
}
}
}
and on Tooltip Creation, I set the class as the ToolTipManager class
protected function helpToolTip_toolTipCreateHandler(event:ToolTipEvent):void
{
ToolTipManager.toolTipClass = HTMLToolTip;
helpToolTip.tooltip = "<img src='ui_graphic/testimage.png' width='20' height='20'/> this is a <b>tool</b> tip";
}
But it just doesn't seem to work anymore in Flex 4 (judging from various comments online too). The images just don't show up. Every other basic HTML-tag I have tried work fine. Has anyone gotten this to work on Flex 4, or should I look into another (more complex) solution?

Create tooltip class extends RichText:
package classes
{
import mx.core.IToolTip;
import spark.components.RichText;
import spark.utils.TextFlowUtil;
public class RichToolTip extends RichText implements IToolTip
{
public function RichToolTip()
{
super();
mouseEnabled = false;
mouseChildren = false;
setStyle("backgroundColor", "0xeeeeee");
}
override public function set text(value:String):void
{
textFlow = TextFlowUtil.importFromString(value);
}
}
}
In application set new tooltip class:
ToolTipManager.toolTipClass = RichToolTip;
And add tooltip for example over button:
btn.toolTip = "<div><img source='assets/bender_saved.png' width='20' height='20' /><p>this is a test <span fontWeight='bold'>bold</span></p></div>";

Related

ActionScript 3.0: myClass extends Button not working

I am newbie to Actionscript 3.0 so any help will be greatly appreciated. I am trying to get into AS3 and class definitions, so I created a myButtonClass extends Button to build buttons dynamically. However, when the button appears on the SWF it cant be clicked, looks like inactive, with no animation at all. I know that I can extend myClass with MovieClip and do all the respective scripting, but I want to understand why it is not working the way I am doing it. Moreover, to make it work I had to add the built-in button to my Library so the needed parts to build the button can be used by the compiler. Here's the script:
package code {
import fl.controls.Button;
import flash.events.MouseEvent;
public class Boton extends Button {
public function Boton() {
setupBoton("My button");
}
function setupBoton(texto: String): void {
super.label = texto;
super.x = 400;
super.y = 100;
super.width = 100;
super.height = 25;
super.enabled = true;
this.addEventListener(MouseEvent.CLICK, changeLabel);
}
function changeLabel(event: MouseEvent): void {
super.label = "Label changed";
}
}
}
What am I missing???
sincerely,
Lorenzo

Flex property binded to datagrid dataProivder array

I have the following datagrid in my application mxml:
<event:SelectRowDataGrid id="resultDG"
dataProvider="{model.EventDTOs}"
...
<event:columns>
...
SelectRowDataGrid is my extension of the Flex DataGrid:
package xx.xx.xx.xx.event
{
import mx.controls.DataGrid;
public class SelectRowDataGrid extends DataGrid
{
private var _checkedItems:Array;
public function SelectRowDataGrid() {
super();
_checkedItems = new Array();
}
public function get checkedItems():Array
{
for each (var event:EventDTO in dataProvider) {
if(event.checked)
_checkedItems.push(event);
}
return _checkedItems;
}
}
}
I am trying to set the enabled property of a button like so:
<controls:PrintButton enabled="{resultDG.checkedItems.length>0}"
But I get the followin error when building:
Multiple markers at this line:
-Data binding will not be able to detect assignments to "length".
-checkedItems
What am I missing?
As hinted by Timofei Davydik
Adding [Bindable] annotation to the class made it happen:
[Bindable]
public class SelectRowDataGrid extends DataGrid
{
...

Actionscript: Classes inside Classes

i'm trying to create a flash game, but i'm having trouble with my classes. i'm importing the classes on the main script. they're imported okay, i've tested it all. but i dont know how to use classes inside another class
this is what i've got so far:
class Class.Player {
public static var self:MovieClip;
public static var bullet:Class.Bullet;
function controls() {
//Shoot
if (Key.isDown(Key.SPACE)) {
bullet = new Bullet(100, 100);
}
}
it loads the class and declares the variable, but it claims "Bullet" is not an existing method. it is an existing method, and it works when i call it from the main script.
also, do i need to declare the class like public static var bullet:Class.Bullet;? it's the only way that works for me but wondered if there's a better way?
It looks like you are having problems with the naming of your classes. You don't have to call your classes Class.Name. Just use Name.
In your case, you could have a file called
Player.as
With this content:
package {
import flash.display.MovieClip;
public class Player extends MovieClip {
public private var bullet:Bullet;
public function Player(){
//constructor
}
function controls() {
//Shoot
if (Key.isDown(Key.SPACE)) {
bullet = new Bullet(100, 100);
}
}
}
}
And then a file called
Bullet.as
With this content:
package {
import flash.display.MovieClip;
public class Bullet extends MovieClip {
public function Bullet(x:Number, y:Number){
//constructor
}
}
}
You can read more information about creating and using custom classes here: http://www.flashandmath.com/bridge/intro/class.html
You're putting your package information in the Class name. I have no idea how this is even compiling for you (especially given that Class is a reserved word.
Your files should look more like:
package somePackage {//somePackage instead of the reserved word Class you were using
import someOtherPackage.Bullet;
public class Player extends MovieClip {
public var bullet:Bullet;
public function Player():void {
super();
//other constructor logic here
}
}
}

I want to override the default value of a style inherited from an ancestor component [flex4]

While adding the [Style ...] metadata tag to my sub-class did make the property showPromptWhenFocused accessible from MXML, the initializeStyles() function does not successfully change the default value to true.
I want the user to be able to set showPromptWhenFocused to false if they want to, but I want the default value to be true.
package com.santacruzsoftware.crafting.controls
{
import mx.core.FlexGlobals;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
import spark.components.TextInput;
[Style(name="showPromptWhenFocused", inherit="yes", type="Boolean")]
public class WatermarkTextInput extends TextInput
{
private static function initializeStyles() : void
{
var style : CSSStyleDeclaration = FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("showPromptWhenFocused");
if (!style)
style = new CSSStyleDeclaration();
style.defaultFactory = function() : void
{
this.showPromptWhenFocused = true;
}
FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("showPromptWhenFocused", style, false);
}
//call the static function immediately after the declaration
initializeStyles();
}
}
Any ideas?
When you call getStyleDeclaration() pass in the name of your class, so you can get the WaterMarkTextInput style declaration:
var style : CSSStyleDeclaration = FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("WatermarkTextInput");
And then do the same thing when you set the style for your class:
FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("WatermarkTextInput", style, false);
Try to override notifyStyleChangeInChildren().
package com.santacruzsoftware.crafting.controls {
import mx.core.FlexGlobals;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
import spark.components.TextInput;
[Style(name="showPromptWhenFocused", inherit="yes", type="Boolean")]
public class WatermarkTextInput extends TextInput {
public var inheritStyles:boolean = true;
private static function initializeStyles():void {
var style : CSSStyleDeclaration = FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("showPromptWhenFocused");
if (!style)
style = new CSSStyleDeclaration();
style.defaultFactory = function():void {
this.showPromptWhenFocused = true;
}
FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("showPromptWhenFocused", style, false);
}
//call the static function immediately after the declaration
initializeStyles();
public override function notifyStyleChangeInChildren(styleProp:String, recursive:Boolean):void {
if (!inheritStyles) {
switch(styleProp) {
case 'showPromptWhenFocused':
return;
}
}
super.notifyStyleChangeInChildren(styleProp, recursive);
}
}

Flex: Does anybody know a TabNavigator component that allows for html labels in the tabs or how to do this?

I'm trying to put html-formatted labels in the tabs of a TabNavigator.
I saw SuperTabNavigator in the FlexLib but it doesn't seem to do the trick for me.
I found this html button code and was able to inject my own TabBar and have it change the class instantiated by the ClassFactory when a navItem is created.
HtmlTabNavigator:
public class HtmlTabNavigator extends TabNavigator
{
public function HtmlTabNavigator()
{
super();
}
override protected function createChildren():void
{
if (!tabBar)
{
tabBar = new HtmlTabBar(); // inject my class
tabBar.name = "tabBar";
tabBar.focusEnabled = false;
tabBar.styleName = new StyleProxy(this, tabBarStyleFilters);
rawChildren.addChild(tabBar);
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_3_0)
{
tabBar.setStyle("paddingTop", 0);
tabBar.setStyle("paddingBottom", 0);
tabBar.setStyle("borderStyle", "none");
}
}
super.createChildren(); // ommits original TabBar creation but continues in inheritance chain
}
public function setHtmlLabels( htmlLabels:Array ):void
{
for (var i:uint = 0; i < tabBar.numChildren; i++)
{
var button:Button = tabBar.getChildAt( i ) as Button;
button.label = htmlLabels[ i ];
}
}
}
HtmlTabBar:
public class HtmlTabBar extends TabBar
{
public function HtmlTabBar()
{
super();
navItemFactory = new ClassFactory(HtmlButton);
}
}
Now I'm having problems with the style of the button as it looks like a regular button and not like a tab anymore. It is not apparent to me why this works when a ButtonBarButton is used.
Any ideas are welcome.
Thanks
Stefan
Like you mentioned, I think its best to built your own component for this scenario. You could consider using a textArea with editable=false for the tab portion since I believe htmlText can be displayed in that component.
Edit: Can you maybe modify the SuperTabNavigator and add in a textArea... so the original label for the tab could be blank (if you cant remove it) then have the textArea on top of it.
With best regards,
Following your example, I tried to specialize the TabBar to use a Custom Button with a Mnemonic Label functionality, but I get a compile time error:
1178: Attempted access of inaccessible
property navItemFactory through a
reference with static type
AspMnemonicTabBar.
Reading the Flex Source Code I found it belongs to a private namespace mx_internal. So how could I access it to set a new ClassFactory ??
package
{
import mx.controls.TabBar;
import mx.core.ClassFactory;
public class AspMnemonicTabBar extends TabBar
{
public function AspMnemonicTabBar()
{
super();
navItemFactory = new ClassFactory(AspMnemonicButton);
}
}
}
Alessandro, navItemFactory is in namespace mx_internal. Access it through mx_internal::navItemFactory, or put the following line below your import statements:
use namespace mx_internal;