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.
En el capítulo anterior del tutorial, ya viste como el usuario podía interactuar con tu aplicación. Eso si, las posibilidades de interacción eran básicas. Por el momento, tan solo podía pulsar botones. Eso si, botones que le permitían hasta elegir una tipografía concreta o un color. Sin embargo, esto no es suficiente. En ocasiones, necesitas que el usuario introduzca algo tan sencillo como su nombre. Para estos casos, para editar texto con Gtk, tienes a tu disposición dos clases muy interesantes como son Gtk.Entry
y Gtk.TextView
. Así, en este capítulo del tutorial te mostraré las opciones que puedes dar al usuario para editar texto.
Con estas dos clases, ya puedes crear formularios en cuadros de diálogo para que el usuario introduzca todo tipo de información y que pueda editar texto con GTK. Por supuesto, que no solo tienes estas dos, también tienes otras clases, combinación de algunas de las que has visto hasta el momento que te permiten introducir números mediante botones, como es Gtk.SpinButton
.
Editar texto con GTK y JavaScript
Para poder ver la funcionalidad de cada una de las clases indicadas anteriormente, que te van a pertmitir editar texto con GTK, utilizaremos un sencillo ejemplo que, como siempre, puedes encontrar en el repositorio que existe para este tutorial.
En este caso, se trata de un cuadro de diálogo, con un par de botones de Aceptar
y Cancelar
, una etiqueta, donde se muestra lo que queremos que el usuario responda y la caja de texto, Gtk.Entry
para que el usuario introduzca el valor.
En el caso de que el usuario pulse el botón aceptar, el valor que haya introducido en la caja de texto se imprimirá directamente en el log
.
#!/usr/bin/env gjs
imports.gi.versions.Gtk = '3.0'
const {Gtk, GObject} = imports.gi;
Gtk.init(null);
var Dialog = GObject.registerClass(
class Dialog extends Gtk.Dialog{
_init(){
super._init({
defaultWidth:200,
defaultHeight: 200
});
let layout = new Gtk.Grid({
margin: 10,
rowSpacing: 5,
columnSpacing: 5
});
this.add_button("Aceptar", Gtk.ResponseType.OK);
this.add_button("Cancelar", Gtk.ResponseType.CANCEL);
this.get_content_area().add(layout);
layout.attach(new Gtk.Label({
label: "Nombre:"
}), 0, 0, 1, 1);
this.entry = new Gtk.Entry();
layout.attach(this.entry, 1, 0, 1, 1);
this.show_all();
}
}
);
let dialog = new Dialog();
if (dialog.run() == Gtk.ResponseType.OK){
log(dialog.entry.get_text());
}
La parte importante, la que te interesa, y sobre la que hay que trabajar es simplemente la que aparece this.entry = new Gtk.Entry()
. Y, por supuesto, la parte donde se devuelve el contenido de la caja de texto, que al final es lo que realmente te interesa.
Gtk.Entry
En este apartado puedes encontrar, como de costumbre, algunas de las propiedades de esta clase. Básicamente, las que he considerado mas interesantes o relevantes. Por supuesto, también encontrarás de la misma forma alguno de los métodos exclusivos de la clase, como de las señales.
Propiedades
Lo primero es modificar el ejemplo anterior, en la parte en la que defines la caja de texto, reemplazando this.entry = new Gtk.Entry()
, por el siguiente código, que mas adelante paso a desgranar,
this.entry = new Gtk.Entry({
text: "Lorenzo",
editable: true,
maxLength: 5,
visibility: true,
invisibleChar: "|",
widthChars: 55,
placeholderText: "Introduce tu nombre",
xalign: 0.5,
primaryIconTooltipText: "Borrar el contenido",
primaryIconStock: Gtk.STOCK_DELETE,
secondaryIconTooltipText: "Ayuda contextual",
secondaryIconStock: Gtk.STOCK_CLEAR
});
text
este propiedad se corresponde con el texto que se mostrará en el propio objeto.editable
en el caso de serfalse
el valor correspondiente a la propiedadtext
no puede ser modificada por el usuario. Solo es posible editarla vía código.maxLength
es el número máximo de caracteres que admite la propiedadtext
.visibility
esta propiedad es la que controla si el usuario ve exactamente lo que está escribiendo, o se muestra un carácter. Esta es la opción que tienes que utilizar para el caso de que quieras que el usuario introduzca una contraseña. Es posible cambiar el carácter que se muestra utilizando la propiedadinvisibleChar
.widthChars
te permite configurar el ancho del objetoGtk.Entry
en número de caracteres.placeholderText
es el texto de ayuda que se muestra en la caja de texto, cuando no has introducido ningún valor, o no hay ningún valor por defecto. Normalmente se suele utilizar o bien un valor de ejemplo, o bien, se utiliza una ayuda. Si, por ejemplo, estás preguntando el nombre del usuario, elplaceholderText
podría serintroduce aquí tu nombre
.xalign
te ayuda a controlar la posición del texto dentro delGkt.Entry
, es decir, sería la alineación del texto. Se trata de un número real, con valor de0.0
a1.0
. El valor0.0
se corresponde a que el texto se sitúa a la izquierda, mientras que un valor de1.0
situaría el texto completamente a la derecha. Si lo que quieres es que el texto aparezca centrado, tienes que utilizar0.5
, como seguramente ya te habrás imaginado.primaryIconStock
, esta propiedad controla el icono que aparece en la parte izquierda de la caja de texto. Normalmente este icono se utiliza para desencadenar determinadas acciones.primaryIconTooltipText
este es un texto de ayuda que se muestra cuando sitúas el ratón sobre elprimaryIcon
.secondaryIconStock
es exactamente igual que elprimaryIconStock
, pero es el que gestiona el icono que se sitúa en la parte derecha de la caja de texto.secondaryIconTooltipText
esta propiedad se encarga de mostrar la ayuda cuando sitúas el ratón sobre elsecondaryIcon
.
Métodos
Por supuesto los dos métodos por excelencia para un objeto de esta clase Gtk.Entry
, son sin lugar a dudas, get_text
y set_text
, que te permiten obtener y establecer el texto del Gtk.Entry
.
Señales
Dentro de las señales que te pueden resultar interesantes, para modificar el comportamiento de un objeto de la clase Gtk.Entry
, tienes
activate
se produce cuando el usuario pulsa la teclaEnter
backspace
exactamente igual que la anterior pero para el caso para la teclaborrar
copy-clipboard
,cut-clipboard
ypaste-clipboard
controlan la interacción con el portapapeles, cuando se copia, se corta o se pega del portapapeles respectivamente.
Gtk.TextView
Esta clase te va a permitir crear objetos para introducir texto, pero donde vas a tener mucho mas control sobre que es lo que se introduce y como se introduce. En este caso, he modificado el ejemplo anterior, como te muestro a continuación,
this.entry = new Gtk.TextView({
buffer: new Gtk.TextBuffer({
text: "Este es un texto mas largo"
}),
editable: true,
justification: Gtk.Justification.CENTER,
leftMargin: 10,
rightMargin: 10,
pixelsAboveLines: 10,
pixelsBelowLines: 10
});
Propiedades
Sin lugar a dudas, la propiedad mas importante de todas las anteriores es buffer
que es la que gestiona y control el texto dentro de un Gtk.TextView
. El resto de propiedades, algunas de las que he puesto en el ejemplo anterior, son de menor importancia, y tienen mas que ver como se muestra el texto dentro de un Gtk.TextView
. Así tienes,
editable
para definir si el contenido es modificable o no.justification
te permite establecer donde se alinea el texto, a la derecha, a la izquierda o centradoleftMargin
yrightMargin
te ayuda a establecer el espacio en pixel que dejas a izquierda y derecha respectivamente.pixelsAboveLines
ypixelsBelowLines
definen los pixel que dejas por la parte superior y por la parte inferior de un párrafo.
Métodos
De nuevo de entre los métodos que tiene la clase Gtk.TextView
los que destaca son los referentes a conseguir el buffer
, que son básicamente get_buffer
y set_buffer
. Pero también tiene otros interesantes, como
scroll_to_iter
que permite desplazar el scroll hasta una posición definida por unGtk.TextIter
scroll_to_mark
igual que el caso anterior pero para unGtk.TextMark
get_iter_location
devuelve un rectángulo que delimita el carácter que se encuentra en la posiciónGtk.TextIter
.get_iter_at_location
devuelve elGtk.TextIter
que se encuentra en unas coordenads determinadas dentro del texto.
Señales
Un objeto de la clase Gtk.TextView
tiene algunas señales similares a las de Gtk.TextEntry
, como pueden ser las relativas al portapapeles, y otras específicas como move-cursor
, mov-focus
, move-viewport
.
Gtk.TextBuffer
Esta clase es la encargada de guardar y gestionar el texto que se muestra en un Gtk.TextView
.
Propiedades
De entre las propiedades de esta clase, cabe destacar dos principalmente,
text
, básicamente el contenido de unGtk.TextBuffer
.cursorPosition
que indica la posición del cursor y es de solo lectura.
Métodos
La clase Gtk.TextBuffer
tiene una gran cantidad de métodos que te permiten gestionar perfectamente el texto que contiene. Sin embargo, hay algunos de ellos, que son imprescindibles hasta para lo más básico, como es el simple hecho de obtener el texto que contiene el objeto.
Además de la clase Gtk.TextBuffer
, tienes que tener presente una clase mas como es Gtk.TextIter
. Esta clase apunta una ubicación dentro de la clase Gtk.TextBuffer
. Por ejemplo, si quieres obtener el inicio del Gtk.TextBuffer
tienes que utilizar el método get_start_iter
, mientras que si quieres obtener el final, tendrías que utilizar el método get_end_iter
. De esta forma para obtener el texto contenido en un Gtk.TextBuffer
, tienes que utilizar algo como lo que te muestro a continuación,
let buffer = dialog.entry.get_buffer();
let inicio = buffer.get_start_iter();
let fin = buffer.get_end_iter();
print(buffer.get_text(inicio, fin, false));
Esto que parece algo engorroso, lo cierto es que te da muchas opciones y posibilidades, dado que Gtk.TextBuffer
pone a tu alcance diferentes herramientas y clases como son las marcas Gtk.TextMark
que se conservan a pesar de las modificaciones que se produzcan. También tienes las etiquetas Gtk.TextTag
, que te permiten aplicar atributos al texto.
Así algunas de las herramientas que puedes utilizar con Gtk.TextBuffer
, además de la que te he comentado para extraer el texto son,
delete
te permite borrar texto entre dosGtk.TextIter
insert
para insertar texto en unGtk.TextIter
insert_at_cursor
igual que el anterior, pero en este caso insertará el texto en la posición del cursor.
Además puedes realizar diferentes operaciones relacionadas con el portapapeles, como
copy_clipboard
para copiar al portapapelescut_clipboard
en el caso de que quieras cortarpaste_clipboard
para pegar desde el portapapeles en la posición indicada por unGtk.TextIter
.
Señales
Por supuesto que Gtk.TextBuffer
viene cargado de señales que te van a facilitar la interacción con este objeto. De las mas interesantes, por supuesto, es changed
que te informa cuando se ha producido un cambio en el contenido. Por ejemplo, si quieres ver el contenido cada vez que se produce un cambio puedes utilizar el siguiente código,
this.buffer.connect('changed', (tb)=>{
let inicio = tb.get_start_iter();
let fin = tb.get_end_iter();
print(tb.get_text(inicio, fin, false));
});
Pero, por supuesto tienes otras señales como apply-tag
, insert-text
, insert-pixbuf
, mark-deleted
, mark-set
, paste-done
.
Conclusiones
Ya has visto algunas de las opciones que puedes ofrecer a un usuario para introducir y editar texto con GTK y JavaScript, en tus aplicaciones. Desde la solución mas sencilla, que te ofrece Gtk.Entry
a una algo mas compleja como es Gtk.TextView
.
Estas, no son las únicas, pero son las que utilizarás, en principio, con mas frecuencia.
Imagen de portada de Michelle Miralles en Unsplash