Blame platform-demos/es/message-board.c.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="message-board.c" xml:lang="es">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
    <title type="text">Cuadro de mensajes (C)</title>
Packit 1470ea
    <link type="guide" xref="c#examples"/>
Packit 1470ea
Packit 1470ea
    <desc>Un programa sencillo usando WebKitGTK+ y el DOM.</desc>
Packit 1470ea
Packit 1470ea
    <revision pkgversion="0.1" version="0.1" date="2010-12-06" status="draft"/>
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Shaun McCance</name>
Packit 1470ea
      <email its:translate="no">shaunm@gnome.org</email>
Packit 1470ea
      <years>2010</years>
Packit 1470ea
    </credit>
Packit 1470ea
    <credit type="editor">
Packit 1470ea
      <name>Marta Maria Casetti</name>
Packit 1470ea
      <email its:translate="no">mmcasetti@gmail.com</email>
Packit 1470ea
      <years>2013</years>
Packit 1470ea
    </credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Daniel Mustieles</mal:name>
Packit 1470ea
      <mal:email>daniel.mustieles@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2011 - 2017</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Nicolás Satragno</mal:name>
Packit 1470ea
      <mal:email>nsatragno@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2012 - 2013</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Jorge González</mal:name>
Packit 1470ea
      <mal:email>jorgegonz@svn.gnome.org</mal:email>
Packit 1470ea
      <mal:years>2011</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
<title>Cuadro de mensajes</title>
Packit 1470ea
Packit 1470ea
<synopsis>
Packit 1470ea
  

En este tutorial aprenderá:

Packit 1470ea
  <list style="compact">
Packit 1470ea
    <item>

Cómo mostrar una página web con WebKit

</item>
Packit 1470ea
    <item>

Como manipular el contenido de una página web usando las funciones del DOM del WebKit.

</item>
Packit 1470ea
  </list>
Packit 1470ea
  

En este tutorial se asume que está familiarizado con el lenguaje de programación C y que tiene un conocimiento básico de GTK+, incluyendo cómo crear y colocar widgets y cómo conectar funciones de retorno de retorno de la llamadas a señales. Consulte la <link xref="image-viewer.c"/> para aprender las nociones básicas de GTK+.

Packit 1470ea
</synopsis>
Packit 1470ea
Packit 1470ea
<media type="video" mime="video/ogg" src="media/message-board.ogv"/>
Packit 1470ea
Packit 1470ea
<links type="section"/>
Packit 1470ea
Packit 1470ea
<section id="create">
Packit 1470ea
  <title>Crear un proyecto en Anjuta</title>
Packit 1470ea
Packit 1470ea
  

La plataforma GNOME incluye WebKitGTK+, construido sobre el potente marco de trabajo WebKit. WebKitGTK se usa en todo GNOME, no sólo para ver páginas web en Internet, sino también para crear interfaces de usuario enriquecidas a las que se pueden añadir estilos fácilmente con CSS.

Packit 1470ea
Packit 1470ea
  

En este tutorial, se creará un cuadro de mensajes sencillo usando WebKit. El cuadro de mensajes le permitirá introducir algún texto y añadirlo a una lista de mensajes en HTML. Antes de empezar, deberá configurar un proyecto en Anjuta.

Packit 1470ea
Packit 1470ea
  <steps>
Packit 1470ea
    <item>

En Anjuta, pulse <guiseq><gui>Archivo</gui><gui>Nuevo</gui> <gui>Proyecto</gui></guiseq> para abrir el asistente para proyecto nuevo.

</item>
Packit 1470ea
    <item>

Seleccione <gui>GTK+ (simple)</gui> en la pestaña <gui>C</gui> y pulse <gui>Continuar</gui>.

</item>
Packit 1470ea
    <item>

Rellene sus detalles en la página <gui>Información básica</gui>. Use <input>cuadro-mensajes</input> para el nombre del proyecto. Pulse <gui>Continuar</gui>.

</item>
Packit 1470ea
    <item>

Desactive la opción <gui>Usar GtkBuilder para la interfaz del usuario</gui>, ya que, en este tutorial, la interfaz de usuario se construye manualmente.

Packit 1470ea
    </item>
Packit 1470ea
    <item>

Deberá indicar a Anjuta que va a usar WebKitGTK+ en este proyecto. En la página <gui>Opciones del proyecto</gui>, seleccione <gui>Configurar paquetes externos</gui>. Pulse <gui>Continuar</gui>. En la página <gui>Configurar paquetes externos</gui> seleccione <gui>webkitgtk-3.0</gui>.

