Added WRTKit
authortasneems@symbian.org
Mon, 01 Feb 2010 13:47:20 -0800
changeset 73 c56c874eef47
parent 72 8373462680d7
child 74 1f72e81a1aa7
Added WRTKit
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/CheckBox.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ContentPanelFoldIcons.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ControlAssemblyBackground.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/DocumentBackground.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/FormButtonCenter.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/FormButtonLeft.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/FormButtonRight.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ListViewCaptionBackground.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/NotificationPopupBackground.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/NotificationPopupTypeIndicator.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar0.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar10.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar100.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar20.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar30.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar40.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar50.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar60.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar70.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar80.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar90.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBarUnknown.gif
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/RadioButton.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarThumbBottom.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarThumbMiddle.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarThumbTop.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarTrackBottom.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarTrackMiddle.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarTrackTop.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/SeparatorCenter.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/SeparatorLeft.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/SeparatorRight.png
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/Thumbs.db
org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/UI.css
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/ActionControl.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Ajax.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/ContentPanel.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Control.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/FormButton.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Label.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/ListView.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/NavigationButton.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/NotificationPopup.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Scrollbar.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/SelectionControl.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/SelectionList.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/SelectionMenu.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Separator.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/TextArea.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/TextEntryControl.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/TextField.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/UIElement.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/UIInit.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/UIManager.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/View.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/Utils/Logger.js
org.symbian.tools.wrttools/projecttemplates/WRTKit/WRTKit.js
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/CheckBox.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ContentPanelFoldIcons.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ControlAssemblyBackground.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/DocumentBackground.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/FormButtonCenter.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/FormButtonLeft.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/FormButtonRight.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ListViewCaptionBackground.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/NotificationPopupBackground.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/NotificationPopupTypeIndicator.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar0.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar10.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar100.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar20.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar30.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar40.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar50.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar60.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar70.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar80.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBar90.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ProgressBarUnknown.gif has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/RadioButton.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarThumbBottom.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarThumbMiddle.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarThumbTop.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarTrackBottom.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarTrackMiddle.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/ScrollbarTrackTop.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/SeparatorCenter.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/SeparatorLeft.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/SeparatorRight.png has changed
Binary file org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/Thumbs.db has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/Resources/UI.css	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,912 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/******************************************************************************/
+/*        Definition of visuals for the WRTKit user interface toolkit         */
+/******************************************************************************/
+
+/******************************************************************************/
+/* Document body rules */
+
+body {
+    margin: 0px;
+    background: url("DocumentBackground.png") repeat-x fixed;
+    font: normal 12px Arial, sans-serif;
+    color: rgb(0,0,0);
+}
+
+
+/******************************************************************************/
+/* Override default WRT styling for HTML form controls */
+
+/* Textarea when focused */
+textarea:focus {
+    outline: none;
+}
+
+/* Textarea when hovering */
+textarea:hover {
+    outline: none;
+}
+
+/* Select elements when focused */
+select:focus {
+    outline: none;
+}
+
+/* Select elements when hovering */
+select:hover {
+    outline: none;
+}
+
+/* Input elements when focused */
+input:focus {
+    outline: none;
+}
+
+/* Input elements when hovering */
+input:hover {
+    outline: none;
+}
+
+/* Link elements */
+a {
+    text-decoration: none;
+    color: rgb(0,0,0);
+}
+
+/* Links when focused */
+a:focus {
+    background: none;
+    outline: none;
+}
+
+/* Links when hovering */
+a:hover {
+    background: none;
+    outline: none;
+}
+
+
+/******************************************************************************/
+/* Rules for default view and document scrollbar containers */
+
+/* Default view container rules */
+.ViewContainer {
+    margin: 0px 0px 0px 0px;
+}
+
+/* Default document scrollbar container rules */
+.DocumentScrollbarContainer {
+    position: fixed;
+    right: 0px;
+    top: 0px;
+    height: 100%;
+    width: 7px;
+}
+
+
+/******************************************************************************/
+/* View style rules */
+
+/* Rules for the list view */
+.ListView {
+    margin: 0px 0px 0px 0px;
+}
+
+/* Rules for the list view caption */
+.ListViewCaption {
+    background: url("ListViewCaptionBackground.png");
+    height: 35px;
+}
+
+/* Rules for the list view caption text */
+.ListViewCaptionText {
+    font-size: 18px;
+    font-weight: bold;
+    padding: 7px 0px 0px 11px;
+}
+
+/* Rules for the list view control list element */
+.ListViewControlList {
+    margin: 1px 10px 1px 3px;
+}
+
+
+/******************************************************************************/
+/* Control style rules */
+
+/* Rules for control root element (rootElement) */
+.Control {
+    
+}
+
+/* Control assembly rules (assemblyElement) */
+.ControlAssembly {
+    background: url("ControlAssemblyBackground.png") repeat-x;
+    padding: 1px 5px;
+}
+
+/* Control assembly in normal state */
+.ControlAssemblyNormal {
+    background-position: 0px 0px;
+}
+
+/* Control assembly in focused state */
+.ControlAssemblyFocus {
+    background-position: 0px -250px;
+}
+
+/* Control assembly in hovering state */
+.ControlAssemblyHover {
+    background-position: 0px -500px;
+}
+
+/* Control assembly in disabled state */
+.ControlAssemblyDisabled {
+    background-position: 0px 0px;
+}
+
+/* Caption for controls (captionElement) */
+.ControlCaption {
+    font-weight: bold;
+    padding: 3px 0px 0px 3px;
+}
+
+/* Caption for controls in normal state */
+.ControlCaptionNormal {
+    
+}
+
+/* Caption for controls when focused */
+.ControlCaptionFocus {
+    color: rgb(255,255,255);
+}
+
+/* Caption for controls when hovering */
+.ControlCaptionHover {
+    
+}
+
+/* Caption for controls when disabled */
+.ControlCaptionDisabled {
+    color: rgb(125,125,125);
+}
+
+/* Control element rules (controlElement) */
+.ControlElement {
+    padding: 3px 3px 3px 3px;
+}
+
+/******************************************************************************/
+/* Label */
+
+/* Rules for the text value of a Label control */
+.LabelText {
+    
+}
+
+
+/******************************************************************************/
+/* ContentPanel */
+
+/* Caption area rules for non-foldable content panels */
+.ContentPanelCaptionNonFoldable {
+    padding: 3px 0px 0px 3px;
+}
+
+/* Caption area rules for foldable content panels */
+.ContentPanelCaptionFoldable {
+    padding: 4px 0px 3px 3px;
+}
+
+/* Rules for fold toggling element in content panel */
+.ContentPanelFoldToggle {
+    background: url("ContentPanelFoldIcons.png") no-repeat;
+    padding-left: 16px;
+}
+
+/* Collapsed fold */
+.ContentPanelFoldToggleCollapsed {
+    background-position: 0px 0px;
+}
+
+/* Expanded fold */
+.ContentPanelFoldToggleExpanded {
+    background-position: 0px -50px;
+}
+
+/* Rules for the content panel caption text */
+.ContentPanelCaptionText {
+    font-weight: bold;
+}
+
+/* Caption text for content panel in normal state */
+.ContentPanelCaptionTextNormal {
+    
+}
+
+/* Caption text for content panel when focused */
+.ContentPanelCaptionTextFocus {
+    color: rgb(255,255,255);
+}
+
+/* Caption text for content panel when hovering */
+.ContentPanelCaptionTextHover {
+    
+}
+
+/* Caption text for content panel when disabled */
+.ContentPanelCaptionTextDisabled {
+    color: rgb(125,125,125);
+}
+
+/* Rules for content in the content panel */
+.ContentPanelContent {
+    padding: 2px 2px 2px 8px;
+}
+
+
+/******************************************************************************/
+/* FormButton */
+
+/* Rules for form button */
+.FormButton {
+    
+}
+
+/* Rules for form button control element */
+.FormButtonControlElement {
+    
+}
+
+/* Rules for form button table (table) */
+.FormButtonTable {
+    width: 100%;
+    border-spacing: 0px;
+    padding: 0px;
+    table-layout: fixed;
+}
+
+/* Form button row (tr) */
+.FormButtonRow {
+    padding: 0px;
+}
+
+/* Rules for form button left cell (td) */
+.FormButtonLeftCell {
+    width: 8px;
+    height: 26px;
+    background: url("FormButtonLeft.png") no-repeat;
+    padding: 0px;
+}
+
+/* Rules for form button center cell (td) */
+.FormButtonCenterCell {
+    height: 26px;
+    background: url("FormButtonCenter.png") repeat-x;
+    padding: 0px;
+    vertical-align: middle;
+    text-align: center;
+}
+
+/* Rules for form button right cell (td) */
+.FormButtonRightCell {
+    width: 8px;
+    height: 26px;
+    background: url("FormButtonRight.png") no-repeat;
+    padding: 0px;
+}
+
+/* Rules for form button left cell in normal state (td) */
+.FormButtonLeftCellNormal {
+    background-position: 0px 0px;
+}
+
+/* Rules for form button left cell in focused state (td) */
+.FormButtonLeftCellFocus {
+    background-position: 0px -50px;
+}
+
+/* Rules for form button left cell in hover state (td) */
+.FormButtonLeftCellHover {
+    background-position: 0px -100px;
+}
+
+/* Rules for form button left cell in disabled state (td) */
+.FormButtonLeftCellDisabled {
+    background-position: 0px -150px;
+}
+
+/* Rules for form button center cell in normal state (td) */
+.FormButtonCenterCellNormal {
+    background-position: 0px 0px;
+}
+
+/* Rules for form button center cell in focused state (td) */
+.FormButtonCenterCellFocus {
+    background-position: 0px -50px;
+}
+
+/* Rules for form button center cell in hover state (td) */
+.FormButtonCenterCellHover {
+    background-position: 0px -100px;
+}
+
+/* Rules for form button center cell in disabled state (td) */
+.FormButtonCenterCellDisabled {
+    background-position: 0px -150px;
+}
+
+/* Rules for form button left cell in normal state (td) */
+.FormButtonRightCellNormal {
+    background-position: 0px 0px;
+}
+
+/* Rules for form button left cell in focused state (td) */
+.FormButtonRightCellFocus {
+    background-position: 0px -50px;
+}
+
+/* Rules for form button left cell in hover state (td) */
+.FormButtonRightCellHover {
+    background-position: 0px -100px;
+}
+
+/* Rules for form button left cell in disabled state (td) */
+.FormButtonRightCellDisabled {
+    background-position: 0px -150px;
+}
+
+/* Rules for form button text */
+.FormButtonText {
+    font-weight: bold;
+}
+
+/* Form button text in normal state */
+.FormButtonTextNormal {
+    color: rgb(255,255,255);
+}
+
+/* Form button text when focused */
+.FormButtonTextFocus {
+    color: rgb(255,255,255);
+}
+
+/* Form button text when hovering */
+.FormButtonTextHover {
+    color: rgb(255,255,255);
+}
+
+/* Form button text when disabled */
+.FormButtonTextDisabled {
+    color: rgb(200,200,200);
+}
+
+
+/******************************************************************************/
+/* NavigationButton */
+
+/* Rules for navigation button */
+.NavigationButton {
+    
+}
+
+/* Rules for navigation button control element */
+.NavigationButtonControlElement {
+    padding: 3px 3px 3px 3px;
+}
+
+/* Rules for navigation button table (table) */
+.NavigationButtonTable {
+    border-spacing: 0px;
+    padding: 0px;
+}
+
+/* Navigation button row (tr) */
+.NavigationButtonRow {
+    padding: 0px;
+}
+
+/* Rules for navigation button image cell (td) */
+.NavigationButtonImageCell {
+    line-height: 1px;
+    font-size: 1px;
+    vertical-align: middle;
+}
+
+/* Rules for navigation button text cell (td) */
+.NavigationButtonTextCell {
+    vertical-align: middle;
+    padding: 0px;
+}
+
+/* Rules for navigation button image */
+.NavigationButtonImage {
+    padding: 0px 5px 0px 0px;
+}
+
+/* Rules for navigation button text */
+.NavigationButtonText {
+    font-weight: bold;
+}
+
+/* Navigation button text in normal state */
+.NavigationButtonTextNormal {
+    
+}
+
+/* Navigation button text when focused */
+.NavigationButtonTextFocus {
+    color: rgb(255,255,255);
+}
+
+/* Navigation button text when hovering */
+.NavigationButtonTextHover {
+    
+}
+
+/* Navigation button text when disabled */
+.NavigationButtonTextDisabled {
+    color: rgb(125,125,125);
+}
+
+
+/******************************************************************************/
+/* TextField */
+
+/* Rules for textField */
+.TextField {
+    width: 100%;
+    border: 1px solid rgb(0,0,0);
+    background: rgb(255,255,255);
+    margin: 0px 0px 3px 0px;
+}
+
+/* TextField in normal state */
+.TextFieldNormal {
+    
+}
+
+/* TextField in focus state */
+.TextFieldFocus {
+    
+}
+
+/* TextField in hover state */
+.TextFieldHover {
+    
+}
+
+/* TextField in disabled state */
+.TextFieldDisabled {
+    color: rgb(50,50,50);
+    background: rgb(200,200,200);
+}
+
+
+/******************************************************************************/
+/* TextArea */
+
+/* Rules for TextArea */
+.TextArea {
+    width: 100%;
+    border: 1px solid rgb(0,0,0);
+    background: rgb(255,255,255);
+    margin: 0px 0px 3px 0px;
+}
+
+/* TextArea in normal state */
+.TextAreaNormal {
+    
+}
+
+/* TextArea in focus state */
+.TextAreaFocus {
+    
+}
+
+/* TextArea in hover state */
+.TextAreaHover {
+    
+}
+
+/* TextArea in disabled state */
+.TextAreaDisabled {
+    color: rgb(50,50,50);
+    background: rgb(200,200,200);
+}
+
+
+/******************************************************************************/
+/* Separator */
+
+/* Rules for Separator (table) */
+.Separator {
+    width: 100%;
+    padding: 0px;
+    border-spacing: 0px;
+    table-layout: fixed;
+    margin: 3px 0px;
+}
+
+/* Separator row (tr) */
+.SeparatorRow {
+    padding: 0px;
+}
+
+/* Separator left cell (td) */
+.SeparatorLeftCell {
+    width: 5px;
+    height: 2px;
+    background: url("SeparatorLeft.png") no-repeat;
+    padding: 0px;
+}
+
+/* Separator center cell (td) */
+.SeparatorCenterCell {
+    height: 2px;
+    background: url("SeparatorCenter.png") repeat-x;
+    padding: 0px;
+}
+
+/* Separator right cell (td) */
+.SeparatorRightCell {
+    width: 6px;
+    height: 2px;
+    background: url("SeparatorRight.png") no-repeat;
+    padding: 0px;
+}
+
+
+/******************************************************************************/
+/* SelectionMenu */
+
+/* Rules for SelectionMenu select element */
+.SelectionMenu {
+    width: 100%;
+    border: 1px solid rgb(0,0,0);
+    background: rgb(255,255,255);
+    margin: 0px 0px 3px 0px;
+}
+
+/* SelectionMenu in normal state */
+.SelectionMenuNormal {
+    
+}
+
+/* SelectionMenu in focus state */
+.SelectionMenuFocus {
+    
+}
+
+/* SelectionMenu in hover state */
+.SelectionMenuHover {
+    
+}
+
+/* SelectionMenu in disabled state */
+.SelectionMenuDisabled {
+    color: rgb(50,50,50);
+    background: rgb(200,200,200);
+}
+
+/* Rules for SelectionMenu option elements */
+.SelectionMenuOption {
+    background: rgb(255,255,255);
+}
+
+/* SelectionMenu option in normal state */
+.SelectionMenuOptionNormal {
+    
+}
+
+/* SelectionMenu option in focus state */
+.SelectionMenuOptionFocus {
+    
+}
+
+/* SelectionMenu option in hover state */
+.SelectionMenuOptionHover {
+    
+}
+
+/* SelectionMenu option in disabled state */
+.SelectionMenuOptionDisabled {
+    color: rgb(50,50,50);
+    background: rgb(200,200,200);
+}
+
+
+/******************************************************************************/
+/* SelectionList */
+
+/* SelectionList option list element */
+.SelectionList {
+    
+}
+
+/* SelectionList option list element in normal state */
+.SelectionListNormal {
+    
+}
+
+/* SelectionList option list element in focus state */
+.SelectionListFocus {
+    
+}
+
+/* SelectionList option list element in hover state */
+.SelectionListHover {
+    
+}
+
+/* SelectionList option list element in disabled state */
+.SelectionListDisabled {
+    
+}
+
+/* SelectionList option element in single selection mode */
+.SelectionListOptionSingle {
+    padding-left: 19px;
+    background: url("RadioButton.png") no-repeat;
+    height: 16px;
+}
+
+/* SelectionList option element in single selection mode, unchecked normal state */
+.SelectionListOptionSingleUncheckedNormal {
+    background-position: 0px 0px;
+}
+
+/* SelectionList option element in single selection mode, unchecked focus state */
+.SelectionListOptionSingleUncheckedFocus {
+    background-position: 0px -50px;
+}
+
+/* SelectionList option element in single selection mode, unchecked diabled state */
+.SelectionListOptionSingleUncheckedDisabled {
+    background-position: 0px -100px;
+}
+
+/* SelectionList option element in single selection mode, checked normal state */
+.SelectionListOptionSingleCheckedNormal {
+    background-position: 0px -150px;
+}
+
+/* SelectionList option element in single selection mode, checked focus state */
+.SelectionListOptionSingleCheckedFocus {
+    background-position: 0px -200px;
+}
+
+/* SelectionList option element in single selection mode, checked diabled state */
+.SelectionListOptionSingleCheckedDisabled {
+    background-position: 0px -250px;
+}
+
+/* SelectionList option element in multi selection mode */
+.SelectionListOptionMulti {
+    padding-left: 19px;
+    background: url("CheckBox.png") no-repeat;
+    height: 16px;
+}
+
+/* SelectionList option element in multi selection mode, unchecked normal state */
+.SelectionListOptionMultiUncheckedNormal {
+    background-position: 0px 0px;
+}
+
+/* SelectionList option element in multi selection mode, unchecked focus state */
+.SelectionListOptionMultiUncheckedFocus {
+    background-position: 0px -50px;
+}
+
+/* SelectionList option element in multi selection mode, unchecked diabled state */
+.SelectionListOptionMultiUncheckedDisabled {
+    background-position: 0px -100px;
+}
+
+/* SelectionList option element in multi selection mode, checked normal state */
+.SelectionListOptionMultiCheckedNormal {
+    background-position: 0px -150px;
+}
+
+/* SelectionList option element in multi selection mode, checked focus state */
+.SelectionListOptionMultiCheckedFocus {
+    background-position: 0px -200px;
+}
+
+/* SelectionList option element in multi selection mode, checked diabled state */
+.SelectionListOptionMultiCheckedDisabled {
+    background-position: 0px -250px;
+}
+
+/* SelectionList option text */
+.SelectionListOptionText {
+    
+}
+
+/* SelectionList option text in normal state */
+.SelectionListOptionTextNormal {
+    
+}
+
+/* SelectionList option text in focus state */
+.SelectionListOptionTextFocus {
+    color: rgb(255,255,255);
+}
+
+/* SelectionList option text in hover state */
+.SelectionListOptionTextHover {
+    
+}
+
+/* SelectionList option text in disabled state */
+.SelectionListOptionTextDisabled {
+    color: rgb(125,125,125);
+}
+
+
+/******************************************************************************/
+/* Scrollbar */
+
+/* Scrollbar root element */
+.Scrollbar {
+    position: absolute;
+    height: 100%;
+    width: 7px;
+}
+
+/* Top portion of scrollbar track */
+.ScrollbarTrackTop {
+    position: absolute;
+    background: url("ScrollbarTrackTop.png") no-repeat;
+    width: 7px;
+    height: 4px;
+}
+
+/* Middle portion of scrollbar track */
+.ScrollbarTrackMiddle {
+    position: absolute;
+    background: url("ScrollbarTrackMiddle.png") repeat-y;
+    width: 7px;
+}
+
+/* Bottom portion of scrollbar track */
+.ScrollbarTrackBottom {
+    position: absolute;
+    background: url("ScrollbarTrackBottom.png") no-repeat;
+    width: 7px;
+    height: 4px;
+}
+
+/* Top portion of scrollbar thumb */
+.ScrollbarThumbTop {
+    position: absolute;
+    background: url("ScrollbarThumbTop.png") no-repeat;
+    width: 7px;
+    height: 5px;
+}
+
+/* Middle portion of scrollbar thumb */
+.ScrollbarThumbMiddle {
+    position: absolute;
+    background: url("ScrollbarThumbMiddle.png") repeat-y;
+    width: 7px;
+}
+
+/* Bottom portion of scrollbar thumb */
+.ScrollbarThumbBottom {
+    position: absolute;
+    background: url("ScrollbarThumbBottom.png") no-repeat;
+    width: 7px;
+    height: 5px;
+}
+
+
+/******************************************************************************/
+/* NotificationPopup */
+
+/* Container that defines the area for the popup dialog */
+.NotificationPopupContainer {
+    position: fixed;
+    bottom: 0px;
+    left: 50%;
+    margin-left: -115px;
+    width: 230px;
+    height: 85px;
+}
+
+/* Notification popup dialog */
+.NotificationPopup {
+    position: absolute;
+    width: 230px;
+    height: 85px;
+    background: url("NotificationPopupBackground.png") repeat-x;
+    border: 1px solid rgb(0,0,0);
+}
+
+/* Notification type indicator */
+.NotificationPopupTypeIndicator {
+    position: absolute;
+    left: 195px;
+    top: 10px;
+    width: 24px;
+    height: 34px;
+    background: url("NotificationPopupTypeIndicator.png") no-repeat;
+}
+
+/* Notification type indicator for notifications of undefined type */
+.NotificationPopupTypeIndicatorNone {
+    background-position: 0px 0px;
+}
+
+/* Notification type indicator for info notifications */
+.NotificationPopupTypeIndicatorInfo {
+    background-position: 0px -50px;
+}
+
+/* Notification type indicator for warning notifications */
+.NotificationPopupTypeIndicatorWarning {
+    background-position: 0px -100px;
+}
+
+/* Notification type indicator for wait notifications */
+.NotificationPopupTypeIndicatorWait {
+    background-position: 0px -150px;
+}
+
+/* Notification text area */
+.NotificationPopupText {
+    position: absolute;
+    left: 10px;
+    top: 8px;
+    width: 180px;
+    height: 50px;
+}
+
+/* Progress bar */
+.NotificationPopupProgressBar {
+    position: absolute;
+    left: 6px;
+    top: 60px;
+    width: 218px;
+    height: 16px;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/ActionControl.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,144 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (ÒNokiaÓ) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under NokiaÕs copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The ActionControl class is an abstract base class for action controls like
+// buttons. Don't use ActionControl directly.
+
+// Constructor.
+function ActionControl(id, caption) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption);
+    }
+}
+
+// ActionControl inherits from Control.
+ActionControl.prototype = new Control(UI_NO_INIT_ID);
+
+// Reference to the button element.
+ActionControl.prototype.buttonElement = null;
+
+// Reference to the link element.
+ActionControl.prototype.linkElement = null;
+
+// Enabled status.
+ActionControl.prototype.enabled = false;
+
+// Initializer - called from constructor.
+ActionControl.prototype.init = function(id, caption) {
+    uiLogger.debug("ActionControl.init(" + id + ", " + caption + ")");
+    
+    // call superclass initializer
+    Control.prototype.init.call(this, id, caption);
+    
+    // the control defaults to enabled
+    this.enabled = true;
+}
+
+// Common event listeners hookup function called from subclasses.
+ActionControl.prototype.bindActionControlListeners = function() {
+    var self = this;
+    this.linkElement.addEventListener("focus", function() { self.focusStateChanged(true); }, false);
+    this.linkElement.addEventListener("blur", function() { self.focusStateChanged(false); }, false);
+    this.buttonElement.addEventListener("mouseover", function() { self.hoverStateChanged(true); }, false);
+    this.buttonElement.addEventListener("mouseout", function() { self.hoverStateChanged(false); }, false);
+    this.buttonElement.addEventListener("mousedown", function(event) {
+                                                       self.controlClicked(event);
+                                                       event.stopPropagation();
+                                                       event.preventDefault();
+                                                   }, true);
+    this.buttonElement.addEventListener("keydown", function(event) {
+                                                    // center and enter trigger the action
+                                                    if (event.keyCode == 0 || event.keyCode == 13) {
+                                                        self.controlClicked();
+                                                        event.stopPropagation();
+                                                        event.preventDefault();
+                                                    }
+                                                 }, true);
+}
+
+// Returns the enabled state.
+ActionControl.prototype.isEnabled = function() {
+    return this.enabled;
+}
+
+// Sets the enabled state.
+ActionControl.prototype.setEnabled = function(enabled) {
+    uiLogger.debug("ActionControl.setEnabled(" + enabled + ")");
+    // switch the state
+    this.enabled = enabled;
+}
+
+// Sets the focused state for the control.
+// Note: This may not always succeed.
+ActionControl.prototype.setFocused = function(focused) {
+    uiLogger.debug("ActionControl.setFocused(" + focused + ")");
+    if (this.enabled) {
+        if (focused) {
+            this.linkElement.focus();
+        } else {
+            this.linkElement.blur();
+        }
+    }
+}
+
+// Callback for clicks.
+ActionControl.prototype.controlClicked = function(event) {
+    uiLogger.debug("ActionControl.controlClicked()");
+    
+    // if we're enabled then a click results in an action performed event
+    if (this.enabled) {
+        // focus when clicked
+        if (!this.focused) {
+            this.linkElement.focus();
+        }
+        
+        // notify event listeners
+        this.actionPerformed(event);
+    }
+}
+
+// Callback for action performed events.
+ActionControl.prototype.actionPerformed = function(event) {
+    uiLogger.debug("ActionControl.actionPerformed()");
+    // notify event listeners
+    this.fireEvent(this.createEvent("ActionPerformed", event));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Ajax.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,103 @@
+/*
+� Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (�Nokia�) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia�s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Ajax utility calss to create XmlHttpRequest object
+function Ajax() 
+{
+	//	xmlHttpRequest object	
+	var request = null;
+
+    // branch for native XMLHttpRequest object
+    if(window.XMLHttpRequest && !(window.ActiveXObject)) {
+    	try 
+		{
+			request = new XMLHttpRequest();
+			try
+			{
+				//	attach the Bypass code, if the browser is firefox
+				if(netscape.security.PrivilegeManager.enablePrivilege)
+				{
+					//	duplicate the function
+					request._open = request.open;
+					
+					//	redefine the function definition
+					request.open = function(method, url, flag)
+					{
+						try
+						{
+							// Enable Universal Browser Read
+							netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+
+							//	call the native XmlHttpRequest.open method
+							this._open(method, url, flag);
+						}catch(e)
+						{
+							//	call the native XmlHttpRequest.open method
+							this._open(method, url, flag);
+						}
+					}
+				}
+			}
+			catch(e)
+			{
+				//	eatup all exceptions
+			}
+		} 
+		catch(e) {
+			request = null;
+        }
+    // branch for IE/Windows ActiveX version
+    } else if(window.ActiveXObject) {
+       	try {
+        	request = new ActiveXObject("Msxml2.XMLHTTP");
+      	} catch(e) {
+        	try {
+          		request = new ActiveXObject("Microsoft.XMLHTTP");
+        	} catch(e) {
+          		alert('Failed to create XmlHttprequest');
+				return null;
+        	}
+		}
+    }
+	
+	return (request);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/ContentPanel.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,367 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The ContentPanel class is a control for displaying content. The panel
+// can be expanded and collapsed.
+
+// Constructor.
+function ContentPanel(id, caption, content, foldable, expanded) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption, content, foldable, expanded);
+    }
+}
+
+// ContentPanel inherits from Control.
+ContentPanel.prototype = new Control(UI_NO_INIT_ID);
+
+// The element hierarchy in a content panel is as follows:
+//
+// rootElement
+//     assemblyElement
+//         captionElement
+//             foldToggleElement
+//                 captionLinkElement
+//                     captionTextElement
+//     contentElement
+//
+// captionTextElement is moved under foldToggleElement if disabled
+// or captionElement if not foldable
+
+// The fold toggle element used for folding content panels.
+ContentPanel.prototype.foldToggleElement = null;
+
+// The caption link element of this control.
+ContentPanel.prototype.captionLinkElement = null;
+
+// The caption text element of this control.
+ContentPanel.prototype.captionTextElement = null;
+
+// The content element of this control.
+ContentPanel.prototype.contentElement = null;
+
+// The foldable state of this control.
+ContentPanel.prototype.foldable = false;
+
+// The expanded state of this control.
+ContentPanel.prototype.expanded = false;
+
+// Enabled status.
+ContentPanel.prototype.enabled = false;
+
+// Initializer - called from constructor.
+ContentPanel.prototype.init = function(id, caption, content, foldable, expanded) {
+    uiLogger.debug("ContentPanel.init(" + id + ", " + caption + ", " + content + ", " + foldable + ", " + expanded + ")");
+    
+    // call superclass initializer
+    Control.prototype.init.call(this, id, caption);
+    
+    // the control defaults to enabled
+    this.enabled = true;
+    
+    // create caption text element
+    this.captionTextElement = document.createElement("span");
+    
+    // disconnect the control element
+    this.assemblyElement.removeChild(this.controlElement);
+    
+    // set the foldable state
+    this.foldable = foldable;
+    
+    // is this a foldable content panel?
+    if (foldable) {
+        // create fold toggle element
+        this.foldToggleElement = document.createElement("div");
+        this.captionElement.appendChild(this.foldToggleElement);
+        
+        // create caption link and add to caption element
+        this.captionLinkElement = document.createElement("a");
+        this.captionLinkElement.href = "JavaScript:void(0)";
+        this.foldToggleElement.appendChild(this.captionLinkElement);
+        
+        // add the text element to the link element
+        this.captionLinkElement.appendChild(this.captionTextElement);
+        
+        // bind event listeners
+        var self = this;
+        this.captionLinkElement.addEventListener("focus", function() { self.focusStateChanged(true); }, false);
+        this.captionLinkElement.addEventListener("blur", function() { self.focusStateChanged(false); }, false);
+        this.foldToggleElement.addEventListener("mouseover", function() { self.hoverStateChanged(true); }, false);
+        this.foldToggleElement.addEventListener("mouseout", function() { self.hoverStateChanged(false); }, false);
+        this.foldToggleElement.addEventListener("mousedown", function(event) {
+                                                                 self.captionClicked();
+                                                                 event.stopPropagation();
+                                                                 event.preventDefault();
+                                                             }, true);
+        this.foldToggleElement.addEventListener("keydown", function(event) {
+                                                               // center and enter trigger the action
+                                                               if (event.keyCode == 0 || event.keyCode == 13) {
+                                                                   self.captionClicked();
+                                                                   event.stopPropagation();
+                                                                   event.preventDefault();
+                                                               }
+                                                           }, true);
+        
+        this.expanded = expanded;
+    } else {
+        // since this is not a foldable panel the content should be expanded
+        this.expanded = true;
+        
+        // add the text element directly to the caption element
+        this.captionElement.appendChild(this.captionTextElement);
+    }
+    
+    // create content element
+    this.contentElement = document.createElement("div");
+    this.contentElement.style.display = this.expanded ? "block" : "none";
+    this.rootElement.appendChild(this.contentElement);
+    
+    // set caption, content and expanded state
+    this.setCaption(caption);
+    this.setContent(content);
+    
+    // update style
+    this.updateStyleFromState();
+}
+
+// Returns the enabled state.
+ContentPanel.prototype.isEnabled = function() {
+    return this.enabled;
+}
+
+// Sets the enabled state.
+ContentPanel.prototype.setEnabled = function(enabled) {
+    uiLogger.debug("ContentPanel.setEnabled(" + enabled + ")");
+    
+    // bail out early if there is no change in state
+    if (this.enabled == enabled) {
+        return;
+    }
+    
+    // set the enabled state
+    this.enabled = enabled;
+    
+    // is this a foldable content?
+    if (this.foldable) {
+         // the caption link must be disabled
+        if (this.enabled) {
+            // diabled -> enabled
+            this.foldToggleElement.removeChild(this.captionTextElement);
+            this.foldToggleElement.appendChild(this.captionLinkElement);
+            this.captionLinkElement.appendChild(this.captionTextElement);
+        } else {
+            // enabled -> diabled
+            this.captionLinkElement.removeChild(this.captionTextElement);
+            this.foldToggleElement.removeChild(this.captionLinkElement);
+            this.foldToggleElement.appendChild(this.captionTextElement);
+        }
+    }
+    
+    // update style
+    this.updateStyleFromState();    
+}
+
+// Returns the caption; null if none.
+ContentPanel.prototype.getCaption = function() {
+    return this.caption;
+}
+
+// Sets the caption; null if none.
+ContentPanel.prototype.setCaption = function(caption) {
+    // bail out if the caption text element has not been created
+    // this is to prevent the superclass init calling this before
+    // we've initialized our custom caption
+    if (this.captionTextElement == null)
+        return;
+    
+    uiLogger.debug("ContentPanel.setCaption(" + caption + ")");
+    
+    // set the display style
+    this.captionElement.style.display = (caption == null) ? "none" : "block";
+    
+    // set the caption
+    this.caption = caption;
+    this.captionTextElement.innerHTML = (caption == null) ? "" : caption;
+    
+    // update style
+    this.updateStyleFromState();
+}
+
+// Returns the content.
+ContentPanel.prototype.getContent = function() {
+    return this.contentElement.innerHTML;
+}
+
+// Sets the content.
+ContentPanel.prototype.setContent = function(content) {
+    uiLogger.debug("ContentPanel.setContent(" + content + ")");
+    this.contentElement.innerHTML = (content == null) ? "" : content;
+}
+
+// Returns the focusable state for the control.
+ContentPanel.prototype.isFocusable = function() {
+    // a content panel is focusable if it's foldable and enabled
+    return (this.foldable && this.enabled);
+}
+
+// Sets the focused state for the control.
+// Note: This may not always succeed.
+ContentPanel.prototype.setFocused = function(focused) {
+    uiLogger.debug("ContentPanel.setFocused(" + focused + ")");
+    if (this.enabled && this.foldable) {
+        if (focused) {
+            this.captionLinkElement.focus();
+        } else {
+            this.captionLinkElement.blur();
+        }
+    }
+    // note that this.focused gets set as a result of focusStateChanged() being called
+    // rather than setting it explicitly here
+}
+
+// Returns the expanded state.
+ContentPanel.prototype.isExpanded = function() {
+    return this.expanded;
+}
+
+// Sets the expanded state.
+ContentPanel.prototype.setExpanded = function(expanded) {
+    uiLogger.debug("ContentPanel.setExpanded(" + expanded + ")");
+    
+    // make sure only foldable content panels are folded
+    if (!this.foldable) {
+        uiLogger.warn("Cannot fold a non-foldable content panel!");
+        return;
+    }
+    
+    this.expanded = expanded;
+    if (this.expanded) {
+        // expand
+        this.contentElement.style.display = "block";
+        
+        // find out control top and bottom
+        var controlTop = this.getAbsoluteTop(this.rootElement);
+        var controlHeight = this.rootElement.clientHeight;
+        var controlBottom = controlTop + controlHeight;
+        
+        // find out the viewport top and bottom
+        var viewportTop = window.scrollY;
+        var viewportHeight = window.innerHeight;
+        var viewportBottom = viewportTop + viewportHeight;
+        
+        // make sure the control is positioned so that it can be seen
+        var overflow = controlBottom - viewportBottom;
+        if (overflow > 0) {
+            // there's overflow so we need to scroll to get the control
+            // into the viewport - however not so far that the control
+            // goes past the viewport top.
+            var distanceToTop = controlTop - viewportTop;
+            var scrollAmount = Math.min(overflow, distanceToTop);
+            window.scrollBy(0, scrollAmount);
+        }
+    } else {
+        // collapse
+        this.contentElement.style.display = "none";
+    }
+    
+    // notify event listeners
+    this.fireEvent(this.createEvent("ExpandedStateChanged", this.expanded));
+    
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Returns the absolute position (y) of the given element.
+ContentPanel.prototype.getAbsoluteTop = function(element) {
+    // traverse from element to root and add top-offset
+    // for each element we find on the way
+    var absTop = 0;
+    while (element != null) {
+        absTop += element.offsetTop;
+        element = element.offsetParent;
+    }
+    return absTop;
+}
+
+// Callback for when the caption is clicked.
+ContentPanel.prototype.captionClicked = function() {
+    uiLogger.debug("ContentPanel.captionClicked()");
+    
+    // if we're enabled then a click results toggling the expanded state
+    if (this.enabled) {
+        // focus when clicked
+        if (!this.focused) {
+            this.captionLinkElement.focus();
+        }
+        
+        // toggle the expanded state
+        this.setExpanded(!this.expanded);
+    }
+}
+
+// Updates the style of the control to reflects the state of the control.
+ContentPanel.prototype.updateStyleFromState = function() {
+    uiLogger.debug("ContentPanel.updateStyleFromState()");
+
+    // determine the state name
+    var stateName = this.getStyleStateName();
+    
+    // set root element class name
+    this.setClassName(this.rootElement, "Control");
+
+    // set the control assembly class names
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssembly" + stateName);
+    
+    if (this.foldable) {
+        // foldable content panel
+        this.setClassName(this.captionElement, "ContentPanelCaptionFoldable");
+        this.setClassName(this.foldToggleElement, "ContentPanelFoldToggle ContentPanelFoldToggle" + (this.expanded ? "Expanded" : "Collapsed"));
+    } else {
+        // non-folding
+        this.setClassName(this.captionElement, "ContentPanelCaptionNonFoldable");
+    }
+    
+    // set the content caption text class names
+    this.setClassName(this.captionTextElement, "ContentPanelCaptionText ContentPanelCaptionText" + stateName);
+    
+    // set the content element class names
+    this.setClassName(this.contentElement, "ContentPanelContent");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Control.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,231 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The Control class is an abstract base class for all user interface controls.
+
+// Constructor.
+function Control(id, caption) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption);
+    }
+}
+
+// Control inherits from UIElement.
+Control.prototype = new UIElement(UI_NO_INIT_ID);
+
+// The view that control belongs to.
+Control.prototype.view = null;
+
+// Is the control focused?
+Control.prototype.focused = false;
+
+// Is the pointer over this control?
+Control.prototype.hovering = false;
+
+// The element hierarchy in a control is as follows:
+//
+// rootElement
+//     assemblyElement
+//         captionElement
+//         controlElement
+//
+// The assembly element groups the portion of a control that typically handle
+// the visual effects for focus and hover states. Having a separate root and
+// assembly elements allows other elements to be added to a control without
+// them being affected by the CSS rules of the assembly element.
+
+// The assembly element of this control.
+Control.prototype.assemblyElement = null;
+
+// The caption of this control; null if none.
+Control.prototype.caption = null;
+
+// The caption element of this control.
+Control.prototype.captionElement = null;
+
+// The control element of this control.
+Control.prototype.controlElement = null;
+
+// Initializer - called from constructor.
+Control.prototype.init = function(id, caption) {
+    uiLogger.debug("Control.init(" + id + ", " + caption + ")");
+    
+    // call superclass initializer
+    UIElement.prototype.init.call(this, id);
+    
+    // create assembly, caption and control elements
+    this.assemblyElement = document.createElement("div");
+    this.captionElement = document.createElement("div");
+    this.assemblyElement.appendChild(this.captionElement);
+    this.controlElement = document.createElement("div");
+    this.assemblyElement.appendChild(this.controlElement);
+    this.rootElement.appendChild(this.assemblyElement);
+    
+    // set the caption
+    // style is not updated because the subclass will update the style later
+    // when it has completely initialized the component
+    this.setCaption(caption, true);
+}
+
+// Returns the caption; null if none.
+Control.prototype.getCaption = function() {
+    return this.caption;
+}
+
+// Sets the caption; null if none.
+Control.prototype.setCaption = function(caption, noStyleUpdate) {
+    uiLogger.debug("Control.setCaption(" + caption + ")");
+    
+    // set the display style
+    this.captionElement.style.display = (caption == null) ? "none" : "block";
+    
+    // set the caption
+    this.caption = caption;
+    this.captionElement.innerHTML = (caption == null) ? "" : caption;
+    
+    // update style
+    if (!noStyleUpdate) {
+        this.updateStyleFromState();
+    }
+}
+
+// Returns the enabled state.
+// Override this in subclasses as required to implement the state change.
+Control.prototype.isEnabled = function() {
+    return false;
+}
+
+// Sets the enabled state.
+// Override this in subclasses as required to implement the state change.
+Control.prototype.setEnabled = function(enabled) {
+    uiLogger.debug("Control.setEnabled(" + enabled + ")");
+}
+
+// Returns the focusable state for the control.
+// Defaults focusable if enabled - override this in subclasses as required.
+Control.prototype.isFocusable = function() {
+    return this.isEnabled();
+}
+
+// Returns the focused state for the control.
+Control.prototype.isFocused = function() {
+    return this.focused;
+}
+
+// Sets the focused state for the control.
+// Note: This may not always succeed.
+// Override this in subclasses as required to implement the state change.
+Control.prototype.setFocused = function(focused) {
+    uiLogger.debug("Control.setFocused(" + focused + ")");
+    // note that this.focused gets set as a result of focusStateChanged() being called
+    // rather than setting it explicitly here
+}
+
+// Called when the focus state has changed for this control.
+Control.prototype.focusStateChanged = function(focused) {
+    uiLogger.debug("Control.focusStateChanged(" + focused + ")");
+    if (this.focused != focused) {
+        this.focused = focused;
+        
+        // let the view know about the focus change
+        if (this.view != null) {
+            this.view.focusedControlChanged(focused ? this : null);
+        }
+        
+        // update the style from the current state
+        this.updateStyleFromState();
+        
+        // notify event listeners
+        this.fireEvent(this.createEvent("FocusStateChanged", focused));
+    }
+}
+
+// Called when the hover state has changed for this control.
+Control.prototype.hoverStateChanged = function(hovering) {
+    uiLogger.debug("Control.hoverStateChanged(" + hovering + ")");
+    if (this.hovering != hovering) {
+        this.hovering = hovering;
+        
+        // update the style from the current state
+        this.updateStyleFromState();
+        
+        // notify event listeners
+        this.fireEvent(this.createEvent("HoverStateChanged", hovering));
+    }
+}
+
+// Helper method that returns the state name for the current state.
+Control.prototype.getStyleStateName = function() {
+    var focusable = this.isFocusable();
+    if (focusable && this.focused) {
+        return "Focus";
+    } else if (focusable && this.hovering) {
+        return "Hover";
+    } else if (!this.isEnabled()) {
+        return "Disabled";
+    } else {
+        return "Normal";
+    }
+}
+
+// Resets the state tracking for focus and hover.
+// Override this in subclasses as required to implement the state reset.
+Control.prototype.resetFocusState = function() {
+    uiLogger.debug("Control.resetFocusState()");
+    this.hovering = false;
+    this.focused = false;
+    this.updateStyleFromState();
+}
+
+// Helper function that sets a classname for an element.
+// Only sets the class name if it actually is different from the current value.
+Control.prototype.setClassName = function(element, className) {
+    if (element.className != className) {
+        element.className = className;
+    }
+}
+
+// Updates the style of the control to reflects the state of the control.
+// Override this in subclasses as required to implement the state change.
+Control.prototype.updateStyleFromState = function() {
+    uiLogger.debug("Control.updateStyleFromState()");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/FormButton.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,177 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The FormButton class implements a button control for use in form-style UIs.
+
+// Constructor.
+function FormButton(id, text) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, text);
+    }
+}
+
+// FormButton inherits from ActionControl.
+FormButton.prototype = new ActionControl(UI_NO_INIT_ID);
+
+// Button table element.
+FormButton.prototype.tableElement = null;
+
+// Button table row element.
+FormButton.prototype.tableRowElement = null;
+
+// Button table left cell element.
+FormButton.prototype.tableLeftCellElement = null;
+
+// Button table center cell element.
+FormButton.prototype.tableCenterCellElement = null;
+
+// Button text element.
+FormButton.prototype.textElement = null;
+
+// Button table right cell element.
+FormButton.prototype.tableRightCellElement = null;
+
+// Initializer - called from constructor.
+FormButton.prototype.init = function(id, text) {
+    uiLogger.debug("FormButton.init(" + id + ", " + text + ")");
+    
+    // call superclass initializer
+    ActionControl.prototype.init.call(this, id, null);
+    
+    // remove caption element
+    this.assemblyElement.removeChild(this.captionElement);
+    
+    // construct the button
+    this.buttonElement = document.createElement("div");
+    this.tableElement = document.createElement("table");
+    this.tableRowElement = document.createElement("tr");
+    this.tableLeftCellElement = document.createElement("td");
+    this.tableCenterCellElement = document.createElement("td");
+    this.linkElement = document.createElement("a");
+    this.linkElement.href = "JavaScript:void(0)";
+    this.textElement = document.createElement("span");
+    this.tableRightCellElement = document.createElement("td");
+    this.tableElement.appendChild(this.tableRowElement);
+    this.tableRowElement.appendChild(this.tableLeftCellElement);
+    this.tableRowElement.appendChild(this.tableCenterCellElement);
+    this.tableCenterCellElement.appendChild(this.linkElement);
+    this.linkElement.appendChild(this.textElement);
+    this.tableRowElement.appendChild(this.tableRightCellElement);
+    this.buttonElement.appendChild(this.tableElement);
+    this.controlElement.appendChild(this.buttonElement);
+    
+    // set the text
+    this.setText(text);
+    
+    // bind event listeners
+    this.bindActionControlListeners();
+    
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Sets the enabled state.
+FormButton.prototype.setEnabled = function(enabled) {
+    uiLogger.debug("FormButton.setEnabled(" + enabled + ")");
+    
+    // bail out early if there is no change in state
+    if (this.enabled == enabled) {
+        return;
+    }
+    
+    // set the enabled state
+    this.enabled = enabled;
+    
+    if (this.enabled) {
+        // diabled -> enabled
+        this.tableCenterCellElement.removeChild(this.textElement);
+        this.tableCenterCellElement.appendChild(this.linkElement);
+        this.linkElement.appendChild(this.textElement);
+    } else {
+        // enabled -> diabled
+        this.linkElement.removeChild(this.textElement);
+        this.tableCenterCellElement.removeChild(this.linkElement);
+        this.tableCenterCellElement.appendChild(this.textElement);
+    }
+    
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Returns the button text.
+FormButton.prototype.getText = function() {
+    return this.textElement.innerHTML;
+}
+
+// Sets the button text.
+FormButton.prototype.setText = function(text) {
+    uiLogger.debug("FormButton.setText(" + text + ")");
+    this.textElement.innerHTML = (text == null) ? "" : text;;
+}
+
+// Updates the style of the control to reflects the state of the control.
+FormButton.prototype.updateStyleFromState = function() {
+    uiLogger.debug("FormButton.updateStyleFromState()");
+    
+    // determine the state name
+    var stateName = this.getStyleStateName();
+    
+    // set root element class name
+    this.setClassName(this.rootElement, "Control");
+    
+    // set the control assembly class names
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssemblyNormal");
+    
+    // control element
+    this.setClassName(this.controlElement, "ControlElement FormButtonControlElement");
+    
+    // set the button table class names
+    this.setClassName(this.buttonElement, "FormButton");
+    this.setClassName(this.tableElement, "FormButtonTable");
+    this.setClassName(this.tableRowElement, "FormButtonRow");
+    this.setClassName(this.tableLeftCellElement, "FormButtonLeftCell FormButtonLeftCell" + stateName);
+    this.setClassName(this.tableCenterCellElement, "FormButtonCenterCell FormButtonLeftCell" + stateName);
+    this.setClassName(this.tableRightCellElement, "FormButtonRightCell FormButtonLeftCell" + stateName);
+    
+    // set the button text class name
+    this.setClassName(this.textElement, "FormButtonText FormButtonText" + stateName);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Label.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,105 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The Label class implements a control that displays textual content.
+
+// Constructor.
+function Label(id, caption, text) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption, text);
+    }
+}
+
+// Label inherits from Control.
+Label.prototype = new Control(UI_NO_INIT_ID);
+
+// Content element for label text.
+Label.prototype.contentElement = null;
+
+// Initializer - called from constructor.
+Label.prototype.init = function(id, caption, text) {
+    uiLogger.debug("Label.init(" + id + ", " + caption + ", " + text + ")");
+    
+    // call superclass initializer
+    Control.prototype.init.call(this, id, caption);
+    
+    // create content element
+    this.contentElement = document.createElement("div");
+    this.controlElement.appendChild(this.contentElement);
+    
+    // set the text
+    this.setText(text);
+}
+
+// Returns the enabled state for the control.
+Label.prototype.isEnabled = function() {
+    return true;
+}
+
+// Returns the focusable state for the control.
+Label.prototype.isFocusable = function() {
+    return false;
+}
+
+// Returns the control text.
+Label.prototype.getText = function() {
+    return this.contentElement.innerHTML;
+}
+
+// Sets the text for the control.
+Label.prototype.setText = function(text) {
+    uiLogger.debug("Label.setText(" + text + ")");
+    this.contentElement.innerHTML = (text == null) ? "" : text;
+    this.updateStyleFromState();
+}
+
+// Updates the style of the control to reflects the state of the control.
+Label.prototype.updateStyleFromState = function() {
+    uiLogger.debug("Label.updateStyleFromState()");
+    
+    // set element class names
+    this.setClassName(this.rootElement, "Control");
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssemblyNormal");
+    this.setClassName(this.captionElement, "ControlCaption ControlCaptionNormal");
+    this.setClassName(this.controlElement, "ControlElement");
+    this.setClassName(this.contentElement, "LabelText");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/ListView.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,189 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The ListView class implements a vertical list view that hosts controls
+// as child components.
+
+// Constructor.
+function ListView(id, caption) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption);
+    }
+}
+
+// ListView inherits from View.
+ListView.prototype = new View(UI_NO_INIT_ID);
+
+// The caption of this view; null if none.
+ListView.prototype.caption = null;
+
+// The caption element of this view.
+ListView.prototype.captionElement = null;
+
+// The caption text element of this view.
+ListView.prototype.captionTextElement = null;
+
+// Root HTML element for controls.
+ListView.prototype.listElement = null;
+
+// List of controls in the view.
+ListView.prototype.controls = null;
+
+// Initializer for ListView.
+ListView.prototype.init = function(id, caption) {
+    uiLogger.debug("ListView.init(" + id + ", " + caption + ")");
+    
+    // call superclass initializer
+    View.prototype.init.call(this, id);
+    
+    // init control array
+    this.controls = [];
+    
+    // set style class name for root element
+    this.rootElement.className = "ListView";
+    
+    // create caption and caption text elements
+    this.captionElement = document.createElement("div");
+    this.captionElement.className = "ListViewCaption";
+    this.captionTextElement = document.createElement("div");
+    this.captionTextElement.className = "ListViewCaptionText";
+    this.captionElement.appendChild(this.captionTextElement);
+    this.rootElement.appendChild(this.captionElement);
+    
+    // create root element for controls and add to the view root element
+    this.listElement = document.createElement("div");
+    this.listElement.className = "ListViewControlList";
+    this.rootElement.appendChild(this.listElement);
+    
+    // set the caption
+    this.setCaption(caption);
+}
+
+// Returns the caption; null if none.
+ListView.prototype.getCaption = function() {
+    return this.caption;
+}
+
+// Sets the caption; null if none.
+ListView.prototype.setCaption = function(caption) {
+    uiLogger.debug("ListView.setCaption(" + caption + ")");
+    
+    // set the display style
+    this.captionElement.style.display = (caption == null) ? "none" : "block";
+    
+    // set the caption
+    this.caption = caption;
+    this.captionTextElement.innerHTML = (caption == null) ? "" : caption;
+}
+
+// Returns an array of controls in the view.
+ListView.prototype.getControls = function() {
+    return this.controls;
+}
+
+// Adds a control to the view.
+ListView.prototype.addControl = function(control) {
+    uiLogger.debug("ListView.addControl(" + control + ")");
+    
+    // add the control to the controls array and attach it to the list element
+    this.controls.push(control);
+    this.listElement.appendChild(control.rootElement);
+    control.view = this;
+}
+
+// Inserts a control to the view before the specified control.
+ListView.prototype.insertControl = function(control, beforeControl) {
+    uiLogger.debug("ListView.insertControl(" + control + ", " + beforeControl + ")");
+    
+    // iterate through current controls
+    for (var i = 0; i < this.controls.length; i++) {
+        // is this the control we should insert before?
+        if (this.controls[i] == beforeControl) {
+            // we found the control to insert before - insert here and connect to list element
+            this.controls.splice(i, 0, control);
+            this.listElement.insertBefore(control.rootElement, beforeControl.rootElement);
+            control.view = this;
+            return;
+        }
+    }
+    
+    // the control wasn't found so we'll add it last
+    this.addControl(control);
+}
+
+// Removes a control from the view.
+ListView.prototype.removeControl = function(control) {
+    uiLogger.debug("ListView.removeControl(" + control + ")");
+    
+    // iterate through current controls
+    for (var i = 0; i < this.controls.length; i++) {
+        // is this the control we should remove?
+        if (this.controls[i] == control) {
+            // we found the control to remove - remove it from the list element
+            this.controls.splice(i, 1);
+            this.listElement.removeChild(control.rootElement);
+            control.view = null;
+        }
+    }
+}
+
+// Attempts to focus the first focusable control.
+ListView.prototype.focusFirstControl = function() {
+    uiLogger.debug("ListView.focusFirstControl()");
+    for (var i = 0; i < this.controls.length; i++) {
+        // is this control focusable?
+        var control = this.controls[i];
+        if (control.isFocusable()) {
+            control.setFocused(true);
+            break;
+        }
+    }
+}
+
+// Attempts to reset all control focus states.
+// Override in subclasses as required.
+ListView.prototype.resetControlFocusStates = function() {
+    uiLogger.debug("ListView.resetControlFocusStates()");
+    for (var i = 0; i < this.controls.length; i++) {
+        this.controls[i].resetFocusState();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/NavigationButton.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,220 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The NavigationButton class implements a button control for use in
+// navigational contexts in menu-style UIs.
+
+// Constructor.
+function NavigationButton(id, image, text) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, image, text);
+    }
+}
+
+// NavigationButton inherits from ActionControl.
+NavigationButton.prototype = new ActionControl(UI_NO_INIT_ID);
+
+// Button table element.
+NavigationButton.prototype.tableElement = null;
+
+// Button table row element.
+NavigationButton.prototype.tableRowElement = null;
+
+// Button table left cell element.
+NavigationButton.prototype.tableLeftCellElement = null;
+
+// Button table right cell element.
+NavigationButton.prototype.tableRightCellElement = null;
+
+// Button image element.
+NavigationButton.prototype.imageElement = null;
+
+// Button link element.
+NavigationButton.prototype.linkElement = null;
+
+// Button text element.
+NavigationButton.prototype.textElement = null;
+
+// Initializer - called from constructor.
+NavigationButton.prototype.init = function(id, image, text) {
+    uiLogger.debug("NavigationButton.init(" + id + ", " + image + ", " + text + ")");
+    
+    // call superclass initializer
+    ActionControl.prototype.init.call(this, id, null);
+    
+    // remove caption element
+    this.assemblyElement.removeChild(this.captionElement);
+    
+    // construct the button
+    this.buttonElement = document.createElement("div");
+    this.tableElement = document.createElement("table");
+    this.tableRowElement = document.createElement("tr");
+    this.tableLeftCellElement = document.createElement("td");
+    this.tableRightCellElement = document.createElement("td");
+    this.imageElement = null;
+    this.linkElement = document.createElement("a");
+    this.linkElement.href = "JavaScript:void(0)";
+    this.textElement = document.createElement("span");
+    this.tableElement.appendChild(this.tableRowElement);
+    this.tableRowElement.appendChild(this.tableLeftCellElement);
+    this.tableRowElement.appendChild(this.tableRightCellElement);
+    this.tableRightCellElement.appendChild(this.linkElement);
+    this.linkElement.appendChild(this.textElement);
+    this.buttonElement.appendChild(this.tableElement);
+    this.controlElement.appendChild(this.buttonElement);
+    
+    // set the image and text
+    this.setImage(image);
+    this.setText(text);
+    
+    // bind event listeners
+    this.bindActionControlListeners();
+    
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Sets the enabled state.
+NavigationButton.prototype.setEnabled = function(enabled) {
+    uiLogger.debug("NavigationButton.setEnabled(" + enabled + ")");
+    
+    // bail out early if there is no change in state
+    if (this.enabled == enabled) {
+        return;
+    }
+    
+    // set the enabled state
+    this.enabled = enabled;
+    
+    if (this.enabled) {
+        // diabled -> enabled
+        this.tableRightCellElement.removeChild(this.textElement);
+        this.tableRightCellElement.appendChild(this.linkElement);
+        this.linkElement.appendChild(this.textElement);
+    } else {
+        // enabled -> diabled
+        this.linkElement.removeChild(this.textElement);
+        this.tableRightCellElement.removeChild(this.linkElement);
+        this.tableRightCellElement.appendChild(this.textElement);
+    }
+    
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Returns the button image (URL); null if none.
+NavigationButton.prototype.getImage = function() {
+    return (this.imageElement != null) ? this.imageElement.src : null;
+}
+
+// Sets the button image (URL); null if none.
+NavigationButton.prototype.setImage = function(image) {
+    uiLogger.debug("NavigationButton.setImage(" + image + ")");
+    
+    if (image == null) {
+        // remove image - if any
+        if (this.imageElement != null) {
+            this.tableLeftCellElement.removeChild(this.imageElement);
+        }
+    } else {
+        // default to not append image element
+        var append = false;
+        
+        // create image element if one doesn't exist
+        if (this.imageElement == null) {
+            this.imageElement = document.createElement("img");
+            this.imageElement.setAttribute("alt", "");
+            append = true;
+        }
+        
+        // set image source URL
+        this.imageElement.src = image;
+        
+        // append the image element to the left cell?
+        if (append) {
+            this.tableLeftCellElement.appendChild(this.imageElement);
+        }
+    }
+}
+
+// Returns the button text.
+NavigationButton.prototype.getText = function() {
+    return this.textElement.innerHTML;
+}
+
+// Sets the button text.
+NavigationButton.prototype.setText = function(text) {
+    uiLogger.debug("NavigationButton.setText(" + text + ")");
+    this.textElement.innerHTML = (text == null) ? "" : text;;
+}
+
+// Updates the style of the control to reflects the state of the control.
+NavigationButton.prototype.updateStyleFromState = function() {
+    uiLogger.debug("NavigationButton.updateStyleFromState()");
+    
+    // determine the state name
+    var stateName = this.getStyleStateName();
+    
+    // set root element class name
+    this.setClassName(this.rootElement, "Control");
+    
+    // set the control assembly class names
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssembly" + stateName);
+    
+    // control element
+    this.setClassName(this.controlElement, "ControlElement NavigationButtonControlElement");
+    
+    // set the button table class names
+    this.setClassName(this.buttonElement, "NavigationButton");
+    this.setClassName(this.tableElement, "NavigationButtonTable");
+    this.setClassName(this.tableRowElement, "NavigationButtonRow");
+    this.setClassName(this.tableLeftCellElement, "NavigationButtonImageCell");
+    this.setClassName(this.tableRightCellElement, "NavigationButtonTextCell");
+    
+    // set image class names
+    if (this.imageElement) {
+        this.setClassName(this.imageElement, "NavigationButtonImage");
+    }
+    
+    // set the button text class name
+    this.setClassName(this.textElement, "NavigationButtonText NavigationButtonText" + stateName);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/NotificationPopup.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,330 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The NotificationPopup class handles the display of notifications such as
+// warnings, information messages and progress indication.
+
+// Constructor.
+function NotificationPopup() {
+    // create notification popup
+    this.containerElement = document.createElement("div");
+    this.containerElement.className = "NotificationPopupContainer";
+    this.popupElement = document.createElement("div");
+    this.popupElement.className = "NotificationPopup";
+    this.typeIndicatorElement = document.createElement("div");
+    this.typeIndicatorElement.className = "NotificationPopupTypeIndicator";
+    this.textElement = document.createElement("div");
+    this.textElement.className = "NotificationPopupText";
+    this.progressBarElement = document.createElement("div");
+    this.progressBarElement.className = "NotificationPopupProgressBar";
+    
+    // assemble popup
+    this.popupElement.appendChild(this.typeIndicatorElement);
+    this.popupElement.appendChild(this.textElement);
+    this.popupElement.appendChild(this.progressBarElement);
+    this.containerElement.appendChild(this.popupElement);
+    
+    // create progress bar image element and initialize it
+    this.progressBarImageElement = document.createElement("img");
+    var self = this;
+    this.progressBarImageElement.addEventListener("load", function() { self.progressBarImageLoadingCompleted(); }, false);
+    this.progressBarImageElement.setAttribute("alt", "");
+    this.progressBarImageURL = this.getProgressBarImage(0);
+    this.progressBarImageElement.src = this.progressBarImageURL;
+    this.progressBarElement.appendChild(this.progressBarImageElement);
+    
+    // init the popup to be fully down
+    this.popupElement.style.top = "100%";
+    
+    // set default popup contents
+    this.setPopupContents(null, null, null);
+}
+
+// Notification container element.
+NotificationPopup.prototype.containerElement = null;
+
+// Notification popup element.
+NotificationPopup.prototype.popupElement = null;
+
+// Type indicator element.
+NotificationPopup.prototype.typeIndicatorElement = null;
+
+// Notification text element.
+NotificationPopup.prototype.textElement = null;
+
+// Progress bar element.
+NotificationPopup.prototype.progressBarElement = null;
+
+// Progress bar image element.
+NotificationPopup.prototype.progressBarImageElement = null;
+
+// Progress bar image URL.
+NotificationPopup.prototype.progressBarImageURL = null;
+
+// Has the progress bar image been loaded?
+NotificationPopup.prototype.progressBarImageLoaded = false;
+
+// Flag that tracks whether we're in the middle of starting to
+// show a notification popup.
+NotificationPopup.prototype.processingShowNotification = false;
+
+// Notification popup position (0 = hidden, 1 = showing).
+NotificationPopup.prototype.popupPosition = 0;
+
+// Interval for timer ticks (in milliseconds)
+NotificationPopup.prototype.ANIM_TIMER_INTERVAL = 25;
+
+// Animation timer identifier or null if no active timer.
+NotificationPopup.prototype.animTimerId = null;
+
+// Time in milliseconds for the popup animation to complete
+NotificationPopup.prototype.ANIM_TIME = 300;
+
+// Flag that determines the behavior of showNotification(). If set to true
+// the popup will snap open when showNotification() is called instead of
+// animation.
+NotificationPopup.prototype.SHOW_SNAPS_OPEN = true;
+
+// Animation direction (0 = no movement, -1 hiding, +1 = showing).
+NotificationPopup.prototype.animDir = 0;
+
+// Auto-hide timer identifier or null if no active timer.
+NotificationPopup.prototype.autoHideTimerId = null;
+
+// The commanded display time.
+NotificationPopup.prototype.displayTime = -1;
+
+// Displays a notification.
+NotificationPopup.prototype.showNotification = function(displayTime, type, text, progress) {
+    uiLogger.debug("NotificationPopup.showNotification(" + displayTime + ", " + type + ", " + text + ", " + progress + ")");
+    
+    // mark that showNotification() has been called and that we are in
+    // the middle of starting to show the notification popup
+    this.processingShowNotification = true;
+    
+    // remember the display time
+    this.displayTime = displayTime;
+    
+    // attach the popup to the document if not attached
+    if (this.containerElement.parentNode == null) {
+        document.body.appendChild(this.containerElement);
+        uiLogger.debug("Notification popup attached to document");
+    }
+    
+    // set popup contents and update style
+    this.setPopupContents(type, text, progress);
+    
+    // if the progress image is loaded then we can complete the showing
+    // of the notification popup immediately - otherwise the image loaded
+    // allback will complete the process.
+    if (this.progressBarImageLoaded) {
+        this.completeShowNotification();
+    }
+}
+
+// Completes displaying of a notification.
+// Note: Used internally - don't call this directly.
+NotificationPopup.prototype.completeShowNotification = function() {
+    uiLogger.debug("NotificationPopup.completeShowNotification()");
+    
+    // animation direction is +1 for showing the popup
+    if (this.popupPosition != 1) {
+        if (this.SHOW_SNAPS_OPEN) {
+            if (this.popupPosition == 0) {
+                this.popupPosition = 1;
+            }
+        }
+        this.animatePopup(1);
+    }
+    
+    // setup auto hiding if a display time is specified
+    if (this.displayTime > 0) {
+        // stop any existing timer
+        if (this.autoHideTimerId != null) {
+            clearTimeout(this.autoHideTimerId);
+            uiLogger.debug("Auto hide timer stopped");
+        }
+        // set timer to hide notification
+        var self = this;
+        this.autoHideTimerId = setTimeout(function() {
+                                              if (self.displayTime > 0) {
+                                                  self.hideNotification();
+                                              }
+                                          }, this.ANIM_TIME + this.displayTime);
+        uiLogger.debug("Auto hide timer started");
+    }
+    
+    // mark us as no longer processing a show notification call
+    this.processingShowNotification = false;
+}
+
+// Hides the currently displayed notification.
+NotificationPopup.prototype.hideNotification = function() {
+    uiLogger.debug("NotificationPopup.hideNotification()");
+    // mark us as no longer processing a show notification call
+    this.processingShowNotification = false;
+    
+    // animation direction is -1 for hiding the popup
+    if (this.popupPosition != 0) {
+        this.animatePopup(-1);
+    }
+    
+    // stop auto hide timer if one is set
+    if (this.autoHideTimerId != null) {
+        clearTimeout(this.autoHideTimerId);
+        this.autoHideTimerId = null;
+        uiLogger.debug("Auto hide timer stopped");
+    }
+}
+
+// Starts animation of the popup (1 to show, -1 to hide).
+NotificationPopup.prototype.animatePopup = function(direction) {
+    uiLogger.debug("NotificationPopup.animatePopup(" + direction + ")");
+    // set the direction and star the animation timer
+    this.animDir = direction;
+    if (this.animTimerId == null) {
+        var self = this;
+        this.animTimerId = setInterval(function() { self.animate(); }, this.ANIM_TIMER_INTERVAL);
+        uiLogger.debug("Notification popup animation started");
+    }
+}
+
+// Callback for animation timer.
+NotificationPopup.prototype.animate = function() {
+    // calculate new popup position and clamp
+    var animStep = (this.ANIM_TIMER_INTERVAL / this.ANIM_TIME) * this.animDir;
+    var newPos = this.popupPosition + animStep;
+    if (newPos < 0) {
+        newPos = 0;
+    } else if (newPos > 1) {
+        newPos = 1;
+    }
+    
+    // set the new position to the popup element
+    this.popupPosition = newPos;
+    this.popupElement.style.top = (100 - Math.round(this.popupPosition * 100)) + "%";
+    
+    // have we reached the end of the animation?
+    if (newPos == 0 || newPos == 1) {
+        // reset animation direction
+        this.animDir = 0;
+        
+        // remove the popup from the body if its hidden
+        if (newPos == 0) {
+            document.body.removeChild(this.containerElement);
+            uiLogger.debug("Notification popup detached from document");
+        }
+        
+        // stop timer
+        clearTimeout(this.animTimerId);
+        this.animTimerId = null;
+        uiLogger.debug("Notification popup animation stopped");
+    }
+}
+
+// Returns a URL for the progress bar image to use for the specified progress.
+NotificationPopup.prototype.getProgressBarImage = function(progress) {
+    // path for progress bar images
+    var progressBarImagePath = "WRTKit/Resources/";
+    
+    if (progress < 0) {
+        // unknown progress
+        return progressBarImagePath + "ProgressBarUnknown.gif";
+    } else {
+        // known progress (should be between 0 and 1)
+        var progPct = Math.round(progress * 10) * 10;
+        if (progPct < 0) {
+            progPct = 0;
+        } else if (progPct > 100) {
+            progPct = 100;
+        }
+        return progressBarImagePath + "ProgressBar" + progPct + ".png";
+    }
+}
+
+// Sets the contents of the popup.
+NotificationPopup.prototype.setPopupContents = function(type, text, progress) {
+    uiLogger.debug("NotificationPopup.setPopupContents(" + type + ", " + text + ", " + progress + ")");
+    
+    // figure out notification type style name
+    var typeName = (type == null) ? "none" : type.toLowerCase();
+    typeName = typeName.charAt(0).toUpperCase() + typeName.substring(1);
+    
+    // set type element class names
+    this.typeIndicatorElement.className = "NotificationPopupTypeIndicator NotificationPopupTypeIndicator" + typeName;
+    
+    // set notification text
+    this.textElement.innerHTML = (text == null) ? "" : text;
+    
+    // set progress
+    this.progressBarElement.style.display = (progress == null) ? "none" : "block";
+    if (progress != null) {
+        var imgURL = this.getProgressBarImage(progress);
+        if (imgURL != this.progressBarImageURL) {
+            // load new image
+            this.progressBarImageLoaded = false;
+            this.progressBarImageURL = imgURL;
+            this.progressBarImageElement.src = imgURL;
+        } else {
+            // the correct image is already loaded
+            this.progressBarImageLoaded = true;
+        }
+    } else {
+        // there is no progress bar so there is no need
+        // to load any progress bar image
+        this.progressBarImageLoaded = true;
+    }
+}
+
+// Callback for notifying the object that its progress bar image completed loading.
+NotificationPopup.prototype.progressBarImageLoadingCompleted = function() {
+    uiLogger.debug("NotificationPopup.progressBarImageLoadingCompleted()");
+    
+    // mark the progress bar image as loaded
+    this.progressBarImageLoaded = true;
+    
+    // complete the process of displaying the notification popup
+    // if it has been commanded but not yet completed
+    if (this.processingShowNotification) {
+        this.completeShowNotification();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Scrollbar.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,173 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The Scrollbar class is an implementation of a user interface element that
+// indicates the current viewport position in a document.
+
+// Constructor.
+function Scrollbar(parentElement) {
+    uiLogger.debug("Scrollbar(" + parentElement + ")");
+    
+    // get the parent element
+    this.parentElement = parentElement;
+    
+    // create the root element
+    this.rootElement = document.createElement("div");
+    this.rootElement.className = "Scrollbar";
+    this.rootElement.style.visibility = "hidden";
+    
+    // create the scrollbar
+    // the scrollbar consists of a root element with six children
+    // (three track elements and three thumb elements)
+    
+    // track
+    this.trackTopElement = document.createElement("div");
+    this.trackTopElement.className = "ScrollbarTrackTop";
+    this.trackMiddleElement = document.createElement("div");
+    this.trackMiddleElement.className = "ScrollbarTrackMiddle";
+    this.trackBottomElement = document.createElement("div");
+    this.trackBottomElement.className = "ScrollbarTrackBottom";
+    
+    // thumb
+    this.thumbTopElement = document.createElement("div");
+    this.thumbTopElement.className = "ScrollbarThumbTop";
+    this.thumbMiddleElement = document.createElement("div");
+    this.thumbMiddleElement.className = "ScrollbarThumbMiddle";
+    this.thumbBottomElement = document.createElement("div");
+    this.thumbBottomElement.className = "ScrollbarThumbBottom";
+    
+    // assemble and attach the scrollbar
+    this.rootElement.appendChild(this.trackTopElement);
+    this.rootElement.appendChild(this.trackMiddleElement);
+    this.rootElement.appendChild(this.trackBottomElement);
+    this.rootElement.appendChild(this.thumbTopElement);
+    this.rootElement.appendChild(this.thumbMiddleElement);
+    this.rootElement.appendChild(this.thumbBottomElement);
+    this.parentElement.appendChild(this.rootElement);
+    
+    // bring the scrollbar up to date
+    this.update(0, 100, 100);
+}
+
+// Parent element for the scrollbar.
+Scrollbar.prototype.parentElement = null;
+
+// Root HTML element in the scrollbar.
+Scrollbar.prototype.rootElement = null;
+
+// Scrollbar track top element.
+Scrollbar.prototype.trackTopElement = null;
+
+// Scrollbar track middle element.
+Scrollbar.prototype.trackMiddleElement = null;
+
+// Scrollbar track bottom element.
+Scrollbar.prototype.trackBottomElement = null;
+
+// Scrollbar thumb top element.
+Scrollbar.prototype.thumbTopElement = null;
+
+// Scrollbar thumb middle element.
+Scrollbar.prototype.thumbMiddleElement = null;
+
+// Scrollbar thumb bottom element.
+Scrollbar.prototype.thumbBottomElement = null;
+
+// Is the scrollbar needed?
+Scrollbar.prototype.scrollbarNeeded = false;
+
+// Updates the scrollbar.
+Scrollbar.prototype.update = function(scrollY, viewportHeight, documentHeight) {
+    // figure out current heights
+    var scrollbarHeight = this.rootElement.clientHeight;
+    var trackTopHeight = this.trackTopElement.clientHeight;
+    var trackBottomHeight = this.trackBottomElement.clientHeight;
+    var thumbTopHeight = this.thumbTopElement.clientHeight;
+    var thumbBottomHeight = this.thumbBottomElement.clientHeight;
+    
+    // scrollable height is the larger of document and viewport heights
+    var scrollableHeight = documentHeight;
+    var scrollbarNeeded = true;
+    if (viewportHeight >= documentHeight) {
+        scrollableHeight = viewportHeight;
+        scrollbarNeeded = false;
+    }
+    
+    // show or hide scrollbar?
+    if (scrollbarNeeded != this.scrollbarNeeded) {
+        this.scrollbarNeeded = scrollbarNeeded;
+        this.rootElement.style.visibility = scrollbarNeeded ? "visible" : "hidden";
+    }
+    
+    // calculate thumb top position...
+    var thumbTopPct = scrollY / scrollableHeight;
+    var thumbTop = scrollbarHeight * thumbTopPct;
+    // ...and bottom position...
+    var thumbBottomPct = (scrollY + viewportHeight) / scrollableHeight;
+    var thumbBottom = scrollbarHeight * thumbBottomPct;
+    
+    // ...and thumb height
+    var thumbHeight = thumbBottom - thumbTop;
+    
+    // ensure that the thumb is not too small
+    var thumbMinHeight = thumbTopHeight + thumbBottomHeight;
+    if (thumbHeight < thumbMinHeight) {
+        var underflow = thumbMinHeight - thumbHeight;
+        // adjust thumb top pos assuming a shorter scrollbar track
+        var thumbMid = (scrollbarHeight - underflow) * ((thumbTopPct + thumbBottomPct) / 2) + (underflow / 2);
+        thumbTop = thumbMid - (thumbMinHeight / 2);
+        thumbBottom = thumbTop + thumbMinHeight;
+        thumbHeight = thumbBottom - thumbTop;
+    }
+    
+    // position and size track element (add 1 to the middle section height for rounding errors)
+    this.trackTopElement.style.top = "0px";
+    this.trackMiddleElement.style.top = Math.round(trackTopHeight) + "px";
+    this.trackMiddleElement.style.height = Math.round(scrollbarHeight - trackTopHeight - trackBottomHeight + 1) + "px";
+    this.trackBottomElement.style.top = Math.round(scrollbarHeight - trackTopHeight) + "px";
+    
+    // position and size thumb element (add 1 to the middle section height for rounding errors)
+    this.thumbTopElement.style.top = Math.round(thumbTop) + "px";
+    this.thumbMiddleElement.style.top = Math.round(thumbTop + thumbTopHeight) + "px";
+    this.thumbMiddleElement.style.height = Math.round(thumbHeight - thumbTopHeight - thumbBottomHeight + 1) + "px";
+    this.thumbBottomElement.style.top = Math.round(thumbBottom - thumbBottomHeight) + "px";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/SelectionControl.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,189 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The SelectionControl class is an abstract base class for controls that lets
+// the user select one or more options from a list of options. Don't use
+// SelectionControl directly.
+
+// Constructor.
+function SelectionControl(id, caption, options, multipleSelection, selected) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption, options, multipleSelection, selected);
+    }
+}
+
+// SelectionControl inherits from Control.
+SelectionControl.prototype = new Control(UI_NO_INIT_ID);
+
+// List of options.
+SelectionControl.prototype.options = null;
+
+// The single selected option in single selection controls
+// or list of options in multi selection controls.
+SelectionControl.prototype.selected = null;
+
+// Single or multiple selection.
+SelectionControl.prototype.multipleSelection = false;
+
+// Initializer - called from constructor.
+SelectionControl.prototype.init = function(id, caption, options, multipleSelection, selected) {
+    uiLogger.debug("SelectionControl.init(" + id + ", " + caption + ", " + options + ", " + multipleSelection + ", " + selected + ")");
+    
+    // call superclass initializer
+    Control.prototype.init.call(this, id, caption);
+    
+    // set the multiple selection property
+    this.multipleSelection = multipleSelection;
+    
+    // init options and selected (makes copies of the original arrays)
+    this.options = (options != null) ? options.slice(0) : [];
+    if (multipleSelection) {
+        this.selected = (selected == null) ? [] : selected.slice(0);
+    } else {
+        this.selected = selected;
+    }
+    this.validateSelected();
+}
+
+// Returns true if the control is a multiple selection control; false if single.
+SelectionControl.prototype.isMultipleSelection = function() {
+    return this.multipleSelection;
+}
+
+// Returns true if the specified option is selected; false if not.
+SelectionControl.prototype.isSelected = function(option) {
+    if (this.multipleSelection) {
+        // multiple selection
+        // iterate through all selected options and look for the specified option
+        for (var i = 0; i < this.selected.length; i++) {
+            if (this.selected[i] == option) {
+                return true;
+            }
+        }
+        return false;
+    } else {
+        // single selection
+        return (this.selected == option);
+    }
+}
+
+// Returns the currently selected option in a single selection control or
+// an array of selected options in a multiple selection control. If there are
+// no selected options a single selection control returns null and a multiple
+// selection control returns an empty array.
+SelectionControl.prototype.getSelected = function() {
+    return this.multipleSelection ? this.selected.slice(0) : this.selected;
+}
+
+// Sets the currently selected options. Pass a single option in a single selection
+// control or an array of selected controls in a multiple selection control. To
+// deselect all options pass null in a single selection control and an empty array
+// in a multiple selection control.
+// Override in sublcasses to provide full implementation.
+SelectionControl.prototype.setSelected = function(selected) {
+    this.selected = this.multipleSelection ? selected.slice(0) : selected;
+    // make sure the selected option or options are legal
+    this.validateSelected();
+}
+
+// Ensures that the selected option or options exist among the options in this control.
+SelectionControl.prototype.validateSelected = function() {
+    if (this.multipleSelection) {
+        // multiple selection
+        // iterate through all selected options and ensure they exist among the options
+        for (var i = 0; i < this.selected.length; i++) {
+            // check that the selected option exists among the options
+            var found = false;
+            for (var j = 0; j < this.options.length; j++) {
+                if (this.options[j] == this.selected[i]) {
+                    // found - stop looking for this option
+                    found = true;
+                    break;
+                }
+            }
+            // not found - remove this selected element
+            if (!found) {
+                this.selected.splice(i, 1);
+                // since we removed an entry we must re-check this position
+                i--;
+            }
+        }
+    } else {
+        // single selection
+        if (this.selected != null) {
+            // check that the selected option exists among the options
+            for (var i = 0; i < this.options.length; i++) {
+                if (this.options[i] == this.selected) {
+                    // found - we're done
+                    return;
+                }
+            }
+            // not found - remove the selection
+            this.selected = null;
+        }
+    }
+}
+
+// Returns the options in the control as an array of option objects with
+// a value and text property.
+SelectionControl.prototype.getOptions = function() {
+    return this.options;
+}
+
+// Sets the options in the control.
+// Override in sublcasses to provide full implementation.
+SelectionControl.prototype.setOptions = function(options) {
+    this.options = options.slice(0);
+    // make sure the selected option or options are legal
+    this.validateSelected();
+}
+
+// Returns the option that has the specified value; null if none.
+SelectionControl.prototype.getOptionForValue = function(value) {
+    // iterate through all options and look for a match
+    for (var i = 0; i < this.options.length; i++) {
+        if (this.options[i].value == value) {
+            return this.options[i];
+        }
+    }
+    return null;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/SelectionList.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,355 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The SelectionList class implements a single or multi selection control
+// that lets users select one or more options from a list of options.
+
+// Constructor.
+function SelectionList(id, caption, options, multipleSelection, selected) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption, options, multipleSelection, selected);
+    }
+}
+
+// SelectionList inherits from SelectionControl.
+SelectionList.prototype = new SelectionControl(UI_NO_INIT_ID);
+
+// Root element for options.
+SelectionList.prototype.optionListElement = null;
+
+// Array for tracking option elements.
+SelectionList.prototype.optionElements = null;
+
+// Tracking for currently focused option; null if none.
+SelectionList.prototype.focusedOption = null;
+
+// Enabled status.
+SelectionList.prototype.enabled = false;
+
+// Initializer - called from constructor.
+SelectionList.prototype.init = function(id, caption, options, multipleSelection, selected) {
+    uiLogger.debug("SelectionList.init(" + id + ", " + caption + ", " + options + ", " + multipleSelection + ", " + selected + ")");
+    
+    // call superclass initializer
+    SelectionControl.prototype.init.call(this, id, caption, options, multipleSelection, selected);
+    
+    // create option list element
+    this.optionListElement = document.createElement("div");
+    this.controlElement.appendChild(this.optionListElement);
+    
+    // the control defaults to enabled
+    this.enabled = true;
+    
+    // init option element arrays
+    this.optionElements = [];
+    
+    // update the option elements to match the options in this control
+    this.updateOptionElements();
+}
+
+// Returns the enabled state.
+SelectionList.prototype.isEnabled = function() {
+    return this.enabled;
+}
+
+// Sets the enabled state.
+SelectionList.prototype.setEnabled = function(enabled) {
+    uiLogger.debug("SelectionList.setEnabled(" + enabled + ")");
+    // switch the state and update the the control
+    this.enabled = enabled;
+    this.updateOptionElements();
+}
+
+// Sets the focused state for the control.
+// Note: This may not always succeed.
+SelectionList.prototype.setFocused = function(focused) {
+    uiLogger.debug("SelectionList.setFocused(" + focused + ")");
+    if (this.enabled && this.optionElements.length > 0) {
+        if (focused) {
+            this.optionElements[0].link.focus();
+        } else {
+            this.optionElements[0].link.blur();
+        }
+    }
+}
+
+// Sets the currently selected options. Pass a single option in a single selection
+// control or an array of selected controls in a multiple selection control. To
+// deselect all options pass null in a single selection control and an empty array
+// in a multiple selection control.
+SelectionList.prototype.setSelected = function(selected) {
+    // call superclass setSelected()
+    SelectionControl.prototype.setSelected.call(this, selected);
+    this.updateStyleFromState();
+}
+
+// Sets the options in the control.
+SelectionList.prototype.setOptions = function(options) {
+    // call superclass setOptions()
+    SelectionControl.prototype.setOptions.call(this, options);
+    this.updateOptionElements();
+}
+
+// Updates the option elements for the control element.
+SelectionList.prototype.updateOptionElements = function() {
+    uiLogger.debug("SelectionControl.updateOptionElements()");
+    
+    // start by removing all current options from the option list element
+    while (this.optionListElement.firstChild != null) {
+        this.optionListElement.removeChild(this.optionListElement.firstChild);
+    }
+    
+    // iterate through the options and add (and possibly create) a
+    // properly configured option element for each option
+    for (var i = 0; i < this.options.length; i++) {
+        // get the option and option element we're working on
+        var option = this.options[i];
+        
+        // option, link and text elements for this option
+        var optionElement;
+        var optionLinkElement;
+        var optionTextElement;
+        
+        // get the elements
+        if (i == this.optionElements.length) {
+            // we need to create a new option element...
+            optionElement = document.createElement("div");
+            
+            // ...and a new option link element...
+            optionLinkElement = document.createElement("a");
+            optionLinkElement.href = "JavaScript:void(0)";
+            
+            // ...and a new option text element
+            optionTextElement = document.createElement("span");
+            
+            // hook up event listeners to the element
+            var self = this;
+            optionLinkElement.addEventListener("focus", function(event) { self.optionFocusStateChanged(event, true); }, false);
+            optionLinkElement.addEventListener("blur", function(event) { self.optionFocusStateChanged(event, false); }, false);
+            optionElement.addEventListener("mouseover", function() { self.hoverStateChanged(true); }, false);
+            optionElement.addEventListener("mouseout", function() { self.hoverStateChanged(false); }, false);
+            optionElement.addEventListener("mousedown", function(event) {
+                                                               self.optionClicked(event)
+                                                               event.stopPropagation();
+                                                               event.preventDefault();
+                                                        }, true);
+            optionElement.addEventListener("keydown", function(event) {
+                                                            // center and enter trigger the action
+                                                            if (event.keyCode == 0 || event.keyCode == 13) {
+                                                                self.optionClicked(event)
+                                                                event.stopPropagation();
+                                                                event.preventDefault();
+                                                            }
+                                                      }, true);
+            
+            // add the elements to the option element array
+            this.optionElements.push({ option: optionElement, link: optionLinkElement, text: optionTextElement });
+        } else {
+            // we already have ready elements so we'll reuse them
+            optionElement = this.optionElements[i].option;
+            optionLinkElement = this.optionElements[i].link;
+            optionTextElement = this.optionElements[i].text;
+            
+            // remove the option link element from its current parent - if any
+            if (optionLinkElement.parentNode != null) {
+                optionLinkElement.parentNode.removeChild(optionLinkElement);
+            }
+            
+            // remove the option text element from its current parent - if any
+            if (optionTextElement.parentNode != null) {
+                optionTextElement.parentNode.removeChild(optionTextElement);
+            }
+        }
+        
+        // set the option text
+        optionTextElement.innerHTML = option.text;
+        
+        // hook up the option to the control
+        if (this.enabled) {
+            // add the option link element to the option element
+            optionElement.appendChild(optionLinkElement);
+            // add the text element to the option element
+            optionLinkElement.appendChild(optionTextElement);
+        } else {
+            // add the text element directly to the control element
+            optionElement.appendChild(optionTextElement);
+        }
+        // add the option element to the option list element
+        this.optionListElement.appendChild(optionElement);
+    }
+    
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Callback for focus state change events.
+SelectionList.prototype.optionFocusStateChanged = function(event, focused) {
+    uiLogger.debug("SelectionControl.optionFocusStateChanged()");
+    
+    // get the event source option
+    var option = null;
+    var optionElement = null;
+    for (var i = 0; i < this.optionElements.length; i++) {
+        optionElement = this.optionElements[i];
+        if (optionElement.link == event.currentTarget) {
+            option = this.options[i];
+            break;
+        }
+    }
+    
+    // remember the focused option; or null if none is focused
+    if (focused) {
+        this.focusedOption = option;
+    } else {
+        this.focusedOption = null;
+    }
+    
+    // call the superclass focus state change handler
+    this.focusStateChanged(focused);
+}
+
+// Callback for clicks.
+SelectionList.prototype.optionClicked = function(event) {
+    uiLogger.debug("SelectionControl.optionClicked()");
+    
+    // bail out if we're not enabled
+    if (!this.enabled) {
+        return false;
+    }
+    
+    // get the changed option
+    var option = null;
+    var optionElement = null;
+    for (var i = 0; i < this.optionElements.length; i++) {
+        optionElement = this.optionElements[i];
+        if (optionElement.option == event.currentTarget) {
+            option = this.options[i];
+            break;
+        }
+    }
+    
+    // make sure the option is focused
+    optionElement.link.focus();
+    
+    // toggle the selection
+    if (this.multipleSelection) {
+        // iterate through the selected options and see if this
+        // option is selected. if not then add it to the selection.
+        // if it already is selected then them remove it.
+        var found = false;
+        for (var i = 0; i < this.selected.length; i++) {
+            if (this.selected[i] == option) {
+                // remove from selected set
+                found = true;
+                this.selected.splice(i, 1);
+                break;
+            }
+        }
+        if (!found) {
+            // add to the selected set
+            this.selected.push(option);
+        }
+    } else {
+        // update the selected option
+        this.selected = option;
+    }
+    
+    // update the style
+    this.updateStyleFromState();
+    
+    // notify event listeners
+    this.fireEvent(this.createEvent("SelectionChanged", this.getSelected()));
+}
+
+// Resets the state tracking for focus and hover.
+// Override this in subclasses as required to implement the state reset.
+SelectionList.prototype.resetFocusState = function() {
+    uiLogger.debug("SelectionList.resetFocusState()");
+    this.hovering = false;
+    this.focused = false;
+    this.focusedOption = null;
+    this.updateStyleFromState();
+}
+
+// Updates the style of the control to reflects the state of the control.
+SelectionList.prototype.updateStyleFromState = function() {
+    uiLogger.debug("SelectionList.updateStyleFromState()");
+    
+    // determine the state name
+    var stateName = this.getStyleStateName();
+    
+    // set element class names
+    this.setClassName(this.rootElement, "Control");
+    this.setClassName(this.controlElement, "ControlElement");
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssembly" + stateName);
+    this.setClassName(this.captionElement, "ControlCaption ControlCaption" + stateName);
+    
+    // set option list and option class names
+    this.setClassName(this.optionListElement, "SelectionList SelectionList" + stateName);
+    for (var i = 0; i < this.options.length; i++) {
+        var option = this.options[i];
+        
+        // get the option and option text elements for this option
+        var optionElement = this.optionElements[i].option;
+        var optionTextElement = this.optionElements[i].text;
+        
+        // figure out the option state
+        var optionStateName = this.isSelected(option) ? "Checked" : "Unchecked";
+        if (!this.enabled) {
+            optionStateName += "Disabled";
+        } else if (this.focusedOption == option) {
+            optionStateName += "Focus";
+        } else {
+            optionStateName += "Normal";
+        }
+        
+        // set option element class names
+        if (this.multipleSelection) {
+            this.setClassName(optionElement, "SelectionListOptionMulti SelectionListOptionMulti" + optionStateName);
+        } else {
+            this.setClassName(optionElement, "SelectionListOptionSingle SelectionListOptionSingle" + optionStateName);
+        }
+        
+        // set option text class names
+        this.setClassName(optionTextElement, "SelectionListOptionText SelectionListOptionText" + stateName);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/SelectionMenu.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,204 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The SelectionMenu class implements a single or multi selection control
+// that lets users select one or more options from a menu.
+
+// Constructor.
+function SelectionMenu(id, caption, options, multipleSelection, selected) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption, options, multipleSelection, selected);
+    }
+}
+
+// SelectionMenu inherits from SelectionControl.
+SelectionMenu.prototype = new SelectionControl(UI_NO_INIT_ID);
+
+// Reference to the peer HTML element.
+SelectionControl.prototype.peerElement = null;
+
+// Array for tracking option elements.
+SelectionMenu.prototype.optionElements = null;
+
+// Initializer - called from constructor.
+SelectionMenu.prototype.init = function(id, caption, options, multipleSelection, selected) {
+    uiLogger.debug("SelectionMenu.init(" + id + ", " + caption + ", " + options + ", " + multipleSelection + ", " + selected + ")");
+    
+    // call superclass initializer
+    SelectionControl.prototype.init.call(this, id, caption, options, multipleSelection, selected);
+    
+    // create the control
+    this.peerElement = document.createElement("select");
+    this.peerElement.multiple = multipleSelection;
+    this.controlElement.appendChild(this.peerElement);
+    
+    // init option elements array
+    this.optionElements = [];
+    
+    // update the option elements to match the options in this control
+    this.updateOptionElements();
+    
+    // bind event listeners
+    var self = this;
+    this.peerElement.addEventListener("focus", function() { self.focusStateChanged(true); }, false);
+    this.peerElement.addEventListener("blur", function() { self.focusStateChanged(false); }, false);
+    this.peerElement.addEventListener("mouseover", function() { self.hoverStateChanged(true); }, false);
+    this.peerElement.addEventListener("mouseout", function() { self.hoverStateChanged(false); }, false);
+    this.peerElement.addEventListener("change", function() { self.selectionChanged(); }, false);
+}
+
+// Returns the enabled state.
+SelectionMenu.prototype.isEnabled = function() {
+    return !this.peerElement.disabled;
+}
+
+// Sets the enabled state.
+SelectionMenu.prototype.setEnabled = function(enabled) {
+    uiLogger.debug("SelectionMenu.setEnabled(" + enabled + ")");
+    this.peerElement.disabled = !enabled;
+}
+
+// Sets the focused state for the control.
+// Note: This may not always succeed.
+SelectionMenu.prototype.setFocused = function(focused) {
+    uiLogger.debug("SelectionMenu.setFocused(" + focused + ")");
+    if (focused) {
+        this.peerElement.focus();
+    } else {
+        this.peerElement.blur();
+    }
+}
+
+// Sets the currently selected options. Pass a single option in a single selection
+// control or an array of selected controls in a multiple selection control. To
+// deselect all options pass null in a single selection control and an empty array
+// in a multiple selection control.
+SelectionMenu.prototype.setSelected = function(selected) {
+    // call superclass setSelected()
+    SelectionControl.prototype.setSelected.call(this, selected);
+    
+    // iterate through the options and set the selected state
+    // on the corresponding option element
+    for (var i = 0; i < this.options.length; i++) {
+        this.optionElements[i].selected = this.isSelected(this.options[i]);
+    }
+}
+
+// Sets the options in the control.
+SelectionMenu.prototype.setOptions = function(options) {
+    // call superclass setOptions()
+    SelectionControl.prototype.setOptions.call(this, options);
+    this.updateOptionElements();
+}
+
+// Updates the option elements for the peer select element.
+SelectionMenu.prototype.updateOptionElements = function() {
+    // start by removing all current options from the select element
+    while (this.peerElement.firstChild != null) {
+        this.peerElement.removeChild(this.peerElement.firstChild);
+    }
+    
+    // iterate through the options and add (and possibly create) a
+    // properly configured option element for each option
+    for (var i = 0; i < this.options.length; i++) {
+        // do we need to create a new option element?
+        if (i == this.optionElements.length) {
+            this.optionElements.push(document.createElement("option"));
+        }
+        
+        // get the option and option element we're working on
+        var option = this.options[i];
+        var optionElement = this.optionElements[i];
+        
+        // set the state for this option element and add it to the
+        // peer select element
+        optionElement.text = option.text;
+        optionElement.selected = this.isSelected(option);
+        this.peerElement.appendChild(optionElement);
+    }
+    
+    // update the style
+    this.updateStyleFromState();    
+}
+
+// Callback for selection change events.
+SelectionMenu.prototype.selectionChanged = function() {
+    uiLogger.debug("SelectionControl.selectionChanged()");
+    
+    // update the selected options array or reference
+    this.selected = (this.multipleSelection) ? [] : null;
+    for (var i = 0; i < this.options.length; i++) {
+        if (this.optionElements[i].selected) {
+            if (this.multipleSelection) {
+                this.selected.push(this.options[i]);
+            } else {
+                this.selected = this.options[i];
+                break;
+            }
+        }
+    }
+    
+    // notify event listeners
+    this.fireEvent(this.createEvent("SelectionChanged", this.getSelected()));
+}
+
+// Updates the style of the control to reflects the state of the control.
+SelectionMenu.prototype.updateStyleFromState = function() {
+    uiLogger.debug("SelectionMenu.updateStyleFromState()");
+    
+    // determine the state name
+    var stateName = this.getStyleStateName();
+    
+    // set element class names
+    this.setClassName(this.rootElement, "Control");
+    this.setClassName(this.controlElement, "ControlElement");
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssembly" + stateName);
+    this.setClassName(this.captionElement, "ControlCaption ControlCaption" + stateName);
+    
+    // set select and option element class names
+    var peerStateName = this.isEnabled() ? stateName : "Disabled";
+    this.setClassName(this.peerElement, "SelectionMenu SelectionMenu" + peerStateName);
+    for (var i = 0; i < this.options.length; i++) {
+        var option = this.optionElements[i];
+        this.setClassName(option, "SelectionMenuOption SelectionMenuOption" + peerStateName);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/Separator.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,119 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The Separator class is used to provide a visual separator in a list.
+
+// Constructor.
+function Separator(id) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id);
+    }
+}
+
+// Separator inherits from Control.
+Separator.prototype = new Control(UI_NO_INIT_ID);
+
+// Reference to the separator element.
+Separator.prototype.separatorElement = null;
+
+// Separator row element.
+Separator.prototype.tableRowElement = null;
+
+// Left cell element.
+Separator.prototype.tableLeftCellElement = null;
+
+// Center cell element.
+Separator.prototype.tableCenterCellElement = null;
+
+// Right cell element.
+Separator.prototype.tableRightCellElement = null;
+
+// Initializer - called from constructor.
+Separator.prototype.init = function(id) {
+    uiLogger.debug("Separator.init(" + id + ")");
+    
+    // call superclass initializer
+    Control.prototype.init.call(this, id, null);
+    
+    // remove caption and control elements
+    this.assemblyElement.removeChild(this.captionElement);
+    this.assemblyElement.removeChild(this.controlElement);
+    
+    // create separator
+    this.separatorElement = document.createElement("table");
+    this.tableRowElement = document.createElement("tr");
+    this.tableLeftCellElement = document.createElement("td");
+    this.tableCenterCellElement = document.createElement("td");
+    this.tableRightCellElement = document.createElement("td");
+    this.tableRowElement.appendChild(this.tableLeftCellElement);
+    this.tableRowElement.appendChild(this.tableCenterCellElement);
+    this.tableRowElement.appendChild(this.tableRightCellElement);
+    this.separatorElement.appendChild(this.tableRowElement);
+    this.assemblyElement.appendChild(this.separatorElement);
+    
+    // update style
+    this.updateStyleFromState();
+}
+
+// Returns the enabled state for the control.
+Separator.prototype.isEnabled = function() {
+    return true;
+}
+
+// Returns the focusable state for the control.
+Separator.prototype.isFocusable = function() {
+    return false;
+}
+
+// Updates the style of the control to reflects the state of the control.
+Separator.prototype.updateStyleFromState = function() {
+    uiLogger.debug("Separator.updateStyleFromState()");
+    
+    // set element class names
+    this.setClassName(this.rootElement, "Control");
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssemblyNormal");
+    this.setClassName(this.separatorElement, "Separator");
+    this.setClassName(this.tableRowElement, "SeparatorRow");
+    this.setClassName(this.tableLeftCellElement, "SeparatorLeftCell");
+    this.setClassName(this.tableCenterCellElement, "SeparatorCenterCell");
+    this.setClassName(this.tableRightCellElement, "SeparatorRightCell");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/TextArea.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,96 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The TextArea class implements a multi line text entry control.
+
+// Constructor.
+function TextArea(id, caption, value, rows) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption, value, rows);
+    }
+}
+
+// TextArea inherits from TextEntryControl.
+TextArea.prototype = new TextEntryControl(UI_NO_INIT_ID);
+
+// Initializer - called from constructor.
+TextArea.prototype.init = function(id, caption, value, rows) {
+    uiLogger.debug("TextArea.init(" + id + ", " + caption + ", " + value + ", " + rows + ")");
+    
+    // call superclass initializer
+    TextEntryControl.prototype.init.call(this, id, caption);
+    
+    // create the peer element
+    this.peerElement = document.createElement("textarea");
+    // default rowcount is 3 if not defined
+    // width always comes from style but is a required attribute
+    this.peerElement.rows = (rows != null) ? rows : 3;
+    this.peerElement.cols = 20;
+    this.controlElement.appendChild(this.peerElement);
+    
+    // set the value
+    this.peerElement.value = (value == null) ? "" : value;
+    
+    // bind event listeners
+    this.bindTextEntryControlListeners();
+    
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Updates the style of the control to reflects the state of the control.
+TextArea.prototype.updateStyleFromState = function() {
+    uiLogger.debug("TextArea.updateStyleFromState()");
+    
+    // determine the state name
+    var stateName = this.getStyleStateName();
+    
+    // set element class names
+    this.setClassName(this.rootElement, "Control");
+    this.setClassName(this.controlElement, "ControlElement");
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssembly" + stateName);
+    this.setClassName(this.captionElement, "ControlCaption ControlCaption" + stateName);
+    
+    // set peer element class names
+    var peerStateName = this.isEnabled() ? stateName : "Disabled";
+    this.setClassName(this.peerElement, "TextArea TextArea" + stateName);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/TextEntryControl.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,125 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The TextEntryControl class is an abstract base class for the single and multi-
+// line text entry controls TextField and TextArea. Don't use TextEntryControl
+// directly.
+
+// Constructor.
+function TextEntryControl(id, caption) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption);
+    }
+}
+
+// TextEntryControl inherits from Control.
+TextEntryControl.prototype = new Control(UI_NO_INIT_ID);
+
+// Reference to the peer HTML element.
+TextEntryControl.prototype.peerElement = null;
+
+// Initializer - called from constructor.
+TextEntryControl.prototype.init = function(id, caption) {
+    uiLogger.debug("TextEntryControl.init(" + id + ", " + caption + ")");
+    
+    // call superclass initializer
+    Control.prototype.init.call(this, id, caption);
+}
+
+// Common event listeners hookup function called from subclasses.
+TextEntryControl.prototype.bindTextEntryControlListeners = function() {
+    var self = this;
+    this.peerElement.addEventListener("focus", function() { self.focusStateChanged(true); }, false);
+    this.peerElement.addEventListener("blur", function() { self.focusStateChanged(false); }, false);
+    this.peerElement.addEventListener("mouseover", function() { self.hoverStateChanged(true); }, false);
+    this.peerElement.addEventListener("mouseout", function() { self.hoverStateChanged(false); }, false);
+    this.peerElement.addEventListener("change", function() { self.valueChanged(); }, false);
+}
+
+// Returns the enabled state.
+// Override this in subclasses as required to implement the state change.
+TextEntryControl.prototype.isEnabled = function() {
+    return !this.peerElement.readOnly;
+}
+
+// Sets the enabled state.
+// Override this in subclasses as required to implement the state change.
+TextEntryControl.prototype.setEnabled = function(enabled) {
+    uiLogger.debug("TextEntryControl.setEnabled(" + enabled + ")");
+    this.peerElement.readOnly = !enabled;
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Returns the control text.
+TextEntryControl.prototype.getText = function() {
+    return this.peerElement.value;
+}
+
+// Sets the text for the control.
+TextEntryControl.prototype.setText = function(text) {
+    this.peerElement.value = text;
+}
+
+// Returns the focusable state for the control.
+TextEntryControl.prototype.isFocusable = function() {
+    // text entry controls are always focusable
+    return true;
+}
+
+// Sets the focused state for the control.
+// Note: This may not always succeed.
+TextEntryControl.prototype.setFocused = function(focused) {
+    uiLogger.debug("TextEntryControl.setFocused(" + focused + ")");
+    if (focused) {
+        this.peerElement.focus();
+    } else {
+        this.peerElement.blur();
+    }
+}
+
+// Callback for value change events.
+TextEntryControl.prototype.valueChanged = function() {
+    uiLogger.debug("TextEntryControl.valueChanged()");
+    // notify event listeners
+    this.fireEvent(this.createEvent("ValueChanged", this.peerElement.value));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/TextField.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,93 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The TextField class implements a single line text entry control.
+
+// Constructor.
+function TextField(id, caption, value, masked) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id, caption, value, masked);
+    }
+}
+
+// TextField inherits from TextEntryControl.
+TextField.prototype = new TextEntryControl(UI_NO_INIT_ID);
+
+// Initializer - called from constructor.
+TextField.prototype.init = function(id, caption, value, masked) {
+    uiLogger.debug("TextField.init(" + id + ", " + caption + ", " + value + ", " + masked + ")");
+    
+    // call superclass initializer
+    TextEntryControl.prototype.init.call(this, id, caption);
+    
+    // create the peer element
+    this.peerElement = document.createElement("input");
+    this.peerElement.type = masked ? "password" : "text";
+    this.controlElement.appendChild(this.peerElement);
+    
+    // set the value
+    this.peerElement.value = (value == null) ? "" : value;
+    
+    // bind event listeners
+    this.bindTextEntryControlListeners();
+    
+    // update the style
+    this.updateStyleFromState();
+}
+
+// Updates the style of the control to reflects the state of the control.
+TextField.prototype.updateStyleFromState = function() {
+    uiLogger.debug("TextField.updateStyleFromState()");
+    
+    // determine the state name
+    var stateName = this.getStyleStateName();
+    
+    // set element class names
+    this.setClassName(this.rootElement, "Control");
+    this.setClassName(this.controlElement, "ControlElement");
+    this.setClassName(this.assemblyElement, "ControlAssembly ControlAssembly" + stateName);
+    this.setClassName(this.captionElement, "ControlCaption ControlCaption" + stateName);
+    
+    // set peer element class names
+    var peerStateName = this.isEnabled() ? stateName : "Disabled";
+    this.setClassName(this.peerElement, "TextField TextField" + peerStateName);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/UIElement.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,114 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The UIElement class is the base class for all user interface elements.
+
+// Constructor.
+function UIElement(id) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id);
+    }
+}
+
+// UI element identifier.
+UIElement.prototype.id = null;
+
+// Root HTML element in the UI element.
+UIElement.prototype.rootElement = null;
+
+// Initializer for UIElement.
+UIElement.prototype.init = function(id) {
+    uiLogger.debug("UIElement.init(" + id + ")");
+    
+    // copy identifier
+    this.id = id;
+    
+    // init event listener array
+    this.eventListeners = [];
+    
+    // create the root element
+    this.rootElement = document.createElement("div");
+    if (id != null) {
+        this.rootElement.id = id;
+    }
+}
+
+// Returns an array containing the current event listeners.
+UIElement.prototype.getEventListeners = function() {
+    return this.eventListeners;
+}
+
+// Adds an event listener.
+UIElement.prototype.addEventListener = function(eventType, listener) {
+    var listenerDef = { type: eventType, listener: listener };
+    this.eventListeners.push(listenerDef);
+}
+
+// Removes an event listener.
+UIElement.prototype.removeEventListener = function(eventType, listener) {
+    // iterate through current listeners and remove the specified
+    // listener when its found
+    for (var i = 0; i < this.eventListeners.length; i++) {
+        var listenerDef = this.eventListeners[i];
+        if ((listenerDef.type == eventType) &&
+                (listenerDef.listener == listener)) {
+            this.eventListeners.splice(i, 1);
+            return;
+        }
+    }
+}
+
+// Factory method for an event object where this object is the source object.
+UIElement.prototype.createEvent = function(type, value) {
+    return { source: this, type: type, value: value };
+}
+
+// Fires an event to all listeners.
+UIElement.prototype.fireEvent = function(event) {
+    // iterate through all event listeners and notify them of the event
+    for (var i = 0; i < this.eventListeners.length; i++) {
+        var listenerDef = this.eventListeners[i];
+        if (listenerDef.type == null || listenerDef.type == event.type) {
+            listenerDef.listener.call(this, event);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/UIInit.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,49 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The UIInit script is included before the rest of the UI scripts to setup
+// any resources needed by the UI toolkit.
+
+// Create UI logger.
+var uiLogger = new Logger();
+uiLogger.level = uiLogger.LOG_LEVEL_OFF;
+uiLogger.filter = ["QECR"];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/UIManager.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,240 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (ÒNokiaÓ) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under NokiaÕs copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The UI manager manages a set of views and other user interface elements.
+
+// Constructor.
+function UIManager(viewParentElement, scrollbarParentElement, enableScrollBar, delayInit) {    
+    uiLogger.debug("UIManager(" + viewParentElement + ", " + scrollbarParentElement + ")");
+    if (delayInit == null) {
+        this.init(viewParentElement, enableScrollBar, scrollbarParentElement);
+    }
+}
+
+// Parent element for views.
+UIManager.prototype.viewParentElement = null;
+
+// Parent element for scrollbar.
+UIManager.prototype.scrollbarParentElement = null;
+
+// The currently displayed view.
+UIManager.prototype.currentView = null;
+
+// Reference to the scrollbar.
+UIManager.prototype.scrollbar = null;
+
+// Current scroll Y position.
+UIManager.prototype.scrollY = -1;
+
+// Current viewport height.
+UIManager.prototype.viewportHeight = -1;
+
+// Current document height.
+UIManager.prototype.documentHeight = -1;
+
+// Timer identifier or null if no active timer.
+UIManager.prototype.timerId = null;
+
+// Interval for timer ticks for the UI manager timer (in milliseconds)
+UIManager.prototype.TIMER_INTERVAL = 250;
+
+// Reference to the notification popup used to displays notifications.
+UIManager.prototype.notificationPopup = null;
+
+// is scrollbar enabled
+UIManager.prototype.enableScrollBar = null;
+
+// init function
+UIManager.prototype.init = function(viewParentElement, enableScrollBar, scrollbarParentElement) {
+    this.enableScrollBar = enableScrollBar;
+    
+    // parent element for views
+    if (viewParentElement == null) {
+        // create a parent for views
+        this.viewParentElement = document.createElement("div");
+        this.viewParentElement.className = "ViewContainer";
+        document.body.appendChild(this.viewParentElement);
+    }
+    else {
+        this.viewParentElement = viewParentElement;
+    }
+    
+    // parent element for scrollbar
+    if (enableScrollBar) {
+        if (scrollbarParentElement == null) {
+            // create a parent for the scrollbar
+            this.scrollbarParentElement = document.createElement("div");
+            this.scrollbarParentElement.className = "DocumentScrollbarContainer";
+            document.body.appendChild(this.scrollbarParentElement);
+        }
+        else {
+            this.scrollbarParentElement = scrollbarParentElement;
+        }
+    }
+    
+    // currently selected view
+    this.currentView = null;
+    
+    // create the notification popup
+    // the notification popup adds itself as a child element to the document body
+    this.notificationPopup = new NotificationPopup();
+    
+    // create scrollbar
+    if (enableScrollBar) {
+        this.scrollbar = new Scrollbar(this.scrollbarParentElement);
+    }
+    
+    // setup scrollbar tracking
+    var self = this;
+    this.startTimer();
+    if (enableScrollBar) {
+        window.addEventListener("resize", function(){
+            self.updateScrollbar();
+        }, false);
+        window.addEventListener("scroll", function(){
+            self.updateScrollbar();
+        }, false);
+    }
+}
+
+// Returns the current view.
+UIManager.prototype.getView = function() {
+    return this.currentView;
+}
+
+// Switches to the specified view.
+UIManager.prototype.setView = function(view) {
+    uiLogger.debug("View set to " + view.id);
+    
+    // remove the current view from the parent element
+    if (this.currentView != null) {
+        this.viewParentElement.removeChild(this.currentView.rootElement);
+    }
+    
+    // reset scroll
+    window.scrollTo(0, 0);
+    
+    // add the new view to the parent element
+    if (view != null) {
+        this.currentView = view;
+        this.currentView.resetControlFocusStates();
+        this.viewParentElement.appendChild(this.currentView.rootElement);
+    }
+    
+    // update scrollbar
+    if (this.enableScrollBar) {
+        this.updateScrollbar();
+    }
+    
+    // focus the first focusable control
+    // a timer is used to prevent unwanted focus shift
+    setTimeout(function() { view.focusFirstControl(); }, 1);
+}
+
+// Updates the scrollbar.
+UIManager.prototype.updateScrollbar = function() {
+    if (this.enableScrollBar) {
+        // get current viewport and document position and dimensions
+        var scrollY = window.scrollY;
+        var viewportHeight = window.innerHeight;
+        var documentHeight = Math.max(document.documentElement.scrollHeight, document.height);
+        
+        // check if the scroll position or view has changed
+        if (this.scrollY != scrollY ||
+                this.viewportHeight != viewportHeight ||
+                this.documentHeight != documentHeight) {
+            // scroll position or view has changed
+            this.scrollY = scrollY;
+            this.viewportHeight = viewportHeight;
+            this.documentHeight = documentHeight;
+            
+            // update the scrollbar
+            this.scrollbar.update(scrollY, viewportHeight, documentHeight);
+            uiLogger.debug("Scrollbar updated");
+        }
+    }
+}
+
+// Starts the view manager timer.
+UIManager.prototype.startTimer = function() {
+    if (this.timerId == null) {
+        uiLogger.debug("UIManager timer started");
+        var self = this;
+        // setup the timer
+        this.timerId = setInterval(function() { self.onTimer(); }, this.TIMER_INTERVAL);
+    } else {
+        uiLogger.warn("UIManager timer already running");
+    }
+}
+
+// Stops the view manager timer.
+UIManager.prototype.stopTimer = function() {
+    if (this.timerId != null) {
+        // stop the timer
+        clearTimeout(this.timerId);
+        this.timerId = null;
+    } else {
+        uiLogger.warn("UIManager timer already stopped");
+    }
+}
+
+// Timer callback function.
+UIManager.prototype.onTimer = function() {
+    if (this.enableScrollBar) {
+        // make sure the scrollbar is up to date
+        this.updateScrollbar();
+    }
+}
+
+// Displays a notification.
+UIManager.prototype.showNotification = function(displayTime, type, text, progress) {
+    uiLogger.debug("UIManager.showNotification(" + displayTime + ", " + type + ", " + text + ", " + progress + ")");
+    // use the notification popup to show the notification
+    this.notificationPopup.showNotification(displayTime, type, text, progress);
+}
+
+// Hides the currently displayed notification.
+UIManager.prototype.hideNotification = function() {
+    uiLogger.debug("UIManager.hideNotification()");
+    // hide the notification popup
+    this.notificationPopup.hideNotification();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/UI/View.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,90 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (“Nokia”) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia’s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// The View class is an abstract base class for views in the UI toolkit.
+// Don't use the View directly - instead use a concrete subclass like ListView.
+
+// Constructor.
+function View(id) {
+    if (id != UI_NO_INIT_ID) {
+        this.init(id);
+    }
+}
+
+// View inherits from UIElement.
+View.prototype = new UIElement(UI_NO_INIT_ID);
+
+// Currently focused control.
+View.prototype.focusedControl = null;
+
+// Initializer - called from constructor.
+View.prototype.init = function(id) {
+    uiLogger.debug("View.init(" + id + ")");
+    
+    // call superclass initializer
+    UIElement.prototype.init.call(this, id);
+}
+
+// Returns the currently focused control; null if none.
+View.prototype.getFocusedControl = function() {
+    return this.focusedControl;
+}
+
+// Used to notify the view that the focused control has changed.
+View.prototype.focusedControlChanged = function(control) {
+    uiLogger.debug("View.focusedControlChanged(" + control + ")");
+    this.focusedControl = control;
+    // notify event listeners
+    this.fireEvent(this.createEvent("FocusedControlChanged", this.focusedControl));
+}
+
+// Attempts to focus the first focusable control.
+// Override in subclasses as required.
+View.prototype.focusFirstControl = function() {
+    uiLogger.debug("View.focusFirstControl()");
+}
+
+// Attempts to reset all control focus states.
+// Override in subclasses as required.
+View.prototype.resetControlFocusStates = function() {
+    uiLogger.debug("View.resetControlFocusStates()");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/Utils/Logger.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,117 @@
+/*
+© Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (ÒNokiaÓ) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under NokiaÕs copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Logger utility class that uses the Firebug console class.
+
+// Constructor (everything is static so this is empty).
+function Logger() {
+    // Set default logger level.
+    this.level = this.LOG_LEVEL_OFF;
+}
+
+// Logger levels.
+Logger.prototype.LOG_LEVEL_DEBUG = 0;
+Logger.prototype.LOG_LEVEL_INFO = 1;
+Logger.prototype.LOG_LEVEL_WARN = 2;
+Logger.prototype.LOG_LEVEL_ERROR = 3;
+Logger.prototype.LOG_LEVEL_OFF = 4;
+
+Logger.prototype.level = null;
+Logger.prototype.filter = null;
+
+// Disable logging on other browsers except Firefox.
+Logger.prototype.enabled = (navigator.userAgent.indexOf("Firefox") != -1);
+
+// Dumps an objects properties and methods to the console.
+Logger.prototype.dump = function(obj) {
+    if (this.enabled) {
+        console.dir(obj);
+    }
+}
+
+// Dumps a stracktrace to the console.
+Logger.prototype.trace = function() {
+    if (this.enabled) {
+        console.trace();
+    }
+}
+
+// Prints a debug message to the console.
+Logger.prototype.debug = function(str) {
+    if (this.enabled && this.level <= this.LOG_LEVEL_DEBUG) {
+        if (this.filter == null) {
+            console.debug(str);
+        } else {
+            var show = false;
+            for (i in this.filter) {
+                if (str.indexOf(this.filter[i]) >= 0) {
+                    show = true;
+                    break;
+                }
+            }
+            if (show) {
+                console.debug(str);
+            }
+        }
+    }
+}
+
+// Prints an info message to the console.
+Logger.prototype.info = function(str) {
+    if (this.enabled && this.level <= this.LOG_LEVEL_INFO) {
+        console.info(str);
+    }
+}
+
+// Prints a warning message to the console.
+Logger.prototype.warn = function(str) {
+    if (this.enabled && this.level <= this.LOG_LEVEL_WARN) {
+        console.warn(str);
+    }
+}
+
+// Prints an error message to the console.
+Logger.prototype.error = function(str) {
+    if (this.enabled && this.level <= this.LOG_LEVEL_ERROR) {
+        console.error(str);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/projecttemplates/WRTKit/WRTKit.js	Mon Feb 01 13:47:20 2010 -0800
@@ -0,0 +1,90 @@
+/*
+� Copyright 2008 Nokia Corporation. All rights reserved.
+
+IMPORTANT:  The Nokia software ("WRTKit and Example Widget files") is supplied to you by Nokia
+Corporation (�Nokia�) in consideration of your agreement to the following terms. Your use, installation
+and/or redistribution of the WRTKit and Example Widget files constitutes acceptance of these terms. If
+you do not agree with these terms, please do not use, install, or redistribute the WRTKit and Example
+Widget files.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Nokia
+grants you a personal, non-exclusive license, under Nokia�s copyrights in the WRTKit and Example
+Widget files, to use, reproduce, and redistribute the WRTKit and Example files, in text form (for HTML,
+CSS, or JavaScript files) or binary form (for associated images), for the sole purpose of creating S60
+Widgets.
+
+If you redistribute the WRTKit and Example files, you must retain this entire notice in all such
+redistributions of the WRTKit and Example files.
+
+You may not use the name, trademarks, service marks or logos of Nokia to endorse or promote products
+that include the WRTKit and Example files without the prior written explicit agreement with Nokia.
+Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by
+Nokia herein, including but not limited to any patent rights that may be infringed by your products that
+incorporate the WRTKit and Example files or by other works in which the WRTKit and Example files
+may be incorporated.
+
+The WRTKit and Example files are provided on an "AS IS" basis.  NOKIA MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE, REGARDING THE EXAMPLES OR ITS USE AND OPERATION
+ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, AND/OR
+DISTRIBUTION OF THE EXAMPLES, HOWEVER CAUSED AND WHETHER UNDER THEORY
+OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE,
+EVEN IF NOKIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// This script includes the WRTKit for use in a widget.
+
+// WRTKit version (major.minor.revision, e.g. 1.0.0).
+var WRTKIT_VERSION_MAJOR = 1;
+var WRTKIT_VERSION_MINOR = 0;
+var WRTKIT_VERSION_REVISION = 0;
+var WRTKIT_RESOURCE_DIRECTORY = "WRTKit/Resources/";
+
+// Include util script files.
+includeScript("WRTKit/Utils/Logger.js");
+
+// Include UI visual definition.
+includeStyleSheet("WRTKit/Resources/UI.css");
+
+// Include all UI toolkit script files.
+var UI_NO_INIT_ID = "UI_NO_INIT_ID";
+
+includeScript("WRTKit/UI/UIInit.js");
+includeScript("WRTKit/UI/UIElement.js");
+includeScript("WRTKit/UI/Scrollbar.js");
+includeScript("WRTKit/UI/NotificationPopup.js");
+includeScript("WRTKit/UI/UIManager.js");
+includeScript("WRTKit/UI/View.js");
+includeScript("WRTKit/UI/ListView.js");
+includeScript("WRTKit/UI/Control.js");
+includeScript("WRTKit/UI/Separator.js");
+includeScript("WRTKit/UI/Label.js");
+includeScript("WRTKit/UI/ContentPanel.js");
+includeScript("WRTKit/UI/TextEntryControl.js");
+includeScript("WRTKit/UI/TextField.js");
+includeScript("WRTKit/UI/TextArea.js");
+includeScript("WRTKit/UI/SelectionControl.js");
+includeScript("WRTKit/UI/SelectionMenu.js");
+includeScript("WRTKit/UI/SelectionList.js");
+includeScript("WRTKit/UI/ActionControl.js");
+includeScript("WRTKit/UI/FormButton.js");
+includeScript("WRTKit/UI/NavigationButton.js");
+includeScript("WRTKit/UI/Ajax.js");
+
+// Includes a script file by writing a script tag.
+function includeScript(src) {
+    document.write("<script type=\"text/javascript\" src=\"" + src + "\"></script>");
+}
+
+// Includes a style sheet by writing a style tag.
+function includeStyleSheet(src) {
+    document.write("<style type=\"text/css\"> @import url(\"" +  src + "\"); </style>");
+}