SDK Multiplataforma en C logo

SDK Multiplataforma en C

Layout

❮ Anterior
Siguiente ❯

Funciones

Layout*layout_create (...)
Cell*layout_cell (...)
voidlayout_label (...)
voidlayout_button (...)
voidlayout_popup (...)
voidlayout_edit (...)
voidlayout_combo (...)
voidlayout_updown (...)
voidlayout_slider (...)
voidlayout_progress (...)
voidlayout_view (...)
voidlayout_textview (...)
voidlayout_imageview (...)
voidlayout_panel (...)
voidlayout_layout (...)
Label*layout_get_label (...)
Button*layout_get_button (...)
PopUp*layout_get_popup (...)
Edit*layout_get_edit (...)
Combo*layout_get_combo (...)
UpDown*layout_get_updown (...)
Slider*layout_get_slider (...)
Progress*layout_get_progress (...)
View*layout_get_view (...)
TextView*layout_get_textview (...)
ImageView*layout_get_imageview (...)
voidlayout_taborder (...)
voidlayout_tabstop (...)
voidlayout_hsize (...)
voidlayout_vsize (...)
voidlayout_hmargin (...)
voidlayout_vmargin (...)
voidlayout_hexpand (...)
voidlayout_hexpand2 (...)
voidlayout_hexpand3 (...)
voidlayout_vexpand (...)
voidlayout_vexpand2 (...)
voidlayout_vexpand3 (...)
voidlayout_halign (...)
voidlayout_valign (...)
voidlayout_show_col (...)
voidlayout_show_row (...)
voidlayout_margin (...)
voidlayout_margin2 (...)
voidlayout_margin4 (...)
voidlayout_bgcolor (...)
voidlayout_skcolor (...)
voidlayout_update (...)
voidlayout_dbind (...)
voidlayout_dbind_obj (...)

Un Layout es una rejilla virtual y transparente vinculada siempre con un Panel que sirve para ubicar los diferentes elementos de la interfaz (Figura 1). Sus celdas interiores tienen la capacidad de dimensionarse automáticamente en función de su contenido, con lo que se consigue una gran portabilidad debido a que no es necesario indicar coordenadas ni tamaños específicos para los controles. Para ilustrar el concepto, vamos a simplificar ligeramente el código de ¡Hola Edit y UpDown! (Listado 1), cuyo resultado podemos verlo en (Figura 2).


1. Dimensionado natural

El resultado de (Figura 2), si bien no es muy estético, es lo que denominamos dimensionado natural que es la maquetación por defecto aplicada en función del contenido de las celdas. En (Tabla 1) tienes las medidas por defecto de cada control. El ancho de columna se fija al del elemento más ancho y de igual forma se calcula la altura de las filas. El tamaño final del layout será la suma de las medidas tanto de columnas como de filas.

Tabla 1: Dimensionado natural de controles.
Control Anchura Altura
Label Ajustado al texto. Ajustado al texto considerando '\n'.
Button (push) Ajustado al texto + márgen. Según el tema del S.O.
Button (check/radio) Ajustado al texto + icono. Ajustado al icono.
Button (flat) Ajustado al icono + margen. Ajustado al icono + margen.
PopUp Ajustado al texto mas largo. Según el tema del S.O.
Edit 100 Unidades (px). Ajustado al texto + margen.
Combo 100 Unidades (px). Según el tema del S.O.
UpDown Según el tema del S.O. Según el tema del S.O.
Slider (horizontal) 100 Unidades (px). Según el tema del S.O.
Slider (vertical) Según el tema del S.O. 100 Unidades (px).
Progress 100 Unidades (px). Según el tema del S.O.
TextView 256 px o textview_size. 144 px o textview_size.
View 128 px o view_size. 128 px o view_size.
Panel Dimensión natural. Dimensión natural.

Los márgenes y constantes aplicados a los controles son los necesarios para cumplir con las human guidelines de cada gestor de ventanas. Esto quiere decir que un PushButton con el texto "Hello" no tendrá las mismas dimensiones en WindowsXP que en macOS Mavericks o Ubuntu 16.

Las celdas vacías se dimensionarán con tamaño 0 y no afectarán a la composición.

2. Márgenes y formato

