2 Replies Latest reply on Jul 20, 2010 4:42 AM by andrewd13

    Adding a child canvas immediately

    andrewd13

      Hi there,

       

      I'm trying to add a canvas to my application which fills the screen while a CPU intensive action runs in the background. No matter what I try, I cannot get the loading screen to appear until after the slow action has finished.

       

      Code (belongs in a subclass of Canvas):

       

      private function saveBitmap(event:ContextMenuEvent):void
      {
          loadingScreen.visible = true;
          loadingScreen.appLoadingText.text = "Preparing bitmap...";
          addChild(loadingScreen);
          
          validateNow();
      
           // Slow code!
          var bmpd:BitmapData = new BitmapData(canv.width, canv.height);
          bmpd.draw(canv);
          
          var fr:FileReference = new FileReference();
          fr.addEventListener(Event.COMPLETE, removeLoadingScreen);
          fr.addEventListener(Event.CANCEL, removeLoadingScreen);
          var png:PNGEncoder = new PNGEncoder();
          var iba:ByteArray = png.encode(bmpd);
          fr.save(iba, "export.png");    
      }
      

       

      Unfortunately sticking the slow code into callLater() doesn't work because then the FileReference() can't be created.

       

      Any ideas?

       

      Cheers

        • 1. Re: Adding a child canvas immediately
          rootsounds Level 4

          Try executing the "slow code" on the updateComplete event of the Canvas.

          • 2. Re: Adding a child canvas immediately
            andrewd13 Level 1

            Thanks for the reply. What I've ended up with is quite strange:

             

            private function saveBitmap(event:ContextMenuEvent):void
            {
                loadingScreen.visible = true;
                loadingScreen.appLoadingText.text = "Preparing bitmap...";
                <point a>
                addChild(loadingScreen); 
            
                validateNow();
                <point b>
                trace("Fired!");
            }
            
            private function prepareBitmap(event:FlexEvent):void
            {
                trace("Fired beta!");
                removeEventListener(FlexEvent.UPDATE_COMPLETE, prepareBitmap);
                
                var bmpd:BitmapData = new BitmapData(canv.width, canv.height);
                bmpd.draw(canv);
                
                var fr:FileReference = new FileReference();
                fr.addEventListener(Event.COMPLETE, removeLoadingScreen);
                fr.addEventListener(Event.CANCEL, removeLoadingScreen);
                var png:PNGEncoder = new PNGEncoder();
                var iba:ByteArray = png.encode(bmpd);
                fr.save(iba, "export.png");    
            }
            

             

            If I put addEventListener(FlexEvent.UPDATE_COMPLETE, prepareBitmap); at point a, then I get "Fired beta" then "Fired" (this makes sense I think, since the validateNow() will block until the UPDATE_COMPLETE event is finished) with no loading screen.

             

            If I put it the listener at point b then "Fired" is first and the loading screen appears, followed by a small (5 sec?) delay before "Fired Beta" is printed and the application dies from "Error: Error #2176: Certain actions, such as those that display a pop-up window, may only be invoked upon user interaction, for example by a mouse click or button press.".