domingo, 12 de junio de 2016

Capítulo 38: Small Basic. Eventos


Diario de un programador día 82

Eventos en Small Basic

Según el manual, “Los eventos son como señales que se levantan, por ejemplo, en respuesta a acciones del usuario, como el movimiento del mouse, o hacer clic con él. En cierto sentido, los eventos son opuestos a las operaciones. En el caso de las operaciones, usted como programador las invoca para hacer que el equipo haga algo, mientras que en el caso de los eventos, el ordenador le indica cuándo ha ocurrido algo interesante. Los eventos son fundamentales para introducir interactividad a un programa. Si usted desea permitir a un usuario interactuar con su programa, los eventos son lo que usted usará. Digamos que está escribiendo un programa de las tres en raya. Deseará permitir al usuario elegir su jugada, ¿cierto? Ahí es donde intervienen los eventos: usted recibirá la entrada del usuario en su programa usando eventos

En el programa, se pueden identificar porque su icono es una figura circular de color verde con un rayo en su interior.

Para poder utilizar los eventos, es necesario utilizar las subrutinas, ya que los eventos son activados cuando son asignados a una de estas.
Por ejemplo. Se creará un simple evento, el cual se activará cuando el usuario haga clic en la pantalla gráfica.

GraphicsWindow.MouseDown = clic
Sub clic
  GraphicsWindow.ShowMessage("Hola","Saludo")
EndSub

La primera línea utiliza el evento MouseDown, que sirve para lanzar un evento cada vez que se hace clic con el ratón (derecho o izquierdo). Ese evento, necesariamente tiene que ser asignado a una subrutina para que funcione. En este caso, la subrutina fue llamada “clic”. Más abajo aparece la subrutina “clic”, la cual tiene solamente una instrucción, que es mostrar un mensaje. Como esta subrutina está “enlazada” al evento MouseDown, entonces se ejecutará cada vez que el usuario haga clic con el ratón.
Otro ejemplo. En esta ocasión aparecerá un pequeño círculo coloreado en pantalla cada vez que el usuario haga clic.


GraphicsWindow.MouseDown = clic
Sub clic
  GraphicsWindow.BrushColor = GraphicsWindow.GetRandomColor()
  x = GraphicsWindow.MouseX
  y = GraphicsWindow.MouseY
  GraphicsWindow.FillEllipse(x-10,y-10, 20,20)
EndSub


Otro ejemplo. Este programa lo que hará será pedir al usuario que ingrese su nombre en un cuadro de texto. Cuando el usuario ingrese su nombre y luego presione el botón “enviar”, se mostrará un mensaje saludándolo.

GraphicsWindow.DrawText(10,10, "Ingresa tu nombre")
texto = Controls.AddTextBox(10,30)
Controls.AddButton("Enviar",10,60)

Controls.ButtonClicked = btnEnviar
Sub btnEnviar
  nombre = Controls.GetTextBoxText(texto)
  GraphicsWindow.ShowMessage("Bienvenido " + nombre,"Saludo")
EndSub


Poco a poco esto se va poniendo más interesante y se van expandiendo las posibilidades. Aquí se agregaron dos nuevos elementos: Un cuadro de texto y un botón, se explicará a continuación.
En la primera línea se agregó el texto “Ingresa tu nombre”. En la línea siguiente se crea una variable llamada “texto” a la cual se le asigna el cuadro de texto, se asignó a una variable debido a que la instrucción Controls.GetTextBox que se encuentra en la subrutina, requiere que le entregue el nombre del cuadro de texto sobre el cual trabajará. Para crear el cuadro de texto se usa la instrucción Controls.AddTextBox(x,y), donde x,y son la posición del cuadro. La siguiente línea es la que crea el botón, Controls.AddButton("Texto",x,y) Donde Texto, es el texto a mostrar y (x,y) son la posición del botón.
Más abajo se asigna la subrutina btnEnviar al evento Controls.ButtonClicked. Este evento se activa cuando un botón es presionado. Posteriormente se crea la subrutina btnEnviar y dentro de ella están todas las instrucciones que se ejecutarán cuando el botón sea presionado.
Lo primero que hace esta subrutina es capturar o leer lo que está escrito en el cuadro de texto, para ello se utilizó la instrucción Controls.GetTextBox, la cual requiere como parámetro, el nombre del cuadro de texto que va a leer, en este caso se le entregó el nombre de la variable “texto”, el cual corresponde a la variable que tiene asignado el cuadro de texto. Una vez capturado o leído el texto, este se asigna a la siguiente instrucción GraphicsWindow.ShowMessage("Bienvenido " + nombre,"Saludo"), la cual muestra un mensaje en pantalla con el texto introducido por el usuario.
Las respuestas hasta ahora, solamente se han visto utilizando el ShowMessage, pero también es posible mostrar una respuesta en la misma ventana gráfica, simplemente cambiando el ShowMessage por un DrawText. Quedando así:

GraphicsWindow.DrawText(10,10, "Ingresa tu nombre")
texto = Controls.AddTextBox(10,30)
Controls.AddButton("Enviar",10,60)

Controls.ButtonClicked = btnEnviar
Sub btnEnviar
  nombre = Controls.GetTextBoxText(texto)
  GraphicsWindow.DrawText(10,90,"Bienvenido " + nombre)
EndSub


El problema de mostrar un resultado en la pantalla gráfica es que si se vuelve a ingresar un nombre, éste aparecerá encima del resultado anterior ya que el mensaje anterior no se borra.


