[gnome-devel-docs] g-t whitespace adjustment, image-viewer.c removed text, i-v.js started editing
- From: Phil Bull <philbull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-devel-docs] g-t whitespace adjustment, image-viewer.c removed text, i-v.js started editing
- Date: Mon, 6 Dec 2010 15:03:21 +0000 (UTC)
commit 97be91f69597a630ef7a429ca4a8ac253801d47a
Author: Phil Bull <philbull gmail com>
Date: Mon Dec 6 09:18:24 2010 +0000
g-t whitespace adjustment, image-viewer.c removed text, i-v.js started editing
demos/C/guitar-tuner.c.page | 2 +-
demos/C/image-viewer.c.page | 276 +-----------------------------------------
demos/C/image-viewer.js.page | 67 ++++++----
3 files changed, 42 insertions(+), 303 deletions(-)
---
diff --git a/demos/C/guitar-tuner.c.page b/demos/C/guitar-tuner.c.page
index 5a52045..6f1536a 100644
--- a/demos/C/guitar-tuner.c.page
+++ b/demos/C/guitar-tuner.c.page
@@ -15,7 +15,7 @@
<credit type="author">
<name>Johannes Schmid</name>
<email>jhs gnome org</email>
- </credit>
+ </credit>
</info>
<title>Guitar Tuner</title>
diff --git a/demos/C/image-viewer.c.page b/demos/C/image-viewer.c.page
index c9c2c71..879bfaf 100644
--- a/demos/C/image-viewer.c.page
+++ b/demos/C/image-viewer.c.page
@@ -29,281 +29,7 @@
<section>
<title>Introduction</title>
- <p>This demo uses the Javascript language. You need the <em>gjs</em> interpreter (already present in GNOME 3). We are not going to teach the Javascript language itself, instead, we are going to show the best practices in development for GNOME with Javascript.</p>
- <p>In order to run this demo, just save the code into a file (for instance iv.js) and run the following command:</p>
- <screen>gjs iv.js</screen>
-</section>
-
-<section>
- <title>Program Structure</title>
- <media type="image" mime="image/png" src="media/image-viewer.png"/>
- <p>This demo is a simple GTK application (with a single window) capable of showing an image on the screen. The window has only two elements: On the top, there is a widget that shows the image. On the bottom, there's a button that allows you to choose an image from the file system.
- </p>
-</section>
-
-<section>
- <title>Hello World</title>
- <p>Before enter in the Image Viewer demo itself, we are going to do a bit explanation about Javascript usage in GNOME.</p>
- <p>Of course, the very first contact with a language is the Hello World program:</p>
- <code mime="text/javascript">print ("Hello world!");</code>
- <p>That's it. Very simple, isn't it?</p>
-</section>
-
-<section>
- <title>Classes in Javascript</title>
- <note><p>It's not the scope of this tutorial to discuss class versus prototypes in Javascript. If you want to do a deeper study on this topic, please refer to the Javascript documentation.</p></note>
- <p>Let's see the standard way to define a class in GNOME's Javascript:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
-function MyClass () {
- this._init ();
-}
-
-MyClass.prototype = {
- _init: function () {
- this.propertyA = "This is an object's field";
- this.propertyB = 10;
- },
-
- aMethod: function (arg1, arg2) {
- print ("inside aMethod: " + arg1 + " " + arg2);
- },
-
- dumpProperties: function () {
- print (this.propertyA);
- print (this.propertyB);
- }
-}]]>
- </code>
- <p>This defines a class called <code>MyClass</code>. That's what we do:</p>
- <steps>
- <item><p>Create a function that serves as a constructor. The function name is the name of the class. It just calls the <code>_init</code> method.</p></item>
- <item><p>Actually define the class structure - its fields and methods - using the JSON syntax. In the snippet above, <code>MyClass</code> class has 2 fields: <code>propertyA</code> and <code>propertyB</code>, and 2 methods: <code>aMethod()</code> and <code>dumpProperties()</code>.</p></item>
- </steps>
-
- <p>Now we can use this class and play with it:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
-var o = new MyClass ();
-o.aMethod ("Hello", "world");
-o.propertyA = "Just changed its value!";
-o.dumpProperties ();]]>
- </code>
-</section>
-
-<section>
- <title>Very first Gtk application</title>
- <p>Let's continue our tutorial by showing how a very basic Gtk application looks like in Javascript:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
-const Gtk = imports.gi.Gtk;
-
-Gtk.init (0, null);
-
-var w = new Gtk.Window ({title: "Image Viewer Demo"});
-w.show ();
-
-Gtk.main ();]]>
- </code>
- <p>Explanation line-by-line:</p>
- <list>
- <item><p>Line 1: Let's import the Gtk namespace. It's coming from GObject Introspection (gi). This works like the C #include, or the Python import statements.</p></item>
- <item><p>Line 3: Initialize the Gtk library. It's mandatory for all Gtk programs.</p></item>
- <item><p>Line 5: Create the main window. You can pass several properties at the same time in the constructor by using a JSON syntax, <code>{property: value, property: value, ...}</code>. In this case we are providing the title of the window. This ability is valid to every constructor coming from GObject Introspection (basically all GNOME libraries).</p></item>
- <item><p>Line 6: Explicitly show the window. In Gtk every widget is hidden by default.</p></item>
- <item><p>Line 8: Run the main loop. In other words, execute the program.</p></item>
- </list>
-
- <note><p>If you run the application above (you should), you will notice that the application does not quit when you close the window. For now you can just hit <keyseq><key>Ctrl</key><key>C</key></keyseq> to terminate the application. Later on this tutorial we will get on this.</p></note>
-</section>
-
-<section>
- <title>Adding classes to our first app</title>
- <p>The proper way of doing Gtk programming is by using classes. So, let's change a bit the code above by adding a class:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
-const Gtk = imports.gi.Gtk;
-
-function ImageViewer () {
- this._init ();
-}
-
-ImageViewer.prototype = {
- _init: function () {
- this.window = new Gtk.Window ({title: "Image Viewer Demo"});
- this.window.show ();
- }
-}
-
-Gtk.init (0, null);
-var iv = new ImageViewer ();
-Gtk.main ();]]>
- </code>
- <p>Notice that the program is the same, we just moved the window creation code to our own class (lines 3-12), and then we instantiate that class by creating an object (line 15). This makes the code cleaner, modular and easy to be split in multiple files. That's the recommended way to code in Javascript for GNOME.</p>
-</section>
-
-<section>
- <title>Signals</title>
- <p>One of the key concepts in the Gtk programming is signals. But what are they? Think of them like something that happens to an object. Some event. If you are interested in being notified when that event happens, you must connect a function (or a class method) with that event signal. For instance, a Button has a signal called <em>clicked</em>, which is triggered every time the button receives a click. See the code snippet below:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
-function button_clicked () {
- print ("you clicked me!");
-}
-var b = new Gtk.Button ({label:"Click me"});
-b.connect ("clicked", button_clicked);]]>
- </code>
- <p>As you can see on the line 5, the syntax for connect signals to functions is: <code mime="text/javascript"><![CDATA[object.connect (<signal_name>, <function_to_be_called>);]]></code>. The snippet above connects the <em>clicked</em> signal of the Button object to the function <code>button_clicked</code>. So, every time the button is clicked, the code in the <code>button_clicked</code> function will be executed.</p>
- <note>
- <p>
- You can simplify the code by making use of the inline functions in Javascript:
- <code mime="text/javascript"><![CDATA[
-b.connect ("clicked", function () { print ("you clicked me!"); });]]></code>
- </p>
- </note>
-</section>
-
-<section>
- <title>Properly closing our window</title>
- <p>Now we know how to use signals, let's understand how to properly close our application window.</p>
- <p>In Gtk, when you close a window (by clicking on the X button of the window, or hitting <keyseq><key>Alt</key><key>F4</key></keyseq> on the keyboard), it is not really closed, it's supposed to hide. That gives the possibility of keeping the window around (specially in applications with several windows) as well it allows you to ask the user if it really wants to close the window.</p>
- <p>OK, we just want to close the window. What should we do? The simplest way of doing that is by connecting to the <em>hide</em> signal of the window object with a function that closes the application. Let's look how it works:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
-const Gtk = imports.gi.Gtk;
-
-function ImageViewer () {
- this._init ();
-}
-
-ImageViewer.prototype = {
- _init: function () {
- this.window = new Gtk.Window ({title: "Image Viewer Demo"});
- this.window.connect ("hide", Gtk.main_quit);
- this.window.show ();
- }
-}
-
-Gtk.init (0, null);
-var iv = new ImageViewer ();
-Gtk.main ();]]>
- </code>
- <p>The only addition here was the line 10, that does exactly what we talked above: connects the <em>hide</em> signal of our window to the Gtk's function <code>main_quit()</code>. This function ends the execution of the Gtk's main loop (which was started at line 17). Once the Gtk's main loop finishes, the function <code>Gtk.main()</code> returns, which means our program would continue to execute every code posted after line 17. As we don't have any code, the program just ends.</p>
- <p>If you want to try, just put an statement like <code>print ("exiting...");</code> after line 17. You will see that this line is only executed when you close the window.</p>
-</section>
-
-<section>
- <title>Layout in Gtk</title>
- <p>You can put your controls (we call them <em>widgets</em>) on the window by making use of containers. You can organise the layout of your window by mixing different types of containers: boxes, grids, etc.</p>
- <p>In a window you can only put one widget. In our demo (as you can see the screenshot above) we have two widgets (the image and the button). How was that possible then? That's simple: we put in the window a single widget called <em>Box</em>. <em>Box</em> is capable of receive several widgets organised horizontally or vertically. After putting it in the window, we can now put our 2 widgets in the box. You can even do more complicated layouts by putting a box inside another box, and mixing containers in the window. That's what happens on real life.</p>
- <note><p>There is a tool called <app>Glade</app> that makes the creation of windows interfaces really easy. It's a visual tool where you can draw your GUI without coding at all. As our demo is really simple, we are not going to use Glade at this time.</p></note>
- <p>Let's see how to add boxes and widgets to our application:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
-var main_box = new Gtk.Box ({orientation: Gtk.Orientation.VERTICAL, spacing: 0});
-this.window.add (main_box);]]>
- </code>
- <list>
- <item>
- <p>Line 1: Create a box object. We pass to the constructor two properties:</p>
- <list>
- <item><p>orientation: VERTICAL means the widgets added to the box are packed one under another. HORIZONTAL means widgets are packed side-by-side</p></item>
- <item><p>spacing: the space between the widgets</p></item>
- </list>
- </item>
- <item><p>Line 2: Add that newly created box to the window. Remember: the window object can hold one and only one widget.</p></item>
- </list>
- <p>At this time the window contains an empty box. So, if you run the application with the snippet above added, you will see no changes at all. That's because we haven't add any widget to the box. Also, the box is only a container, it's a sort of "transparent" widget.</p>
- <p>Let's now add real widgets into the box container:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
-ImageViewer.prototype = {
- _init: function () {
- this.window = new Gtk.Window ({title: "Image Viewer Demo"});
- this.window.connect ("hide", Gtk.main_quit);
-
- this.image = new Gtk.Image ();
- main_box.pack_start (this.image, true, true, 0);
-
- var open_button = new Gtk.Button ({label: "Open a picture..."});
- main_box.pack_start (open_button, false, false, 0);
-
- this.window.show ();
- }
-}]]>
- </code>
- <p>New stuff happens between lines 6 and 10:</p>
- <list>
- <item><p>Line 6: Create the image widget. It will store the actual image, to be picken from the file system.</p></item>
- <item>
- <p>Line 7: Add the image widget to the box container. We're using the <code>pack_start()</code> method of the Box class to do that. It takes 4 arguments:</p>
- <steps>
- <item><p><em>child</em>: The widget to be packed into the box. In our case, the image widget.</p></item>
- <item><p><em>expand</em>: true if the widget should use all remain space available to the box.</p></item>
- <item><p><em>fill</em>: if <em>expand</em> is true, then this parameter tells if the entire space should be actually used by the widget.</p></item>
- <item><p><em>padding</em>: extra space in pixels to put between this widget and its neighbours.</p></item>
- </steps>
- </item>
- <item><p>Line 9: Create the "open..." button. More about its behavior below.</p></item>
- <item><p>Line 10: Add the button to the box. Notice that we are passing <code>false</code> to the <em>expand</em> argument. By doing that, we are telling: Let the image takes all available space, and let the button take only the space it needs. So, when you maximize the window, the button size remains the same, but the image size changes (increases) taking all window space.</p></item>
- </list>
- <note>
- <p>You are not supposed to understand how all this packing stuff works just by reading the explanation above. Go and play with those parameters, to see the result in practice.</p>
- </note>
-</section>
-
-<section>
- <title>Loading the image</title>
- <p>This is the last and crucial step of our demo: Actually show the image on the window. The plan is really simple: When the user clicks on the Open button, a dialog should appear so that the user can pick a picture. Once an image is chosen, we should show it in our image widget.</p>
- <section>
- <title>Connecting to the button's signal</title>
- <p>So, the first step is to connect the <em>clicked</em> signal of our button with a function. Let's put the code below just after the button creation:</p>
- <code mime="text/javascript"><![CDATA[
-open_button.connect ("clicked", Lang.bind (this, this._openClicked));]]></code>
- <p>We are using the <em>Lang</em> Javascript helper here. It allows us to pass a class method as an argument to the <code>connect()</code> function. Don't worry about that for now. Just use it. You need to put the line below on the top of the file:</p>
- <code mime="text/javascript">const Lang = imports.lang;</code>
- </section>
-
- <section>
- <title>Implementing the signal's callback</title>
- <p>Now let's create the <code>_openClicked()</code> method:</p>
- <code mime="text/javascript" style="numbered"><![CDATA[
- _openClicked: function () {
- var chooser = new Gtk.FileChooserDialog ({title: "Select an image",
- action: Gtk.FileChooserAction.OPEN,
- transient_for: this.window,
- modal: true});
- chooser.add_button (Gtk.STOCK_CANCEL, 0);
- chooser.add_button (Gtk.STOCK_OPEN, 1);
- chooser.set_default_response (1);
-
- var filter = new Gtk.FileFilter ();
- filter.add_pixbuf_formats ();
- chooser.filter = filter;
-
- if (chooser.run () == 1)
- this.image.file = chooser.get_filename ();
-
- chooser.destroy ();
- }]]></code>
- <p>Line-by-line explanation:</p>
- <list>
- <item>
- <p>Line 2: Create the "Open" dialog. We are passing some properties to the constructor:</p>
- <list>
- <item><p><em>title</em>: The title of the dialog. Notice that Dialog is a subclass of Window, so actually this property comes from Window class.</p></item>
- <item><p><em>action</em>: The type of this dialog. It could be SAVE if the intention is to save a file.</p></item>
- <item><p><em>transient_for</em>: It sets the parent window of this dialog.</p></item>
- <item><p><em>modal</em>: It doesn't allow the user to click on other area of the application until the dialog is closed.</p></item>
- </list>
- </item>
- <item><p>Lines 6-7: Add two buttons to the dialog, Cancel and Open. The first argument of this function is the label of the button, and the second is a value that is returned when the button is pressed. Notice that I'm using <em>stock</em> button names from Gtk, instead of manually type "Cancel" or "Open". The advantage of using Gtk stock names is that they come already translated to the user's language.</p></item>
- <item><p>Line 8: Set the default button to be pressed in case the user double clicks some file or hit <key>enter</key>. The button becomes bold. In our case, we are using the Open button as default (the value 1 as the argument is the same value we set on the line 7).</p></item>
- <item><p>Lines 10-12: Kind of a cosmetic feature: Use filters to limit the type of files shown in the Open dialog. In line 10 we create the filter object. In Line 11 we add to that filter all kind of files supported by GtkPixbuf (png, jpg, etc). In line 12 we set the dialog's filter property to our filter.</p></item>
- <item><p>Line 14: Show the open dialog. This function will return the value of the button clicked (that we setup on lines 6 and 7). We are only interested in the case the user pressed the Open button. That explains our <code>if</code> statement.</p></item>
- <item><p>Line 15: If the user pressed the Open button, we just set the <em>file</em> property of our Image widget to be the filename the user chose on the Open dialog. We use the dialog's method <code>get_filename()</code> for that. By setting this <em>file</em> property, the Image widget will show the picture on the window.</p></item>
- <item><p>Line 17: Finally, close the Open dialog.</p></item>
- </list>
-
- </section>
-</section>
-
-<section>
- <title>That's it!</title>
- <p>We reached the end of this tutorial. By now you have a complete Gtk application done in a few minutes in the Javascript language.</p>
- <p>Download the full source code of this demo and starting improving it!</p>
+ <p></p>
</section>
<section>
diff --git a/demos/C/image-viewer.js.page b/demos/C/image-viewer.js.page
index 12fa3ef..d657b46 100644
--- a/demos/C/image-viewer.js.page
+++ b/demos/C/image-viewer.js.page
@@ -6,7 +6,7 @@
<link type="guide" xref="index#js"/>
- <desc>A little bit more than a simple "Hello world" Gtk application.</desc>
+ <desc>A little bit more than a simple "Hello world" application - write an image viewer in GTK.</desc>
<revision pkgversion="0.1" version="0.1" date="2010-12-03" status="stub"/>
<credit type="author">
@@ -19,45 +19,42 @@
<title>Image Viewer</title>
<synopsis>
- <p>In this tutorial, you will learn:</p>
+ <p>In this tutorial, we're going to write a very simple GTK application that loads and displays an image file. You will learn how to:</p>
<list>
- <item><p>Some basic concepts of the Javascript language, specially the best practices when developing for GNOME</p></item>
- <item><p>How to write a Gtk application in Javascript</p></item>
+ <item><p>Write a basic GTK user interface in JavaScript</p></item>
+ <item><p>Deal with events by connecting signals to signal handlers</p></item>
+ <item><p>Lay out GTK user interfaces using containers</p></item>
+ <item><p>Load and display image files</p></item>
+ </list>
+ <p>You'll need the following to be able to follow this tutorial:</p>
+ <list>
+ <item><p>An installed copy of the <link xref="getting-ready">Anjuta IDE</link></p></item>
+ <item><p>An installed copy of the <em>gjs</em> interpreter</p></item>
+ <item><p>Basic knowledge of any object-orientated programming language</p></item>
</list>
</synopsis>
-<section>
- <title>Introduction</title>
- <p>This demo uses the Javascript language. You need the <em>gjs</em> interpreter (already present in GNOME 3). We are not going to teach the Javascript language itself, instead, we are going to show the best practices in development for GNOME with Javascript.</p>
- <p>In order to run this demo, just save the code into a file (for instance iv.js) and run the following command:</p>
- <screen>gjs iv.js</screen>
-</section>
+<!-- <screen>gjs iv.js</screen> -->
-<section>
- <title>Program Structure</title>
- <media type="image" mime="image/png" src="media/image-viewer.png"/>
- <p>This demo is a simple GTK application (with a single window) capable of showing an image on the screen. The window has only two elements: On the top, there is a widget that shows the image. On the bottom, there's a button that allows you to choose an image from the file system.
- </p>
-</section>
+<media type="image" mime="image/png" src="media/image-viewer.png"/>
<section>
- <title>Hello World</title>
- <p>Before enter in the Image Viewer demo itself, we are going to do a bit explanation about Javascript usage in GNOME.</p>
- <p>Of course, the very first contact with a language is the Hello World program:</p>
+ <title>JavaScript basics: Hello World</title>
+ <p>Before we start writing the image viewer, let's find out more about the way JavaScript is used in GNOME. Of course, your very first contact with any programming language should be the Hello World program:</p>
<code mime="text/javascript">print ("Hello world!");</code>
- <p>That's it. Very simple, isn't it?</p>
+ <p>This should look quite natural if you're familiar with almost any other programming language. The function <code>print</code> is called with the argument <code>"Hello world!"</code>, which will be printed on the screen. Note that each line of code ends with a semicolon.</p>
</section>
<section>
- <title>Classes in Javascript</title>
- <note><p>It's not the scope of this tutorial to discuss class versus prototypes in Javascript. If you want to do a deeper study on this topic, please refer to the Javascript documentation.</p></note>
- <p>Let's see the standard way to define a class in GNOME's Javascript:</p>
+ <title>Classes in JavaScript</title>
+ <p>This is the standard way to define a class in JavaScript:</p>
<code mime="text/javascript" style="numbered"><![CDATA[
function MyClass () {
this._init ();
-}
+}the constructor just calls the <code>_init</code> method.
MyClass.prototype = {
+
_init: function () {
this.propertyA = "This is an object's field";
this.propertyB = 10;
@@ -71,12 +68,28 @@ MyClass.prototype = {
print (this.propertyA);
print (this.propertyB);
}
+
}]]>
</code>
- <p>This defines a class called <code>MyClass</code>. That's what we do:</p>
+ <p>This defines a class called <code>MyClass</code>. Let's go through each part of the class definition:</p>
<steps>
- <item><p>Create a function that serves as a constructor. The function name is the name of the class. It just calls the <code>_init</code> method.</p></item>
- <item><p>Actually define the class structure - its fields and methods - using the JSON syntax. In the snippet above, <code>MyClass</code> class has 2 fields: <code>propertyA</code> and <code>propertyB</code>, and 2 methods: <code>aMethod()</code> and <code>dumpProperties()</code>.</p></item>
+ <item>
+ <p><code>function MyClass ()</code> is the constructor of the class - its name must match the class's name. You can access any member of the class by using the <code>this</code> object; here, the constructor calls the class's <code>_init</code> method.</p>
+ </item>
+ <item>
+ <p>The <code>MyClass.prototype</code> block defines the structure of the class. Each class is made up of methods (functions) and fields (variables); there are three methods and two fields in this example.</p>
+ </item>
+ <item>
+ <p>The first method defined here is called <code>_init</code>, and we specify that it is a function with no arguments:</p>
+ <code>_init: function ()</code>
+ <p>We write the function inside some curly braces. Two fields are defined here, <code>propertyA</code> and <code>propertyB</code>. The first is set to a string and the second is set to an integer (10). The function doesn't return any value.</p>
+ </item>
+ <item>
+ <p>The next fu</p>
+ </item>
+ <item>
+ <p>The next three blocks of code define the class structure (its fields and methods) - using the JSON syntax. In the snippet above, <code>MyClass</code> class has 2 fields: <code>propertyA</code> and <code>propertyB</code>, and 2 methods: <code>aMethod()</code> and <code>dumpProperties()</code>.</p>
+ </item>
</steps>
<p>Now we can use this class and play with it:</p>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]