Can't apply filter to Sprite - apache-flex

I have this simple class:
import spark.effects.GlowFilter;
public class Letter extends Sprite {
private var glowFilter:GlowFilter = new GlowFilter();
public function Letter() {
filters = [glowFilter];
}
}
And in gaves "Error #2005: Parameter 0 - incorrect type. Should be type Filter" in runtime. If I change parent class to UIComponent everything works great. But I do not need all UIComponent functionality, I need just that damn filter works. =)
So, the question is what is the problem? Why it is not working with "Sprite" as parent class?
Using Flex 4.1.

You are trying to apply a flex specific filter to a non flex based object.
Try changing the import to
import flash.filters.GlowFilter;
This will use the standard flash filter instead.

Related

GWT DataGrid : "Unable to find ImageResource method value("cellTableLoading")" when overriding styles

I tried to override styles for GWT DataGrid component like described here :
DataGrid / CellTable styling frustration -- overriding row styles
My interface
public interface DataGridResources extends DataGrid.Resources {
#Source({ DataGrid.Style.DEFAULT_CSS, "myDataGrid.css" })
DataGrid.Style dataGrid();
}
public static final DataGridResources dataGridResources =
Datagrid instance using Inteface
GWT.create(DataGridResources.class);
static {
dataGridResources.dataGrid().ensureInjected();
}
...
dataGrid = new DataGrid<User>(10, dataGridResources);
But I get the following error :
Rebinding xxx.DataGridResources
-Invoking generator com.google.gwt.resources.rebind.context.InlineClientBundleGenerator
--Creating assignment for dataGrid()
---Creating image sprite classes
----Unable to find ImageResource method value("cellTableLoading") in xxx.DataGridResources : Could not find no-arg method named cellTableLoading in type xxx.DataGridResources
--Generator 'com.google.gwt.resources.rebind.context.InlineClientBundleGenerator' threw an exception while rebinding 'xxx.DataGridResources'
-Deferred binding failed for 'xxx.DataGridResources'; expect subsequent failures
The following works. Really.
public interface Resources extends DataGrid.Resources {
interface Style extends DataGrid.Style { }
#Source(value = {DataGrid.Style.DEFAULT_CSS, "myDataGrid.css"})
public Style dataGridStyle();
}
Also you don't need to call ensureInjected() since DataGrid will call it for you.
Anyway there is something wrong in the error log: it looks for cellTableLoading style which is not part of the DataGrid.Resources interface (is part of CellTable.Resources). Have you left some spurious CSS classes in myDataGrid.css that are not defined in the original interface?
Maybe you have moved from CellTable to DataGrid by simply renaming the css, but without changing the inner class names.

Flex Type Ahead DropDownList

I need to implement multi character type ahead functionality on a DropDownList. Im using spark components Flex 4.5.1.
I wish the long list to for example if I type bl
It will go to Blue not to the first B then the first L
Its a common requirement and all browsers now support it, hope its something that already exists or someone has customized a version.
Why wouldn't you use the Flex Spark ComboBox, which has the type ahead feature built right in?
You can probably customize one of the many autocompletes. I posted the following snippet in another question on how to do an autocomplete.
package autoCompleteExample
{
import mx.collections.ICollectionView;
import mx.collections.IList;
import spark.components.ComboBox;
import spark.events.TextOperationEvent;
public class AutoCompleteExample extends ComboBox
{
override protected function textInput_changeHandler(event:TextOperationEvent):void{
super.textInput_changeHandler(event);
ICollectionView(dataProvider).refresh();
}
override public function set dataProvider(value:IList):void{
ICollectionView(value).filterFunction = defaultFilterFunction;
super.dataProvider = value;
}
private function defaultFilterFunction(item:Object):Boolean{
return (textInput.text.toLowerCase() == String(item[labelField].toLowerCase()).substr( 0, textInput.text.length ));
}
}
}
You can probably just change the text operation handler to select the first item AFTER the refresh. Not sure how well it would work.

Flex List Scroll Speed With Mouse Wheel