</item>
Packit 1470ea
  </steps>
Packit 1470ea
Packit 1470ea
  

Cuando termine el asistente de creación de un nuevo proyecto, abra el archivo <file>src/main.c</file> desde la pestaña <gui>Proyecto</gui> o desde <gui>Archivo</gui>. Anjuta lo habrá rellenado con algo de código GTK+ básico de sus plantillas. Ya que está creando un proyecto WebKit, primero debe incluir las cabeceras de WebKit. Después de la línea que incluye gtk/gtk.h, añada la siguiente línea:

Packit 1470ea
Packit 1470ea
  #include <webkit/webkit.h>
Packit 1470ea
Packit 1470ea
  

Verifique que todo funciona construyendo lo que tiene hasta ahora. Pulse <guiseq><gui>Construir</gui><gui>Construir proyecto</gui></guiseq> o simplemente pulse <keyseq><key>Mayús</key><key>F7</key></keyseq>. La primera vez que construya, se le pedirán algunas opciones de configuración. Simplemente acepte los valores predeterminados y pulse <gui>Ejecutar</gui>.

Packit 1470ea
Packit 1470ea
  

Ahora debería poder ejecutar el programa. Pulse <guiseq><gui>Ejecutar</gui><gui>Ejecutar</gui></guiseq> o simplemente pulse <key>F3</key>. Debería ver aparecer una ventana vacía.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="webview">
Packit 1470ea
  <title>La disposición de la ventana y la vista web</title>
Packit 1470ea
Packit 1470ea
  

Ahora que puede mostrar una ventana, es el momento de empezar a trabajar con WebKit. Para este tutorial, se creará una entrada de texto y una vista web y ambas se empaquetarán en una ventana. Busque la función create_window y reemplácela con lo siguiente

Packit 1470ea
Packit 1470ea
Packit 1470ea
static GtkWidget*
Packit 1470ea
create_window (void)
Packit 1470ea
{
Packit 1470ea
    GtkWidget *window, *box, *scroll, *view, *entry;
Packit 1470ea
Packit 1470ea
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
Packit 1470ea
    gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
Packit 1470ea
    gtk_window_set_title (GTK_WINDOW (window), "Message Board");
Packit 1470ea
    g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
Packit 1470ea
Packit 1470ea
    box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit 1470ea
    gtk_container_set_border_width (GTK_CONTAINER (box), 6);
Packit 1470ea
    gtk_container_add (GTK_CONTAINER (window), box);
Packit 1470ea
Packit 1470ea
    entry = gtk_entry_new ();
Packit 1470ea
    gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 0);
Packit 1470ea
Packit 1470ea
    scroll = gtk_scrolled_window_new (NULL, NULL);
Packit 1470ea
    g_object_set (scroll, "shadow-type", GTK_SHADOW_IN, NULL);
Packit 1470ea
    gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
Packit 1470ea
Packit 1470ea
    view = webkit_web_view_new ();
Packit 1470ea
    gtk_container_add (GTK_CONTAINER (scroll), view);
Packit 1470ea
    webkit_web_view_load_string (WEBKIT_WEB_VIEW (view),
Packit 1470ea
                                 "<html><body></body></html>",
Packit 1470ea
                                 "text/html",
Packit 1470ea
                                 "UTF-8",
Packit 1470ea
                                 NULL);
Packit 1470ea
Packit 1470ea
    gtk_widget_show_all (GTK_WIDGET (box));
Packit 1470ea
    return window;
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
Packit 1470ea
  

Primero cree un objeto GtkWindow y establezca su título y su tamaño predeterminado. También puede conectar la función gtk_main_quit a la señal delete-event. La señal delete-event se emite cuando se cierra la ventana. La función gtk_main_quit es parte de GTK+, y sale de la aplicación.

Packit 1470ea
Packit 1470ea
  

Ahora cree una caja vertical y añádala a la ventana. Una ventana sólo puede contener un widget hijo, por lo que necesitará una caja para añadir varios widgets. El segundo argumento de gtk_box_new configura la cantidad de espacio (en píxeles) entre cada hijo, y la siguiente línea añade un borde de seis píxeles alrededor de la cosa completa.

Packit 1470ea
Packit 1470ea
  

