Lección 7: Arquitectura | Curso de UI Emacs Lisp

Lección 7: Arquitectura

Construir una UI con widgets no solo consiste en ir añadiendo elementos uno detrás de otro, debe existir una estructura mínima que permita relacionarse entre sí. Que un widget pueda utilizar recursos de otro (obtener el texto introducido por el usuario, saber si esta validado, conocer la opción marcada…). Para ello aprenderemos los conceptos mínimos con el objetivo de crear interfaces escalables y reutilizables.

Vamos a explorar el orden y pasos que debe seguir una UI para ser creada.

1. Importaciones

Al inicio debemos importar el paquete widget y wid-edit.

;; Imports
(require 'widget)

(eval-when-compile
  (require 'wid-edit))

En realidad el paquete widget esta vacío, se conserva por retrocompatibilidad. Internamente importa el paquete wid-edit, que es el que contiene todas las funcionalidades. De ahí la condición eval-when-compile que permite que el paquete wid-edit se compile antes de ser usado.

Si utilizas otros paquetes, es el lugar adecuado para importarlos.

2. Variables

Cuando creas un widget, este se añade al buffer actual pero se pierde su referencia. Para poder acceder a él, debemos crear una variable que lo contenga. Por ejemplo:

(defvar input-email)

Más adelante, cuando creemos el widget, lo asignaremos a esta variable.

(setq input-email (widget-create 'editable-field
                 :size 30
                 :format "Email: %v"))

Nunca crearemos la variable y el widget en el mismo paso ya que los widgets se crear donde esta el cursor. Debemos tener el control de donde se crean.

3. Funciones

Todas la lógica que usarán los botones, campos de texto, validaciones, utilidades, etc.

Deberías tener una función dedicada en exclusividad a redibujas los widgets dependiendo del estado de la aplicación o las variables.

4. Layout

Las funciones que crean los widgets y los añaden al buffer. En otras palabras, la interfaz de usuario.

Te recomiendo crear una función llamada main-layout con los widgets principales y otras funciones menores para actualizar partes de la interfaz. Por ejemplo: header-layout, first-step-layout, contact-layout, modal-layout, etc.

Un layout principal, o main-layout, debe seguir el siguiente esquema:

;; Opcional, si va a ser llamada desde un botón
(interactive)
;; Cambia a un buffer nuevo
(switch-to-buffer "Nombre del buffer")
;; Limpia el buffer de variables locales y overlays
(kill-all-local-variables)
(let ((inhibit-read-only t))
    (erase-buffer))
(remove-overlays)

;; Aquí irán los widgets
(widget-insert "Titulo \n\n")
(setq input-field-1 (widget-create 'editable-field
                     :size 5
                     :tag "Number 1"
                     :help-echo "Type a number"
                     :valid-regexp "^[0-9]+$"
                     :error "Invalid number"
                     :notify #'input-show-error
                     :format "%v"))
;; Aquí terminan los widgets

;; Establece el mapa de teclas para los widgets
(use-local-map widget-keymap)
;; Configura todos los widgets para la interacción del usuario, por ejemplo, mostrarlos con el aspecto adecuado, permitir la navegación entre ellos con el teclado y responder a los eventos del mouse
(widget-setup)
;; Opcional, da el foco al primer widget
(widget-forward 1)

5. Inicialización

Llamamos a la función main-layout, o como la hayas llamado, para que se ejecute y muestre la interfaz de usuario.

(main-layout)

Resumen

Una buena forma de crear UI es mantener la siguiente estructura:

;; Importaciones

;; Variables
(defvar state)
(defvar input-email)

;; Funciones
(defun init ())
(defun update ())

;; Layouts
(defun main-layout ())
(defun login-layout ())

;; Inicialización
(init)

Si te fijas en todos los ejemplos anteriores, encontrarás esta misma estructura. Y más adelante continuaremos utilizándola para crear interfaces más complejas.

Practica y mantén tu código ordenado.

En las siguientes lecciones vamos a centrarnos en organizar y reutilizar los widgets.

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Me ayudas?

Comprame un café
Pulsa sobre la imagen

No te sientas obligado a realizar una donación, pero cada aportación mantiene el sitio en activo logrando que continúe existiendo y sea accesible para otras personas. Además me motiva a crear nuevo contenido.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario