I already added a stop button with autoplay but I need to make it so when you click the button again after you had stopped it, the music starts playing.
Source code:
var music:Sound = new Sound(new URLRequest("calmingsong.mp3"));
var sc:SoundChannel = music.play();
button1.addEventListener(MouseEvent.CLICK, stopMusic);
function stopMusic(e:Event):void
{
sc.stop();
}
If you just want to play the sound over from the beginning, just call the Sound object's play() method again (you get a new SoundChannel object when you do this).
If you'd like to resume playing the sound at the point where the user stopped it, you'll need to add additional variables to store the current "playback state"... Something like this:
var music:Sound = new Sound(new URLRequest("calmingsong.mp3"));
var sc:SoundChannel = music.play();
var startPosition:Number = 0;
var isPlaying = true; // default to true cause you auto play...
button1.addEventListener(MouseEvent.CLICK, togglePlayback);
function togglePlayback(e:Event):void
{
if (isPlaying)
{
startPosition = sc.position;
sc.stop();
isPlaying = false;
}
else
{
sc = music.play(startPosition);
isPlaying = true;
}
}
Related
New to coding in general, was wondering if its possible to change a content of a variable and update it to the UI with replace() or change()? I believe its much more harder than that but I can't wrap my head around it.
(function(thisObj) {
scriptBuildUI(thisObj)
function scriptBuildUI(thisObj) {
var win = (thisObj instanceof Panel) ? thisObj : new Window("palette", "replaceTest", undefined, 0);
win.alignChildren = ['center','top'];
var myTab = win.add("panel", undefined);
var replacebutton = myTab.add("button",undefined,"Replace");
var myTab2 = "x";
replacebutton.onClick = function(){ myTab2.replace("x",function(){hO()}) };
function hO() {myTab.add("button", undefined,"Retgf")};
win.onResizing = win.onResize = function() {
this.layout.resize();
};
win instanceof Window
? (win.center(), win.show()) : (win.layout.layout(true), win.layout.resize());
}
})(this);
I am not sure what you try to do here. myTab2 is a string variable and .replace() is a string function there. It returns a string. So you are trying to replace the "x" with the content of the function? To what end?
Also, the way i see it, that would just add another button to myTab.
If you could tell me what you try to do, maybe we can find a work-around.
Edit: To just assign your function to myTab2, you can directly do that. And if you want changes to your UI, i think you need to run win.layout.layout(true); to make them vissible. The folowing code adds a button to your tab every time it's clicked.
(function(thisObj) {
scriptBuildUI(thisObj)
function scriptBuildUI(thisObj) {
var win = (thisObj instanceof Panel) ? thisObj : new Window("palette", "replaceTest", undefined, 0);
win.alignChildren = ['center','top'];
var myTab = win.add("panel", undefined);
var replacebutton = myTab.add("button",undefined,"Replace");
var myTab2 = "x";
replacebutton.onClick = function(){ myTab2=hO() };
function hO() {
myTab.add("button", undefined,"Retgf");
win.layout.layout(true);
};
win.onResizing = win.onResize = function() {
this.layout.resize();
};
win instanceof Window
? (win.center(), win.show()) : (win.layout.layout(true), win.layout.resize());
}
})(this);
I would like to display a progress indicator while recording sound in my app.
The amount of time allocated for the recording is predefined. I set that up in code, lets say 10 seconds maximum recording time, but the user can stop the recording in less time, and of course he progress indicator would stop and reset.
I have been trying to make it work right could you please offer some guidance.
Note: I am using the NateRickard AudioRecorder nuget package.
if (!recorder.IsRecording)
{
buttonRecord.IsEnabled = false;
buttonPlay.IsEnabled = false;
DependencyService.Get<IAudioService>().PrepareRecording();
// start recording
var recordTask = await recorder.StartRecording();
// set up progress bar
//progressBarRecordTime.Progress = 1.0;
//await progressBarRecordTime.ProgressTo(1.0, 10000, Easing.Linear);
buttonRecord.Text = "Stop Recording";
buttonRecord.IsEnabled = true;
// get the recorded file
var recordedAudioFile = await recordTask;
buttonRecord.Text = "Record";
buttonPlay.IsEnabled = true;
if (recordedAudioFile != null)
{
var recordingFileDestinationPath = Path.Combine(FileSystem.AppDataDirectory, AppConstants.CUSTOM_ALERT_FILENAME);
if (File.Exists(recordingFileDestinationPath))
{
File.Delete(recordingFileDestinationPath);
}
File.Copy(recordedAudioFile, recordingFileDestinationPath);
}
}
Place an ActivityIndicator (name it ind) in your xaml code (view)
At the top of your code above:
ind.IsRunning = true;
//
if (!recorder.IsRecording)
//
when you are done, add this below your code
//
}
File.Copy(recordedAudioFile, recordingFileDestinationPath);
}
}
ind.IsRunning = false;
I'm working on a requirement where I have a datasource named 'emailSearchResults' where I search for email messages metadata and load the results in the datasource.
The fields in the datasource are not relevant, however I set the datasource to have 50 records per page as per the below screenshot:
The script I used to load the datasource is shown in the query field, that call the following script:
function getMessageDetails(userId, msgID)
{
var messageDetails = [];
var messageData;
var msgID_,subject_,from_,date_;
messageData=Gmail.Users.Messages.get(userId,msgID,{format:"metadata", metadataHeaders:["Message-ID", "Subject", "From", "Date"]});
console.log(messageData.payload.headers);
//console.log(msgID);
//console.log(messageData.payload.headers[3].value);
date_="<na>";
from_="<na>";
subject_="<na>";
msgID_="<na>";
for (var counter =0;counter<4;counter++)
{
if (messageData.payload.headers[counter].name=="Message-ID")
{
msgID_=messageData.payload.headers[counter].value;
}
if (messageData.payload.headers[counter].name=="Subject")
{
subject_=messageData.payload.headers[counter].value;
}
if (messageData.payload.headers[counter].name=="From")
{
from_=messageData.payload.headers[counter].value;
}
if (messageData.payload.headers[counter].name=="Date")
{
date_=messageData.payload.headers[counter].value;
}
}
messageDetails.push(date_);
messageDetails.push(from_);
messageDetails.push(subject_);
messageDetails.push(msgID_);
return messageDetails;
}
function searchMessages(userId,condition)
{
//
// first we build the conditions
// we can make it fixed
// or we can make it dynamic
var searchResult;
var deleteResult;
var currentMessage;
var results = [];
var pageToken;
var params = {};
var _stat;
var options = {
includeSpamTrash: "true",
pageToken: pageToken
};
var msgRecord = [];
do
{
searchResult=Gmail.Users.Messages.list(userId,options);
for (var i = 0; i < searchResult.messages.length; i++)
{
var record=app.models.emailSearchResults.newRecord();
msgRecord=getMessageDetails(userId,searchResult.messages[i].id);
record.msgMainID=searchResult.messages[i].id;
record.msgID=msgRecord[3];
record.subject=msgRecord[2];
record.senderAddress=msgRecord[1];
record.msgDate=msgRecord[0];
/*console.log(searchResult.messages[i].id);
console.log(msgRecord[3]);
console.log(msgRecord[2]);
console.log(msgRecord[1]);
console.log(msgRecord[0]);
return;*/
results.push(record);
msgRecord=null;
}
if (searchResult.nextPageToken) {
options.pageToken = searchResult.nextPageToken;
}
} while (searchResult.pageToken);
searchResult=null;
return results;
}
On the main page I put a table and linked it to the datasource, and I enabled pagination on the table, so I get the pager buttons at the bottom of the table as below:
When I execute the app and the datasource is filled, I see the first page results in a correct way, however when I want to move to the next page, I click the next page button and once the loading is complete I find out that I still see the same results from the first page on the table.
I am not familiar with how to make the table show the results of the second page then the third page, and I am going in circles on this...
Hope the explanation is clear and addresses the issue..
I would really appreciate any help on this!
Regards
Currently pagination isn't working as expected with calculated datasources. You can, however, build your own. There are several changes you'll need to make to accomplish this. First you'll want to refactor your searchMessages function to something like this:
function searchMessages(userId, pageToken){
var results = [];
var options = {
includeSpamTrash: "true",
pageToken: pageToken,
maxResults: 50
};
var searchResult = Gmail.Users.Messages.list(userId, options);
for (var i = 0; i < searchResult.messages.length; i++){
var record = app.models.emailSearchResults.newRecord();
var msgRecord = getMessageDetails(userId,searchResult.messages[i].id);
record.msgMainID = searchResult.messages[i].id;
record.msgID = msgRecord[3];
record.subject = msgRecord[2];
record.senderAddress = msgRecord[1];
record.msgDate = msgRecord[0];
results.push(record);
}
return {records: results, nextPageToken: searchResult.nextPageToken};
}
Then you'll want to change your datasource query. You'll need to add a number parameter called page.
var cache = CacheService.getUserCache();
var page = query.parameters.page || 1;
var pageToken;
if(page > 1){
pageToken = cache.get('pageToken' + page.toString());
}
var results = searchMessages('me', pageToken);
var nextPage = (page + 1).toString();
cache.put('pageToken' + nextPage, results.nextPageToken);
return results.records;
You'll need to modify the pagination widget's various attributes. Here are the previous/next click functions:
Previous:
widget.datasource.query.pageIndex--;
widget.datasource.query.parameters.page = widget.datasource.query.pageIndex;
widget.datasource.load();
Next:
widget.datasource.query.pageIndex++;
widget.datasource.query.parameters.page = widget.datasource.query.pageIndex;
widget.datasource.load();
You should be able to take it from there.
I would like to know how to detect when no buttons are pressed on a movieclip,
such as
if (no keys are pressed){
this.gotoAndStop("idle");
}
Firstly if you expand your question as you expand your purpose of what you achieve, maybe I can present a more in depth solllution ... ;) I can not imagine why you need a no buttons pressed event. Anyway you can use this code snippet.
//This belongs to no button pressed event.
var def = 0;
var keyListener:Object = new Object();
keyListener.onKeyDown = function() {
def = 1;
};
keyListener.onKeyUp = function() {
def = 0;
};
Key.addListener(keyListener);
//First Part for the whole movie clip
_root.onEnterFrame = function (){
trace(def);
if(def == 1){
this.gotoAndStop("idle");
}
}
So I made a drag and drop app where I can drop in an image, it get's resized and saved automatically on the desktop.
But now I want to do the same when there are multiple images dragged in.
This is where I'm stuck...
private function onDrop(e:NativeDragEvent):void
{
trace("Dropped!");
var dropfiles:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
for each (var file:File in dropfiles){
var ldr:Loader = new Loader();
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
switch (file.extension.toLowerCase()){
case "png" :
ldr.load(new URLRequest(file.url));
trace('png');
break;
case "jpg" :
ldr.load(new URLRequest(file.url));
trace('jpg');
break;
case "jpeg" :
ldr.load(new URLRequest(file.url));
trace('jpeg');
break;
case "gif" :
ldr.load(new URLRequest(file.url));
break;
default:
Alert.show("Kies een geldige afbeelding!");
}
}
}
private function completeHandler(event:Event):void {
var ldr:Loader = Loader(event.target.loader);
var b:Bitmap = Bitmap(ldr.content);
var encoder:PNGEncoder = new PNGEncoder();
var bytes:ByteArray = encoder.encode(resizeimage(b.bitmapData, 600, 600));
//new FileReference().save(bytes, "abc.png");
}
The problem is that I want the completeHandler() to run after every ldr.load() but in my code it only runs once right after the for each loop.
Does anyone know what I'm doing wrong here?
It looks like you the Loaders are only referenced as local variables. After the function onDrop ends, they're probably getting garbage collected. Once that happens, they won't be around to call your event handler. You need to save them somewhere to keep them memory.
I'd save them in an Array. Make a private variable on your class, like this:
private var _loaders:Array = [];
Then, when you create a Loader, save it:
var ldr:Loader = new Loader()
_loaders.push(ldr);
In your completeHandler, or whereever you're done with the Loader, be sure to remove it from the Array:
var index:int = _loaders.indexOf(ldr);
_loaders.splice(index, 1);