Botones en JavaScript para GNOME

Este es uno de los capítulos del tutorial Aplicaciones nativas en JavaScript con GJS. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.

Hasta el momento, en los diferentes capítulos del tutorial, básicamente el usuario de tu aplicación, poco podía hacer. En el capítulo anterior, viste como mostrar un texto a tu usuario para que pudiera leerlo, pero, sinceramente, tu quieres que el usuario interactúe con tu aplicación, que se relacione. Una forma, sencilla, de interacción es mediante el uso de botones. Pulsando un botón u otro botón, puedes conseguir esa interacción que buscas. Así, en este capítulo verás como implementar botones con JavaScript.

Ciertamente, en capítulos anteriores del tutorial ya lo hacías, a través de los propios botones de las ventanas que has utilizado para mostrar otros widgets. En este capítulo, tienes la oportunidad de exprimir los botones al máximo.

Botones en JavaScript

Botones en JavaScript

La clase Gtk.Button es la clase base de la que derivan otros tipos de botones en JavaScript. Por supuesto, tu también la puedes utilizar como la clase base para tus propios botones. Este tipo de botones, pueden contener tanto texto como imágenes.

El ejemplo

Para ver todas las propiedades de un objeto de la clase Gtk.Button, utilizaré el siguiente ejemplo. En ejemplos posteriores, tendrás que sustituir la definición del Gtk.Button.

#!/usr/bin/env gjs

imports.gi.versions.Gtk = '3.0'
const {Gtk, GObject} = imports.gi;

Gtk.init(null);

var Ventana = GObject.registerClass(
    class Ventana extends Gtk.Window{
        _init(){
            super._init({
                defaultWidth:200,
                defaultHeight: 200
            });
            this.connect('destroy', ()=>{
                Gtk.main_quit();
            });
            let layout = new Gtk.Grid({
                margin: 10
            });
            this.add(layout);
            let button = new Gtk.Button({
                label: 'Di_alogo',
                alwaysShowImage: true,
                focusOnClick: true,
                image: new Gtk.Image({iconName: 'starred'}),
                imagePosition: Gtk.PositionType.BOTTOM,
                relief: Gtk.ReliefStyle.NORMAL,
                useUnderline: true
            });
            button.connect('clicked', () => {
                let dialog = new Gtk.MessageDialog({
                    title: 'Ejemplo',
                    text: 'Ejemplo de diálogo'
                });
                dialog.add_button('Si', Gtk.ResponseType.YES);
                dialog.run();
                dialog.destroy();
            });
            layout.attach(button, 0, 0, 1, 1);
        }
    }
);

let ventana = new Ventana();
ventana.show_all();

Gtk.main();

Las propiedades de los botones en JavaScript

Quiero destacar un pequeño detalle, y es como están declaradas las propiedades. En la documentación encontrarás image_position, sin embargo, en el caso de JavaScript, puedes utilizar de forma indistinta tanto esta forma, como imagePosition. Si bien, la convención es utilizar esta segunda manera. Es decir, utilizar CamelCase, que consiste en utilizar mayúsculas al inicio de cada palabra en una palabra compuesta.

En el ejemplo anterior, he definido algunas de las propiedades intrínsecas de Gtk.Button, y que te describo a continuación,

  • label: 'Di_alogo'. Esto mostrará el texto Dialogo en el botón, siempre y cuando la propiedad useUnderline sea cierta. Mas adelante te comento que es esto del underline.
  • alwaysShowImage: true. Por defecto en los botones y otros objetos no se muestran imágenes, excepto que esta propiedad esté definida como true porque su valor por defecto es false.
  • focusOnClick: true. Con esta propiedad defines el comportamiento del botón ante un clic sobre el mismo. Por defecto esta propiedad tiene el valor true, y es que cuando haces clic sobre el botón el botón gana el foco. Si lo defines a falso, cuando hagas clic el botón no ganará el foco, y permanecerá en el que lo tuviera en ese momento.
  • image: new Gtk.Image({iconName: 'starred'}). Esta propiedad te permite añadir una imagen en el botón. No te preocupes por este objeto Gtk.Image por que lo podrás ver con detenimiento en un capítulo del tutorial dedicado en exclusiva. Por supuesto, para que se muestre la imagen es necesario que la propiedad que has visto antes, alwaysShowImage esté definida como true.
  • imagePosition: Gtk.PositionType.BOTTOM. En el caso de que exista una imagen, esta propiedad define donde se mostrará la imagen en el botón. Esta propiedad toma los valores BOTTOM, LEFT, RIGHT y TOP.
  • relief: Gtk.ReliefStyle.NORMAL. Esta propiedad se refiere a como se muestra el botón. Los valores que puede tomar la propiedad son HALF, NONE y NORMAL.
  • useUnderline: true. En este caso, esta propiedad te permite definir aceleradores. Los aceleradores son atajos de teclado que te permitirán realizar acciones sin necesidad de recurrir al ratón. Esta propiedad se utiliza en combinación con la propiedad label, tal y como te he comentado antes. Para indicar cual es el atajo de teclado tienes que utilizar un guión bajo, _ delante de la letra que quieres que se convierta en acelerador. En el caso de este ejemplo Di_alogo. Si ahora, pulsas la tecla Alt, verás que la letra a aparece subrayada. Pulsando a sin dejar de pulsar Alt verás que haces clic en el botón.

