SDK Multiplataforma en C logo

SDK Multiplataforma en C

View

❮ Anterior
Siguiente ❯

Funciones

View*view_create (...)
voidview_data (...)
type*view_get_data (...)
voidview_size (...)
voidview_OnDraw (...)
voidview_OnSize (...)
voidview_OnEnter (...)
voidview_OnExit (...)
voidview_OnMove (...)
voidview_OnDown (...)
voidview_OnUp (...)
voidview_OnClick (...)
voidview_OnDrag (...)
voidview_OnWheel (...)
voidview_OnKeyDown (...)
voidview_OnKeyUp (...)
voidview_OnFocus (...)
voidview_keybuf (...)
voidview_get_size (...)
voidview_content_size (...)
voidview_scroll_to (...)
voidview_viewport (...)
voidview_point_scale (...)
voidview_update (...)

Los controles View o vistas personalizadas (Figura 1) son áreas en blanco dentro de la ventana que nos permiten implementar nuestros propios componentes. Tendremos total libertad para dibujar y capturar los eventos del teclado o ratón que nos permitan interactuar con la misma.


1. Dibujar en vistas.

No podemos actualizar el área de dibujo cuando queramos. Esta puede verse afectada por otras ventanas del entorno, por lo que el framebuffer es gestionado directamente por el sistema operativo. Este último mandará una notificación cada vez que el control deba refrescar su contenido.

  • Utiliza view_OnDraw para establecer el manejador de dibujo.
  • Utiliza view_update para forzar la actualización del área.

En Die tienes una sencilla aplicación de ejemplo que implementa el dibujado de vistas personalizadas. El ciclo completo puede resumirse en estos pasos (Figura 2):

  • Se produce algún evento que requiere actualizar el contenido de la vista.
  • La aplicación llama al método view_update para notificar que la vista debe ser actualizada.
  • En el momento oportuno, el sistema mandará un evento OnDraw con un contexto DCtx listo para dibujar.
  • Gráfico con las diferentes fases de la actualización de una vista.
    Figura 2: Ciclo de refresco de una vista personalizada.
El sistema operativo puede lanzar eventos OnDraw en cualquier momento sin que hallamos llamado previamente a view_update.

2. Vistas con scroll

Es posible que la "escena" a representar sea mucho más grande que el propio control, por lo que este mostrará solo un pequeño fragmento de la misma (Figura 3). En estos casos diremos que la vista es un viewport de la escena. Podemos gestionarlo de dos maneras:

Relación de una escena 2D con el viewport donde de visualiza.
Figura 3: Escena y vista (viewport).
  • Utilizar draw_matrix para indicar la transformación que integra el desplazamiento, zoom y posible rotación del viewport con respecto a la escena. Todo ello debe ser gestionado por la aplicación y no tenemos que hacer nada especial, salvo llamar a view_update() cuando sea necesario.
  • Utilizar barras de scroll que permitan al usuario desplazarse libremente por el contenido. En este caso la gestión de la vista se complica un poco más. Esto es lo que debemos tener en cuenta:
    • Incluir las constantes ekVSCROLL y ekHSCROLL en el constructor.
    • Utilizar view_content_size para indicar las medidas de la escena, con el fin de que se dimensionen correctamente las barras.
    • Utilizar view_scroll_to para mover el origen del área visible.
    • Utilizar view_viewport para obtener la posición y dimensiones del área visible.

Algo muy importante es evitar dibujar elementos no visibles, sobre todo en escenas muy grandes o con multitud de objetos. El sistema operativo mandará sucesivos eventos OnDraw() a medida que el usuario manipule las scrollbars, indicando en la estructura EvDraw los parámetros del área visible. En Dibujos con scroll tienes un ejemplo de como gestionar correctamente este tipo de casos.

Es posible que las dimensiones del viewport recibido en OnDraw() sean algo superiores a las medidas reales devueltas por view_viewport(). Esto es debido a que determinados sistemas (macOS, Linux) obligan a dibujar en ciertas zonas no visibles cercanas a los bordes, con el fin de evitar parpadeos en desplazamientos muy rápidos.

3. Uso del ratón

Para poder interactuar con el control es necesario definir manejadores para los diferentes eventos del ratón (Figura 4). El sistema operativo notificará las acciones del usuario con el fin de que la aplicación pueda lanzar las acciones pertinentes. No es necesario utilizarlos todos, tan solo los imprescindibles en cada caso.