Después, cree un objeto GtkEntry y empaquételo en una caja. Los argumentos tercero y cuarto de gtk_box_pack_start especifican que la entrada no debería coger ningún espacio adicional que tenga la caja. El cuarto es la cantidad de relleno que quiere alrededor de la entrada. En este caso, se establece el relleno a cero, ya que se está permitiendo que la caja maneje todo el relleno.

Packit 1470ea
Packit 1470ea
  

Antes de añadir la vista web debe crear una ventana desplazada para ponerla dentro. La ventana desplazada contendrá barras de desplazamiento a la derecha y abajo cuando sea necesario, y evitará que la vista web abarque la pantalla entera. En este momento, se pasa TRUE y TRUE a gtk_box_pack_start para permitir que la ventana desplazada (y por lo tanto, la vista web) usen el espacio adicional disponible en la caja.

Packit 1470ea
Packit 1470ea
  

Finalmente, cree una WebKitWebView y añádala a la ventana desplazada. Entonces cargue una página HTML muy simple en la vista web llamando a webkit_web_view_load_string con los siguientes argumentos:

Packit 1470ea
Packit 1470ea
  <terms>
Packit 1470ea
    <item>
Packit 1470ea
      <title>WEBKIT_WEB_VIEW (view)</title>
Packit 1470ea
      

La vista en sí. Ya que view es de tipo GtkWidget*, debe usar WEBKIT_WEB_VIEW para convertir el tipo del objeto con seguridad.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
      <title>"<html><body></body></html>"</title>
Packit 1470ea
      

El archivo HTML más simple que pueda escribir.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
      <title>"text/html"</title>
Packit 1470ea
      

El tipo MIME del contenido que ha proporcionado. En este caso, está usando HTML plano.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
      <title>"UTF-8"</title>
Packit 1470ea
      

La codificación de caracteres del contenido que ha proporcionado. Aunque sólo use caracteres ASCII, es una buena idea especificar UTF-8, ya que es la codificación que se usa de manera predeterminada en toda la plataforma GNOME.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
      <title>NULL</title>
Packit 1470ea
      

El URI base. En este ejemplo no se necesita, pero puede querer proporcionar un URI <sys>file:</sys> si añade imágenes u otras características cuando quiera usar referencias a URI relativos.

Packit 1470ea
    </item>
Packit 1470ea
  </terms>
Packit 1470ea
Packit 1470ea
  <note style="sidebar">
Packit 1470ea
    

Cada vez que añade un widget, debe llamar a la función gtk_widget_show sobre él para hacerlo visible. Si llama a gtk_widget_show en un contenedor de widgets como GtkBox, GTK+ mostrará automáticamente todos los widgets del contenedor, en cualquier nivel. Algunas veces no se quiere llamar a la función gtk_widget_show_all, como cuando se quieren ocultar o mostrar dinámicamente algunos objetos en respuesta a determinados eventos.

Packit 1470ea
  </note>
Packit 1470ea
Packit 1470ea
  

Finalmente, debe llamar a la función gtk_widget_show_all sobre la caja. De otro modo, ninguno de los widgets que haya creado será visible. (La ventana se muestra en la función main con gtk_widget_show.)

Packit 1470ea
Packit 1470ea
  

Construya y ejecute el cuadro de mensajes de nuevo. Debería ver una ventana con una entrada de texto y una vista web. Todavía no hace nada porque la entrada de texto y la vista web no saben nada la una acerca de la otra.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="signals">
Packit 1470ea
  <title>Conectar señales</title>
Packit 1470ea
Packit 1470ea
  

Ahora se quiere hacer que el cuadro haga algo cuando se introduce texto en la entrada de texto. Para hacer esto, conecte una función de retorno de la llamada a la señal activate de entry. GTK+ emite la señal activate cuando el usuario pulsa <key>Intro</key> en la entrada. Añada lo siguiente en create_window, en cualquier lugar después de que entry y view se hayan definido:

Packit 1470ea
Packit 1470ea
Packit 1470ea
g_signal_connect (entry, "activate", G_CALLBACK (entry_activate_cb), view);
Packit 1470ea
Packit 1470ea
Packit 1470ea
  

Entonces se debe definir entry_activate_cb. Defínalo como quiera, en cualquier lugar por encima de create_window:

