org.symbian.tools.wrttools.doc.WRTKit/html/WRTKit_Travel_Companion_user_interface-GUID-989d17cc-f019-46bb-b6f5-49166e258aca.html
changeset 230 7848c135d915
equal deleted inserted replaced
229:716254ccbcc0 230:7848c135d915
       
     1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       
     2 <html lang="en" xml:lang="en">
       
     3 <head>
       
     4 <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
       
     5 <meta name="copyright" content="(C) Copyright 2005" />
       
     6 <meta name="DC.rights.owner" content="(C) Copyright 2005" />
       
     7 <meta content="concept" name="DC.Type" />
       
     8 <meta name="DC.Title" content="Travel Companion user interface" />
       
     9 <meta scheme="URI" name="DC.Relation" content="WRTKit_Travel_Companion_Tutorial-GUID-be79ba64-fa03-4968-964e-d7dcc42d7053.html" />
       
    10 <meta content="XHTML" name="DC.Format" />
       
    11 <meta content="GUID-989D17CC-F019-46BB-B6F5-49166E258ACA" name="DC.Identifier" />
       
    12 <meta content="en" name="DC.Language" />
       
    13 <link href="commonltr.css" type="text/css" rel="stylesheet" />
       
    14 <title>
       
    15 Travel Companion user interface</title>
       
    16 </head>
       
    17 <body id="GUID-989D17CC-F019-46BB-B6F5-49166E258ACA"><a name="GUID-989D17CC-F019-46BB-B6F5-49166E258ACA"><!-- --></a>
       
    18 
       
    19 
       
    20 
       
    21     <h1 class="topictitle1">
       
    22 Travel Companion user interface</h1>
       
    23 
       
    24     <div>
       
    25 
       
    26         <div class="section"><h2 class="sectiontitle">
       
    27 Handling multiple views</h2>
       
    28 
       
    29             
       
    30             <p>
       
    31 
       
    32                 The Travel Companion widget will follow many of the same patterns that the Hello World
       
    33                 and RSS Reader widgets have followed. The entry point to the widget is the init() function
       
    34                 that we call from the onload event handler in the main HTML file TravelCompanion.html.
       
    35                 We will implement the init() function along with the rest of the widget and user interface
       
    36                 in the TravelCompanion.js file. Let's start with the init() function so that we get the
       
    37                 widget up and running.
       
    38             </p>
       
    39 
       
    40             <p>
       
    41 
       
    42                 From previous widgets we already know a lot of things about the WRTKit and about what
       
    43                 we will need. For example we know that we will have a user interface manager and that
       
    44                 we'll need a reference to each of the views that our widget uses. And since we have
       
    45                 designed the Travel Companion widget we know what views we will have. Before we write the
       
    46                 init() function we can go ahead and declare the variables that we will use to refer to
       
    47                 the views and the user interface manager. And while we're at it we can also declare the
       
    48                 variable that we'll use to refer to the Travel Companion engine. All of these variables
       
    49                 are globals and thus go outside the init() function:
       
    50             </p>
       
    51 
       
    52 <pre>
       
    53 
       
    54 // Reference to travel companion engine that implements the business logic.
       
    55 var engine;
       
    56 
       
    57 // Reference to the WRTKit user interface manager.
       
    58 var uiManager;
       
    59 
       
    60 // References to views.
       
    61 var mainView;
       
    62 var infoView;
       
    63 var converterView;
       
    64 var weatherView;
       
    65 var settingsView;
       
    66 </pre>
       
    67 
       
    68             <p>
       
    69 
       
    70                 Previously we've written the init() function so that it creates the entire user interface
       
    71                 but because the Travel Companion widget has a much larger user interface than anything
       
    72                 we've done before, it's probably a good idea to split things up into smaller functions
       
    73                 so we don't end up with a huge init() function that will be hard to read and maintain.
       
    74                 Let's create a function for the creation of each view, and then one function that will
       
    75                 call these view creation functions and setup all other things that we need for the user
       
    76                 interface, such as the Options menu. We'll just create stub functions for now but we
       
    77                 will soon get to implement the functions:
       
    78             </p>
       
    79 
       
    80 <pre>
       
    81 
       
    82 // Creates the user interface.
       
    83 function createUI() {
       
    84 }
       
    85 
       
    86 // Creates the main view.
       
    87 function createMainView() {
       
    88 }
       
    89 
       
    90 // Creates the info view.
       
    91 function createInfoView() {
       
    92 }
       
    93 
       
    94 // Creates the converter view.
       
    95 function createConverterView() {
       
    96 }
       
    97 
       
    98 // Creates the weather view.
       
    99 function createWeatherView() {
       
   100 }
       
   101 
       
   102 // Creates the settings view.
       
   103 function createSettingsView() {
       
   104 }
       
   105 </pre>
       
   106 
       
   107             <p>
       
   108 
       
   109                 In the RSS Reader widget we used functions called showMainView() and showSettings() to
       
   110                 move between views. That allowed us to implement all the logic that was required when
       
   111                 moving between views in one place regardless of what action triggered the change of
       
   112                 views. We'll do the same thing in the Travel Companion widget but this time we'll need
       
   113                 five functions since we have five views. Let's create stubs for these too at this stage
       
   114                 so that the functions exist if we need to refer to them.
       
   115             </p>
       
   116 
       
   117 <pre>
       
   118 
       
   119 // Displays the main view.
       
   120 function showMainView() {
       
   121 }
       
   122 
       
   123 // Displays the info view.
       
   124 function showInfoView() {
       
   125 }
       
   126 
       
   127 // Displays the converter view.
       
   128 function showConverterView() {
       
   129 }
       
   130 
       
   131 // Displays the weather view.
       
   132 function showWeatherView() {
       
   133 }
       
   134 
       
   135 // Displays the settings view.
       
   136 function showSettingsView() {
       
   137 }
       
   138 </pre>
       
   139 
       
   140             <p>
       
   141 
       
   142                 Since we will create each user interface view in its own function our init() function
       
   143                 will be much simpler than in previous widgets. We will create the business logic engine,
       
   144                 create the user interface by calling createUI() and then display the main view.
       
   145             </p>
       
   146 
       
   147 <pre>
       
   148 
       
   149 // Called from the onload event handler to initialize the widget.
       
   150 function init() {
       
   151     // initialize the business logic engine
       
   152     engine = new Engine();
       
   153     
       
   154     // create the user interface
       
   155     createUI();
       
   156     
       
   157     // display the main view
       
   158     showMainView();
       
   159 }
       
   160 </pre>
       
   161 
       
   162             <p>
       
   163 
       
   164                 Let's get started with creating the user interface by returning to the createUI()
       
   165                 function. We'll want to widget to show the softkey bar and we'll want it to be in
       
   166                 tab navigation mode instead of the default pointer navigation mode. We then need
       
   167                 to create the user interface manager and the five views that this widget has. Of 
       
   168                 course those five views are actually created by the five create-functions that we
       
   169                 just wrote stubs for so we just need to call those functions from createUI().
       
   170             </p>
       
   171 
       
   172 <pre>
       
   173 
       
   174 // Creates the user interface.
       
   175 function createUI() {
       
   176     if (window.widget) {
       
   177         // set tab-navigation mode and show softkeys
       
   178         widget.setNavigationEnabled(false);
       
   179         menu.showSoftkeys();
       
   180     }
       
   181     
       
   182     // create UI manager
       
   183     uiManager = new UIManager();
       
   184     
       
   185     // create views
       
   186     createMainView();
       
   187     createInfoView();
       
   188     createConverterView();
       
   189     createWeatherView();
       
   190     createSettingsView();
       
   191 }
       
   192 </pre>
       
   193 
       
   194             <p>
       
   195 
       
   196                 Because we created the stub functions for moving between views, we can also create
       
   197                 the Options menu now. We'll only add one item to the menu in addition to the default
       
   198                 "Exit" menu item. The item we'll add is one that will take the user to the settings
       
   199                 view. We'll first need to create a global menu item identifier:
       
   200             </p>
       
   201 
       
   202 <pre>
       
   203 
       
   204 // Constants for menu item identifiers.
       
   205 var MENU_ITEM_SETTINGS = 0;
       
   206 </pre>
       
   207 
       
   208             <p>
       
   209 
       
   210                 Now that we have the menu item identifier we can actually create the menu item. Because
       
   211                 the Options menu functionality is only available in the S60 Web Runtime and not in PC
       
   212                 browsers we'll add that code in the same if-clause where we set the navigation mode and
       
   213                 show the softkey bar.
       
   214             </p>
       
   215 
       
   216 <pre>
       
   217 
       
   218 // create menu
       
   219 var settingsMenuItem = new MenuItem("Settings", MENU_ITEM_SETTINGS);
       
   220 settingsMenuItem.onSelect = menuItemSelected;
       
   221 menu.append(settingsMenuItem);
       
   222 </pre>
       
   223 
       
   224             <p>
       
   225 
       
   226                 When the menu item is selected it calls a function called menuItemSelected(). Let's
       
   227                 create that function and handle the case when the settings menu item is selected.
       
   228                 When it is, we want to call showSettingsView() so that the user ends up in the settings
       
   229                 view as expected:
       
   230             </p>
       
   231 
       
   232 <pre>
       
   233 
       
   234 // Callback for when menu items are selected.
       
   235 function menuItemSelected(id) {
       
   236     switch (id) {
       
   237         case MENU_ITEM_SETTINGS:
       
   238             showSettingsView();
       
   239             break;
       
   240     }
       
   241 }
       
   242 </pre>
       
   243 
       
   244             <p>
       
   245 
       
   246                 The framework that we'll need when implementing the actual views is now nearly complete.
       
   247                 But before we move on let's talk about how we'll be using softkeys in the Travel
       
   248                 Companion widget.
       
   249             </p>
       
   250 
       
   251             <p>
       
   252 
       
   253                 In the main view we want the right softkey to be the default "Exit". But in the
       
   254                 four functional views we don't want it to exit the widget but rather to return to
       
   255                 the main view. We'll thus use "Back" as the title in the functional views, except
       
   256                 in the settings view where we'll use "Cancel".
       
   257             </p>
       
   258 
       
   259             <p>
       
   260 
       
   261                 Let's create three functions that will handle setting the widget right softkey to
       
   262                 these configurations. The functions will check if we're actually in the S60 Web
       
   263                 Runtime before attempting to change the right softkey in order to make the widget
       
   264                 also work in a PC browser for testing purposes.
       
   265             </p>
       
   266 
       
   267 <pre>
       
   268 
       
   269 // Sets the softkeys for the main view.
       
   270 function setMainViewSoftkeys() {
       
   271     if (window.widget) {
       
   272         // set right softkey to "exit"
       
   273         menu.setRightSoftkeyLabel("", null);
       
   274     }
       
   275 }
       
   276 
       
   277 // Sets the softkeys for sub views.
       
   278 function setSubViewSoftkeys() {
       
   279     if (window.widget) {
       
   280         // set right softkey to "back" (to main view)
       
   281         menu.setRightSoftkeyLabel("Back", showMainView);
       
   282     }
       
   283 }
       
   284 
       
   285 // Sets the softkeys for settings view.
       
   286 function setSettingsViewSoftkeys() {
       
   287     if (window.widget) {
       
   288         // set right softkey to "cancel" (returns to main view)
       
   289         menu.setRightSoftkeyLabel("Cancel", showMainView);
       
   290     }
       
   291 }
       
   292 </pre>
       
   293 
       
   294         </div>
       
   295 
       
   296         <div class="section"><h2 class="sectiontitle">
       
   297 Main view</h2>
       
   298 
       
   299             
       
   300             <p>
       
   301 
       
   302                 Let's create our main view now so that we get something visible. The main view is
       
   303                 of course created in the function createMainView() for which we already created a
       
   304                 stub function. The main view will have four WRTKit NavigationButton controls in it,
       
   305                 one for each of the views (not counting the main view itself) in the widget. Using
       
   306                 the NavigationButton control is just like using a FormButton, with the difference
       
   307                 that it looks different and can have an icon image in addition to just text. Earlier
       
   308                 when we looked at the files that were in the Examples/TravelCompanion directory we
       
   309                 noticed that there were four icons there. Now it's time to use them as icons in the
       
   310                 navigation buttons.
       
   311             </p>
       
   312 
       
   313             <p>
       
   314 
       
   315                 We will add event listerners to the buttons so that when they are clicked (when they
       
   316                 emit an ActionPerformed event) they will call the functions we have created for
       
   317                 moving between views. At this point the functions are just stubs, but we will of
       
   318                 course fix that later.
       
   319             </p>
       
   320 
       
   321             <p>
       
   322 
       
   323                 We've had captions for the views that we've created so far in the Hello World and
       
   324                 RSS Reader widgets and the Travel Companion will also have view captions. However
       
   325                 for the Travel Companion we'll use an image as our view caption. We will set the
       
   326                 view caption to an empty string because if it's undefined or null then the view
       
   327                 caption area will be hidden. Then we will create a CSS rule for the ListViewCaptionText
       
   328                 class that is used by the area where the caption text goes in a list view. Because
       
   329                 our CSS rule is defined after the default WRTKit CSS rule for ListViewCaptionText,
       
   330                 our rule will be override the default one. Let's open up TravelCompanion.css and
       
   331                 create this rule:
       
   332             </p>
       
   333 
       
   334 <pre>
       
   335 
       
   336 /* Place logo in list view caption */
       
   337 .ListViewCaptionText {
       
   338     background: url("ListViewCaptionLogo.png") no-repeat;
       
   339     height: 35px;
       
   340 }
       
   341 </pre>
       
   342 
       
   343             <p>
       
   344 
       
   345                 We specified a height in addition to the background image. The height is needed
       
   346                 so that the caption text area won't collapse to zero height since it won't contain
       
   347                 any text. We're now ready to implement the createMainView() function:
       
   348             </p>
       
   349 
       
   350 <pre>
       
   351 
       
   352 // Creates the main view.
       
   353 function createMainView() {
       
   354     // empty caption text to display the caption bar - custom background using CSS
       
   355     mainView = new ListView(null, "");
       
   356     
       
   357     // info
       
   358     var navToInfoButton = new NavigationButton(null, "NavInfoIcon.png", "Information");
       
   359     navToInfoButton.addEventListener("ActionPerformed", showInfoView);
       
   360     mainView.addControl(navToInfoButton);
       
   361     
       
   362     // converter
       
   363     var navToConverterButton = new NavigationButton(null, "NavConverterIcon.png", "Currency Converter");
       
   364     navToConverterButton.addEventListener("ActionPerformed", showConverterView);
       
   365     mainView.addControl(navToConverterButton);
       
   366     
       
   367     // weather
       
   368     var navToWeatherButton = new NavigationButton(null, "NavWeatherIcon.png", "Weather Forecast");
       
   369     navToWeatherButton.addEventListener("ActionPerformed", showWeatherView);
       
   370     mainView.addControl(navToWeatherButton);
       
   371     
       
   372     // settings
       
   373     var navToSettingsButton = new NavigationButton(null, "NavSettingsIcon.png", "Settings");
       
   374     navToSettingsButton.addEventListener("ActionPerformed", showSettingsView);
       
   375     mainView.addControl(navToSettingsButton);
       
   376 }
       
   377 </pre>
       
   378 
       
   379             <p>
       
   380 
       
   381                 We now have a main view and our widget even calls showMainView() when it starts
       
   382                 but nothing will actually show up yet because we haven't implemented the showMainView()
       
   383                 function yet. Let's do that now:
       
   384             </p>
       
   385 
       
   386 <pre>
       
   387 
       
   388 // Displays the main view.
       
   389 function showMainView() {
       
   390     setMainViewSoftkeys();
       
   391     uiManager.setView(mainView);
       
   392 }
       
   393 </pre>
       
   394 
       
   395             <p>
       
   396 
       
   397                 The function calls the setMainViewSoftkeys() function to put the right softkey
       
   398                 in the proper state and then asks the user interface manager to show the main
       
   399                 view. Remember that we're already calling the showMainView() function from the
       
   400                 init() function so we can go ahead and test this now in a PC browser, emulator
       
   401                 or handset. Notice the custom list view caption image and the navigation button
       
   402                 icons. Clicking the navigation buttons doesn't do anything yet because we don't
       
   403                 have any other views yet and the functions to show other views except the main
       
   404                 view aren't implemented. But then again, because we wrote stub functions we are
       
   405                 also not getting any error messages.
       
   406             </p>
       
   407 
       
   408             <div class="fignone" id="GUID-989D17CC-F019-46BB-B6F5-49166E258ACA__GUID-B006B086-0D8B-4EA4-8A71-179507B7595A"><a name="GUID-989D17CC-F019-46BB-B6F5-49166E258ACA__GUID-B006B086-0D8B-4EA4-8A71-179507B7595A"><!-- --></a><span class="figcap">Figure 1. 
       
   409 Travel Companion main view</span>
       
   410 
       
   411                 
       
   412                 <br /><img src="Travel_Companion_Main_Screenshot_1.png" /><br />
       
   413             </div>
       
   414 
       
   415         </div>
       
   416 
       
   417         <div class="section"><h2 class="sectiontitle">
       
   418 Settings view</h2>
       
   419 
       
   420             
       
   421             <p>
       
   422 
       
   423                 It's a good idea to implement the settings view as early as possible because
       
   424                 that allows you to test the rest of the widget more easily. In order to get
       
   425                 the settings view up and running we'll need to do three things. First of all
       
   426                 we'll need to implement the createSettingsView() function so that the widget
       
   427                 actually has a settings view. Second, we'll need to implement the actions
       
   428                 that can be performed in that view. There are two actions: "Save" and "Cancel".
       
   429                 Of these, save is the tricker one and we'll implement it in a function that
       
   430                 we will call saveSettingsClicked(). The cancel action will simply take us back
       
   431                 to the main view and will be handled by the showMainView() function that we
       
   432                 have already implemented. And third, we need to implement the showSettingsView()
       
   433                 function so that clicking on the settings navigation button in the main view
       
   434                 takes us to the settings view and sets it up correctly so that the view
       
   435                 reflects the current preferences.
       
   436             </p>
       
   437 
       
   438             <p>
       
   439 
       
   440                 The settings view will have four sections that we will separate using a WRTKit
       
   441                 Separator control. The first section lets the user select the home city and the
       
   442                 whether the home city is in daylight saving time. Here we'll use a SelectionMenu
       
   443                 control for the city selection and a SelectionList control with a single option
       
   444                 for the daylight saving time option. We could have used a SelectionList with
       
   445                 two options "Daylight saving time" and "Normal time". Since the selection would
       
   446                 have been a single selection this would have resulted in two radio buttons. But
       
   447                 partly for the sake of usability and partly to show how to do it, we'll implement
       
   448                 it so that it's a single checkbox instead. Thus, we'll use a SelectionList with
       
   449                 a single option but we'll get the checkboxes instead of radio buttons by putting
       
   450                 the SelectionList in multiple selection mode. Because there's only one option
       
   451                 there will only be one checkbox.
       
   452             </p>
       
   453 
       
   454             <p>
       
   455 
       
   456                 The second section is just like the first one but for the local city. The third
       
   457                 section is for the temperature unit selection (Celsius or Fahrenheit) and we'll
       
   458                 implement it as a single selection SelectionList control. And finally the fourth
       
   459                 section is for the Save and Cancel FormButton controls.
       
   460             </p>
       
   461 
       
   462             <p>
       
   463 
       
   464                 The options for the selection controls will be created just before we create
       
   465                 the controls themselves. The daylight saving time and temperature unit options
       
   466                 are just static JSON defined option lists since we know what the options are.
       
   467                 But for the city selection we'll create it dynamically by asking the business
       
   468                 logic engine for a list of all the supported cities. We'll then create one option
       
   469                 for each city.
       
   470             </p>
       
   471 
       
   472             <p>
       
   473 
       
   474                 Because we'll need to access the controls in the settings view from outside the
       
   475                 creation function we'll need to create global references to them:
       
   476             </p>
       
   477 
       
   478 <pre>
       
   479 
       
   480 // Settings view controls.
       
   481 var homeCitySelection;
       
   482 var homeCityDSTSelection;
       
   483 var localCitySelection;
       
   484 var localCityDSTSelection;
       
   485 var temperatureUnitSelection;
       
   486 </pre>
       
   487 
       
   488             <p>
       
   489 
       
   490                 We can now implement the settings view creation function:
       
   491             </p>
       
   492 
       
   493 <pre>
       
   494 
       
   495 // Creates the settings view.
       
   496 function createSettingsView() {
       
   497     // empty caption text to display the caption bar - custom background using CSS
       
   498     settingsView = new ListView(null, "");
       
   499     
       
   500     // create city options from cities array
       
   501     var cityOptions = [];
       
   502     var cities = engine.getCities();
       
   503     for (var i = 0; i &lt; cities.length; i++) {
       
   504         cityOptions.push({ value: cities[i], text: cities[i].name });
       
   505     }
       
   506     
       
   507     // create DST option
       
   508     dstOptions = [ { value: true, text: "DST (+1h)" } ];
       
   509     
       
   510     // home city
       
   511     homeCitySelection = new SelectionMenu(null, "Home City", cityOptions);
       
   512     settingsView.addControl(homeCitySelection);
       
   513     
       
   514     // home city DST (using a multiple selection but only one option to get a single checkbox)
       
   515     homeCityDSTSelection = new SelectionList(null, "Daylight Saving Time (home)", dstOptions, true);
       
   516     settingsView.addControl(homeCityDSTSelection);
       
   517     
       
   518     // separator
       
   519     settingsView.addControl(new Separator());
       
   520     
       
   521     // local city
       
   522     localCitySelection = new SelectionMenu(null, "Local City", cityOptions);
       
   523     settingsView.addControl(localCitySelection);
       
   524     
       
   525     // local city DST (using a multiple selection but only one option to get a single checkbox)
       
   526     localCityDSTSelection = new SelectionList(null, "Daylight Saving Time (local)", dstOptions, true);
       
   527     settingsView.addControl(localCityDSTSelection);
       
   528     
       
   529     // separator
       
   530     settingsView.addControl(new Separator());
       
   531     
       
   532     // temperature unit
       
   533     var temperatureUnitOptions = [ { value: "c", text: "Celsius" }, { value: "f", text: "Fahrenheit" } ];
       
   534     temperatureUnitSelection = new SelectionList(null, "Temperature Unit", temperatureUnitOptions);
       
   535     settingsView.addControl(temperatureUnitSelection);
       
   536     
       
   537     // separator
       
   538     settingsView.addControl(new Separator());
       
   539     
       
   540     // save button
       
   541     var saveSettingsButton = new FormButton(null, "Save");
       
   542     saveSettingsButton.addEventListener("ActionPerformed", saveSettingsClicked);
       
   543     settingsView.addControl(saveSettingsButton);
       
   544     
       
   545     // cancel button
       
   546     var cancelSettingsButton = new FormButton(null, "Cancel");
       
   547     cancelSettingsButton.addEventListener("ActionPerformed", showMainView);
       
   548     settingsView.addControl(cancelSettingsButton);
       
   549 }
       
   550 </pre>
       
   551 
       
   552             <p>
       
   553 
       
   554                 Note that we used the actual city as the value for the city options. You can
       
   555                 use anything you want for the value property for a selection control option
       
   556                 and in this case we used the actual city object because it will come in handy
       
   557                 later when we want to set the home and local cities that the user has selected
       
   558                 to the engine.
       
   559             </p>
       
   560 
       
   561             <p>
       
   562 
       
   563                 Our save button calls the saveSettingsClicked() function we talked about earlier
       
   564                 but we haven't created that function yet. We'll continue implementing the user
       
   565                 interface by writing this function.
       
   566             </p>
       
   567 
       
   568             <p>
       
   569 
       
   570                 You'll recall that the business logic engine actually stores all the preferences
       
   571                 so all we really need to do is read what values have been selected in the settings
       
   572                 view, telling these values to the engine, calling the savePreferences() method in
       
   573                 the engine to persist the settings, and then return to the main view.
       
   574             </p>
       
   575 
       
   576 <pre>
       
   577 
       
   578 // Called when the user clicks on the "save" button in the settings view.
       
   579 function saveSettingsClicked() {
       
   580     // update the selected home city
       
   581     var selectedHomeCityOption = homeCitySelection.getSelected();
       
   582     if (selectedHomeCityOption != null) {
       
   583         engine.setHomeCity(selectedHomeCityOption.value);
       
   584     }
       
   585     
       
   586     // update the selected local city
       
   587     var selectedLocalCityOption = localCitySelection.getSelected();
       
   588     if (selectedLocalCityOption != null) {
       
   589         engine.setLocalCity(selectedLocalCityOption.value);
       
   590     }
       
   591     
       
   592     // update home and local city DST
       
   593     // there's only one checkbox but we are using a multiple-selection menu.
       
   594     // if the selected array has one element then the checkbox is checked.
       
   595     engine.setHomeCityDST(homeCityDSTSelection.getSelected().length == 1);
       
   596     engine.setLocalCityDST(localCityDSTSelection.getSelected().length == 1);
       
   597     
       
   598     // update temperature unit
       
   599     var selectedTemperatureUnitOption = temperatureUnitSelection.getSelected();
       
   600     if (selectedTemperatureUnitOption != null) {
       
   601         engine.setTemperatureUnit(selectedTemperatureUnitOption.value);
       
   602     }
       
   603     
       
   604     // save settings
       
   605     engine.savePreferences();
       
   606     
       
   607     // go back to the main view
       
   608     showMainView();
       
   609 }
       
   610 </pre>
       
   611 
       
   612             <p>
       
   613 
       
   614                 We're writing defensive code here and making sure that the selection controls
       
   615                 actually have anything selected at all. This should never be possible with
       
   616                 single selection control if they have one option already selected, but we'll
       
   617                 use the principle of "better safe than sorry".
       
   618             </p>
       
   619 
       
   620             <p>
       
   621 
       
   622                 Notice that the daylight saving time selection is checked by asking for the
       
   623                 selected options array (we're using a multiple selection control) and checking
       
   624                 if there is exactly one selected option. We don't care about the actual selected
       
   625                 option because we know that there's only one. Either it's selected or it's not.
       
   626             </p>
       
   627 
       
   628             <p>
       
   629 
       
   630                 We have now implemented two of the three steps we said were necessary to get the
       
   631                 settings view fully functional. Let's implement the final step: showing the view.
       
   632                 Showing the settings view is done by first updating the settings view controls
       
   633                 to reflect the current configuration, setting the right softkey to the state that
       
   634                 it should be in for the settings view and then asking the user interface manager
       
   635                 to show the settings view.
       
   636             </p>
       
   637 
       
   638 <pre>
       
   639 
       
   640 // Displays the settings view.
       
   641 function showSettingsView() {
       
   642     // update settings view controls to match current configuration
       
   643     // the DST selected sets are either the options array with its single option or an empty array
       
   644     
       
   645     // home city and DST setting
       
   646     homeCitySelection.setSelected(homeCitySelection.getOptionForValue(engine.getHomeCity()));
       
   647     homeCityDSTSelection.setSelected(engine.getHomeCityDST() ? homeCityDSTSelection.getOptions() : []);
       
   648     
       
   649     // local city and DST setting
       
   650     localCitySelection.setSelected(localCitySelection.getOptionForValue(engine.getLocalCity()));
       
   651     localCityDSTSelection.setSelected(engine.getLocalCityDST() ? localCityDSTSelection.getOptions() : []);
       
   652     
       
   653     // temperature unit
       
   654     temperatureUnitSelection.setSelected(temperatureUnitSelection.getOptionForValue(engine.getTemperatureUnit()));
       
   655     
       
   656     setSettingsViewSoftkeys();
       
   657     uiManager.setView(settingsView);
       
   658 }
       
   659 </pre>
       
   660 
       
   661             <p>
       
   662 
       
   663                 We're using the convenient getOptionForValue() function that all selection controls
       
   664                 have to retrieve the right option to select for each of the selection controls. The
       
   665                 way we handle the daylight saving time selection controls may seem a little strange
       
   666                 at first but remember that we only have a single option and thus if that option should
       
   667                 be selected then the selected options array is identical with the options array - both
       
   668                 are arrays containing the one and same option. Selection controls always copy the options
       
   669                 and selected options arrays when the setOptions() and setSelected() methods are called
       
   670                 so there is no problem in passing the options array as the selected options array.
       
   671             </p>
       
   672 
       
   673             <p>
       
   674 
       
   675                 The settings view is now completed. You can try it out and play with it, change the
       
   676                 settings, open it up again, change some more settings, cancel the changes, etc. to
       
   677                 verify that it's working as it should.
       
   678             </p>
       
   679 
       
   680             <div class="fignone" id="GUID-989D17CC-F019-46BB-B6F5-49166E258ACA__GUID-66154A40-DD96-45B3-BF53-01594426BA71"><a name="GUID-989D17CC-F019-46BB-B6F5-49166E258ACA__GUID-66154A40-DD96-45B3-BF53-01594426BA71"><!-- --></a><span class="figcap">Figure 2. 
       
   681 Travel Companion settings view</span>
       
   682 
       
   683                 
       
   684                 <br /><img src="Travel_Companion_Settings_Screenshot_1.png" /><br />
       
   685             </div>
       
   686 
       
   687         </div>
       
   688 
       
   689     </div>
       
   690 
       
   691 <div>
       
   692 <div class="familylinks">
       
   693 <div class="parentlink"><strong>Parent topic:</strong> <a href="WRTKit_Travel_Companion_Tutorial-GUID-be79ba64-fa03-4968-964e-d7dcc42d7053.html">Travel Companion</a></div>
       
   694 </div>
       
   695 </div>
       
   696 
       
   697 </body>
       
   698 </html>