Usar ventanas múltiples.

Ventanas

Hasta ahora, hemos usado la terminal como un medio de salida a pantalla completa. Este método es suficiente para los programas pequeños y sencillos, pero la biblioteca curses va mucho más allá. Puede mostrar múltiples ventanas de diferentes tamaños simultáneamente en la pantalla física. Mucha de las funciones de esta sección son aceptadas únicamente por lo que X/Open denomina cursesextendida“. Sin embargo, como ncurses las acepta, no debería existir un problema mayor para que estén disponibles en la mayoría de plataformas.

La estructura WINDOW

Aunque ya hemos mencionado a stdscr, la pantalla estándar, hasta ahora apenas hemos necesitado a usarla, ya que casi todas las funciones que hemos presentado hasta el momento dan por hecho que estamos trabajando en stdscr y no es necesario transmitirlo como un parámetro.

stdscr es simplemente un caso especial de la estructura WINDOW, al igual que stdout es un caso especial de un flujo de archivos. Normalmente, la estructura WINDOW se declara en curses.h , y aunque puede resultar instructivo examinarla, los programas no podrán acceder directamente nunca, ya que la estructura puede variar, y varía, de implementación.

Puede crear y destruir ventanas usando las llamadas newwin y delwin:

estructura_WINDOW

estructura_WINDOW1

estructura_WINDOW2

Envía un indicador de posición de la nueva ventana, o null si la creación falló. Si desea que la nueva ventana tenga su esquina superior derecha en la esquina inferior derecha de la pantalla, puede proporcionar cero líneas y columnas. newwin fallará si si cualquier parte de la nueva ventana sobrepasa el área de pantalla. La nueva ventana creada por newwin es totalmente independiente a todas las ventanas existentes. Por defecto, se sitúa en la parte superior de cualquier ventana existente, ocultando (sin modificar nada) sus contenidos.

estructura_WINDOW3

peligro

Una vez hayamos creado una nueva ventana ¿como podemos escribir en ella? La respuesta es que casi todas las funciones que hemos visto hasta el momento disponen de versiones generalizadas que operan en ventanas específicas, y por comodidad tambien se incluye el movimiento del cursor.

Funciones generalizadas