I have a custom class that extends List which I am using as a container. However, the scroll speed is too fast on the mouse wheel, as in it scrolls loads even if you only move the wheel a tiny bit. I tried adding an event listener to my list for MouseEvent.MOUSE_WHEEL and setting the value of event.delta but this has had no effect. Does anyone know how I can make it slower?
My custom class is nothing special, I just created it so I could have a different itemRenders for different item types. It looks like:
public class MultipleRenderersList extends List
{
override public function createItemRenderer(data:Object):IListItemRenderer
{
if (data is IRenderable)
{
return data.getDiaryRenderer();
}
else if (data is Array)
{
if (data.length > 0)
{
if (data[0] is IRenderable)
{
return data[0].getDiaryRenderer(data);
}
}
}
return null;
}
}
The List class has a mouseWheelHandler function that you can override. Just override the function, update the delta property of the mouseevent, and call super. This example will quarter the delta, reducing the speed substantially:
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import mx.controls.Alert;
import mx.controls.List;
public class MyList extends List
{
override protected function mouseWheelHandler(event:MouseEvent):void {
event.delta = event.delta/4;
super.mouseWheelHandler(event);
}
}
}
However, in many cases the scroll speed / delta will be driven off of a system preference, so doing this may cause unexpected behavior for some users. The reason that adding the handler and updating the delta failed to work is that by that point mouseWheelHandler had already been called.
A very simple way to modify this is to change the verticalLineScrollSize property. This is a property of all containers and it defaults to 5. (for flex 3)
Actually, what HandOfCode said isn't relevant here. Because he made the same mistake as i did, which is to think that a List component or TileList component are containers. They aren't. So, they don't have verticalLineScrollSize property.
Sean solution is the only one that worked for my case. I would add that event.delta may have a positive or negative value depending of the direction of the wheel action. So you better do something like this if you plan to scroll, for example one line at a time :
override protected function mouseWheelHandler(event:MouseEvent):void
{
event.delta = (event.delta > 0) ? 1:-1;
super.mouseWheelHandler(event);
}

How do I manage library symbols with linked classes in Flash CS4 to compile/debug in Flash Builder 4?

