--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools.doc.WRTKit/html/WRTKit_Creating_the_Hello_World_widget-GUID-d638159a-d12b-476c-a74c-99055672b7be.html Fri Mar 05 19:31:41 2010 -0800
@@ -0,0 +1,534 @@
+<?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">
+<html lang="en" xml:lang="en">
+<head>
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<meta name="copyright" content="(C) Copyright 2005" />
+<meta name="DC.rights.owner" content="(C) Copyright 2005" />
+<meta content="concept" name="DC.Type" />
+<meta name="DC.Title" content="Creating the Hello World widget" />
+<meta scheme="URI" name="DC.Relation" content="WRTKit_Hello_World_Tutorial-GUID-67e0a561-48ac-4938-8f1b-852422b71380.html" />
+<meta content="XHTML" name="DC.Format" />
+<meta content="GUID-D638159A-D12B-476C-A74C-99055672B7BE" name="DC.Identifier" />
+<meta content="en" name="DC.Language" />
+<link href="commonltr.css" type="text/css" rel="stylesheet" />
+<title>
+Creating the Hello World widget</title>
+</head>
+<body id="GUID-D638159A-D12B-476C-A74C-99055672B7BE"><a name="GUID-D638159A-D12B-476C-A74C-99055672B7BE"><!-- --></a>
+
+
+
+ <h1 class="topictitle1">
+Creating the Hello World widget</h1>
+
+ <div>
+
+ <div class="section"><h2 class="sectiontitle">
+What goes in the widget?</h2>
+
+
+ <p>
+
+ One of the main reasons why Hello World is a good example to start with is
+ because it is a minimal widget and shows the minimal set of steps that you
+ would go through to create a widget that uses the WRTKit for its user interface.
+ We will create just two files, an HTML file called HelloWorld.html and a JavaScript
+ file called HelloWorld.js and both will be very short.
+ </p>
+
+ <p>
+
+ Before we'll start writing code let's talk about what exactly it is that we want
+ to build. A typical Hello World application simply displays the text Hello World
+ with the minimal amount of code. But because using the WRTKit is so simple, we'll
+ go one step further and make it a bit fancier.
+ </p>
+
+ <p>
+
+ WRTKit user interfaces are composed of views and controls. A view is one logical
+ group of stuff that you can see on the screen. A view can be longer than what fits
+ on the screen at once in which case the user has to scroll, but it's still one view.
+ For example in a web browser application you might have one view for the bookmarks,
+ another for settings and a third view for viewing actual web pages. Controls are
+ user interface elements like buttons, text fields, checkboxes, etc. that either
+ let the user perform some kind of interactive action or simply shows some information.
+ When you create a user interface with the WRTKit you create one or more controls,
+ one or more views, and place the controls on the views. After this, all you have to
+ do is ask one of the views to be displayed and the rest happens automatically.
+ </p>
+
+ <p>
+
+ Since this is a very simple widget we will just have one view and we'll call it
+ the "main view". Instead of just saying "Hello World" we will let the user input
+ their name and then click a button to popup a dialog that says hello to the user
+ by name. E.g. if the user enters "John" we will popup "Hello John!". But we will
+ also create some error handling so that if the user doesn't input a name we will
+ popup a warning dialog that says "Please enter your name!" instead.
+ </p>
+
+ </div>
+
+ <div class="section"><h2 class="sectiontitle">
+The HelloWorld.html file</h2>
+
+
+ <p>
+
+ As mentioned earlier, you create user interfaces using JavaScript rather than
+ HTML when you use the WRTKit. Because of this it's perhaps not so surprising
+ that the HTML file is extremely short. What might come as a surprise however is
+ that it's extremely short and nearly identical no matter what kind of widget
+ you are building if you are using the WRTKit. In fact it typically only has
+ about 10 lines of code, including the DOCTYPE declaration! Here's what it looks
+ like:
+ </p>
+
+<pre>
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title></title>
+ <script type="text/javascript" src="WRTKit/WRTKit.js"></script>
+ <script type="text/javascript" src="HelloWorld.js"></script>
+ </head>
+ <body onload="init()">
+ </body>
+</html>
+</pre>
+
+ <p>
+
+ We're using XHTML 1.0 so the DOCTYPE declaration is for XHTML 1.0 Strict. And
+ because this is XHTML we also have the normal XML declaration (<?xml...).
+ After that the content should be familiar even if you've used previously only
+ used HTML rather than XHTML. We have a normal html root level tag with a head
+ and body. Note that in XHTML tags are case sensitive and should be in lowercase
+ as in the example above. The xmlns attribute is a name space declaration that
+ states that all the tags used here are part of the XHTML standard.
+ </p>
+
+ <p>
+
+ Because we're creating a widget and not a web page we don't need to have a title. If you
+ want you can define one here but you won't see it anywhere. Next comes an important
+ bit: <samp class="codeph">
+<script type="text/javascript" src="WRTKit/WRTKit.js"></script>.</samp>
+ That piece of code instructs the Web Runtime to load a JavaScript file called WRTKit.js
+ from a directory called WRTKit. The WRTKit.js file takes care of loading the WRTKit and
+ including all the files that are needed by it. Those files are all inside the WRTKit
+ directory and you don't need to concern yourself with them at this point. In fact
+ all you need to do to use the WRTKit in a widget is to copy the WRTKit directory into
+ your own widget's root directory and then include the XHTML script tag presented above
+ that loads the WRTKit/WRTKit.js JavaScript file. If you are creating a widget of your own
+ you can find the WRTKit directory in the Library directory in the WRTKit SDK. But for your
+ convenience it has already been copied to the Hello World example.
+ </p>
+
+ <p>
+
+ Notice that there's another script tag too, this one loading a file called HelloWorld.js.
+ This is where we'll put all the JavaScript code that implements our Hello World widget.
+ We could have just written the JavaScript code inline between a <script> and
+ </script> tag in the HelloWorld.html file but the HTML file is less cluttered if
+ we move all JavaScript to a separate file.
+ </p>
+
+ <p>
+
+ Finally let's look at the body tag. There are two things of interest here. First of all
+ there's no content between <body> and </body>. That's because all of the
+ content will be created by the WRTKit using JavaScript. And that leads us to the other
+ point of interest in the body: the <samp class="codeph">
+onload="init()"</samp> attribute of the
+ body tag. This sets up an event handler that gets called after the widget has loaded
+ all of its content. The event handler calls a JavaScript function called init(). This
+ is the point where we jump from the HTML to JavaScript. From this point on everything
+ will be JavaScript and the place where it all starts is the init() function that gets
+ called thanks to this little onload event handler for the body tag.
+ </p>
+
+ </div>
+
+ <div class="section"><h2 class="sectiontitle">
+The HelloWorld.js file</h2>
+
+
+ <p>
+
+ The HTML file that we created above set things up so that there is a function call
+ to a function named "init()" when the widget is done loading. No such function exists
+ a this point so we have to create it. The init() function is the entry point to our
+ JavaScript and this is also where we will start the implementation.
+ </p>
+
+ <p>
+
+ The S60 Web Runtime supports two kinds of user interface interaction: tab and
+ pointer. The WRTKit supports but methods but usually the tab interaction method
+ (also known as "navigation mode") is preferred. Unfortunately the pointer based
+ navigation mode is the default so we'll have to disable it and switch to the tab
+ navigation mode. Also by default the softkey bar is hidden, which we don't want
+ because we want to give the user a clue about how to exit the widget. The good news
+ is that these two tweaks are easy to do and only requires two simple method calls.
+ The bad news is that those method calls are done through objects that only exist
+ in the Web Runtime but not in a PC web browser. Due to this, we'll create the
+ init() function as follows:
+ </p>
+
+<pre>
+
+// Called from the onload event handler to initialize the widget.
+function init() {
+ // set tab-navigation mode and show softkeys
+ // (only if we are in the WRT environment)
+ if (window.widget) {
+ widget.setNavigationEnabled(false);
+ menu.showSoftkeys();
+ }
+}
+</pre>
+
+ <p>
+
+ We wrapped the calls to disable the pointer navigation and show the softkeys
+ in an if-clause that checks if there's such an object available as window.widget.
+ This will evaluate to false on a PC web browser but true in the S60 Web Runtime.
+ </p>
+
+ <p>
+
+ Now that we've tuned the Web Runtime to our liking we can create the actual
+ user interface. We'll create four things: the so-called "user interface manager"
+ that is in charge of managing views and other user interface resources, the main
+ view for the widget, a text field where users can enter their name, and finally
+ a button that they can click on to popup a notification dialog that says "Hello"
+ Notice that we don't have to create the notification dialog because this is done
+ for us by the user interface manager.
+ </p>
+
+ <p>
+
+ Before we create those four objects we will declare four global variables so that
+ we can access those objects elsewhere in the widget. So let's add the following
+ to the top of the file (outside the init() function):
+ </p>
+
+<pre>
+
+// References to the WRTKit user interface manager and main view.
+var uiManager;
+var mainView;
+
+// References to controls in the main view.
+var helloButton;
+var nameField;
+</pre>
+
+ <p>
+
+ Now that we have some variables that can track the objects we are about to create
+ we can actually craete those objects. We'll create the objects inside the init()
+ function so that the user interface gets created right after the widget has loaded.
+ </p>
+
+ <p>
+
+ The first thing we create is the user interface manager. This is quite simple and
+ requires only a single line of code:
+ </p>
+
+<pre>
+
+// create UI manager
+uiManager = new UIManager();
+</pre>
+
+ <p>
+
+ Next we'll create the main view. The WRTKit allows all kinds of views to be created
+ if one has special needs for how user interface controls should be laid out. However
+ in the vast majority of cases the ListView class will be sufficient and that's what
+ we'll create this time too:
+ </p>
+
+<pre>
+
+// create main view
+mainView = new ListView(null, "Hello World");
+</pre>
+
+ <p>
+
+ The first argument to the ListView constructor is a unique identifier for the view.
+ All user interface elements in the WRTKit can have a unique identifier. The identifier
+ is helpful if you want to specifically target a view or control with some CSS style
+ rule or if you want to identify the source of an event in an event listener callback,
+ etc. However we don't need it here so we don't bother giving our main view a unique
+ id and just pass a null identifier value instead. The second argument is a caption for
+ the view. We'll just call our view "Hello World". The caption will be displayed at the
+ very top of the screen when we display the main view. But before we do that, let's
+ create the rest of the user interface.
+ </p>
+
+ <p>
+
+ The widget should have a text field to let users enter their name and a button to
+ trigger the greeting popup. Both the text field and the button are WRTKit controls
+ and will be created and added to the main view that we just created. There are two
+ kinds of buttons in the WRTKit though, form buttons and navigation buttons. Form
+ buttons are meant to trigger actions whereas navigation buttons are meant for
+ situations where clicking it would result in moving from one view to another. Clearly
+ therefore, we want a form button in this case.
+ </p>
+
+ <p>
+
+ Creating the textfield and form button is done as follows:
+ </p>
+
+<pre>
+
+// add a text field to the view
+nameField = new TextField(null, "Enter your name");
+mainView.addControl(nameField);
+
+// add a button to the view
+helloButton = new FormButton(null, "Say Hello!");
+mainView.addControl(helloButton);
+</pre>
+
+ <p>
+
+ The first argument for both the textfield and button is the same as for the view:
+ an optional unique identifier. We won't need it here either so rather than scratching
+ our heads trying to come up with a unique identifier that we'll end up ignoring we'll
+ just define it as null. The second argument for the textfield constructor is a caption.
+ All controls except buttons have captions and this is the second argument in all
+ constructors for controls with captions. The caption is displayed above the control
+ and tells the user what the control does. In our case we want to have a textfield where
+ the user should enter the name so we'll use "Enter your name" as the control caption.
+ The second argument for the button constructor is the text for the button. The button
+ text for form buttons should be a verb or other descriptive text that lets the user know
+ what happens if the button is pressed. We'll put "Say Hello!" on our button.
+ </p>
+
+ <p>
+
+ After we have created a control we can add it to a view. Custom views can have their
+ own ways to do so but in the case of the default ListView that you'll use in most cases
+ you add a control by calling the addControl() method.
+ </p>
+
+ <p>
+
+ The user interface for the main view is now ready and we can show it. Showing a view
+ is done by calling setView() in the user interface manager. So we'll add one more line
+ of code to the end of the init() function:
+ </p>
+
+<pre>
+
+// display the main view
+uiManager.setView(mainView);
+</pre>
+
+ <p>
+
+ If you zipped up the widget directory, renamed it HelloWorld.wgz and installed the
+ widget on an emulator or handset, or just simply ran it in a PC web browser, you'd
+ notice that the user interface seems to work. There's just one problem. Clicking on
+ the button doesn't do anything! But don't worry, we're about to fix that.
+ </p>
+
+ </div>
+
+ <div class="section"><h2 class="sectiontitle">
+Handling events</h2>
+
+
+ <p>
+
+ The thing that is missing is that we have no way of knowing when the button was
+ pressed. And without knowing when it's pressed we can't react to the press and
+ show a greeting. A user interface action such as pressing a button is called an
+ "event". In the WRTKit events are reported to "listener" functions that developers
+ can register to controls. The way this is done is by creating a function that you
+ want to get called when an event occurrs, and then calling addEventListener() on
+ the control whose events you are interested in, passing the function to that method.
+ However there are many types of events and you are almost surely not interested in
+ all of them. Because of this you can specify the type of event that you want to get
+ notified about by giving the event type name to the addEventListener() method. The
+ event types and their names are described in the
+ <a href="WRTKit_API_Reference-GUID-00e47c27-0a1a-443f-ae85-cf3381635170.html">
+WRTKit API Reference</a>
+ for each control. Note that because controls inherit from other classes they also
+ inherit event types.
+ </p>
+
+ <p>
+
+ The event type that we're interested in here is "ActionPerformed". That event is
+ fired by form buttons whenever a user clicks on them. In order to get notified
+ of this event we'll need two things: create a function that will get called when
+ the event occurs and register that function as an event listener to our button.
+ Let's create the function first but leave the implementation empty for now:
+ </p>
+
+<pre>
+
+// Called when the hello-button is clicked.
+function helloButtonClicked(event) {}
+</pre>
+
+ <p>
+
+ Now that we have the event handler callback function we can add the event listener
+ registration code. Let's put that right after where we create the button in
+ the init() function:
+ </p>
+
+<pre>
+
+helloButton.addEventListener("ActionPerformed", helloButtonClicked);
+</pre>
+
+ <p>
+
+ Now our helloButtonClicked() function will get called whenever the button is
+ clicked. Notice that the function has an argument called event. This argument
+ will receive an event object that describes the event that occurred. This can
+ be useful if you have an event handler function that handles many different
+ events. The event object contains three properties that you can examine to
+ decide on what to do: a property called "source" that points back to the control
+ or view from where the event was fired, a property called "type" that contains
+ the event type name for this event, and a property called "value" that has
+ helpful additional info that depends on the event type. You'll find more detailed
+ information about this in the API Reference.
+ </p>
+
+ </div>
+
+ <div class="section"><h2 class="sectiontitle">
+Notification popup dialogs</h2>
+
+
+ <p>
+
+ All that remains now is to write the code that shows the greeting popup dialog
+ when the button is pressed. This code will naturally go in the helloButtonClicked()
+ function.
+ </p>
+
+ <p>
+
+ Using notification popup dialogs is very easy with the WRTKit. The user interface
+ manager has two methods: showNotification() and hideNotification() that are used
+ to show and hide notification popup dialogs. The showNotification() method takes
+ four arguments: displayTime, type, text and progress. The displayTime argument is
+ used to supply a time (in milliseconds) for how long the notification popup should
+ be shown for. We want our greeting to be visible for 3 seconds so we'll pass 3000
+ to this argument. The type argument is a string that tells the method what kind of
+ popup to show, which determines the visual style of the popup. We'll be using two types:
+ "info" and "warning". The "info" type for when we show the greeting and "warning" if
+ the user didn't enter a name and we want to show a notification dialog that complains
+ about this. The text argument is simply the text to show in the notification dialog.
+ And finally the progess argument is a decimal number between 0.0 and 1.0 that is
+ used in progress dialogs to display how far along a process is.
+ </p>
+
+ <p>
+
+ A progress of 0.0 means "0% progress" and 1.0 means "100% progress". So for example
+ if some process is 25% completed, you'd pass 0.25 to this argument. If you don't know
+ how long a process will take you can pass a negative number. This will result in an
+ animated progress bar that has a visual style that indicates that the progress is
+ unknown. Typically you'd use the "wait" notification type is you want to show a
+ progress dialog. If you don't want to show any progress information in the dialog,
+ such as in our case, you can omit the progress argument or pass a null to it.
+ </p>
+
+ <p>
+
+ Before we can write our code we need one more thing. We need to know what the user
+ wrote in the name textfield. This value can be retrieved by calling the getText()
+ method for the textfield. We're now ready to write the code for the helloButtonClicked()
+ function:
+ </p>
+
+<pre>
+
+var name = nameField.getText();
+if (name.length == "") {
+ uiManager.showNotification(3000, "warning", "Please enter your name!");
+} else {
+ uiManager.showNotification(3000, "info", "Hello " + name + "!");
+}
+</pre>
+
+ <div class="fignone" id="GUID-D638159A-D12B-476C-A74C-99055672B7BE__GUID-A2B73DB1-6494-4806-A11E-2E7F9BB1B3E7"><a name="GUID-D638159A-D12B-476C-A74C-99055672B7BE__GUID-A2B73DB1-6494-4806-A11E-2E7F9BB1B3E7"><!-- --></a><span class="figcap">Figure 1.
+The Hello World widget</span>
+
+
+ <br /><img src="Hello_World_Screenshot_1.png" /><br />
+ </div>
+
+ </div>
+
+ <div class="section"><h2 class="sectiontitle">
+Wrapping up</h2>
+
+
+ <p>
+
+ The Hello World widget is now done and you can zip it up, rename it to HelloWorld.wgz
+ and deploy it on a handset or emulator. But before that, let's try it in a normal PC
+ browser. Testing in a PC browser is useful because it allows you to use deubugging tools
+ (like the Firebug JavaScript debugger for Firefox) in case something isn't working. Using
+ a PC browser to test is also very fast because you don't have to install the widget to
+ the emulator or handset. Just hit reload in the web browser when you make a change and
+ you can see the results immediately. Of course there are features that will be missing
+ in a web browser, such as that you won't have access to the Options menu or any other
+ advanced widget functionality. But for the purpose of rapidly testing user interfaces
+ it can be very helpful.
+ </p>
+
+ <p>
+
+ There are a couple of points that are good to note now that the widget is ready.
+ First of all, your widget now works with both the pointer and tab navigation modes. If
+ you comment out the <samp class="codeph">
+widget.setNavigationEnabled(false)</samp> call in the init()
+ function you can try this out. Second, your widget works resolution independently.
+ You can try this either by resizing the PC browser window or by trying the widget out
+ with different resolutions in the S60 emulator. Third, the widget correctly handles
+ screen rotations and other resizes, e.g. if the softkey bar is hidden / shown. Fourth,
+ the widget looks can be customized without needing to touch any code - simply by changing
+ the UI.css and image files that you can find in the WRTKit/Resources directory.
+ </p>
+
+ <p>
+
+ But perhaps more important than any of the above is the fact that the WRTKit simplifies
+ the separation of user interface code from data and logic code. That's not something
+ that is apparent in a simple widget like this one, but it becomes very important as
+ you create something more complex and especially if the user interface contains elements
+ that are created dynamically for example based on data that has been fetched from the
+ Internet using AJAX.
+ </p>
+
+ </div>
+
+ </div>
+
+<div>
+<div class="familylinks">
+<div class="parentlink"><strong>Parent topic:</strong> <a href="WRTKit_Hello_World_Tutorial-GUID-67e0a561-48ac-4938-8f1b-852422b71380.html">Hello World</a></div>
+</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file