Message board (C) Un programa sinxelo usando WebKitGTK+ e DOM. Shaun McCance shaunm@gnome.org 2010 Marta Maria Casetti mmcasetti@gmail.com 2013 Fran Dieguez frandieguez@gnome.org 2012-2013. Message board

Neste titorial aprenderá:

Como mostrar unha páxina web con WebKit

Como manipular os contidos dunha páxina web usando as funcións de DOM de WebKit.

Este titorial asume que vostede está familiarizado co linguaxe de programación C e ten coñecementos básicos de GTK+, incluíndo como crear e dispor widgets e como conectar funcións de callback a sinais. Vexa para aprender o básico de GTK+.

Cree un proxecto de Anjuta

A paltaforma GNOME inclúe WebKitGTK+, construído sobre o potente marco de traballo WebKit. WebKitGTK usase en todo GNOME, non só para ver páxinas web en Internet, senón tamén para crear interfaces de usuario enriquecidas ás que se poden engadir estilos de forma doada con CSS.

Neste titorial, vostede creará un taboleiro de mensaxes sinxelo usando WebKit. O taboleiro de mensaxes permitiralle inserir algún texto e engadilo a unha lista de mensaxes en HTML. Antes de comezar debe configurar un proxecto en Anjuta.

In Anjuta, click FileNew Project to open the new project assistant.

Select GTK+ (simple) on the C tab, and click Continue.

Fill out your details on the Basic information page. Use message-board for the project name. Click Continue.

Desactive a opción Usar GtkBuilder para a interface de usuario xa que neste titorial construirase a interface de usuario de forma manual.

You need to tell Anjuta you're using WebKitGTK+ on this project. On the Project options page, select Configure external packages. Click Continue. On the Configure external packages page, check webkitgtk-3.0.

After you finish the new project assistant, open the file src/main.c from either the Project or the File tab. Anjuta will have filled this in with some basic GTK+ code from its templates. Since you are creating a WebKit project, you first need to include the WebKit headers. After the line that includes gtk/gtk.h, add the following line:

#include <webkit/webkit.h>

Verify that everything works by building what you have so far. Click BuildBuild Project or just press ShiftF7. The first time you build, you will be asked for some configure options. Just accept the defaults and click Execute.

You should now be able to run the program. Click RunExecute or just press F3. You should see an empty window appear.

Dispor a súa xanela e a vista web

Agora que pode mostrar unha xanela, é hora de comezar o traballo con webkit. Para este titorial, crearemos unha entrada de texto e unha vista web e empaquetarémolas nunha xanela. Busque a función create_window e substitúaa co seguinte:

", "text/html", "UTF-8", NULL); gtk_widget_show_all (GTK_WIDGET (box)); return window; } ]]>

Primeiro cree un obxecto GtkWindow e estabeleza o seu título e o seu tamaño predeterminado. Tamén pode conectar a función gtk_main_quit ao sinal delete-event. O sinal delete-event emítese cando se pecha a xanela. A función gtk_main_quit é parte de GTK+, e sae do aplicativo.

You then create a vertical box and add it to the window. A window can only hold a single child widget, so you need to use a box to add multiple widgets. The second argument to gtk_box_new sets the amount of padding (in pixels) between each child, and the next line puts a six-pixel border around the entire thing.

You next create a GtkEntry object and pack it into the box. The third and fourth arguments to gtk_box_pack_start specify that the entry shouldn't take up any extra space the box has available. The fourth argument is the amount of padding you want around the entry. In this case, you set the padding to zero, because you're allowing the box to handle all the padding.

Before you add a web view, you have to create a scrolled window to put it inside of. The scrolled window will place scrollbars on the right and bottom when necessary, and prevent your web view from filling your entire screen. This time, you pass TRUE and TRUE to gtk_box_pack_start to allow the scrolled window (and thus, the web view) to use any extra space available in the box.

Finally, you create a WebKitWebView and add it to the scrolled window. Then load a very basic HTML page into the web view by calling webkit_web_view_load_string with the following arguments:

<code>WEBKIT_WEB_VIEW (view)</code>

A vista por si mesma. Xa que view é de tipo GtkWidget*, debe usar WEBKIT_WEB_VIEW para converter o tipo de obxecto con seguranza.

<code>"<html><body></body></html>"</code>

O ficheiro HTLM máis sinxelo que pode escribir.

<code>"text/html"</code>

O tipo MIME do contido que forneceu. Neste caso, está usando HTML plano.

<code>"UTF-8"</code>

A codificación de caracteres do contido que forneceu. Aínda que só se usen caracteres ASCII é boa idea especificar UTF-8. UTF-8 úsase como a codificación predeterminada na plataforma GNOME.

<code>NULL</code>

O URI base. Non o precisa neste exemplo sinxelo, pero podería fornecer unha URI file: se quere engadir imaxes ou outras características onde queira usar preferencias relativas a URI.

