We reached this point, as we had pointed out in the previous article, there are a series of methods that are in charge of telling certain parts of the launcher what to do. These calls are programmed into the menu.py script.
This menu.py is in charge of drawing the sprites and receiving the information from the threads mentioned in the previous article, as well as deciding what action to take in the event that one of these actions is executed.
It encompasses all the components displayed in the menu, and its main class is:
The functionality of this script is divided into three classes, each of them is a sprite that together define a single component that we will explain below:
This sprite is in charge of painting the base of the menu that we see on the screen. It is the simplest of the three.
This base is programmed in a layer, and this layer contains, because it is a sprite, an image. The main function of this sprite is to display the menu wallpaper, which occupies the entire screen and resizes the image to the resolution specified in the program creating the wallpaper.
It is in charge of painting the sprite that contains the upper horizontal bar and its elements, that is, the widgets. This sprite is on a top layer, above the MenuBoard.
These widgets have their own logic and their own method within the class that at the moment indicate connectivity and audio levels, but as more functionalities are implemented in the launcher this class will grow and can be decomposed into classes of type MenuWidget .
For the moment due to its low level of complexity, it will be left that way until more are implemented.
Each of the menu items is found within the MenuItems class, so it could be defined as the sprite in charge of painting each of the options that the user sees on their screen (from the menu).
It is a class that is closely linked with MenuCursor, since depending on where the user selector is, there may be certain effects to paint (such as horizontal scrolling of texts, focused on displaying long texts that do not fit on the screen). All of this is defined in the draw method.
Visually this class is a sprite in charge of painting the user a blue rectangle in the correct place, which indicates in which menu item they are. This sprite is located behind the text (MenuItems) and above the background (MenuBoard).
Besides being the class that is in charge of painting where the user is at this moment, in a specific layer, it is the main class of the three previously specified, responsible for keeping track of user actions and menus.
Among its responsibilities:
- Depending on which method is executed by the actions of the user, the cursor must be placed higher or lower.
- It must show or hide a keyboard and not move through the menu
- When performing an action, it is responsible for calling the system, executing an action in the background or showing a message to the user of what result has launched an action external to the python script itself.
From it the graphic components are invoked to give the user more options than a horizontal text menu. These components are sprites and they are:
It is a component located in core / component / dialog.py and its class is Dialog (). This class is in charge of showing the user a message with a title and one or more buttons in which the user can interact.
By default this option will be OK to close the window or dialog and return control to the program.
The keyboard, like the Dialog, is a component located in the same core / component folder in the keyboard.py script. It is outside the MenuCursor but the control of where the user's focus is, that is, on which key or coordinate the user has placed the selector.
It is responsible for showing the user certain information with an interface, in this case the virtual keys and the information "written" by the user. This component contains two classes divided into a basic structure, the keyboard and each key, and for that MenuCursor must pass the information to raise, lower, left, right and select.
These components, like the rest of the user actions, are coordinated from the "select" method. This is perhaps the most important of the entire launcher, and it is responsible for loading the information from the menus and the controller responsible for deciding what action to execute at any time.
Menus are easily user-editable .json files that contain a structure similar to the following:
They have been thought to be customized by each user without the need to program anything, so the json elements are easily understood by an inexperienced user. But the most important thing to keep in mind is:
- Todos los elementos de un menú contienen un título, este título se refleja en el elemento con la clave 'title'
- Todos los items de un menú tienen un nodo en común que definen de qué tipo son, y por lo tanto qué acción ejecutar en caso de ser seleccionados por parte del usuario. Esta acción está definida en el contenido con clave 'action' y puede tener los siguientes valores:
- Un conjunto de valores que definen qué deben de pasar a las funciones (si se invoca a una función) como argumentos. Este elemento es opcional
- name and value: en caso de que se guardara el valor retornado por un método, temporalmente pueden guardar información con un nombre y valor. También es opcional.
Dependiendo de estos valoes el método select es capaz de diferenciar mediante condiciones a qué callback debe de llamar, y según lo retornado pintar o ejecutar nuevos menús y efectos visuales, como puede ser el efecto de pixelado definido en core/effect/pixelate.py. Pero de esto ya hablaremos en otro artículo.