7. Architecture

Building a UI with widgets does not only consist of adding elements one after another; there must be a minimal structure that lets them relate to each other. So a widget can use resources of another (get the text entered by the user, know if it is validated, know the selected option...). For that we will learn the minimal concepts with the goal of creating scalable and reusable interfaces.

We are going to explore the order and steps a UI must follow to be created.

1. Imports

At the start we must import the widget and wid-edit packages.

;; Imports
(require 'widget)

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

Actually the widget package is empty, it is kept for backward compatibility. Internally it imports the wid-edit package, which is the one that contains all the functionality. Hence the eval-when-compile condition that lets the wid-edit package be compiled before being used.

If you use other packages, this is the right place to import them.

2. Variables

When you create a widget, it is added to the current buffer but its reference is lost. To be able to access it, we must create a variable that contains it. For example:

(defvar input-email)

Later, when we create the widget, we will assign it to this variable.

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

We will never create the variable and the widget in the same step since widgets are created where the cursor is. We must have control over where they are created.

3. Functions

All the logic that the buttons, text fields, validations, utilities, etc. will use.

You should have a function dedicated exclusively to redrawing the widgets depending on the state of the application or the variables.

4. Layout

The functions that create the widgets and add them to the buffer. In other words, the user interface.

I recommend creating a function called main-layout with the main widgets and other minor functions to update parts of the interface. For example: header-layout, first-step-layout, contact-layout, modal-layout, etc.

A main layout, or main-layout, must follow the following scheme:

;; Optional, if it is going to be called from a button
(interactive)
;; Switch to a new buffer
(switch-to-buffer "Buffer name")
;; Clear the buffer of local variables and overlays
(kill-all-local-variables)
(let ((inhibit-read-only t))
    (erase-buffer))
(remove-overlays)

;; The widgets will go here
(widget-insert "Title \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"))
;; The widgets end here

;; Set the keymap for the widgets
(use-local-map widget-keymap)
;; Configure all the widgets for user interaction, for example, show them with the right appearance, allow navigation between them with the keyboard and respond to mouse events
(widget-setup)
;; Optional, give focus to the first widget
(widget-forward 1)

5. Initialization

We call the main-layout function, or whatever you have called it, so it runs and shows the user interface.

(main-layout)

Summary

A good way to create a UI is to keep the following structure:

;; Imports

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

;; Functions
(defun init ())
(defun update ())

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

;; Initialization
(init)

If you look at all the previous examples, you will find this same structure. And later we will keep using it to create more complex interfaces.

Practice and keep your code tidy.

In the following lessons we are going to focus on organizing and reusing the widgets.

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Desafíos de programación atemporales y multiparadigmáticos

Desafíos de programación atemporales y multiparadigmáticos

Te encuentras ante un librillo de actividades, divididas en 2 niveles de dificultad. Te enfrentarás a los casos más comunes que te puedes encontrar en pruebas técnicas o aprender conceptos elementales de programación.

Buy the book

Will you buy me a coffee?

This is how I keep writing without ads or paywalls.

Comments

There are no comments yet.