6.4 Ventanas panelables y marcos de ratio fijo

El widged de ventana panelable (paned window) resulta muy útil cuando quieres dividir un área en dos partes, y que el usuario pueda determinar el tamaño relativo de ambas. Se dibuja una línea entre ambas partes, con una flecha doble que el usuario puede arrastrar para cambiar el tamaño de ambas porciones (lo que se agranda una se empequeñece la otra). La división puede ser horizontal HPaned, o vertical, VPaned.

Para crear una ventana panelable puedes usar:

hPanedNew :: IO HPanel
vPanedNew :: IO VPaned 

La posición del divisor se establece con:

panedSetPosition :: PanedClass self => self -> Int -> IO ()

Tras crear la ventana panelable, necesitas añadir widgets hijos a las dos mitades.

panedAdd1 :: (PanedClass self, WidgetClass child) => self -> child -> IO ()
panedAdd2 :: (PanedClass self, WidgetClass child) => self -> child -> IO ()

El primero se situa en la parte superior (derecha) , el segundo lo hace en la parte inferior (izquierda) de la ventana panelable. Si no quieres que algún hijo no se expanda o reduzca con el widget panelable debes usar panedPack1 y panedPack2.

Un marco de ratio fijo (Aspect Frame) es un marco para el que puedes definir una relación constante entre la altura y la anchura. Este no cambiará al cambiar el tamaño del marco. Para crear uno puedes usar:

aspectFrameNew :: Float -> Float -> Maybe Float -> IO AspectFrame

El primer parámetro establece el alineamiento horizontal del hijo dentro del marco (entre 0.0 y 1.0). El segundo hace lo mismo con el alineamiento vertical. Opcionalmente, puedes establecer la proporción deseada con el tercer parámetro. Como un widget AspectFrame es un widget de tipo Frame , puedes añadirle una etiqueta.

En el ejemplo siguiente hemos creado un panel vertical de ratio fijo con un marco de ratio fijo en la mitad superior.

Paned Window

Hemos creado un widget DrawingArea (área de dibujo) en el AspectFrame. Un widget DrawingArea es un widget vacío, que puede usarse para dibujar en él, aunque aquí sólo le hemos puesto un color de fondo para demostrar el uso del AspectFrame. En la mitad inferior del widget VPaned hemos creado un widget TextView . Este es un visor y editor de texto multilínea con muchas y poderosas características. Aquí, sin embargo, simplemente hemos tomado el buffer de texto asociado y hemos contado los caracteres cada vez que el usuario edita algún texto.

import Graphics.UI.Gtk

main :: IO ()
main = do
     initGUI
     window <- windowNew
     set window [windowTitle := "Paned Window", containerBorderWidth := 10,
                 windowDefaultWidth := 400, windowDefaultHeight := 400 ]

     pw <- vPanedNew
     panedSetPosition pw 250
     containerAdd window pw
     af <- aspectFrameNew 0.5 0.5 (Just 3.0)
     frameSetLabel af "Aspect Ratio: 3.0"
     frameSetLabelAlign af 1.0 0.0
     panedAdd1 pw af

     da <- drawingAreaNew
     containerAdd af da
     widgetModifyBg da StateNormal (Color 65535 0 0)
   
     tv <- textViewNew
     panedAdd2 pw tv
     buf <- textViewGetBuffer tv

     onBufferChanged buf $ do cn <- textBufferGetCharCount buf
                              putStrLn (show cn)   

     widgetShowAll window 
     onDestroy window mainQuit
     mainGUI