El dimensionado natural que acabamos de ver ajusta el panel al tamaño mínimo necesario para albergar correctamente todos los controles, pero no siempre resulta estético. Podemos darle forma añadiendo márgenes o forzando un tamaño determinado para filas y columnas (Listado 2) (Figura 3).


3. Alineación

Es habitual que la anchura un control sea inferior a la anchura de la columna que lo contiene, bien porque se ha forzado un ancho fijo o bien porque existan elementos más anchos en la misma columna. En estos casos, podemos indicar la alineación horizontal o vertical del control respecto a la celda (Figura 4). En (Tabla 2) tienes las alineaciones por defecto.


4. Sub-layouts

Consideremos ahora el panel de (Figura 5). No es difícil darse cuenta que esta disposición no encaja de ninguna manera en una rejilla rectangular, por lo que ha llegado el momento de utilizar sublayouts. Además de controles individuales, una celda admite también otro layout, por lo que podemos dividir el panel original en tantas partes como sean necesarias hasta conseguir la maquetación deseada. El layout principal irá dimensionando cada sublayout de forma recursiva e integrándolo en la composición final. En ¡Hola Sublayout! tienes el código que genera este ejemplo.

  • Utiliza layout_layout para asignar un layout completo a una celda de otro layout.
  • Ventana con diferentes controles organizados en bloques.
    Figura 5: Composición de panel compleja.

En este caso hemos aplicado la filosofía del divide y vencerás, hasta asegurar que cada parte encaje en una rejilla individual (Figura 6). Cada sublayout lo hemos codificado en una función independiente para darle mayor consistencia al código, aplicando márgenes y formato de forma individual dentro de cada una de ellas (Listado 3).

Esquema que muestra los límites de cada sub-layout.
Figura 6: Sublayouts necesarios para componer el panel de (Figura 5).
Listado 3: Integración de sublayouts (parcial).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
static Layout *i_main_layout(void)
{
    Layout *layout1 = layout_create(1, 2);
    Layout *layout2 = i_top_layout();
    Layout *layout3 = i_bottom_layout();
    layout_layout(layout1, layout2, 0, 0);
    layout_layout(layout1, layout3, 0, 1);
    layout_margin(layout1, 5);
    layout_vmargin(layout1, 0, 5);
    return layout1;
}

5. Expansión de celdas

En ciertas ocasiones, el tamaño de un layout viene forzado por condiciones externas. Esto ocurre cuando tenemos un sublayout en una celda con alineación ekJUSTIFY (expansión interna) o cuando el usuario cambia el tamaño de una ventana re-dimensionable (expansión externa). Esto producirá un "exceso de píxeles" entre el dimensionado natural y el tamaño real de la celda (Figura 7). Esta situación se resuelve repartiendo el sobrante por igual entre todas las columnas del sublayout, que a su vez, se irán expandiendo de forma recursiva hasta llegar a una celda vacía o un control individual. Podemos cambiar este reparto equitativo mediante estas funciones:

  • Utiliza layout_hexpand para expandir una única celda y dejar el resto con su tamaño por defecto.
  • Utiliza layout_hexpand2 para expandir dos celdas indicando la proporción de crecimiento de cada una.
  • Utiliza layout_hexpand3 para expandir tres celdas.
  • Comportamiento de un sublayout cuando su tamaño se expande para ajustarse a una celda.
    Figura 7: Cuando el tamaño del sublayout viene dado por condiciones externas, se reparte por igual el exceso de píxeles entre las columnas (expansión horizontal) y filas (expansión vertical).
La expansión vertical funciona exactamente igual, repartiendo el espacio sobrante entre las filas del layout.

6. Tabstops

Es una práctica habitual en la mayoría de sistemas utilizar la tecla [TAB] y la combinación [LSHIFT]+[TAB] para navegar por los diferentes controles de una ventana o formulario. Términos como taborder o tabstop hacen referencia tanto al orden de navegación como a la pertenencia (o no) de un elemento a dicha lista. Si bien es posible organizar los elementos de un tab-list aleatoriamente, los layouts proporcionan un orden natural coherente basado en la ubicación de los controles. Por defecto, cada layout enumera los controles por filas (Figura 8), pero podemos cambiarlo:

  • Utiliza layout_taborder para organizar por filas o columnas.
  • Animación que muestra la navegación con la tecla [TAB] tabstops. Organización de los controles de la tablist.
    Figura 8: Taborder por filas en layouts y sublayouts.