Packit 1470ea
Packit 1470ea
Packit 1470ea
static void
Packit 1470ea
entry_activate_cb (GtkEntry *entry, WebKitWebView *view)
Packit 1470ea
{
Packit 1470ea
    WebKitDOMDocument *document;
Packit 1470ea
    WebKitDOMElement *body, *div;
Packit 1470ea
Packit 1470ea
    document = webkit_web_view_get_dom_document (view);
Packit 1470ea
    body = webkit_dom_document_query_selector (document, "body", NULL);
Packit 1470ea
    div = webkit_dom_document_create_element (document, "div", NULL);
Packit 1470ea
    webkit_dom_node_set_text_content (WEBKIT_DOM_NODE (div),
Packit 1470ea
                                      gtk_entry_get_text (entry),
Packit 1470ea
                                      NULL);
Packit 1470ea
    webkit_dom_node_append_child (WEBKIT_DOM_NODE (body),
Packit 1470ea
                                  WEBKIT_DOM_NODE (div),
Packit 1470ea
                                  NULL);
Packit 1470ea
    gtk_entry_set_text (entry, "");
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
Packit 1470ea
  

Lo primero que hacer es obtener un objeto WebKitDOMDocument que representa el documento HTML mostrado en la view. Las clases DOM y los métodos de WebKit le permiten inspeccionar y manipular el documento HTML, y trabajar de manera similar a las API DOM que ya debería conocer de JavaScript.

Packit 1470ea
Packit 1470ea
  

Una vez que tenga el documento, querrá obtener el elemento body para poder añadirle elementos div. La función webkit_dom_document_query_selector le permite encontrar un elemento en el documento usando selectores CSS. Esto le evita tener que escribir bucles tediosos para recorrer el documento.

Packit 1470ea
Packit 1470ea
  

Ahora, cree un elemento div que contenga el mensaje. Cada elemento que cree se debe adjuntar se debe adjuntar a un documento, por lo que la función para crear un elemento toma el WebKitDOMDocument como primer argumento. Debe entonces establecer el contenido del elemento con el contenido de la entrada de texto. Dado que gtk_entry_get_text devuelve un const gchar*, no tiene que liberar el resultado.

Packit 1470ea
Packit 1470ea
  

Finalmente, añada el nuevo elemento div al cuerpo y limpie la salida de texto para poder escribir algo nuevo. Construya y ejecute el programa otra vez y pruébelo por su cuenta.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
Packit 1470ea
<section id="css">
Packit 1470ea
  <title>Mejorar el aspecto con CSS</title>
Packit 1470ea
Packit 1470ea
  

En este punto, su programa es completamente funcional, pero no es muy atractivo. Puede añadir estilos a la visualización de los mensajes con CSS, igual que puede hacer con una página web. Hay muchas maneras de incluir un CSS en la página: puede añadirlo al documento HTML inicial, añadirlo en línea usando el atributo style de los elementos div o puede incluso construirlo con programación usando las API DOM.

Packit 1470ea
Packit 1470ea
  

En este tutorial se adjuntará el CSS usando la propiedad user-stylesheet-uri del objeto WebKitWebSetting empotrado en la vista web. En una aplicación más completa, se podría querer guardar y cargar el archivo HTML. Mantener la información de estilo fuera del HTML actual significa que se puede cambiar el estilo completo de la aplicación sin tener que cambiar los archivos del usuario. Normalmente se instala un archivo junto con la aplicación, pero simplemente para mantener todo en un archivo en esta demostración, se usará un truco llamado URI de datos. En primer lugar, se define el CSS como una cadena estática cerca del principio del archivo.

Packit 1470ea
Packit 1470ea
Packit 1470ea
static const guchar CSS[] =
Packit 1470ea
"body { margin: 0; padding: 0; }\n"
Packit 1470ea
"div { "
Packit 1470ea
" -webkit-border-radius: 2px;"
Packit 1470ea
" background: -webkit-gradient(linear, 0% 100%, 0% 0%,"
Packit 1470ea
" from(#f1f1f1), to(white));"
Packit 1470ea
" border: solid 1px #c6c6c6;"
Packit 1470ea
" -webkit-box-shadow: 0px 0px 2px #c6c6c6;"
Packit 1470ea
" margin: 12px; padding: 6px;"
Packit 1470ea
"}";
Packit 1470ea
Packit 1470ea
Packit 1470ea
  

Todo lo que tiene en este ejemplo son elementos div dentro de un elemento body. Si ha creado HTML más complejo, puede usar cualquier CSS que sea necesario. Si se siente cómodo usando CSS debería intentar cambiar esto por algo que le guste más.

Packit 1470ea
Packit 1470ea
  

Para aplicar el CSS, configure la user-stylesheet-uri en la función create_window, en cualquier lugar después de que view se haya definido.

Packit 1470ea
Packit 1470ea
Packit 1470ea
tmp = g_base64_encode (CSS, strlen((gchar *) CSS));
Packit 1470ea
css = g_strconcat ("data:text/css;charset=utf-8;base64,",
Packit 1470ea
                   tmp, NULL);
Packit 1470ea
g_object_set (webkit_web_view_get_settings (WEBKIT_WEB_VIEW (view)),
Packit 1470ea
              "user-stylesheet-uri", css, NULL);
Packit 1470ea
g_free (css);
Packit 1470ea
g_free (tmp);
Packit 1470ea
Packit 1470ea
Packit 1470ea
  

Asegúrese de añadir declaraciones de variables para tmp y css a la parte superior de create_window.

Packit 1470ea
Packit 1470ea
Packit 1470ea
gchar *tmp, *css;
Packit 1470ea
Packit 1470ea
Packit 1470ea
 

Un URI de datos empieza por <sys>data:</sys> y cierta información sobre el tipo de contenido y cómo se codifican los datos. Los datos reales siguen después de una coma, en este caso, codificados en Base64. A diferencia de otros esquemas de URI como <sys>http:</sys>, <sys>ftp:</sys>, y <sys>file:</sys>, the <sys>data:</sys>, el esquema del URI no especifica dónde encontrar un archivo que cargar. En vez de eso, ofrece el contenido completo del archivo.

Packit 1470ea
Packit 1470ea
 

El código anterior primero codifica las definiciones CSS en Base64, y luego las combina con una cadena fija para crear una URI de datos. La función g_strconcat puede tomar cualquier número de argumentos de cadena y concatenarlos todos juntos, por lo que tiene que pasar NULL como argumento final para que sepa dónde parar. No olvide liberar esas cadenas temporales después de establecer la propiedad de la hoja de estilos.

Packit 1470ea
Packit 1470ea
 

Construya y ejecute el programa de nuevo. Debería funcionar exactamente igual que al final de la última sección, excepto que los mensajes tendrán estilos con un borde y un degradado de fondo sutil.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="more">
Packit 1470ea
  <title>Aprender más</title>
Packit 1470ea
Packit 1470ea
  

Este tutorial le ha mostrado cómo crear una aplicación sencilla usando GTK+ y WebKit, incluyendo cómo mostrar un documento y manipular su contenido. Para crear una aplicación real, probablemente quiera hacer algo más. Pruebe a añadir características usted mismo. Aquí hay algunas ideas:

Packit 1470ea
Packit 1470ea
  <list>
Packit 1470ea
    <item>

Si se siente cómo usando CSS, pruebe a cambiar el estilo de la visualización del mensaje. Es fácil iniciarse en CSS, pero cada vez es más potente. Hay una gran cantidad de tutoriales de CSS en Internet, y casi todo lo que se puede hacer en una página web, se puede hacer en esta aplicación.

</item>
Packit 1470ea
Packit 1470ea
    <item>

Ahora mismo, todos los mensajes se pierden al cerras el cuadro de mensajes. Pruebe a guardar el contenido HTML después de cada envío, y a cargar el archivo guardado (si existe) al inicio.

</item>
Packit 1470ea
Packit 1470ea
    <item>

Si guarda sus mensajes durante mucho tiempo, empezará a preguntarse dónde los escribió. Añada una marca de tiempo a cada mensaje cuando se envía. Probablemente quiera crear algún elemento div hijo adicional con diferentes clases que puede modelar en el CSS.

Packit 1470ea
    </item>
Packit 1470ea
Packit 1470ea
    <item>

Este programa guarda los mensajes para siempre. Piense alguna manera para que el usuario pueda eliminar mensajes. Tal vez quiera que los mensajes desaparezca automáticamente cuando son muy antiguos o después de que haya cierto número de mensajes por delante. O podría añadir un enlace en cada mensaje para eliminarlo. También puede omitir el menú contextual cuando pulsa con el botón derecho sobe un mensaje. Esta características implican explorar más la API del DOM de WebKit.

</item>
Packit 1470ea
  </list>
Packit 1470ea
</section>
Packit 1470ea
</page>