tags:

views:

639

answers:

3

Hello

I am creating a canvas in actionscript like :

private var cvs_preview:Canvas = null;

      private function show_preview():void
      {        
       this.cvs_preview = new Canvas();  
       this.cvs_preview.id = "cvs_preview_1";  
       this.cvs_preview.setStyle('backgroundColor', 0x000000);
       this.cvs_preview.setStyle('backgroundAlpha', 1);
       this.cvs_preview.setStyle('borderColor', 0x417FDD);
       this.cvs_preview.setStyle('cornerRadius', 10);
       this.cvs_preview.setStyle('borderStyle', 'solid');
       this.cvs_preview.setStyle('dropShadowEnabled', true);
       var pt:Point = image.localToGlobal(new Point(image.x, image.y));    
       this.cvs_preview.x = pt.x - 50;
       this.cvs_preview.y = pt.y - 50;
       this.cvs_preview.height = 200;
       this.cvs_preview.width = 250; 
       //this.cvs_preview.addEventListener(FlexEvent.CREATION_COMPLETE, get_focus_on_canvas);
       //this.cvs_preview.focusManager.setFocus(
       //this.cvs_preview.addEventListener(MouseEvent.CLICK, end_preview_on_focus_change);
       this.cvs_preview.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, end_preview_on_focus_change);
Application.application.addChild(this.cvs_preview); //add as top-most visible container

       btn_mini_preview.enabled = false;

      }

So on the focus change i want to run the "end_preview_on_focus_change()"

but this is not working.

As per my understanding, i think the canvas not getting any focus in the first place. I was trying to use focusManager.setFocus to do that after the canvas's creation complete. but even that is giving me an error.

the code i was trying on Creation.Complete is :

private function get_focus_on_canvas(e:FlexEvent)
      {
       focusManager.setFocus(e.target);
       //Alert.show("testing img complete");
      }

this is giving me an error "1118: Implicit coercion of a value with static type Object to a possibly unrelated type mx.managers:IFocusManagerComponent."

basically i just want to use the focus out event of the canvas.

Can someone help me with this... I have been on this issue since a long time.

Regards Zeeshan

+1  A: 

I see two problems, and no perfect solutions. With any luck, this can help you out.

First of all, e.target returns an object typecast with type Object. This explains your implict coercion error, because Object does not implement IFocusManagerComponent.

Second, iFocusManagerComponent is only implemented by Accordion, AdvancedListBase, Button, ButtonBar, ChartBase, ComboBase, DateChooser, DateField, HTML, ListBase, MenuBar, NumericStepper, TabNavigator, TextArea, TextInput, UIMovieClip as per this entry in the Flex 3.4 AS3 Reference.

This leads me to believe that a Canvas element cannot take focus and has simply inherited access to the FocusManager through inheritance of UIComponent.

The only solutions I can see are to utilize something other than Canvas to handle your focus related concerns, or subclass Canvas and implement iFocusManagerComponent, though that looks fairly complex.

Edit Apologies for missing drawFocus in the above solution.

Tegeril
+2  A: 

The error is correct. You have an object of type Object which you are trying to use as an IFocusManagerComponent. This will not work. To accomplish that line of code, you need to do something like

focusManager.setFocus( IFocusManagerComponent( e.target ) );

This, of course, assumes that the target implements IFocusManagerComponent. It will give you an error otherwise (and likely will in this case because Canvas is not listed as an IFocusManagerComponent). The good news is that Canvas does have a drawFocus method which will accomplish the same thing.

As to your MOUSE_FOCUS_CHANGE event, that will only be fired if an object already HAS focus and then loses it. I think you are better off using FlexEvent.CREATION_COMPLETE. This will ensure that the component has registered itself with all of the appropriate classes in the Flex SDK so that the FocusManager can even be aware of the new object. Whatever you do, do not try to set focus on something which has not been added to the stage (ie: Event.ADDED has been called).

As another piece of advice -- Event.ADDED bubbles, make sure that event.currentTarget == event.target to make sure that you are listening to the correct object. Otherwise, you might be calling the same function multiple times erroneously.

Christopher W. Allen-Poole
+2  A: 

Only a few classes implement IFocusManagerComponent as others mentioned and Canvas is not one of them. If you really must call FocusManager.setFocus() you will have to extend the canvas class to implement this interface and use that class instead. You don't have to write any methods to implement this interface, all methods have already been implemented by UIComponent itself

//FocusableCanvas.as (include appropriate package and import statements)
public class FocusableCanvas extends Canvas implements IFocusManagerComponent
{
    public function FocusableCanvas()
    {
        super();
    }
}

//Now use this class instead of Canvas
this.cvs_preview = new FocusableCanvas();


//setFocus in creation complete handler
FocusManager.setFocus(IFocusManagerComponent(e.target));


But if all you want to do is to set focus on the canvas upon it's creation, you can call canvas.setFocus() from the creationComplete handler instead.

private function get_focus_on_canvas(e:FlexEvent)
{
    Canvas(e.currentTarget).setFocus();
    trace("done");
}
Amarghosh