Ilustración de los eventos de ratón de una vista 2d.
Figura 4: Eventos de posición con respecto a la vista.
  • Utiliza view_OnEnter para saber cuando el cursor entre en la vista.
  • Utiliza view_OnExit para saber cuando el cursor salga de la vista.
  • Utiliza view_OnMove para saber cuando el cursor se está moviendo por la vista.
  • Utiliza view_OnDown para saber cuando se pulse un botón dentro de la vista.
  • Utiliza view_OnUp para saber cuando se libere un botón dentro de la vista.
  • Utiliza view_OnClick para identificar un click (Up + Down rápido).
  • Utiliza view_OnDrag para desplazamientos del cursor con un botón pulsado.
  • Utiliza view_OnWheel para el uso de la ruedecilla del ratón.
Si la vista utiliza barras de scroll, la posición (x,y) del cursor pasada a EvMouse en cada evento, hace referencia a los coordenadas globales de la escena, teniendo en cuenta el desplazamiento. En vistas sin barras de scroll, son las coordenadas locales del control.

4. Uso del teclado

Para poder recibir eventos de teclado, es necesario que la vista sea capaz de obtener el foco, algo que por defecto está desactivado.

  • Utiliza layout_tabstop para incluir la vista en el tab-list de la ventana y permitir que reciba el foco del teclado mediante la tecla [TAB] o al hacer clic sobre ella.
  • Utiliza view_OnKeyDown para saber cuando se pulsa una tecla (si la vista tiene el foco).
  • Utiliza view_OnKeyUp para saber cuando se libera una tecla.
  • Utiliza view_OnFocus para notificar a la aplicación cada vez que la vista reciba (o pierda) el foco del teclado. En (Figura 5), la vista cambia el color de la celda activa cuando tiene el foco.
  • Cambio del foco del teclado entre dos controles.
    Figura 5: Vista sin el foco del teclado (izquierda) y con él (derecha).

En los eventos KeyDown y KeyUp se recibirá un vkey_t con el valor de la tecla pulsada. En (Figura 6) y (Figura 7) se muestran la correspondencia de estos códigos.

Representación de un teclado con el código de cada tecla.
Figura 6: Códigos del teclado.
Representación de un teclado extendido con el código de cada tecla extendida.
Figura 7: Códigos extendidos del teclado.

En Aplicaciones síncronas es posible que necesitemos saber si una tecla está pulsada o no durante el ciclo de actualización (síncrono) donde no tenemos acceso a los eventos OnKeyDown y OnKeyUp (asíncronos). Esto es posible hacerlo asignando a la vista un búfer de teclado mediante view_keybuf, que capturá los eventos asociados a cada tecla y nos permitirá consultar su estado en cualquier momento de forma cómoda.


view_create ()

Crea una nueva vista personalizada.

View*
view_create(uint32_t flags);
flags

Opciones de creación. Combinación OR | de valores de view_flag_t.

Retorna

El control vista.


view_data ()

Asocia datos de usuario con la vista.

void
view_data(View *view,
          type **data,
          FPtr_destroy func_destroy_data,
          type);
view

La vista.

data

Datos de usuario.

func_destroy_data

Destructor de los datos de usuario. Será llamado al destruir la vista.

type

Tipo de datos de usuario.


view_get_data ()

Obtiene los datos de usuario asociados con la vista.

type*
view_get_data(const View *view,
              type);
view

La vista.

type

Tipo de datos de usuario.

Retorna

Los datos de usuario.


view_size ()

Establece el tamaño por defecto de la vista.

void
view_size(View *view,
          const S2Df size);
view

La vista.

size

El tamaño.

Observaciones

Corresponde al Dimensionado natural del control. Por defecto 128x128.


view_OnDraw ()

Establece un manejador para dibujar en la vista.

void
view_OnDraw(View *view,
            Listener *listener);
view

La vista.

listener

Función callback que se llamará cada vez que deba refrescarse el dibujo.

Observaciones

Ver Eventos GUI.


view_OnSize ()

Establece un manejador para el cambio de tamaño.

void
view_OnSize(View *view,
            Listener *listener);
view

La vista.

listener

Función callback que se llamará cada vez que la vista cambie de tamaño.

Observaciones

Ver Eventos GUI.


view_OnEnter ()

Establece un manejador para la entrada del ratón.

void
view_OnEnter(View *view,
             Listener *listener);
view

La vista.

listener

Función callback que se llamará cuando el cursor del ratón entre en el área de la vista.

Observaciones

Ver Eventos GUI.


view_OnExit ()

Establece un manejador para la salida del ratón.

void
view_OnExit(View *view,
            Listener *listener);
view

La vista.

listener

Función callback que se llamará cuando el cursor del ratón salga del área de la vista.

Observaciones

Ver Eventos GUI.


view_OnMove ()

Establece un manejador para el movimiento del ratón.

void
view_OnMove(View *view,
            Listener *listener);
view

La vista.

listener

Función callback que se llamará a medida que el cursor del ratón se desplace por encima de la vista.

Observaciones

Ver Eventos GUI.


view_OnDown ()

Establece un manejador para la pulsación de un botón del ratón.