Ya hemos usado las funciones addch y printw para añadir caracteres a la pantalla. Junto con otras muchas funciones, se les puede añadir un prefijo, ya sea una w para ventana, mv para hacer referencia al movimiento, o mvw para movimiento y ventana. Si busca en el archivo de cabecera curses otras implementaciones de curses, verá que la mayoría de funciones usadas hasta el momento son simplemente macros (#defines)  que llaman a esas funciones más generales.

Cuando se añade el prefijo w, hay que colocar un indicador de posición WINDOW adicional delante de la lista de argumentos. Cuando se añade un prefijo mv hay que añadir dos parámetros adicionales, una ubicación y y otra x. Éstos especifican donde va a tener lugar la operación. y y x son relativos a la ventana, en vez de a la pantalla, a pesar que el prefijo sugiere que y y x van antes.

A modo de ejemplo, le mostramos el conjunto completo de prototipos para los conjuntos de funciones addch y printw:

funciones_generalizadas

Muchas otras funciones ,como, inch, también disponen de las variantes de ventana y movimiento.

Mover y actualizar una ventana

Estos comandos le permiten mover y volver a mostrar una ventana:

mover_ventana

trabajo_cap6

mover_actualizar

mover_actualizar2

mover_actualizar3

Gestión de varias ventanas

Con lo aprendido para gestionar más de una ventana, vamos a poner estas nuevas funciones en práctica mediante un programa que llamaremos, multiw1.c. Para hacerlo más breve hemos omitido la comprobación de errores.

  1. En primer lugar organizamos las definiciones:gestion varias ventanas1
  2. Complete la ventana base con caracteres, actualice la pantalla actual una vez que se hayan completado las pantallas lógicas:gestion varias ventanas2
  3. Ahora crearemos una ventana de 10 x 20 y añadimos texto antes de mostrarla por la pantalla:gestion varias ventanas3
  4. Modificaremos el contenido de la ventana del fondo. Cuando actualice la pantalla, la ventana que señala new_window_ptr se oscurecerá:
  5. gestion varias ventanas4Si realizamos una llamada para actualizar la nueva ventana, no variará nada, porque no ha cambiado la nueva ventana:gestion varias ventanas5
  6. Pero si tocamos la ventana primero, y hace que curses piense que la ventana ha sido modificada, la siguiente llamada a wrefresh colocará la nueva ventana otra vez en el frente:gestion varias ventanas6
  7. Añadiremos otra ventana que se solape con su caja alrededor:gestion varias ventanas7
  8. Enrede un poco con las nuevas ventanas desplegables antes de vaciarlas y eliminarlas:

gestion varias ventanas8

Resultado obtenido:

ventana emergentes

varias ventanas

Optimización de la actualizaciones de pantalla

 Actualizar múltiples ventanas puede resultar un poco confuso, pero el proceso no es muy pesado. Sin embargo, cuando la terminal que hay que actualizar está en una red lenta sí que surge un problema más serio. Afortunadamente, hoy en día es un problema poco común, pero la solución es muy sencillo como mostraremos a continuación.

Lo que pretenderemos es minimizar el número de caracteres que aparecen en pantalla, porque una pantalla con enlaces lentos puede resultar escandalosamente lentos. curses proporciona un modo especial para hacerlo, con una pareja de funciones, wnoutrefresh y doupdate:

optimizacion1 optimizacion2

Si sólo llama a wnoutrefresh seguida inmediatamente  de doupdate, el efecto es el mismo que si llama a wrefresh. Sin embargo, si desea volver a mostrar una pila de ventanas, puede llamar a wnoutrefresh en cada ventana(siempre en el orden correcto) y llamar después a doupdate justo detrás del último wnoutrefresh. De esta manera, curses podrá realizar sus cálculos de actualización de pantalla ventana por ventana y sólo  después enviará  la pantalla actualizada. Este método permite a curses reducir, casi siempre, el número de caracteres que han de ser enviados.

Subventanas

Tras estudiar las ventanas múltiples, podemos observar un caso especial de ventanas múltiples, denominado subventanas. Las subventanas se crean y se destruyen mediante estas llamadas:

subventanas1

subventanas2

Al igual que las nuevas ventanas, puede usar las funciones mvw para escribir en las subventanas. de hecho, la mayor parte del tiempo, las subventanas se comportan de un modo muy similar a las nuevas ventanas, con una excepción a tener en cuenta: las subventanas no almacenan ellas mismas un conjunto de caracteres de pantalla, comparten el mismo espacio de almacenamiento de caracteres que la ventana padre especificada cuando se crea la subventana. Esto significa que todos los cambios realizados en una subventana afectan tambien a la ventana padre adyacente, de manera que si elimna una subventana, la pantalla no varía,

Las subventanas se usan principalmente para proporcionar un modo limpio para desplazar ciertas partes  a otra ventana. La necesidad de desplazar una pequeña subsección de la pantalla es realmente común cuando se escribe un programa curses, haciendo que sea una subventana y desplazando después la subventana, podemos conseguir el resultado deseado.

El uso de subventanas tiene una restricción, la aplicación debería llamar a touchwin en la ventana padre antes de actualizar la pantalla.

Subventanas

Con este pequeño ejemplo mostramos cómo trabajan las funciones que acabamos de conocer, y cómo se diferencian de las funciones  de ventanas usadas previamente:

  1. >Creamos la primera sección del código al que llamaremos subsc1.c, que inicia la ventana base con algo de texto:listado_subventana1
  2. Cree ahora una nueva subventana desplazable. Tal como hemos resaltado antes, debe tocar a la ventana padre antes de actualizar la pantalla.subventana_listado2
  3. Elimine los contenidos de la subventana, añada texto, y actualícela. El testo desplazable lo obtendrá mediante un bucle:subventana_listado_3
  4. Una vez que haya acabado el bucle, elimine la subventana, y después actualice la pantalla base:subventana_listado_4

 

La salida que muestra es:

Captura de pantalla de 2014-06-12 09:36:30

Captura de pantalla de 2014-06-12 09:35:03

Captura de pantalla de 2014-06-12 09:37:30

atras

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s