No todas las celdas de un layout tienen porqué ser un tabstop, ya que no tiene sentido que controles estáticos como Label reciban el foco del teclado. En (Tabla 3) tienes que controles se incluyen por defecto en dicha lista.

Cuando el taborder entra en un sublayout, seguirá el órden local de este último. Cuando salga del sublayout continuará con el orden principal.

layout_create ()

Crea un nuevo layout especificando el número de columnas y filas.

Layout*
layout_create(const uint32_t ncols,
              const uint32_t nrows);
ncols

El número de columnas.

nrows

El número de filas.

Retorna

El nuevo layout.


layout_cell ()

Obtiene una celda del layout.

Cell*
layout_cell(Layout *layout,
            const uint32_t col,
            const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

La celda.


layout_label ()

Inserta un control Label en un layout.

void
layout_label(Layout *layout,
             Label *label,
             const uint32_t col,
             const uint32_t row);
layout

El layout.

label

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_button ()

Inserta un control Button en un layout.

void
layout_button(Layout *layout,
              Button *button,
              const uint32_t col,
              const uint32_t row);
layout

El layout.

button

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_popup ()

Inserta un control PopUp en un layout.

void
layout_popup(Layout *layout,
             PopUp *popup,
             const uint32_t col,
             const uint32_t row);
layout

El layout.

popup

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_edit ()

Inserta un control Edit en un layout.

void
layout_edit(Layout *layout,
            Edit *edit,
            const uint32_t col,
            const uint32_t row);
layout

El layout.

edit

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_combo ()

Inserta un control Combo en un layout.

void
layout_combo(Layout *layout,
             Combo *combo,
             const uint32_t col,
             const uint32_t row);
layout

El layout.

combo

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_updown ()

Inserta un control UpDown en un layout.

void
layout_updown(Layout *layout,
              UpDown *updown,
              const uint32_t col,
              const uint32_t row);
layout

El layout.

updown

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_slider ()

Inserta un control Slider en un layout.

void
layout_slider(Layout *layout,
              Slider *slider,
              const uint32_t col,
              const uint32_t row);
layout

El layout.

slider

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_progress ()

Inserta un control Progress en un layout.

void
layout_progress(Layout *layout,
                Progress *progress,
                const uint32_t col,
                const uint32_t row);
layout

El layout.

progress

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_view ()

Inserta una vista View en un layout.

void
layout_view(Layout *layout,
            View *view,
            const uint32_t col,
            const uint32_t row);
layout

El layout.

view

La vista a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_textview ()

Inserta un control TextView en un layout.

void
layout_textview(Layout *layout,
                TextView *view,
                const uint32_t col,
                const uint32_t row);
layout

El layout.

view

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_imageview ()

Inserta un control ImageView en un layout.

void
layout_imageview(Layout *layout,
                 ImageView *view,
                 const uint32_t col,
                 const uint32_t row);
layout

El layout.

view

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_panel ()

Inserta un control Panel en un layout.

void
layout_panel(Layout *layout,
             Panel *panel,
             const uint32_t col,
             const uint32_t row);
layout

El layout.

panel

El control a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_layout ()

Inserta un layout en una celda de otro layout.

void
layout_layout(Layout *layout,
              Layout *sublayout,
              const uint32_t col,
              const uint32_t row);
layout

El layout principal.

sublayout

El layout a insertar.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.


layout_get_label ()

Obtiene el Label de una celda.

Label*
layout_get_label(const Layout *layout,
                 const uint32_t col,
                 const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_button ()

Obtiene el Button de una celda.

Button*
layout_get_button(const Layout *layout,
                  const uint32_t col,
                  const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_popup ()

Obtiene el PopUp de una celda.

PopUp*
layout_get_popup(const Layout *layout,
                 const uint32_t col,
                 const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_edit ()

Obtiene el Edit de una celda.

Edit*
layout_get_edit(const Layout *layout,
                const uint32_t col,
                const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_combo ()

Obtiene el Combo de una celda.

Combo*
layout_get_combo(const Layout *layout,
                 const uint32_t col,
                 const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_updown ()

Obtiene el UpDown de una celda.

UpDown*
layout_get_updown(const Layout *layout,
                  const uint32_t col,
                  const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_slider ()

Obtiene el Slider de una celda.

Slider*
layout_get_slider(const Layout *layout,
                  const uint32_t col,
                  const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_progress ()

Obtiene el Progress de una celda.

Progress*
layout_get_progress(const Layout *layout,
                    const uint32_t col,
                    const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_view ()

Obtiene el View de una celda.

View*
layout_get_view(const Layout *layout,
                const uint32_t col,
                const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

La vista.


layout_get_textview ()

Obtiene el TextView de una celda.

TextView*
layout_get_textview(const Layout *layout,
                    const uint32_t col,
                    const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_get_imageview ()

Obtiene el ImageView de una celda.

ImageView*
layout_get_imageview(const Layout *layout,
                     const uint32_t col,
                     const uint32_t row);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

Retorna

El control.


layout_taborder ()

Establece como se moverá el foco del teclado al pulsar [TAB].

void
layout_taborder(Layout *layout,
                const orient_t order);
layout

El layout.

order

Recorrido por filas o columnas.

Observaciones

Ver Tabstops.


layout_tabstop ()

Establece si una celda del layout recibirá o no el foco del teclado al navegar con [TAB]-[MAYS][TAB].

void
layout_tabstop(Layout *layout,
               const uint32_t col,
               const uint32_t row,
               const bool_t tabstop);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

tabstop

Habilitar o deshabilitar el punto de parada en la celda.

Observaciones

Ver Tabstops.


layout_hsize ()

Establece un ancho fijo para la columna de un layout.

void
layout_hsize(Layout *layout,
             const uint32_t col,
             const real32_t width);
layout

El layout.

col

Índice de la columna.

width

Anchura.


layout_vsize ()

Fuerza un alto fijo para la fila de un layout.

void
layout_vsize(Layout *layout,
             const uint32_t row,
             const real32_t height);
layout

El layout.

row

Índice de la fila.

height

Altura.


layout_hmargin ()

Establece un margen inter-columna dentro del layout. Es la separación entre dos columnas consecutivas.

void
layout_hmargin(Layout *layout,
               const uint32_t col,
               const real32_t margin);
layout

El layout.

col

Índice de la columna. El índice 0 se refiere a la separación entre la columna 0 y la columna 1. ncols-2 es el máximo valor aceptado.

margin

Margen.


layout_vmargin ()

Establece un margen inter-fila dentro del layout. Es la separación entre dos filas consecutivas.

void
layout_vmargin(Layout *layout,
               const uint32_t row,
               const real32_t margin);
layout

El layout.

row

Índice de la fila. El índice 0 se refiere a la separación entre la fila 0 y la fila 1. nrows-2 es el máximo valor aceptado.

margin

Margen.


layout_hexpand ()

Establece la columna que se expandirá horizontalmente.

void
layout_hexpand(Layout *layout,
               const uint32_t col);
layout

El layout.

col

Índice de la columna.

Observaciones

Ver Expansión de celdas.


layout_hexpand2 ()

Establece las dos columnas que se expandirán horizontalmente.

void
layout_hexpand2(Layout *layout,
                const uint32_t col1,
                const uint32_t col2,
                const real32_t exp);
layout

El layout.

col1

Índice de la columna 1.

col2

Índice de la columna 2.

exp

Expansión de col1 entre 0 y 1.

Observaciones

La expansión de col2 = 1 - exp. Ver Expansión de celdas.


layout_hexpand3 ()

Establece las tres columnas que se expandirán horizontalmente.

void
layout_hexpand3(Layout *layout,
                const uint32_t col1,
                const uint32_t col2,
                const uint32_t col3,
                const real32_t exp1,
                const real32_t exp2);
layout

El layout.

col1

Índice de la columna 1.

col2

Índice de la columna 2.

col3

Índice de la columna 3.

exp1

Expansión de col1 entre 0 y 1.

exp2

Expansión de col2 entre 0 y 1.

Observaciones

exp1 + exp2 < = 1. La expansión de col3 = 1 - exp1 - exp2. Ver Expansión de celdas.


layout_vexpand ()

Establece la fila que se expandirá verticalmente.

void
layout_vexpand(Layout *layout,
               const uint32_t row);
layout

El layout.

row

Índice de la fila.

Observaciones

Ver Expansión de celdas.


layout_vexpand2 ()

Establece las dos filas que se expandirán verticalmente.

void
layout_vexpand2(Layout *layout,
                const uint32_t row1,
                const uint32_t row2,
                const real32_t exp);
layout

El layout.

row1

Índice de la fila 1.

row2

Índice de la fila 2.

exp

Expansión de row1 entre 0 y 1.

Observaciones

La expansión de row2 = 1 - exp. Ver Expansión de celdas.


layout_vexpand3 ()

Establece las tres filas que se expandirán verticalmente.

void
layout_vexpand3(Layout *layout,
                const uint32_t row1,
                const uint32_t row2,
                const uint32_t row3,
                const real32_t exp1,
                const real32_t exp2);
layout

El layout.

row1

Índice de la fila 1.

row2

Índice de la fila 2.

row3

Índice de la fila 3.

exp1

Expansión de row1 entre 0 y 1.

exp2

Expansión de row2 entre 0 y 1.

Observaciones

exp1 + exp2 < = 1. La expansión de row3 = 1 - exp1 - exp2. Ver Expansión de celdas.


layout_halign ()

Establece la alineación horizontal de una celda. Tendrá efecto cuando la columna sea más ancha que la celda.

void
layout_halign(Layout *layout,
              const uint32_t col,
              const uint32_t row,
              const align_t align);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

align

Alineación horizontal.


layout_valign ()

Establece la alineación vertical de una celda. Tendrá efecto cuando la fila sea más alta que la celda.

void
layout_valign(Layout *layout,
              const uint32_t col,
              const uint32_t row,
              const align_t align);
layout

El layout.

col

Columna, coordenada x de la celda.

row

Fila, coordenada y de la celda.

align

Alineación vertical.


layout_show_col ()

Muestra u oculta una columna del layout.

void
layout_show_col(Layout *layout,
                const uint32_t col,
                const bool_t visible);
layout

El layout.

col

Índice de columna.

visible

Visible u oculta.


layout_show_row ()

Muestra u oculta una fila del layout.

void
layout_show_row(Layout *layout,
                const uint32_t row,
                const bool_t visible);
layout

El layout.

row

Índice de fila.

visible

Visible u oculta.


layout_margin ()

Establece un margen uniforme para el borde del layout.

void
layout_margin(Layout *layout,
              const real32_t mall);
layout

El layout.

mall

Margen para los cuatro lados (izquierda, derecha, arriba y abajo).


layout_margin2 ()

Establece un margen horizontal y vertical para el borde del layout.

void
layout_margin2(Layout *layout,
               const real32_t mtb,
               const real32_t mlr);
layout

El layout.

mtb

Margen superior e inferior.

mlr

Margen izquierdo y derecho.


layout_margin4 ()

Establece márgenes para el borde del layout.

void
layout_margin4(Layout *layout,
               const real32_t mt,
               const real32_t mr,
               const real32_t mb,
               const real32_t ml);
layout

El layout.

mt

Margen del borde superior.

mr

Margen del borde derecho.

mb

Margen del borde inferior.

ml

Margen del borde izquierdo.


layout_bgcolor ()

Asigna un color de fondo al layout.

void
layout_bgcolor(Layout *layout,
               const color_t color);
layout

El layout.

color

El color. Pasando ekCOLOR_TRANSPARENT se restablece el color por defecto.


layout_skcolor ()

Asigna un color al borde del layout.

void
layout_skcolor(Layout *layout,
               const color_t color);
layout

El layout.

color

El color. Pasando ekCOLOR_TRANSPARENT se restablece el color por defecto.


layout_update ()

Actualiza la ventana asociada con el layout.

void
layout_update(Layout *layout);
layout

El layout.

Observaciones

Es equivalente a llamar a window_update.


layout_dbind ()

Asocia un tipo struct con un layout.

void
layout_dbind(Layout *layout,
             Listener *listener,
             type);
1
layout_dbind(layout, Product);
layout

El layout.

listener

Notificará a través de este listener cada vez que el objeto cambie. Puede ser NULL.

type

El tipo de struct.


layout_dbind_obj ()

Asocia un objeto con un layout para visualizarlo y editarlo.

void
layout_dbind_obj(Layout *layout,
                 type *obj,
                 type);
1
2
Product *product = i_create(...);
layout_dbind_obj(layout, product, Product);
layout

El layout.

obj

El objeto a editar.

type

El tipo del objeto.

❮ Anterior
Siguiente ❯