Presently, I am attempting to add the ability to capture all the slides of a presentation to images and save them to disk. It works now where the first page is capture, then I want an async event to fire when the second page has loaded to capture that page, and so on. Here is where I have added an event listener, though I'm not sure if I should be using stage or this:
import flash.events.Event;
private var jpgEncoder:JPGEncoder;
// ...
private function init():void{
// ...
// Add async event to capture second page after loading
stage.loaderInfo.addEventListener(Event.COMPLETE,onLoadComplete);
// ...
}
private function onPrintButtonClicked():void {
// screen capture code
jpgEncoder = new JPGEncoder(90);
// Page 1 capture
bitmapData1 = new BitmapData(stage.width, stage.height);
bitmapData1.draw(stage, new Matrix());
// move to next page
var curPage:Page = PresentationModel.getInstance().getCurrentPage();
if (curPage != null) {
LOGGER.debug("Go to next page. Current page [{0}]", [curPage.id]);
pageCount++;
dispatchEvent(new GoToNextPageCommand(curPage.id));
} else {
LOGGER.debug("Go to next page. CanNOT find current page.");
}
}
private function onLoadComplete(e:Event)
{
// Get page 2 capture
bitmapData2 = new BitmapData(stage.width, stage.height);
bitmapData2.draw(stage, new Matrix());
// Copy two pages to one bitmap
var rect1:Rectangle = new Rectangle(0, 0, stage.width, stage.height);
var pt1:Point = new Point(0, 0);
bitmapData3 = new BitmapData(stage.width, stage.height * 2);
bitmapData3.copyPixels(bitmapData1, rect1, pt1)
var rect2:Rectangle = new Rectangle(0, 0, stage.width, stage.height);
var pt2:Point = new Point(0, stage.height);
bitmapData3.copyPixels(bitmapData2, rect2, pt2)
// Convert to image
var img:ByteArray = jpgEncoder.encode(bitmapData3);
var file:FileReference = new FileReference();
file.save(img, "capture1.jpg");
}
Does anyone have any ideas as to why the OnLoadComplete function is never called? FYI, here is the full source code: https://github.com/john1726/bigbluebutton/blob/master/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml
TIA
Please note that I've found that the stage was still null in the init() method so an exception was being thrown:
stage.loaderInfo.addEventListener(Event.COMPLETE,onLoadComplete);
Also, after resolving that stage error I found that I have been receiving this error using this tool: https://github.com/capilkey/Vizzy-Flash-Tracer
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.
So the solution is either to re-work the UI so that there is a button press to prepare the files and a second button press to actually save the image or setup them mouseup and mousedown events to call different functions:
s:Button mouseDown="prepare_PDF()" mouseUp="save_PDF()"
Source: Flex's FileReference.save() can only be called in a user event handler -- how can I get around this?
Thank you!
Related
I have a preload movie that loads an interface. In the interface I have many buttons. When I click on a button I want to load a text file into a movie called "TextMovie.swf". I want to be able to click on a button, take the name of the button and load a text file that is the same name as the button instance, and have the window appear close to the mouse click. There will be hundreds of buttons and hundreds of text files. I'm sure this is easy for some. Here is the loader for a button:
button_1.addEventListener(MouseEvent.CLICK, fl_ClickToPosition_2);
function fl_ClickToPosition_2(event:MouseEvent):void
{
var my2ndLoader:Loader = new Loader();
var url2:URLRequest = new URLRequest("TextMovie.swf");
my2ndLoader.load(url2);
addChild(my2ndLoader);
my2ndLoader.x = 200;
my2ndLoader.y = 10;
}
Then in the TextMovie.swf I have:
import flash.net.URLLoader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.text.StyleSheet;
var css:StyleSheet = new StyleSheet();
css.setStyle("a:hover", {textDecoration:"underline"});
var textLoader: URLLoader = new URLLoader();
textLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
textLoader.addEventListener(Event.COMPLETE, textLoaded);
loadText();
function textLoaded(evt: Event): void {
title_txt.htmlText = textLoader.data.txtTitle;
main_txt.htmlText = textLoader.data.txtBody;
URL_txt.htmlText = textLoader.data.txtURL;
URL_txt.styleSheet = css
}
function loadText(): void {
// var fileName: String = "assets/test_01.txt";
var fileName: String = "assets/" + + ".txt";
textLoader.load(new URLRequest(fileName));
}
I'm not sure how to get the name of the button I pushed and apply it to the string that will load the correct text file. I also can't get the window to appear close to the mouse click. Right now I just have it set with an x and y for testing.
I know it's a lot but thanks for any help.
I suggest you take a look at the docs for MouseEvent so you better understand what data is passed as parameters when the event is triggered.
In the event handler, a reference is passed to the object which was clicked: the event target– and from that you can get its name, location, etc. This is good because it means you only need one event handler for all your buttons.
Once you have the name, you can build the string you need for your url. (I wouldn't do it that way if it is a project which is going to have any sort of lifespan but it's an ok approach).
You can get the x and y location of the target, its width and height, and use that data to position your window. The localX and localY properties refer to the click location relative to the rect of the target (button) – with top/left of the target== 0,0.
This is the trace output from the function below:
red red.swf
600 400
25 8.5
button_1.addEventListener(MouseEvent.CLICK, onHandleButtonClick);
function onHandleButtonClick(event:MouseEvent):void
{
var btnName:String = event.target.name;
var swfName:String = btnName + ".swf";
trace(btnName, swfName);
trace(event.target.x, event.target.y);
trace(event.localX, event.localY);
}
How to choose one object(picture that loaded by file) from a sprite when it is several object on that?
I want to drag one that mouse clicked.
private var spstage1:Sprite = new Sprite();
private var vecpic1:Vector.<String> = new Vector.<String>();
private var iconpic1:iconpic=new iconpic();
spstage1.graphics.beginFill(0xcccccc);
spstage1.graphics.drawRect(250,100,450,668);
stage.addChild(spstage1);
spstage1.addChild(iconpic1);
iconpic1.addEventListener(MouseEvent.CLICK, picclicked);
function picclicked(event:MouseEvent):void {
var txtFilter:FileFilter = new FileFilter("picture", "*.jpg;*.png");
//root.browseForOpen("Open", [txtFilter]);
file = new File();
currentload="pic";
file.addEventListener(Event.SELECT, dirSelected);
file.browseForOpen("Select a picture",[txtFilter]);
//
/*file.browse();
file.addEventListener(Event.SELECT,onselect);*/
}
protected function dirSelected(e:Event):void {
var re1:URLRequest=new URLRequest(file.nativePath);
loader=new Loader();
loader.load(re1);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadCompletepic);
}
function loadCompletepic(event:Event):void{
var pic:BitmapData=new BitmapData(loader.width,loader.height,false);
pic.draw(loader);
bitmap=new Bitmap(pic);
spstage1.addChild(bitmap);
bitmap.x=ix;
bitmap.y=iy;
vecpic1.push(bitmap.name);
}
Add MOUSE_DOWN event listener to spstage1.
In the listener handler, check:
function clickHandler(evt:MouseEvent):void {
if (evt.target is Bitmap) {
// here you decide what you have clicked on.
(evt.target as DisplayObject).startDrag(); // do the stuff for dragging etc.
}
}
Here evt.target will be the object that is clicked.
All you have to do is to determine if it is the right object. In this example, it is just checked to be of the Bitmap type. If you have other Bitmaps in the container that don't need to be clicked, use other means, for example store the loaded object somewhere and then compare the target against all the stored objects. Or check for bitmap.name which you seem to already have, etc.
I've an app in which users first insert some data and then print the data in an aligned and table form. But I have a problem with printing the final document when I print this with a custom class FilePrinter which takes only one non-optional parameter "Sprite". I clearly and rightly follow through the codes but when I print, the printed document is nothing but a clear page. I'm not understanding why this so?
But one thing that should be noted is that the sprite is consisted of an image (with resolution not normal) and the size of printed Document becomes much (Round About 12mb to 15mb) when it is ready to print.
If any one knows about the issue so please help me...
Thanks...!
var rslt:MovieClip = new MAIN_DOC();
rslt.box1.text = arr[0].toString();
rslt.box2.text = arr[1].toString();
rslt.box3.text = arr[2].toString();
rslt.box4.text = arr[3].toString();
rslt.box5.text = arr[4].toString();
rslt.box6.text = arr[5].toString();
var BackM:MovieClip = new BackGround();
BackM.PIcont.addChild(picData);
var sprite:Sprite = new Sprite();
sprite.addChild(BackM);
sprite.addChild(rslt);
var print:FilePrinter = new FilePrinter(sprite);
function printBtnClick(e:MouseEvent):void
{
print.print();
}
FilePrinter Class
public class FilePrinter {
private var pJob:PrintJob;
private var opt:PrintJobOptions = new PrintJobOptions(true);
private var sp:Sprite;
public function FilePrinter(sprite:Sprite) {
sp = new Sprite();
sp = sprite;
pJob = new PrintJob();
if (pJob.start())
{
pJob.addPage(sp, null, opt);
}
}
public function startPrint():void {
pJob.send();
}
}
From the Actionscript documentation:
Additionally, a 15 second script timeout limit applies to the following intervals:
PrintJob.start() and the first PrintJob.addPage()
PrintJob.addPage() and the next PrintJob.addPage()
The last PrintJob.addPage() and PrintJob.send()
If any of the above intervals span more than 15 seconds, the next call to PrintJob.start() on the PrintJob instance returns false, and the next PrintJob.addPage() on the PrintJob instance causes the Flash Player or Adobe AIR to throw a runtime exception.
I'd recommend not initalising your FilePrinter class until the button press event triggers, also you seem to be calling print() in your button click listener, but there is no such function in your FilePrinter class, only startPrint()
var print:FilePrinter;
function printBtnClick(e:MouseEvent):void
{
print = new FilePrinter(sprite);
print.startPrint();
}
I have an Adobe Air desktop message board App built in Flash cs5, it loads an external ".txt" file in a dynamic text field and checks for a new file every 2 minutes. I need it to notify user with (NotificationType.CRITICAL) only if the file is new not just everytime it loads it. is it possible?
all the code in the app:
NativeApplication.nativeApplication.startAtLogin=true
stage.nativeWindow.alwaysInFront=true;
//external text file load and recheck every 2 minutes
var myInterval:uint = setInterval (loadUrl, 120000);
var loader:URLLoader = new URLLoader(new URLRequest("https://my_text_file.txt"));
loader.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void {
var loadedText:URLLoader = URLLoader(event.target);
if(myText_txt.htmlText!=loadedText.data){
myText_txt.htmlText = loadedText.data;
stage.nativeWindow.notifyUser(NotificationType.CRITICAL)
}else {
//do nothing
}
}
function loadUrl():void {
loader = new URLLoader(new URLRequest("https:///my_text_file.txt"));
loader.addEventListener(Event.COMPLETE, completeHandler);
}
// button control
Minimize_BTN.addEventListener(MouseEvent.CLICK, minimize);
function minimize(e:MouseEvent){
stage.nativeWindow.minimize();
}
drag_BTN.addEventListener(MouseEvent.MOUSE_DOWN, drag);
function drag(e:MouseEvent){
stage.nativeWindow.startMove();
}
stop(); //Stop on the frame you want
Your code might not work if the myText_txt field is modifying the loaded text (e.g., if myText_txt's condenseWhite property is set to true). A more accurate way to determine if the text has changed would be to store it in a String variable named, for example, oldText and then comparing oldText with the newly loaded text.
Here's part of your code re-written to include the oldText variable. This code is also more efficient because it instantiates some variables only once and it avoids duplicating some code:
import flash.net.URLRequest;
function completeHandler(event:Event):void
{
var newText:String = loader.data;
if(newText != oldText)
{
myText_txt.htmlText = newText;
stage.nativeWindow.notifyUser(NotificationType.CRITICAL);
oldText = newText;
}
}
function loadUrl():void
{
loader.load(req);
}
// Initialize your variables and event handlers only one time
var req:URLRequest = new URLRequest("https:///my_text_file.txt");
// Set cacheResponse to false to prevent a successful response
// from being cached.
req.cacheResponse = false;
// And don't bother checking the cache, either.
// Not necessary, but the request will execute a little faster.
req.useCache = false;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, completeHandler);
// Use oldText inside completeHandler() to determine
// whether the file's text has changed
var oldText:String = "";
var myInterval:uint = setInterval(loadUrl, 120000);
// Start loading the text right away
loadUrl();
Why don't you use FileReference object to find out about some properties like modificationDate and based on this verify if file is different you can also test it's size.
I am working with flash and as3 to try and get a photo loader/viewer/upload tool built. I am using file reference to handle the browse/load/upload functions. My current stage has 2 loader boxes that i load the user selected image into. I need to be able to remove the image though and re-select another if the user decides.
So on the file loaded event i have this code:
// Load Image into Editor Function.
function onMovieClipLoaderComplete(event:Event):void {
var loadedContent:DisplayObject=event.target.content;
currentLoader =event.target.loader as Loader;
currentLoader.x=currentX;
currentLoader.y=currentY;
currentContent.buttonMode=true;
currentContent.addChild(currentLoader);
addChild(currentContent);
currentLoader.mask = currentMask;
addChild(replace_btn);
}
And on my replace button i have:
replace_btn.addEventListener(MouseEvent.CLICK, replaceImage);
function replaceImage(event:Event):void {
currentContent.removeChild(currentLoader);
removeChild(currentContent);
}
On pressing the replace button once it works fine but when i load another image into the loader - the next time i press the replace button (or any subsequent time) i get the following argument error in my flash as3 file:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at MethodInfo-13()
Does anyone know what this means? It's odd that it only happens on the second time onwards not at first. I thought that if i have:
currentContent.addChild(currentLoader); addChild(currentContent);
on load and then just
currentContent.removeChild(currentLoader); removeChild(currentContent);
on the replace function it would work?
Full as3 code is shown below if that also helps
I have only been learning flash for 3-4 months so please go easy on me and i apologise if my code is not done in the best way! :)
Lauren
// Set Start Up Values.
var image1_loader:Loader = new Loader();
var image1_content:Sprite = new Sprite();
var image1_mask:Sprite = new Sprite(); image1_mask.graphics.beginFill(0x000000,1); image1_mask.graphics.drawRect(54, 59, 330, 330); image1_mask.graphics.endFill();
var image2_loader:Loader = new Loader();
var image2_content:Sprite = new Sprite();
var image2_mask:Sprite = new Sprite(); image2_mask.graphics.beginFill(0x000000,1); image2_mask.graphics.drawRect(384, 59, 330, 165); image2_mask.graphics.endFill();
var currentBtn;
var currentLoader;
var currentContent;
var currentMask;
var currentX;
var currentY;
replace_btn.visible=false;
// Define FileReference.
var canvasImage:FileReference;
// Image Buttons Function.
image1_btn.addEventListener(MouseEvent.CLICK, start_fileRef);
image2_btn.addEventListener(MouseEvent.CLICK, start_fileRef);
image1_content.addEventListener(MouseEvent.MOUSE_DOWN, setCurrentSelection);
image2_content.addEventListener(MouseEvent.MOUSE_DOWN, setCurrentSelection);
function setCurrentSelection(e:MouseEvent):void {
if (e.currentTarget===image1_content){currentContent=image1_content;}
if (e.currentTarget===image2_content){currentContent=image2_content;}
}
// Browse File Function.
function start_fileRef(e:MouseEvent):void {
trace("onBrowse");
if (e.target===image1_btn){currentBtn=image1_btn; currentLoader=image1_loader; currentContent=image1_content; currentMask=image1_mask; currentX=54; currentY=59;}
if (e.target===image2_btn){currentBtn=image2_btn; currentLoader=image2_loader; currentContent=image2_content; currentMask=image2_mask; currentX=384; currentY=59;}
canvasImage=new FileReference();
canvasImage.addEventListener(Event.SELECT, onFileSelected);
var imageTypeFilter:FileFilter = new FileFilter("JPG/PNG Files","*.jpeg; *.jpg;*.gif;*.png");
canvasImage.browse([imageTypeFilter]);
}
// Selected File Function.
function onFileSelected(event:Event):void {
trace("onFileSelected");
canvasImage.addEventListener(Event.COMPLETE, onFileLoaded);
canvasImage.addEventListener(ProgressEvent.PROGRESS, onProgress);
var canvasImageName = canvasImage.name;
canvasImage.load();
}
// File Progress Function.
function onProgress(event:ProgressEvent):void {
var percentLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
trace("loaded: "+percentLoaded+"%");
}
// File Loaded Function.
function onFileLoaded(event:Event):void {
var fileReference:FileReference=event.target as FileReference;
var data:ByteArray=fileReference["data"];
trace("File loaded");
var movieClipLoader:Loader=new Loader();
movieClipLoader.loadBytes(data);
movieClipLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onMovieClipLoaderComplete);
canvasImage.removeEventListener(Event.COMPLETE, onFileLoaded);
}
// Load Image into Editor Function.
function onMovieClipLoaderComplete(event:Event):void {
var loadedContent:DisplayObject=event.target.content;
currentLoader =event.target.loader as Loader;
currentLoader.x=currentX;
currentLoader.y=currentY;
currentContent.buttonMode=true;
currentContent.addChild(currentLoader);
addChild(currentContent);
currentLoader.mask = currentMask;
addChild(replace_btn);
// Reveal Retry Button over Hover Function //
currentContent.addEventListener(MouseEvent.ROLL_OVER, hover);
replace_btn.addEventListener(MouseEvent.ROLL_OVER, hover);
currentContent.addEventListener(MouseEvent.ROLL_OUT, unhover);
replace_btn.addEventListener(MouseEvent.ROLL_OUT, unhover);
function hover(event:Event):void {
replace_btn.visible=true;
}
function unhover(event:Event):void {
replace_btn.visible=false;
}
replace_btn.addEventListener(MouseEvent.CLICK, replaceImage);
function replaceImage(event:Event):void {
currentContent.removeChild(currentLoader);
removeChild(currentContent);
}
}
This currentContent.removeChild(currentLoader); should be fine, but this removeChild(currentContent); is most likely the problem source. Because you added it as currentContent.addChild(currentLoader), you must remove the container var (currentContent) with it as well.