org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/NotificationPopup.js
changeset 73 c56c874eef47
child 102 30e0796f3ebb
equal deleted inserted replaced
72:8373462680d7 73:c56c874eef47
       
     1 /*
       
     2 © Copyright 2008 Nokia Corporation. All rights reserved.
       
     3 
       
     4 IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
       
     5 Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
       
     6 and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
       
     7 you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
       
     8 Widget files.
       
     9 
       
    10 In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
       
    11 grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
       
    12 Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
       
    13 CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
       
    14 Widgets.
       
    15 
       
    16 If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
       
    17 redistributions of the WRTKit and Example files.
       
    18 
       
    19 You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
       
    20 that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
       
    21 Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
       
    22 Nokia herein, including but not limited to any patent rights that may be infringed by your products that
       
    23 incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
       
    24 may be incorporated.
       
    25 
       
    26 The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
       
    27 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
       
    28 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
       
    29 PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
       
    30 ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
       
    31 
       
    32 IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
       
    33 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
    34 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
       
    35 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
       
    36 DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
       
    37 OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
       
    38 EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    39 
       
    40 */
       
    41 
       
    42 ///////////////////////////////////////////////////////////////////////////////
       
    43 // The NotificationPopup class handles the display of notifications such as
       
    44 // warnings, information messages and progress indication.
       
    45 
       
    46 // Constructor.
       
    47 function NotificationPopup() {
       
    48     // create notification popup
       
    49     this.containerElement = document.createElement("div");
       
    50     this.containerElement.className = "NotificationPopupContainer";
       
    51     this.popupElement = document.createElement("div");
       
    52     this.popupElement.className = "NotificationPopup";
       
    53     this.typeIndicatorElement = document.createElement("div");
       
    54     this.typeIndicatorElement.className = "NotificationPopupTypeIndicator";
       
    55     this.textElement = document.createElement("div");
       
    56     this.textElement.className = "NotificationPopupText";
       
    57     this.progressBarElement = document.createElement("div");
       
    58     this.progressBarElement.className = "NotificationPopupProgressBar";
       
    59     
       
    60     // assemble popup
       
    61     this.popupElement.appendChild(this.typeIndicatorElement);
       
    62     this.popupElement.appendChild(this.textElement);
       
    63     this.popupElement.appendChild(this.progressBarElement);
       
    64     this.containerElement.appendChild(this.popupElement);
       
    65     
       
    66     // create progress bar image element and initialize it
       
    67     this.progressBarImageElement = document.createElement("img");
       
    68     var self = this;
       
    69     this.progressBarImageElement.addEventListener("load", function() { self.progressBarImageLoadingCompleted(); }, false);
       
    70     this.progressBarImageElement.setAttribute("alt", "");
       
    71     this.progressBarImageURL = this.getProgressBarImage(0);
       
    72     this.progressBarImageElement.src = this.progressBarImageURL;
       
    73     this.progressBarElement.appendChild(this.progressBarImageElement);
       
    74     
       
    75     // init the popup to be fully down
       
    76     this.popupElement.style.top = "100%";
       
    77     
       
    78     // set default popup contents
       
    79     this.setPopupContents(null, null, null);
       
    80 }
       
    81 
       
    82 // Notification container element.
       
    83 NotificationPopup.prototype.containerElement = null;
       
    84 
       
    85 // Notification popup element.
       
    86 NotificationPopup.prototype.popupElement = null;
       
    87 
       
    88 // Type indicator element.
       
    89 NotificationPopup.prototype.typeIndicatorElement = null;
       
    90 
       
    91 // Notification text element.
       
    92 NotificationPopup.prototype.textElement = null;
       
    93 
       
    94 // Progress bar element.
       
    95 NotificationPopup.prototype.progressBarElement = null;
       
    96 
       
    97 // Progress bar image element.
       
    98 NotificationPopup.prototype.progressBarImageElement = null;
       
    99 
       
   100 // Progress bar image URL.
       
   101 NotificationPopup.prototype.progressBarImageURL = null;
       
   102 
       
   103 // Has the progress bar image been loaded?
       
   104 NotificationPopup.prototype.progressBarImageLoaded = false;
       
   105 
       
   106 // Flag that tracks whether we're in the middle of starting to
       
   107 // show a notification popup.
       
   108 NotificationPopup.prototype.processingShowNotification = false;
       
   109 
       
   110 // Notification popup position (0 = hidden, 1 = showing).
       
   111 NotificationPopup.prototype.popupPosition = 0;
       
   112 
       
   113 // Interval for timer ticks (in milliseconds)
       
   114 NotificationPopup.prototype.ANIM_TIMER_INTERVAL = 25;
       
   115 
       
   116 // Animation timer identifier or null if no active timer.
       
   117 NotificationPopup.prototype.animTimerId = null;
       
   118 
       
   119 // Time in milliseconds for the popup animation to complete
       
   120 NotificationPopup.prototype.ANIM_TIME = 300;
       
   121 
       
   122 // Flag that determines the behavior of showNotification(). If set to true
       
   123 // the popup will snap open when showNotification() is called instead of
       
   124 // animation.
       
   125 NotificationPopup.prototype.SHOW_SNAPS_OPEN = true;
       
   126 
       
   127 // Animation direction (0 = no movement, -1 hiding, +1 = showing).
       
   128 NotificationPopup.prototype.animDir = 0;
       
   129 
       
   130 // Auto-hide timer identifier or null if no active timer.
       
   131 NotificationPopup.prototype.autoHideTimerId = null;
       
   132 
       
   133 // The commanded display time.
       
   134 NotificationPopup.prototype.displayTime = -1;
       
   135 
       
   136 // Displays a notification.
       
   137 NotificationPopup.prototype.showNotification = function(displayTime, type, text, progress) {
       
   138     uiLogger.debug("NotificationPopup.showNotification(" + displayTime + ", " + type + ", " + text + ", " + progress + ")");
       
   139     
       
   140     // mark that showNotification() has been called and that we are in
       
   141     // the middle of starting to show the notification popup
       
   142     this.processingShowNotification = true;
       
   143     
       
   144     // remember the display time
       
   145     this.displayTime = displayTime;
       
   146     
       
   147     // attach the popup to the document if not attached
       
   148     if (this.containerElement.parentNode == null) {
       
   149         document.body.appendChild(this.containerElement);
       
   150         uiLogger.debug("Notification popup attached to document");
       
   151     }
       
   152     
       
   153     // set popup contents and update style
       
   154     this.setPopupContents(type, text, progress);
       
   155     
       
   156     // if the progress image is loaded then we can complete the showing
       
   157     // of the notification popup immediately - otherwise the image loaded
       
   158     // allback will complete the process.
       
   159     if (this.progressBarImageLoaded) {
       
   160         this.completeShowNotification();
       
   161     }
       
   162 }
       
   163 
       
   164 // Completes displaying of a notification.
       
   165 // Note: Used internally - don't call this directly.
       
   166 NotificationPopup.prototype.completeShowNotification = function() {
       
   167     uiLogger.debug("NotificationPopup.completeShowNotification()");
       
   168     
       
   169     // animation direction is +1 for showing the popup
       
   170     if (this.popupPosition != 1) {
       
   171         if (this.SHOW_SNAPS_OPEN) {
       
   172             if (this.popupPosition == 0) {
       
   173                 this.popupPosition = 1;
       
   174             }
       
   175         }
       
   176         this.animatePopup(1);
       
   177     }
       
   178     
       
   179     // setup auto hiding if a display time is specified
       
   180     if (this.displayTime > 0) {
       
   181         // stop any existing timer
       
   182         if (this.autoHideTimerId != null) {
       
   183             clearTimeout(this.autoHideTimerId);
       
   184             uiLogger.debug("Auto hide timer stopped");
       
   185         }
       
   186         // set timer to hide notification
       
   187         var self = this;
       
   188         this.autoHideTimerId = setTimeout(function() {
       
   189                                               if (self.displayTime > 0) {
       
   190                                                   self.hideNotification();
       
   191                                               }
       
   192                                           }, this.ANIM_TIME + this.displayTime);
       
   193         uiLogger.debug("Auto hide timer started");
       
   194     }
       
   195     
       
   196     // mark us as no longer processing a show notification call
       
   197     this.processingShowNotification = false;
       
   198 }
       
   199 
       
   200 // Hides the currently displayed notification.
       
   201 NotificationPopup.prototype.hideNotification = function() {
       
   202     uiLogger.debug("NotificationPopup.hideNotification()");
       
   203     // mark us as no longer processing a show notification call
       
   204     this.processingShowNotification = false;
       
   205     
       
   206     // animation direction is -1 for hiding the popup
       
   207     if (this.popupPosition != 0) {
       
   208         this.animatePopup(-1);
       
   209     }
       
   210     
       
   211     // stop auto hide timer if one is set
       
   212     if (this.autoHideTimerId != null) {
       
   213         clearTimeout(this.autoHideTimerId);
       
   214         this.autoHideTimerId = null;
       
   215         uiLogger.debug("Auto hide timer stopped");
       
   216     }
       
   217 }
       
   218 
       
   219 // Starts animation of the popup (1 to show, -1 to hide).
       
   220 NotificationPopup.prototype.animatePopup = function(direction) {
       
   221     uiLogger.debug("NotificationPopup.animatePopup(" + direction + ")");
       
   222     // set the direction and star the animation timer
       
   223     this.animDir = direction;
       
   224     if (this.animTimerId == null) {
       
   225         var self = this;
       
   226         this.animTimerId = setInterval(function() { self.animate(); }, this.ANIM_TIMER_INTERVAL);
       
   227         uiLogger.debug("Notification popup animation started");
       
   228     }
       
   229 }
       
   230 
       
   231 // Callback for animation timer.
       
   232 NotificationPopup.prototype.animate = function() {
       
   233     // calculate new popup position and clamp
       
   234     var animStep = (this.ANIM_TIMER_INTERVAL / this.ANIM_TIME) * this.animDir;
       
   235     var newPos = this.popupPosition + animStep;
       
   236     if (newPos < 0) {
       
   237         newPos = 0;
       
   238     } else if (newPos > 1) {
       
   239         newPos = 1;
       
   240     }
       
   241     
       
   242     // set the new position to the popup element
       
   243     this.popupPosition = newPos;
       
   244     this.popupElement.style.top = (100 - Math.round(this.popupPosition * 100)) + "%";
       
   245     
       
   246     // have we reached the end of the animation?
       
   247     if (newPos == 0 || newPos == 1) {
       
   248         // reset animation direction
       
   249         this.animDir = 0;
       
   250         
       
   251         // remove the popup from the body if its hidden
       
   252         if (newPos == 0) {
       
   253             document.body.removeChild(this.containerElement);
       
   254             uiLogger.debug("Notification popup detached from document");
       
   255         }
       
   256         
       
   257         // stop timer
       
   258         clearTimeout(this.animTimerId);
       
   259         this.animTimerId = null;
       
   260         uiLogger.debug("Notification popup animation stopped");
       
   261     }
       
   262 }
       
   263 
       
   264 // Returns a URL for the progress bar image to use for the specified progress.
       
   265 NotificationPopup.prototype.getProgressBarImage = function(progress) {
       
   266     // path for progress bar images
       
   267     var progressBarImagePath = "WRTKit/Resources/";
       
   268     
       
   269     if (progress < 0) {
       
   270         // unknown progress
       
   271         return progressBarImagePath + "ProgressBarUnknown.gif";
       
   272     } else {
       
   273         // known progress (should be between 0 and 1)
       
   274         var progPct = Math.round(progress * 10) * 10;
       
   275         if (progPct < 0) {
       
   276             progPct = 0;
       
   277         } else if (progPct > 100) {
       
   278             progPct = 100;
       
   279         }
       
   280         return progressBarImagePath + "ProgressBar" + progPct + ".png";
       
   281     }
       
   282 }
       
   283 
       
   284 // Sets the contents of the popup.
       
   285 NotificationPopup.prototype.setPopupContents = function(type, text, progress) {
       
   286     uiLogger.debug("NotificationPopup.setPopupContents(" + type + ", " + text + ", " + progress + ")");
       
   287     
       
   288     // figure out notification type style name
       
   289     var typeName = (type == null) ? "none" : type.toLowerCase();
       
   290     typeName = typeName.charAt(0).toUpperCase() + typeName.substring(1);
       
   291     
       
   292     // set type element class names
       
   293     this.typeIndicatorElement.className = "NotificationPopupTypeIndicator NotificationPopupTypeIndicator" + typeName;
       
   294     
       
   295     // set notification text
       
   296     this.textElement.innerHTML = (text == null) ? "" : text;
       
   297     
       
   298     // set progress
       
   299     this.progressBarElement.style.display = (progress == null) ? "none" : "block";
       
   300     if (progress != null) {
       
   301         var imgURL = this.getProgressBarImage(progress);
       
   302         if (imgURL != this.progressBarImageURL) {
       
   303             // load new image
       
   304             this.progressBarImageLoaded = false;
       
   305             this.progressBarImageURL = imgURL;
       
   306             this.progressBarImageElement.src = imgURL;
       
   307         } else {
       
   308             // the correct image is already loaded
       
   309             this.progressBarImageLoaded = true;
       
   310         }
       
   311     } else {
       
   312         // there is no progress bar so there is no need
       
   313         // to load any progress bar image
       
   314         this.progressBarImageLoaded = true;
       
   315     }
       
   316 }
       
   317 
       
   318 // Callback for notifying the object that its progress bar image completed loading.
       
   319 NotificationPopup.prototype.progressBarImageLoadingCompleted = function() {
       
   320     uiLogger.debug("NotificationPopup.progressBarImageLoadingCompleted()");
       
   321     
       
   322     // mark the progress bar image as loaded
       
   323     this.progressBarImageLoaded = true;
       
   324     
       
   325     // complete the process of displaying the notification popup
       
   326     // if it has been commanded but not yet completed
       
   327     if (this.processingShowNotification) {
       
   328         this.completeShowNotification();
       
   329     }
       
   330 }