Una forma que encontré para solucionar esto fue limpiar la pantalla con la instrucción GraphicsWindow.Clear(). Esta instrucción borra todos los elementos de la pantalla gráfica. No estoy muy convencido con esta solución ya que solamente necesito borrar lo escrito y no toda la pantalla. Al borrar toda la pantalla tendría que volver a dibujarla completamente y todo por querer borrar una pequeña parte de ella. Para volver a dibujar o poner todos los elementos nuevamente en la pantalla, necesariamente tuve que dejar todos esos elementos dentro de una subrutina con la cual puedo llamar a esos elementos. Aquí muestro una modificación del programa anterior

Sub inicio
    GraphicsWindow.DrawText(10,10, "Ingresa tu nombre")
    texto = Controls.AddTextBox(10,30)
    Controls.AddButton("Enviar",10,60)
EndSub

Controls.ButtonClicked = btnEnviar
Sub btnEnviar
    nombre = Controls.GetTextBoxText(texto)
    GraphicsWindow.Clear()
    GraphicsWindow.DrawText(10,90,"Bienvenido " + nombre)
    inicio()
EndSub

inicio()

La instrucción GraphicsWindow.Clear() la puse en ese lugar debido a que si la coloco antes de la variable nombre, no mostraría nada. Esto es debido a que al presionar el botón, esta instrucción borraría todo, incluyendo lo que escrito por el usuario, entonces la variable nombre no encontraría nada para guardar. Si la coloco después de la instrucción DrawText, tampoco me serviría ya que si bien es cierto, la variable nombre capturaría el texto ingresado, el cual posteriormente sería mostrado por DrawText, pero como la siguiente instrucción sería un Clear(), entonces se borraría lo ingresado.
Entonces, siguiendo el orden de instrucciones que hay en la subrutina, lo primero que hace la subrutina btnEnviar es capturar el texto escrito y lo guarda en la variable "nombre". Lo siguiente que hace es borrar todo lo que hay en pantalla con Clear(), borra lo que hay en pantalla, pero no el contenido de la variable, eso se mantiene. Lo siguiente que hace es mostrar el texto en pantalla con DrawText y por último lo que hace es llamar a la subrutina inicio para volver a dibujar el cuadro de texto y el botón que fueron borrados anteriormente. Como todo esto sucede muy rápido no se alcanza a ver el borrado y redibujado de los elementos, pero si se borra o comenta por ejemplo el llamado a la subrutina inicio que está en la subrutina btnEnviar, se puede ver cómo es que los elementos antes mencionados fueron eliminados.

Sub inicio
    GraphicsWindow.DrawText(10,10, "Ingresa tu nombre")
    texto = Controls.AddTextBox(10,30)
    Controls.AddButton("Enviar",10,60)
EndSub

Controls.ButtonClicked = btnEnviar
Sub btnEnviar
    nombre = Controls.GetTextBoxText(texto)
    GraphicsWindow.Clear()
    GraphicsWindow.DrawText(10,90,"Bienvenido " + nombre)
    'inicio()  linea comentada
EndSub
inicio()


Bueno, otra alternativa que se me ocurre para no tener que borrar toda la pantalla, es simplemente mostrar el nuevo resultado debajo del anterior. O sea, en otra línea y para eso modifiqué el código de la siguiente manera.

y = 90
GraphicsWindow.DrawText(10,10, "Ingresa tu nombre")
texto = Controls.AddTextBox(10,30)
Controls.AddButton("Enviar",10,60)

Controls.ButtonClicked = btnEnviar
Sub btnEnviar
  nombre = Controls.GetTextBoxText(texto)
  GraphicsWindow.DrawText(10,y,"Bienvenido " + nombre)
  y = y + 20
EndSub

Lo que hice fue crear una variable a la cual llamé "y". A esta variable inicialmente le asigné el valor de 90, porque este es el valor que corresponde al lugar de la ubicación de este texto (fijarse en los códigos anteriores) Esa variable fue ocupada en la instrucción DrawText. En primera instancia, el texto es mostrado en la posición 10,90 que es el valor inicial de "y". La línea siguiente le suma 20 al valor de "y" por lo que esta variable vale ahora 110. Así que en la próxima llamada, el texto se ubicará en la posición 10,110 y así sucesivamente como se verá a continuación.


Como se puede ver, se han visto 3 formas de responder. Una es mediante un mensaje, la otra es mostrarlo en la pantalla gráfica, limpiándola en cada ingreso y por último mostrando una respuesta bajo otra en la pantalla gráfica. Como ahora ya se sabe no solamente mostrar mensajes sino que también solicitarlos, en el próximo capítulo se van a retomar esos ejercicios que se hicieron con la pantalla negra de texto, pero esta vez mostrados en la pantalla gráfica. Todo esto con la finalidad de practicar, ya que es la única manera de aprender.

Si alguien ha estado leyendo el manual de small basic, se habrá dado cuenta que en esta clase se llegó al final de ese manual, por lo que el día de hoy se ha cubierto el manual prácticamente en su totalidad (recordar que omití las lecciones de la tortuga porque a mi parecer no tiene mucha utilidad práctica). Hasta la próxima clase que esto aún no termina.

Gustavo J. Cerda Nilo
Enero 2016, última actualización Junio 2016



4 comentarios:

C++ El apuntador This

El apuntador This En C++, cada objeto tiene acceso a su propia dirección a través de un puntero o apuntador denominado This. Lo...