I'm building a video player using Flash CS4 (hereby referred to as "Flash") to create the graphic symbols and compiling and debugging with Flash Builder 4 ("FB4"). Here are the steps I take in my current workflow:
--Create the graphic symbols in Flash. I've created a few different symbols for the player, but I'll focus on just the play/pause button ("ppbutton") here.
--In the Library panel, I go to the ppbutton symbol's Linkage properties and link to a class named assets.PlayPauseButtonAsset that extends MovieClip. I do not actually have an assets package nor do I have a class file for PlayPauseButtonAsset as Flash will create them for me when I publish.
--In Flash's Publish settings, I set the project to export a SWC that will be used in FB4, called VideoPlayerAssets.swc.
--After the SWC is created, I create my FB4 project called "VideoPlayer" and add the SWC to my path. FB4 creates the class VideoPlayer in the default package automatically.
--In VideoPlayer.as, I import assets.*, which imports all of the symbol classes I created in Flash and are available via VideoPlayerAssets.swc. I can now instantiate the ppbutton and add to the stage, like this:
var ppbutton:PlayPauseButtonAsset = new PlayPauseButtonAsset();
addChild(ppbutton);
At this point ppbutton doesn't have any functionality because I didn't create any code for it. So I create a new class called video.controls.PlayPauseButtonLogic which extends assets.PlayPauseButtonAsset. I add some logic, and now I can use that new class to put a working ppbutton on the stage:
var ppbutton:PlayPauseButtonLogic = new PlayPauseButtonLogic();
addChild(ppbutton);
This works fine, but you may be asking why I didn't just link the ppbutton symbol in Flash to the video.controls.PlayPauseButtonLogic class in the first place. The reason is that I have a designer creating the UI in Flash and I don't want to have to re-publish the SWC from Flash every time I make a change in the logic. Basically, I want my designer to be able to make a symbol in Flash, link that symbol to a logically named class in Linkage properties, and export the SWC. I do not want to have to touch that .fla file again unless the designer makes changes to the symbols or layout. I'm using a versioning system for the project as well and it's cleaner to make sure only the designer is touching the .fla file.
So, finally, here's the issue I'm running into:
--As the design gets more complex, the designer is nesting symbols to position the video controls on the control bar. He creates a controlbar symbol and links it to assets.ControlBarAsset. The controlbar symbol contains the ppbutton symbol.
--The designer publishes the SWC and ControlBarAsset is now available in FB4. I create new class called video.controls.ControlBarLogic that extends assets.ControlBarAsset so I can add some logic to the controlbar, and I add the controlbar to the stage:
var controlbar:ControlBarLogic = new ControlBarLogic();
addChild(controlbar);
--This works, but the ppbutton doesn't do anything. That's because ppbutton, while inside controlbar, is still only linked to PlayPauseButtonAsset, which doesn't have any logic. I'm no longer instantiating a ppbutton object because it's part of controlbar.
That's where I'm stuck today. I can't seem to simply re-cast controlbar's ppbutton as PlayPauseButtonLogic as I get a Type error. And I don't want to have to make a class that has to instantiate each of the video player controls, the place them at their x and y values on the stage according to how the designer placed them, as that would require me to open the .fla and check the various properties of a symbol, then add those values to the code. If the designer made a change, I'd have to go into the code each time just to update those properties each time. Not good.
How do I re-cast nested symbols to use the logic classes that I create that extend the asset classes? Remember, the solution is not to link Flash symbols to actual classes so I don't have to keep recompiling the SWC, unless there's a way to do that without having to re-compile the SWC. I want the designer to do his thing, publish the SWC, and be done with it. Then I can take his SWC, apply my logic to his assets, and be able to debug and compile the final SWF.
Here is the solution that i use sometimes:
Instead of making PlayPauseButtonLogic extends PlayPauseButtonAsset, use this class as a warpper of PalyPauseButtonAsset, use composition instead of inheritance ! ; ).
You will get something like this in your ControlBarLogic class:
//constructor exemple
public function ControlBarLogic(){
//all logic of PPButton is inside PlayPauseButtonLogic
//you just pass a reference to the PlayPauseButtonAsset button contained inside ControlBarAsset
var ppButtonLogic: PlayPauseButtonLogic=new PlayPauseButtonLogic(refToButtonAsset)
//the warper class can extends EventDispatcher so you will be able to listen to custom or redisatched events
ppButtonLogic.addEventListener("ppPause",onPause)
}
hope it will help you
You can have two classes, one holding functionality and the other providing its graphical implementation (asset/skin)
Have PlayPauseButtonLogic extend AssetWrapper.
A simple way to solve your issue regarding event listeners, you can do the following:
package {
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.events.IEventDispatcher;
public class AssetWrapper implements IEventDispatcher {
private var _skin:DisplayObjectContainer;
public function AssetWrapper( skin:DisplayObjectContainer = null ) {
if ( skin ) setSkin(skin);
}
public function setSkin(skin:DisplayObjectContainer):void{
_skin = skin;
}
public function dispatchEvent(event:Event):Boolean{
_skin.dispatchEvent(event);
}
public function hasEventListener(type:String):Boolean{
return _skin.hasEventListener(type);
}
public function willTrigger(type:String):Boolean{
return _skin.willTrigger(type);
}
public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
_skin.removeEventListener(type, listener, useCapture);
}
public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{
_skin.addEventListener(type, listener, useCapture, priority, useWeakReference);
}
}
}
EDIT:
You can then, of course, just add as many properties/methods to AssetWrapper that delegate to the DisplayObject (skin) as you need. It also gives you more control onto those properties/methods.
i.e:
public function get x( ):Number {
return _skin.x;
}
public function set x( v:Number ):void {
if ( _skin.x = v ) return;
if ( _useWholePixels ) _skin.x = Math.round(v);
else _skin.x = v;
}
That way, for instance, you can tween your AssetWrapper instance directly. Also, you can control if you want it to be placed in round numbers (x=100) or not (x=100.5)
For methods, just the same idea:
public function addChild( child:DisplayObject ):DisplayObject {
return _skin.addChild( child );
}
Then to use it, you would extend AssetWrapper and implement a concrete behavior:
package {
import flash.display.DisplayObjectContainer;
import flash.events.MouseEvent;
public class SimpleButton extends AssetWrapper {
public function SimpleButton( skin:DisplayObjectContainer = null ) {
super(skin)
}
override public function setSkin( skin:DisplayObjectContainer):void {
super.setSkin( skin );
addEventListener(MouseEvent.ROLL_OVER, _onRollOver );
addEventListener(MouseEvent.ROLL_OUT, _onRollOut );
}
protected function _onRollOver(e:MouseEvent):void {
_skin.alpha = .5;
}
...
}
And you would use it as follows:
//you can get your graphical assets in many different ways
var buttonSkin:Sprite = new LibraryButtonSkin
//or
var ButtonSkinClass:Class = this.loaderInfo.applicationDomain.getDefinition("SimpleButtonSkin") as Class;
buttonSkin = new ButtonSkinClass;
var button:SimpleButton = new SimpleButton(buttonSkin);
button.addEventListener(MouseEvent.CLICK, _handleButton);
It is just a guide, in the real implementation you want to make sure you check for things like if a skin already exists, then remove all added listeners. You would probably could listen for an ADDED_TO_STAGE event and trigger a initialize method...
Also is a great to clean up after your instance by implement a destroy() method where you make sure all added listeners are removed and null/stop things like timers, sounds, etc.
Wow all the flow and we sunk in the finish line....
well, what about something like this
AbstractButtonBehavior
PlayButtonBehavior extends...
The trick, the graphic components should all implement some interface that allow them to pass a behavior at instantiation time, or even better, at runtime. The you just plug the login in, the logic will always remain outside and the poor assets will keep asking or answering to the same interface call, allowing you to work outside them.
could be?.

How do I change the appearance of nodes in a Tree control in Flex using an extended TreeItemRenderer?

I'm using a tree control that I want to customize. The data items in the tree's dataProvider have a property name that should be used for labeling the node, and a property type that should be used to select one of several embedded images for use as an icon. The simplest way to do this is by using the labelField and iconFunction properties.
However, I wanted to get started with item renderers and open the door for adding more complex customization later, so I tried making my own item renderer. I extended the TreeItemRenderer class as follows and used it in my tree control:
class DirectoryItemRenderer extends TreeItemRenderer
{
[Embed("assets/directory/DefaultIcon.png")]
private static var _DEFAULT_ICON:Class;
// ... some more icons ...
override public function set data(value:Object):void
{
super.data = value; // let the base class take care of everything I didn't think of
if (value is Node) { // only handle the data if it's our own node class
switch ((value as Node).type) {
// ... some case clauses ...
default:
this._vSetIcon(_DEFAULT_ICON);
}
this.label.text = (value as Node).name;
}
}
private function _vSetIcon(icon:Class):void
{
if (null != this.icon && this.contains(this.icon)) {
this.removeChild(this.icon);
}
this.icon = new icon();
this.addChild(this.icon);
this.invalidateDisplayList();
}
}
This code has no effect whatsoever, icon and label in the tree control remain at their defaults. Using trace(), I verified that my code is actually executed. What did I do wrong?
Looking at the base mx.controls.treeClasses.TreeItemRenderer class, I see that in the updateDisplayList function the renderer gets it's icon and disclosureIcon classes from _listData:TeeListData. Instead of overriding the updateDisplayList function, try modifying the icon and disclosureIcon classes of the renderer's private _listData instance in your _vSetIcon method using the public accessors, like so:
private function _vSetIcon(icon:Class, disclosureIcon:Class = null):void
{
var tmpListData:TreeListData;
if (disclosureIcon == null) disclosureIcon = icon;
tmpListData = this.listData;
tmpListData.icon = icon;
tmpListData.disclosureIcon = disclosureIcon;
this.listData = tmpListData;
}
EDIT
Here is some clarification on the difference between data and listData. You'll have to excuse my omission of package names but I'm editing from my phone so its tough to look them up and I don't know the package names off the top of my head. data is defined in the context of a TreeItemRenderer in the IDataRenderer interface. You create a data renderer by implementing this interface and defining a public property data, which in this case is set by the parent control and contains some data and meta-data from the dataProvider to be rendered by the data renderer class.
listData is defined in the IDropInListItemRenderer interface as a property of type BaseListData and is realized in the TreeItemRenderer class as a property TreeListData. It differs from the data property in that it contains meta-data that describes the TreeListRenderer itself (icon, indent, open) as well as (I believe, I'll have to double check this later) a reference to the data item being rendered. I gather that It's used by the the TreeItemRenderer and I would imagine the parent list control for display update and sizing purposes. Someone is free to correct or add onto that if I'm incorrect or missed something, I'm going of what I remember drom the code.
In this case, you wanted to use meta-data from the data set from the data provider to modify data that determines the display of the renderer, so you would need to modify both.
I think the real confusion here however came from the fact that you extended the TreeItemRenderer class then tried to override functionality on the component in a manner the original developer didn't intend for someone to do, hence the unexpected results. If your goal is education and not ease of implementation you would probably be better served by extending the UIComponent class and using the TreeItemRenderer code as a reference to create a class that implements the same interfaces. That would be a real dive into the pool of custom component development.
I'd probably try something simple, as in this example from the Adobe Cookbooks. I notice that they override updateDisplayList, which may have something to do with your problems.
There's another example (for Flex 2, but looks applicable to Flex 3) that shows how to manage the default icons. It looks like you'll want to manage the icon yourself, setting the default icon styles to null, instead of trying to manipulate the superclass's icon property.
Update -- Looking at the source for TreeItemRenderer, commitProperties has the following before checking the data and setting up the icon and label:
if (icon)
{
removeChild(DisplayObject(icon));
icon = null;
}
Also, it looks like the setter for data calls invalidateProperties. Hence, your icon is wiped out when the framework gets around to calling commitProperties.

Resources