Estas son las propiedades mas interesantes de Gtk.Button, pero además de las propiedades, este objeto está sometido a eventos que generan señales, que tu puedes utilizar para desencadenar acciones.

Las señales

Existen varias señales que puedes utilizar con un objeto de la clase Gtk.Button, pero sin lugar a dudas la que mas importante de ellas es clicked. Básicamente es la señal que se produce cuando se hace clic sobre el botón, como ya te podías imaginar. En el caso del ejemplo anterior, está conectada a una función que te mostrará un sencillo cuadro de diálogo,

button.connect('clicked', () => {
    let dialog = new Gtk.MessageDialog({
        title: 'Ejemplo',
        text: 'Ejemplo de diálogo'
    });
    dialog.add_button('Si', Gtk.ResponseType.YES);
    dialog.run();
    dialog.destroy();
});

De la misma forma tienes estas otras señales, que puedes conectar de la misma forma que lo has hecho con la señal clicked.

  • enter. Esta señal se produce justo en el momento de entrar con el ratón en el área del botón. Así, por ejemplo, podrías hacer exactamente lo mismo que en el caso anterior, pero sin que el usuario de tu aplicación pulse el botón, simplemente con pasar con el ratón sobre el botón.
  • leave. Justo la señal opuesta a la anterior. Es decir, la señal se produce cuando sales del área del botón.

Existen otras señales como puede ser activate, pressed o released, pero actualmente han quedado obsoletas y están deprecadas, por lo que te deberías ceñir a utilizar estas que he indicado.

Gtk.ToggleButton

La primera de las clases derivadas de la clase Gtk.Button es Gtk.ToggleButton. Esta clase tiene un comportamiento un tanto peculiar y diferente a un simple botón. Cuando haces clic sobre un botón este vuelve al estado natural, es como cuando pulsas el timbre de una casa. Sin embargo, un objeto de la clase Gtk.ToggleButton se comporta mas como un interruptor, de forma que se quedará pulsado, y para que vuelva al estado original deberás de pulsar el botón.

Esto queda definido por la propiedad active que te indicará el estado en que se encuentra esté botón. Es decir, que con la propiedad active, sabrás si el botón se encuentra en estado pulsado, si es true o no se encuentra pulsado, si es false.

Además tiene una nueva señal, toggled, que se produce cuando Gtk.ToggleButton cambia de estado, pasando de activo a inactivo o al revés.

Puedes analizar el comportamiento de un objeto de la clase Gtk.ToggleButton modificando algunas líneas del ejemplo anterior por las siguientes,

let button = new Gtk.ToggleButton({
    label: 'Botton'
});
button.connect('toggled', () => {
    log(button.get_active());
});

Gtk.LinkButton

Otro de los botones en JavaScript es Gtk.LinkButton. Esta otra clase derivada te permite colocar enlaces de forma sencilla dentro de tu aplicación. Así, introduce una nueva propiedad uri que te permite indicar el enlace al que apunta, y donde te dirigirá en el caso de hacer clic sobre el botón.

Un ejemplo del funcionamiento,

let button = new Gtk.LinkButton({
    label: 'Llévame a atareao.es',
    uri: 'https://www.atareao.es'
});
button.connect('clicked', () => {
    log('Has hecho clic');
});

Gtk.ColorButton

