4.3 Etiquetas

Las etiquetas se usan mucho en Gtk2Hs, y son relativamente sencillas. Las etiquetas no emiten señales, ya que no tienen una X Window asociada. Si necesitas capturar una señal o apilarlas con otros widgets, debes colocarla dentro de un widget EventBox (Caja de eventos), Los EventBox te permiten capturar señales de widgets que no tienen su propia ventana o botón.

Para crear una nueva etiqueta, puedes usar:

labelNew :: Maybe String -> IO Label

labelNewWithMnemonic :: String -> IO Label

Con la segunda función, si algún caracter de la cadena está precedido de un guión bajo (o subrayado), se subraya al representarlo. Si necesitas un carácter guión bajo en una etiqueta, debes usar "__" (dos subrayados). El primer caracter subrayado que aparece representa un atajo de teclado que denominamos mnemónico. Cuando se pulsa esa tecla, el widget disponible que contiene esa etiqueta (un botón, por ejemplo) se activa. El widget al que queremos asociar un nmemónico se puede establecer con labelSetMnemonicWidget.

Para cambiar el texto de la etiqueta después de haber sido creada, o para conseguir el texto de la misma, puedes usar las funciones:

labelSetText :: LabelClass self => self -> String -> IO ()

labelGetLabel :: LabelClass self => self -> IO String

o, por supuesto, las funciones genéricas set o get. El espacio necesario para la nueva cadena (string) sería ajustado automáticamente si fuera preciso. Se pueden producir etiquetas multilínea, colocando saltos de línea en la cadena de la etiqueta. La justificación del texto en las etiquetas multilínea se realiza con la función:

labelSetJustify :: LabelClass self => self -> Justification -> IO ()

donde el tipo Justification puede usar alguno de estos cuatro constructores:

El widget etiqueta es también capaz de fijar los saltos de línea en el texto automáticamente. Esto se puede activar usando:

labelSetLineWrap :: LabelClass self => self -> Bool -> IO ()

Si quieres que la etiqueta esté subrayada, puedes establecer un patrón para la etiqueta:

labelSetPattern :: LabelClass self => self -> [Int] -> IO ()

La lista de Ints (enteros) marca las partes del texto de la etiqueta que se subrayarán alternando con los caracteres que no se subrayarán. Por ejemplo, [3, 1, 3] significa que se subrayarán los tres primeros caracteres, el siguiente, no y los tres siguientes, sí.

Puedes hacer, también, que se pueda seleccionar el texto de la etiqueta, de modo que el usuario pueda copiarlo y pegarlo, además de usar algunas opciones de formateo.

Abajo hay un ejemplo que ilustra algunas de estas funciones. Usa el widget Frame para demostrar mejor los estilos de la etiqueta. Un Frame no es más que un ornamento, igual que un HSeparator y un VSeparator pero en este caso rodea al widget y es una instancia de Container. Por tanto, el widget que encuadra debe ser añadido con containerAdd. Un Frame puede tener una etiqueta para transmitir información sobre su contenido.

Label examples

Como todas las etiquetas del ejemplo tienen un Frame, se define una función myLabelWithFrameNew, que devuelve una tupla. Gtk2Hs es 100% Haskell, por lo que puedes usar todos los tipos de datos y característas de Haskell. Las justificaciones son obvias pero sólo se refieren a las líneas de dentro de la etiqueta. Así que, para justificar a la derecha label2, necesitas miscSetAlignment tal y como se muestra más abajo. Los últimos dos widgets en la caja horizontal de la izquierda se empaquetan con boxPackEnd en vez del usual boxPackStart. La etiqueta botón demuestra el uso de un mnemónico como atajo. Pulsar Alt-C en el teclado provoca el mismo efecto que pulsar el botón con el ratón.

Nota: Cuando se ha testeado en Fedora 6, pulsar Enter o la barra espaciadora tiene el mismo efecto. Fíjate además en el efecto del carácter "y" en la colocación del subrayado.

import Graphics.UI.Gtk

main:: IO ()
main = do
  initGUI
  window  <- windowNew
  set window [windowTitle := "Labels", containerBorderWidth := 10]
  mainbox <- vBoxNew False 10
  containerAdd window mainbox
  hbox    <- hBoxNew True 5
  boxPackStart mainbox hbox PackNatural 0
  vbox1   <- vBoxNew False 10
  vbox2   <- vBoxNew False 0
  boxPackStart hbox vbox1 PackNatural 0
  boxPackStart hbox vbox2 PackNatural 0

  (label1,frame1) <- myLabelWithFrameNew
  boxPackStart vbox1 frame1 PackNatural 0
  labelSetText label1 "Penny Harter"

  (label2,frame2) <- myLabelWithFrameNew
  boxPackStart vbox1 frame2 PackNatural 0
  labelSetText label2 "broken bowl\nthe pieces\nstill rocking"
  miscSetAlignment label2 0.0 0.0
  hsep1           <- hSeparatorNew
  boxPackStart vbox1 hsep1 PackNatural 10

  (label3,frame3) <- myLabelWithFrameNew
  boxPackStart vbox1 frame3 PackNatural 0
  labelSetText label3 "Gary Snyder"

  (label4,frame4) <- myLabelWithFrameNew
  boxPackStart vbox1 frame4 PackNatural 0
  labelSetText label4 "After weeks of watching the roof leak\nI fixed it tonight\nby moving a single board"
  labelSetJustify label4 JustifyCenter

  (label5,frame5) <- myLabelWithFrameNew
  boxPackStart vbox2 frame5 PackNatural 0
  labelSetText label5 "Kobayashi Issa"

  (label7,frame7) <- myLabelWithFrameNew
  boxPackEnd vbox2 frame7 PackNatural 0
  labelSetText label7 "only one guy and\nonly one fly trying to\nmake the guest room do"
  labelSetJustify label7 JustifyRight

  (label6,frame6) <- myLabelWithFrameNew
  boxPackEnd vbox2 frame6 PackNatural 10
  labelSetText label6 "One Guy"
  frameSetLabel frame6 "Title:"
  labelSetPattern label6 [3, 1, 3]

  button      <- buttonNew
  boxPackEnd mainbox button PackNatural 20
  buttonlabel <- labelNewWithMnemonic "Haiku _Clicked"
  containerAdd button buttonlabel

  widgetShowAll window
  onClicked button (putStrLn "button clicked...")
  onDestroy window mainQuit
  mainGUI


myLabelWithFrameNew :: IO (Label,Frame)
myLabelWithFrameNew = do
  label <- labelNew Nothing
  frame <- frameNew
  containerAdd frame label
  frameSetShadowType frame ShadowOut
  return (label, frame)


-- Haikus quoted from X.J. Kennedy, Dana Gioia, Introduction to Poetry, Longman, 1997