Every time you add a widget, you have to call gtk_widget_show on it for it to be visible. If you call gtk_widget_show_all on a container widget like a GtkBox, GTK+ will automatically show all the widgets inside the container, to any depth. Sometimes you don't want to call gtk_widget_show_all, such as when you want to dynamically hide and show some widgets in response to events.

Finally, you have to call gtk_widget_show_all on the box. Otherwise, none of the widgets you created will be visible. (The window is shown in the main function with gtk_widget_show.)

Build and run the message board again. You should see a window with a text entry and a web view. It doesn't do anything yet because the text entry and the web view don't know anything about each other.

Capturar sinais

Now you want to make the message board actually do something when you enter text into the text entry. To do this, connect a callback function to the activate signal of entry. GTK+ emits the activate signal whenever the user presses Enter in the entry. Add the following into create_window, anywhere after both entry and view have been defined:

You then have to actually define entry_activate_cb. Define it as follows, anywhere above create_window:

The first thing you do is get a WebKitDOMDocument object that represents the HTML document displayed in view. The DOM classes and methods in WebKit allow you to inspect and manipulate the HTML document, and work very similarly to the DOM APIs you might already know from JavaScript.

Once you have the document, you want to get the body element so that you can add div elements to it. The webkit_dom_document_query_selector function lets you find an element in the document using CSS selectors. This keeps you from having to write tedious loops to traverse the document.

Next, you create a new div element to hold the message. Every element you create has to be attached to a document, so the function to create an element takes the WebKitDOMDocument as its first arguments. You then set the text content of the element to the contents of the text entry. Because gtk_entry_get_text returns a const gchar*, you don't have to free the result.

Finally, you append the new div element to the body and clear out the text entry so you can type something new. Build and run the program again and test it for yourself.

Mellorar o aspecto con CSS

At this point, your program is completely functional, but not very pretty. You can style the message display with CSS, just like you can with any other HTML page. There are many ways you could attach some CSS to the page: You could add it in the initial HTML document. You could inline it in the style attribute of the div elements. You could even programmatically construct it using the DOM APIs.

In this tutorial, you'll attach the CSS using the user-stylesheet-uri property of the WebKitWebSetting object attached to your web view. In a more complete application, you would want to save and load your HTML file. Keeping the style information outside the actual HTML means that you can change the styling completely within your application, without having to change users' files. You would normally just install a file along with your application, but just to keep everything in one file for this demo, we'll use a trick called a data URI. First, define the CSS as a static string near the top of your file.

All you have in this example are div elements inside a body element. If you created more complicated HTML, you could use whatever CSS is necessary. In fact, if you're comfortable with CSS, you should trying changing this to something you like better.

To apply the CSS, you set the user-stylesheet-uri in the create_window function, anywhere after view has already been defined.

Also, make sure to add variable declarations for tmp and css to the top of create_window.

gchar *tmp, *css;

A data URI starts with data: and some information about the content type and how the data is encoded. The actual data follows after a comma, in this case encoded in Base64. Unlike other URI schemes like http:, ftp:, and file:, the data: URI scheme doesn't specify where to find a file to load. Rather, it gives the entire contents of the file.

The code above first encodes your CSS definitions in Base64, then combines that with a fixed string to create a data URI. The g_strconcat function can take any number of string arguments and concatenate them all together, so you have to pass NULL as the final argument so it knows when to stop. And don't forget to free those temporary strings after you set the stylesheet property.

Build and run the program again. It should now work exactly the same as at the end of the last section, except the messages will be nicely styled with a border and a subtle background gradient.

Aprender máis

Este titorial mostroulle como crear un aplicativo sinxelo usando GTK+ e WebKit, incluindo como mostrar un documento e manipular o seu contido. Para crear un aplicativo real, probabelmente queira facer algo máis. Probe a engadir características vostede mesmo. Aquí hai algunhas ideas:

Si se sinte comodo usando CSS, probe a cambiar o estilo da visualización da mensaxe. É moi doado iniciarse en CSS, pero cada vez é máis potente. Hai unha gran cantidade de titoriais de CSS en Internet, e case todo o que se pode facer nunha páxina web, pódese facer neste aplicativo.

Agora mesmo, tódalas mesnaxes pérdense ao pechar o cadro de mensaxes. Probe a gardar o contido HTML despois de cada envío, e a cargar o ficheiro cargado (se existe) ao inicio.

If you keep your messages around for a long time, you'll start wondering when you posted them. Add a timestamp to each message when it's posted. You'll probably want to create some additional child div elements with different classes that you can style in the CSS.

Este programa garda as mensaxes para sempre. Pense algunha maneira para que o usuario poida borrar mensaxes. Tal vez queira que as mensaxes desapareza automaticamente cando son moi antigas ou despois de que haxa certo número de mensaxes por diante. Ou podería engadir unha ligazón en cada mensaxe para borrala. Tamén pode omitir o menú contextual cando preme co botón dereito sobe unha mensaxe. Esta características implican explorar máis da API do DOM de WebKit.