Este botón es ideal para permitir al usuario seleccionar un color. Inicialmente, al mostrar el botón se muestra el color que tu hayas predefinido, si es que lo has hecho. La gracia de este botón, es que no es necesario que implementes ninguna acción, porque esta ya está definida por defecto. Al hacer clic sobre este botón, se muestra un cuadro de diálogo que permite al usuario seleccionar el color.

Por ejemplo,

let button = new Gtk.ColorButton({
    rgba: new Gdk.RGBA({
        red: 0.0,
        green: 1.0,
        blue: 1.0,
        alpha: 0.5
    })
});

Este botón tienes varios métodos relacionados con el color que te permite definir u obtener el color seleccionado. Estos métodos son los siguientes,

  • set_color
  • get_color
  • set_alpha
  • get_alpha
  • set_rgba
  • get_rgba
  • get_use_alpha
  • set_use_alpha

Además este botón incorpora una nueva señal set-color que te permite conocer cuando se ha modificado el color.

Gtk.FontButton

Este tipo de botón es muy similar en características al anterior, pero en lugar de permitirte elegir colores te permite elegir tipografías. Me refiero a que es similar al anterior, en el sentido de que no es necesario que implementes ninguna acción para el evento clicked. Y es que al hacer clic, sobre el botón te mostrará un cuadro de diálogo donde puedes seleccionar una tipografía o modificar las características de la tipografía actual.

Este botón tiene algunas propiedades especiales que permiten definir la tipografía que quieres mostrar en el botón y como mostrarla. Por ejemplo,

let button = new Gtk.FontButton({
    fontName: 'Ubuntu 12',
    showSize: true,
    showStyle: true,
    title: 'Selecciona una fuente',
    useFont: true,
    useSize: true
});
  • fontName: 'Ubuntu 12' define la fuente y el tamaño de la misma
  • showSize: true establece si se muestra por defecto el tamaño en el botón, que por defecto es así.
  • showStyle: true igual que en el caso anterior pero para el estilo.
  • title: 'Selecciona una fuente' este es el título que se mostrará en el cuadro de diálogo que aparece al hacer clic sobre el botón.
  • useFont: true define si se utiliza la fuente en el propio botón.
  • useSize: true lo mismo que en el caso anterior pero para el tamaño de la fuente. Imagina que por defecto estableces la tipografía con un tamaño 40. No deberías utilizar este tamaño para el texto del botón.

También, al igual que en el caso anterior, tienes métodos para consultar la tipografía establecida o para establecerla.

Y de la misma forma, tienes la señal set-font que te permite conocer cuando se ha modificado la tipografía. Por ejemplo,

button.connect('font-set', () => {
    log('Has seleccionado una nueva tipografía');
});

Gtk.ScaleButton

Este botón te permite seleccionar un valor de una escala. Al pulsar el botón se despliega una escala. Por ejemplo,

let button = new Gtk.ScaleButton({
    icons: ['battery-empty', 'battery-full'],
    adjustment: new Gtk.Adjustment({
        lower: 0,
        upper: 99,
        pageSize: 10,
        pageIncrement: 5,
        stepIncrement: 1,
        value: 50
    })
});

Aunque Gtk.ScaleButton tiene algunas propiedades mas, me quedo con estas dos que son las mas relevantes para el uso de este botón.

  • icons esta propiedad define los iconos que se mostrarán en función del valor que tenga el botón. En el ejemplo anterior, si el valor es inferior a 50 mostrará un icono de una batería vacía, mientras que si es superior mostrará un icono de una batería llena.Es posible definir mas iconos, pero siempre el primero se corresponde con el menor valor, mientras que el segundo con el mayor valor. El resto, se repartirá.

Por otro lado, este objeto tiene tres señales,

  • popdown esta señal se produce cuando desaparece la escala.
  • popup, la señal opuesta a la anterior, es decir, se produce cuando aparece la escala.
  • value-changed, esta señal se produce cuando cambia el valor.

Conclusiones

Existen algunos botones en JavaScript mas de los que te he mostrado aquí, pero el comportamiento es similar a estos, y son mucho mas específicos.

De la misma forma, aquí no te he expuesto todas y cada una de las propiedades, métodos y señales de estos objetos, pero si, los que he considerado mas relevantes.


Más información,

Imagen de portada de James Orr en Unsplash

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *