Adding a tutorial video to the MobileWebApp sample as an example of using HTML5 video. Also fixing issue 6300 (pressing cancel button doesn't work when adding a new task).

Demo at http://jlabanca-testing.appspot.com/.  Click the "Need Help?" link in the upper right corner to view the video.

Issue: 6300

Review at http://gwt-code-reviews.appspot.com/1425815

Review by: rchandia@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10122 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/activity/TaskEditActivity.java b/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/activity/TaskEditActivity.java
index dea8677..9035240 100644
--- a/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/activity/TaskEditActivity.java
+++ b/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/activity/TaskEditActivity.java
@@ -50,6 +50,12 @@
   private boolean isDead = false;
 
   /**
+   * Indicates whether the activity is editing an existing task or creating a
+   * new task.
+   */
+  private boolean isEditing;
+
+  /**
    * The current task being edited.
    */
   private TaskProxy task;
@@ -76,10 +82,10 @@
   }
 
   public void deleteTask() {
-    if (task == null) {
-      doCancelTask();
-    } else {
+    if (isEditing) {
       doDeleteTask();
+    } else {
+      doCancelTask();
     }
   }
 
@@ -148,12 +154,14 @@
 
     if (taskId == null) {
       // Create a new task.
+      isEditing = false;
       view.setEditing(false);
       TaskRequest request = clientFactory.getRequestFactory().taskRequest();
       task = request.create(TaskProxy.class);
       view.getEditorDriver().edit(task, request);
     } else {
       // Lock the display until the task is loaded.
+      isEditing = true;
       view.setEditing(true);
       view.setLocked(true);
 
diff --git a/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.java b/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.java
index a970973..bbcfadb 100644
--- a/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.java
+++ b/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.java
@@ -18,8 +18,12 @@
 import com.google.gwt.canvas.dom.client.CssColor;
 import com.google.gwt.cell.client.AbstractCell;
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.MediaElement;
+import com.google.gwt.dom.client.VideoElement;
 import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.media.client.Video;
 import com.google.gwt.place.shared.Place;
 import com.google.gwt.place.shared.PlaceChangeEvent;
 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
@@ -37,11 +41,16 @@
 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
 import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.DeckLayoutPanel;
+import com.google.gwt.user.client.ui.DialogBox;
 import com.google.gwt.user.client.ui.DockLayoutPanel;
+import com.google.gwt.user.client.ui.FlowPanel;
 import com.google.gwt.user.client.ui.HasOneWidget;
 import com.google.gwt.user.client.ui.IsWidget;
 import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.google.gwt.view.client.SelectionChangeEvent;
 import com.google.gwt.view.client.SingleSelectionModel;
@@ -124,10 +133,15 @@
    */
   private static final String CHART_URL_ATTRIBUTE = "chart";
 
+  /**
+   * The external URL of the video tutorial for browsers that do not support
+   * video.
+   */
+  private static final String EXTERNAL_TUTORIAL_URL = "http://www.youtube.com/watch?v=oHg5SJYRHA0";
+
   private static MobileWebAppShellDesktopUiBinder uiBinder = GWT
       .create(MobileWebAppShellDesktopUiBinder.class);
 
-  // TODO(jlabanca): Record and show a help video tutorial.
   @UiField
   Anchor helpLink;
 
@@ -163,6 +177,16 @@
   private PieChart pieChart;
 
   /**
+   * The {@link DialogBox} used to display the tutorial.
+   */
+  private PopupPanel tutoralPopup;
+
+  /**
+   * The video tutorial.
+   */
+  private Video tutorialVideo;
+
+  /**
    * Construct a new {@link MobileWebAppShellDesktop}.
    * 
    * @param clientFactory the {@link ClientFactory} of shared resources
@@ -255,6 +279,13 @@
             updatePieChart(event.getTasks());
           }
         });
+
+    // Show a tutorial when the help link is clicked.
+    helpLink.addClickHandler(new ClickHandler() {
+      public void onClick(ClickEvent event) {
+        showTutorial();
+      }
+    });
   }
 
   public boolean isTaskListIncluded() {
@@ -287,6 +318,74 @@
   }
 
   /**
+   * Show a tutorial video.
+   */
+  private void showTutorial() {
+    // Reuse the tutorial dialog if it is already created.
+    if (tutoralPopup != null) {
+      // Reset the video.
+      // TODO(jlabanca): Is cache-control=private making the video non-seekable?
+      if (tutorialVideo != null) {
+        tutorialVideo.setSrc(tutorialVideo.getCurrentSrc());
+      }
+
+      tutoralPopup.center();
+      return;
+    }
+
+    /*
+     * Forward the use to YouTube if video is not supported or if none of the
+     * source formats are supported.
+     */
+    tutorialVideo = Video.createIfSupported();
+    if (tutorialVideo == null) {
+      Label label = new Label("Click the link below to view the tutoral:");
+      Anchor anchor = new Anchor(EXTERNAL_TUTORIAL_URL, EXTERNAL_TUTORIAL_URL);
+      anchor.setTarget("_blank");
+      FlowPanel panel = new FlowPanel();
+      panel.add(label);
+      panel.add(anchor);
+
+      tutoralPopup = new PopupPanel(true, false);
+      tutoralPopup.setWidget(panel);
+      tutoralPopup.setGlassEnabled(true);
+
+      // Hide the popup when the user clicks the link.
+      anchor.addClickHandler(new ClickHandler() {
+        public void onClick(ClickEvent event) {
+          tutoralPopup.hide();
+        }
+      });
+
+      tutoralPopup.center();
+      return;
+    }
+
+    // Add the video sources.
+    tutorialVideo.addSource("video/tutorial.ogv", VideoElement.TYPE_OGG);
+    tutorialVideo.addSource("video/tutorial.mp4", VideoElement.TYPE_MP4);
+
+    // Setup the video player.
+    tutorialVideo.setControls(true);
+    tutorialVideo.setAutoplay(true);
+
+    // Put the video in a dialog.
+    final DialogBox popup = new DialogBox(false, false);
+    popup.setText("Tutorial");
+    VerticalPanel vPanel = new VerticalPanel();
+    vPanel.add(tutorialVideo);
+    vPanel.add(new Button("Close", new ClickHandler() {
+      public void onClick(ClickEvent event) {
+        tutorialVideo.pause();
+        popup.hide();
+      }
+    }));
+    popup.setWidget(vPanel);
+    tutoralPopup = popup;
+    popup.center();
+  }
+
+  /**
    * Update the pie chart with the list of tasks.
    * 
    * @param tasks the list of tasks
diff --git a/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.ui.xml b/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.ui.xml
index 20e857b..401920e 100644
--- a/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.ui.xml
+++ b/samples/mobilewebapp/src/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.ui.xml
@@ -25,7 +25,6 @@
     }
     
     .helpLink {
-      display: none;
       position: absolute;
       top: 10px;
       right: 16px;
@@ -100,7 +99,7 @@
               </g:ScrollPanel>
             </g:center>
 
-            <!-- Pie Chart Legand. -->
+            <!-- Pie Chart Legend. -->
             <g:south
               size="6">
               <g:HTMLPanel>
diff --git a/samples/mobilewebapp/war/WEB-INF/web.xml b/samples/mobilewebapp/war/WEB-INF/web.xml
index d5a080d..144664f 100644
--- a/samples/mobilewebapp/war/WEB-INF/web.xml
+++ b/samples/mobilewebapp/war/WEB-INF/web.xml
@@ -34,5 +34,13 @@
     <extension>wav</extension>
     <mime-type>audio/wav</mime-type>
   </mime-mapping>
+  <mime-mapping>
+    <extension>ogv</extension>
+    <mime-type>video/ogg</mime-type>
+  </mime-mapping>
+  <mime-mapping>
+    <extension>mp4</extension>
+    <mime-type>video/mp4</mime-type>
+  </mime-mapping>
 
 </web-app>
diff --git a/samples/mobilewebapp/war/video/tutorial.mp4 b/samples/mobilewebapp/war/video/tutorial.mp4
new file mode 100644
index 0000000..c80b760
--- /dev/null
+++ b/samples/mobilewebapp/war/video/tutorial.mp4
Binary files differ
diff --git a/samples/mobilewebapp/war/video/tutorial.ogv b/samples/mobilewebapp/war/video/tutorial.ogv
new file mode 100644
index 0000000..75f3d5d
--- /dev/null
+++ b/samples/mobilewebapp/war/video/tutorial.ogv
Binary files differ