michael@0: /*
michael@0: Licensed under the Apache License, Version 2.0 (the "License");
michael@0: you may not use this file except in compliance with the License.
michael@0: You may obtain a copy of the License at
michael@0:
michael@0: http://www.apache.org/licenses/LICENSE-2.0
michael@0:
michael@0: Unless required by applicable law or agreed to in writing, software
michael@0: distributed under the License is distributed on an "AS IS" BASIS,
michael@0: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0: See the License for the specific language governing permissions and
michael@0: limitations under the License.
michael@0: */
michael@0:
michael@0: using System;
michael@0: using System.Windows;
michael@0: using System.Windows.Controls;
michael@0: using Microsoft.Devices;
michael@0: using System.Runtime.Serialization;
michael@0: using System.Threading;
michael@0: using System.Windows.Resources;
michael@0: using Microsoft.Phone.Controls;
michael@0: using Microsoft.Xna.Framework.Audio;
michael@0: using WPCordovaClassLib.Cordova.UI;
michael@0: using System.Diagnostics;
michael@0:
michael@0:
michael@0: namespace WPCordovaClassLib.Cordova.Commands
michael@0: {
michael@0: public class Notification : BaseCommand
michael@0: {
michael@0: static ProgressBar progressBar = null;
michael@0: const int DEFAULT_DURATION = 5;
michael@0:
michael@0: private NotificationBox notifyBox;
michael@0:
michael@0: private class NotifBoxData
michael@0: {
michael@0: public NotificationBox previous {get;set;}
michael@0: public string callbackId { get; set; }
michael@0: }
michael@0:
michael@0: private PhoneApplicationPage Page
michael@0: {
michael@0: get
michael@0: {
michael@0: PhoneApplicationPage page = null;
michael@0: PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
michael@0: if (frame != null)
michael@0: {
michael@0: page = frame.Content as PhoneApplicationPage;
michael@0: }
michael@0: return page;
michael@0: }
michael@0: }
michael@0:
michael@0: // blink api - doesn't look like there is an equivalent api we can use...
michael@0:
michael@0: [DataContract]
michael@0: public class AlertOptions
michael@0: {
michael@0: [OnDeserializing]
michael@0: public void OnDeserializing(StreamingContext context)
michael@0: {
michael@0: // set defaults
michael@0: this.message = "message";
michael@0: this.title = "Alert";
michael@0: this.buttonLabel = "ok";
michael@0: }
michael@0:
michael@0: ///
michael@0: /// message to display in the alert box
michael@0: ///
michael@0: [DataMember]
michael@0: public string message;
michael@0:
michael@0: ///
michael@0: /// title displayed on the alert window
michael@0: ///
michael@0: [DataMember]
michael@0: public string title;
michael@0:
michael@0: ///
michael@0: /// text to display on the button
michael@0: ///
michael@0: [DataMember]
michael@0: public string buttonLabel;
michael@0: }
michael@0:
michael@0: [DataContract]
michael@0: public class PromptResult
michael@0: {
michael@0: [DataMember]
michael@0: public int buttonIndex;
michael@0:
michael@0: [DataMember]
michael@0: public string input1;
michael@0:
michael@0: public PromptResult(int index, string text)
michael@0: {
michael@0: this.buttonIndex = index;
michael@0: this.input1 = text;
michael@0: }
michael@0: }
michael@0:
michael@0: public void alert(string options)
michael@0: {
michael@0: string[] args = JSON.JsonHelper.Deserialize(options);
michael@0: AlertOptions alertOpts = new AlertOptions();
michael@0: alertOpts.message = args[0];
michael@0: alertOpts.title = args[1];
michael@0: alertOpts.buttonLabel = args[2];
michael@0: string aliasCurrentCommandCallbackId = args[3];
michael@0:
michael@0: Deployment.Current.Dispatcher.BeginInvoke(() =>
michael@0: {
michael@0: PhoneApplicationPage page = Page;
michael@0: if (page != null)
michael@0: {
michael@0: Grid grid = page.FindName("LayoutRoot") as Grid;
michael@0: if (grid != null)
michael@0: {
michael@0: var previous = notifyBox;
michael@0: notifyBox = new NotificationBox();
michael@0: notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };
michael@0: notifyBox.PageTitle.Text = alertOpts.title;
michael@0: notifyBox.SubTitle.Text = alertOpts.message;
michael@0: Button btnOK = new Button();
michael@0: btnOK.Content = alertOpts.buttonLabel;
michael@0: btnOK.Click += new RoutedEventHandler(btnOK_Click);
michael@0: btnOK.Tag = 1;
michael@0: notifyBox.ButtonPanel.Children.Add(btnOK);
michael@0: grid.Children.Add(notifyBox);
michael@0:
michael@0: if (previous == null)
michael@0: {
michael@0: page.BackKeyPress += page_BackKeyPress;
michael@0: }
michael@0: }
michael@0: }
michael@0: else
michael@0: {
michael@0: DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
michael@0: }
michael@0: });
michael@0: }
michael@0:
michael@0: public void prompt(string options)
michael@0: {
michael@0: string[] args = JSON.JsonHelper.Deserialize(options);
michael@0: string message = args[0];
michael@0: string title = args[1];
michael@0: string buttonLabelsArray = args[2];
michael@0: string[] buttonLabels = JSON.JsonHelper.Deserialize(buttonLabelsArray);
michael@0: string defaultText = args[3];
michael@0: string aliasCurrentCommandCallbackId = args[4];
michael@0:
michael@0: Deployment.Current.Dispatcher.BeginInvoke(() =>
michael@0: {
michael@0: PhoneApplicationPage page = Page;
michael@0: if (page != null)
michael@0: {
michael@0: Grid grid = page.FindName("LayoutRoot") as Grid;
michael@0: if (grid != null)
michael@0: {
michael@0: var previous = notifyBox;
michael@0: notifyBox = new NotificationBox();
michael@0: notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };
michael@0: notifyBox.PageTitle.Text = title;
michael@0: notifyBox.SubTitle.Text = message;
michael@0:
michael@0: //TextBox textBox = new TextBox();
michael@0: //textBox.Text = defaultText;
michael@0: //textBox.AcceptsReturn = true;
michael@0: //notifyBox.ContentScroller.Content = textBox;
michael@0:
michael@0: notifyBox.InputText.Text = defaultText;
michael@0: notifyBox.InputText.Visibility = Visibility.Visible;
michael@0:
michael@0: for (int i = 0; i < buttonLabels.Length; ++i)
michael@0: {
michael@0: Button button = new Button();
michael@0: button.Content = buttonLabels[i];
michael@0: button.Tag = i + 1;
michael@0: button.Click += promptBoxbutton_Click;
michael@0: notifyBox.ButtonPanel.Orientation = Orientation.Vertical;
michael@0: notifyBox.ButtonPanel.Children.Add(button);
michael@0: }
michael@0:
michael@0: grid.Children.Add(notifyBox);
michael@0: if (previous != null)
michael@0: {
michael@0: page.BackKeyPress += page_BackKeyPress;
michael@0: }
michael@0: }
michael@0: }
michael@0: else
michael@0: {
michael@0: DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
michael@0: }
michael@0: });
michael@0: }
michael@0:
michael@0: public void confirm(string options)
michael@0: {
michael@0: string[] args = JSON.JsonHelper.Deserialize(options);
michael@0: AlertOptions alertOpts = new AlertOptions();
michael@0: alertOpts.message = args[0];
michael@0: alertOpts.title = args[1];
michael@0: alertOpts.buttonLabel = args[2];
michael@0: string aliasCurrentCommandCallbackId = args[3];
michael@0:
michael@0: Deployment.Current.Dispatcher.BeginInvoke(() =>
michael@0: {
michael@0: PhoneApplicationPage page = Page;
michael@0: if (page != null)
michael@0: {
michael@0: Grid grid = page.FindName("LayoutRoot") as Grid;
michael@0: if (grid != null)
michael@0: {
michael@0: var previous = notifyBox;
michael@0: notifyBox = new NotificationBox();
michael@0: notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };
michael@0: notifyBox.PageTitle.Text = alertOpts.title;
michael@0: notifyBox.SubTitle.Text = alertOpts.message;
michael@0:
michael@0: string[] labels = JSON.JsonHelper.Deserialize(alertOpts.buttonLabel);
michael@0:
michael@0: if (labels == null)
michael@0: {
michael@0: labels = alertOpts.buttonLabel.Split(',');
michael@0: }
michael@0:
michael@0: for (int n = 0; n < labels.Length; n++)
michael@0: {
michael@0: Button btn = new Button();
michael@0: btn.Content = labels[n];
michael@0: btn.Tag = n;
michael@0: btn.Click += new RoutedEventHandler(btnOK_Click);
michael@0: notifyBox.ButtonPanel.Children.Add(btn);
michael@0: }
michael@0:
michael@0: grid.Children.Add(notifyBox);
michael@0: if (previous == null)
michael@0: {
michael@0: page.BackKeyPress += page_BackKeyPress;
michael@0: }
michael@0: }
michael@0: }
michael@0: else
michael@0: {
michael@0: DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
michael@0: }
michael@0: });
michael@0: }
michael@0:
michael@0: void promptBoxbutton_Click(object sender, RoutedEventArgs e)
michael@0: {
michael@0: Button button = sender as Button;
michael@0: FrameworkElement promptBox = null;
michael@0: int buttonIndex = 0;
michael@0: string callbackId = string.Empty;
michael@0: string text = string.Empty;
michael@0: if (button != null)
michael@0: {
michael@0: buttonIndex = (int)button.Tag;
michael@0: promptBox = button.Parent as FrameworkElement;
michael@0: while ((promptBox = promptBox.Parent as FrameworkElement) != null &&
michael@0: !(promptBox is NotificationBox)) ;
michael@0: }
michael@0:
michael@0: if (promptBox != null)
michael@0: {
michael@0: NotificationBox box = promptBox as NotificationBox;
michael@0:
michael@0: text = box.InputText.Text;
michael@0:
michael@0: PhoneApplicationPage page = Page;
michael@0: if (page != null)
michael@0: {
michael@0: Grid grid = page.FindName("LayoutRoot") as Grid;
michael@0: if (grid != null)
michael@0: {
michael@0: grid.Children.Remove(promptBox);
michael@0: }
michael@0:
michael@0: NotifBoxData data = promptBox.Tag as NotifBoxData;
michael@0: promptBox = data.previous as NotificationBox;
michael@0: callbackId = data.callbackId as string;
michael@0:
michael@0: if (promptBox == null)
michael@0: {
michael@0: page.BackKeyPress -= page_BackKeyPress;
michael@0: }
michael@0: }
michael@0: }
michael@0: DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new PromptResult(buttonIndex, text)), callbackId);
michael@0: }
michael@0:
michael@0: void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
michael@0: {
michael@0: PhoneApplicationPage page = sender as PhoneApplicationPage;
michael@0: string callbackId = "";
michael@0: if (page != null && notifyBox != null)
michael@0: {
michael@0: Grid grid = page.FindName("LayoutRoot") as Grid;
michael@0: if (grid != null)
michael@0: {
michael@0: grid.Children.Remove(notifyBox);
michael@0: NotifBoxData notifBoxData = notifyBox.Tag as NotifBoxData;
michael@0: notifyBox = notifBoxData.previous as NotificationBox;
michael@0: callbackId = notifBoxData.callbackId as string;
michael@0: }
michael@0: if (notifyBox == null)
michael@0: {
michael@0: page.BackKeyPress -= page_BackKeyPress;
michael@0: }
michael@0: e.Cancel = true;
michael@0: }
michael@0:
michael@0: DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
michael@0: }
michael@0:
michael@0: void btnOK_Click(object sender, RoutedEventArgs e)
michael@0: {
michael@0: Button btn = sender as Button;
michael@0: FrameworkElement notifBoxParent = null;
michael@0: int retVal = 0;
michael@0: string callbackId = "";
michael@0: if (btn != null)
michael@0: {
michael@0: retVal = (int)btn.Tag + 1;
michael@0:
michael@0: notifBoxParent = btn.Parent as FrameworkElement;
michael@0: while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
michael@0: !(notifBoxParent is NotificationBox)) ;
michael@0: }
michael@0: if (notifBoxParent != null)
michael@0: {
michael@0: PhoneApplicationPage page = Page;
michael@0: if (page != null)
michael@0: {
michael@0: Grid grid = page.FindName("LayoutRoot") as Grid;
michael@0: if (grid != null)
michael@0: {
michael@0: grid.Children.Remove(notifBoxParent);
michael@0: }
michael@0:
michael@0: NotifBoxData notifBoxData = notifBoxParent.Tag as NotifBoxData;
michael@0: notifyBox = notifBoxData.previous as NotificationBox;
michael@0: callbackId = notifBoxData.callbackId as string;
michael@0:
michael@0: if (notifyBox == null)
michael@0: {
michael@0: page.BackKeyPress -= page_BackKeyPress;
michael@0: }
michael@0: }
michael@0:
michael@0: }
michael@0: DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal), callbackId);
michael@0: }
michael@0:
michael@0:
michael@0:
michael@0: public void beep(string options)
michael@0: {
michael@0: string[] args = JSON.JsonHelper.Deserialize(options);
michael@0: int times = int.Parse(args[0]);
michael@0:
michael@0: string resourcePath = BaseCommand.GetBaseURL() + "Plugins/org.apache.cordova.dialogs/notification-beep.wav";
michael@0:
michael@0: StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
michael@0:
michael@0: if (sri != null)
michael@0: {
michael@0: SoundEffect effect = SoundEffect.FromStream(sri.Stream);
michael@0: SoundEffectInstance inst = effect.CreateInstance();
michael@0: ThreadPool.QueueUserWorkItem((o) =>
michael@0: {
michael@0: // cannot interact with UI !!
michael@0: do
michael@0: {
michael@0: inst.Play();
michael@0: Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
michael@0: }
michael@0: while (--times > 0);
michael@0:
michael@0: });
michael@0:
michael@0: }
michael@0:
michael@0: // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
michael@0: DispatchCommandResult();
michael@0: }
michael@0:
michael@0: // Display an indeterminate progress indicator
michael@0: public void activityStart(string unused)
michael@0: {
michael@0:
michael@0: Deployment.Current.Dispatcher.BeginInvoke(() =>
michael@0: {
michael@0: PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
michael@0:
michael@0: if (frame != null)
michael@0: {
michael@0: PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
michael@0:
michael@0: if (page != null)
michael@0: {
michael@0: var temp = page.FindName("LayoutRoot");
michael@0: Grid grid = temp as Grid;
michael@0: if (grid != null)
michael@0: {
michael@0: if (progressBar != null)
michael@0: {
michael@0: grid.Children.Remove(progressBar);
michael@0: }
michael@0: progressBar = new ProgressBar();
michael@0: progressBar.IsIndeterminate = true;
michael@0: progressBar.IsEnabled = true;
michael@0:
michael@0: grid.Children.Add(progressBar);
michael@0: }
michael@0: }
michael@0: }
michael@0: });
michael@0: }
michael@0:
michael@0:
michael@0: // Remove our indeterminate progress indicator
michael@0: public void activityStop(string unused)
michael@0: {
michael@0: Deployment.Current.Dispatcher.BeginInvoke(() =>
michael@0: {
michael@0: if (progressBar != null)
michael@0: {
michael@0: progressBar.IsEnabled = false;
michael@0: PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
michael@0: if (frame != null)
michael@0: {
michael@0: PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
michael@0: if (page != null)
michael@0: {
michael@0: Grid grid = page.FindName("LayoutRoot") as Grid;
michael@0: if (grid != null)
michael@0: {
michael@0: grid.Children.Remove(progressBar);
michael@0: }
michael@0: }
michael@0: }
michael@0: progressBar = null;
michael@0: }
michael@0: });
michael@0: }
michael@0:
michael@0: public void vibrate(string vibrateDuration)
michael@0: {
michael@0:
michael@0: int msecs = 200; // set default
michael@0:
michael@0: try
michael@0: {
michael@0: string[] args = JSON.JsonHelper.Deserialize(vibrateDuration);
michael@0:
michael@0: msecs = int.Parse(args[0]);
michael@0: if (msecs < 1)
michael@0: {
michael@0: msecs = 1;
michael@0: }
michael@0: }
michael@0: catch (FormatException)
michael@0: {
michael@0:
michael@0: }
michael@0:
michael@0: VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
michael@0:
michael@0: // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
michael@0: DispatchCommandResult();
michael@0: }
michael@0: }
michael@0: }