void
view_OnDown(View *view,
            Listener *listener);
view

La vista.

listener

Función callback que se llamará cuando se pulse un botón.

Observaciones

Ver Eventos GUI.


view_OnUp ()

Establece un manejador para la liberación de un botón del ratón.

void
view_OnUp(View *view,
          Listener *listener);
view

La vista.

listener

Función callback que se llamará cuando se libere un botón.

Observaciones

Ver Eventos GUI.


view_OnClick ()

Establece un manejador para el clic del ratón.

void
view_OnClick(View *view,
             Listener *listener);
view

La vista.

listener

Función callback que se llamará cada vez que se haga clic sobre la vista.

Observaciones

Ver Eventos GUI.


view_OnDrag ()

Establece un manejador para el arrastre del ratón.

void
view_OnDrag(View *view,
            Listener *listener);
view

La vista.

listener

Función callback que se llamará mientras se esté arrastrando el cursor del ratón sobre la vista.

Observaciones

"Arrastrar" es desplazar el ratón con uno de los botones pulsados. Ver Eventos GUI.


view_OnWheel ()

Establece un manejador para la ruedecilla del ratón.

void
view_OnWheel(View *view,
             Listener *listener);
view

La vista.

listener

Función callback que se llamará cuando se mueva la ruedecilla del ratón sobre la vista.

Observaciones

Ver Eventos GUI.


view_OnKeyDown ()

Establece un manejador para la pulsación de una tecla.

void
view_OnKeyDown(View *view,
               Listener *listener);
view

La vista.

listener

Función callback que se llamará cuando se pulse una tecla y la vista tenga el foco del teclado.

Observaciones

Ver Eventos GUI.


view_OnKeyUp ()

Establece un manejador para la liberación de una tecla.

void
view_OnKeyUp(View *view,
             Listener *listener);
view

La vista.

listener

Función callback que se llamará cuando se libere una tecla y la vista tenga el foco del teclado.

Observaciones

Ver Eventos GUI.


view_OnFocus ()

Establece un manejador para el foco del teclado.

void
view_OnFocus(View *view,
             Listener *listener);
view

La vista.

listener

Función callback que se llamará cuando se reciba o se pierda el foco del teclado.

Observaciones

Ver Uso del teclado y Eventos GUI.


view_keybuf ()

Establece un búfer de teclado para la consulta síncrona o asíncrona del estado de las teclas.

void
view_keybuf(View *view,
            Keybuf *buffer);
view

La vista.

buffer

Bufer de teclado que será mantenido por la vista, capturando los eventos OnKeyDown y OnKeyUp.

Observaciones

Solo mantiene una referencia al búfer, que deberá ser destruido por el objeto que lo creó. Ver Búfer de teclado. La aplicación podrá seguir recibiendo eventos de teclado a través de view_OnKeyDown y view_OnKeyUp.


view_get_size ()

Obtiene el tamaño actual de la vista.

void
view_get_size(const View *view,
              S2Df *size);
view

La vista.

size

El tamaño.


view_content_size ()

Establece el tamaño del área de dibujo cuando existen barras de scroll.

void
view_content_size(View *view,
                  const S2Df size);
view

La vista.

size

El tamaño interno del área de dibujo.

Observaciones

Cuando se crea una vista con scroll, este método indica la totalidad del área de dibujo. El control lo utilizará para dimensionar y posicionar las barras de scroll.


view_scroll_to ()

Desplaza las barras de scroll a la posición indicada.

void
view_scroll_to(View *view,
               const real32_t x,
               const real32_t y);
view

La vista.

x

Nueva posición de la barra horizontal.

y

Nueva posición de la barra vertical.


view_viewport ()

Obtiene las dimensiones del área visible de la vista.

void
view_viewport(const View *view,
              V2Df *pos,
              S2Df *size);
view

La vista.

pos

La posición del viewport. Puede ser NULL.

size

El tamaño del viewport. Puede ser NULL.

Observaciones

Si la vista no tiene barras de scroll, pos será (0,0).


view_point_scale ()

Obtiene el escalado del punto.

void
view_point_scale(const View *view,
                 real32_t *scale);
view

La vista.

scale

El escalado.

Observaciones

El tamaño de la vista y coordenadas de dibujo se expresan en puntos, que normalmente corresponden con píxeles (1pt = 1px). En Pantallas retina puede ocurrir que (1pt = 2px). Si bien los Contextos 2D gestionan esto automáticamente, es posible que necesitemos saber la cantidad de píxeles para crear otro tipo de framebuffers (OpenGL, DirectX, etc). Pixels = view_get_size * view_point_scale.


view_update ()

Manda una orden al sistema operativo que la vista debe ser refrescada.

void
view_update(View *view);
view

La vista.

❮ Anterior
Siguiente ❯