Gtk2Hs tiene varios widgets que pueden ser ajustados visualmente por el usuario usando el ratón o el teclado, como los widgets rango, descritos en su sección. También hay algunos widgets que muestran una porción de un área de datos mayor, como el widget text y el widget viewport. Esta porción también puede ser ajustada por el usuario.
Una aplicación necesita ser capaz de reaccionar a los cambios que hace el usuario en el rango. Un modo de hacerlo podría ser haciendo que cada widget emitiera su propio tipo de señal cuando cambiase su ajuste. Pero puede que quisieras enlazar los ajustes de varios widgets juntos, de modo que al ajustar uno se ajustasen los otros. El ejemplo más claro de esto es la conexión de un scrollbar (barra de deslizamiento) a un panning viewport (ventana de mostrar imágenes con una subpantalla) o a un área de texto con scroll.
El objeto Adjustment (ajuste) se puede usar para almacenar los parámetros y valores de
configuración de los widgets de rango, como los scrollbars y controles de escalado.
Como Adjustment se deriva de GObject y
Object, los ajustes pueden emitir señales, que pueden ser usadas no sólo para
que tu programa reaccione a las entradas del usuario en los widgets ajustables, sino
también para propagar los valores de ajuste de un modo transparente entre widgets ajustables.
Muchos de los widgets que usan objetos Adjustment, como ScrolledWindow, pueden crear
sus propios objetos Adjustment, pero tu mismo los puedes crear con:
adjustmentNew :: Double        -- valor            - El valor inicial del rango
              -> Double        -- mínimo           - Valor mínimo del rango
              -> Double        -- máximo           - Valor máximo del rango
              -> Double        -- incrementoPaso   - El menor de dos posibles incrementos
              -> Double        -- incrementoPágina - El mayor de dos posibles incrementos
              -> Double        -- tamañoPágina     - El tamaño del área visible
              -> IO Adjustment
La función de creación necesita un valor para cada información contenida en el objeto:
valor Es el valor inicial y debe estar contenido entre el maximo y el mínimo.
máximo y mínimo fijan el margen del deslizador. Pulsando en las flechas
se incrementa el valor en incrementPaso. Pulsando en el deslizador (slider) avanza un 
incrementoPágina. El tamañoPágina se necesita para determinar si el final 
del deslizador se mantiene en el rango. Puedes conseguir y establecer todos los parámetros de un
Adjustment por métodos específicos o usando las funciones generales set y get 
en los atributos de Adjustment.
onValueChanged :: Adjustment -> IO () -> IO (ConnectId Adjustment)
es la señal emitida cuando el "valor" de un Adjustment cambia, y:
onAdjChanged :: Adjustment -> IO () -> IO (ConnectId Adjustment)
es la señal emitida cuando cambian uno o más de los otros atributos (diferentes de "valor") de un  Adjustment.
Los widgets de escalado se usan para permitir al usuario la selección visual y la manipulación del valor dentro de un rango especificado usando un deslizador. Podrías querer usar un widget escalable, por ejemplo, para ajustar el nivel de ampliación en una previsualización reducida de una imagen, o para controlar el brillo de un color o para especificar el número de minutos de inactividad antes de que un salvapantallas se active.
Las siguientes funciones crean widgets de escalado vertical y horizontal respectivamente:
vScaleNew :: Adjustment -> IO VScale hScaleNew :: Adjustment -> IO Hscale
También hay dos constructores, que no utilizan el Adjustment:
vScaleNewWithRange :: Double ->. Double -> Double -> IO VScale hScaleNewWithRange :: Double ->. Double -> Double -> IO Hscale
Los parámetros de tipo Double se refieren a los valores máximo, mínimo y el
paso. El incremento del paso (preferiblemente en potencias de 10) es el valor en que se
mueve la escala cuando se usan las teclas de cursor (flechas).
Las escalas horizontal y vertical son instancias de ScaleClass y 
su comportamiento común está definido en el módulo
Graphics.UI.Gtk.Abstract.Scale.
Los widgets de escalado pueden mostrar su valor actual como un número junto al canal. (El área donde se mueve el deslizador) El comportamiento por defecto es mostrar el valor, pero puedes modificarlo con la función:
scaleSetDrawValue :: ScaleClass self => self -> Bool -> IO ()
El valor mostrado por un widget de escalado se redondea en un punto decimal por defecto, igual que el ajuste del campo valor. Esto se puede cambiar con:
scaleSetDigits :: ScaleClass self => self -> Int -> IO ()
Finalmente, el valor puede ser dibujado en diferentes posiciones relativas al canal:
scaleSetValuePos :: ScaleClass self => self -> PositionType -> IO ()
La PositionType (tipo de posición) se define como:
data PositionType = PosLeft | PosRight | PosTop | PosBottom
Scale hereda diferentes métodos de su clase base que es: Range.
La política de actualizaciones de un widget rango define los puntos a los que, durante
la interacción con el usuario, cambiará el campo valor de su
Adjustment y emitirá la señal onRangeValueChanged 
de su Adjustment. La política de actualizaciones esta definida por el
UpdateType, que tiene tres constructores:
UpdateContinuous (Actualización continua )onRangeValueChanged se emite continuamente, 
  p.ej., cuando el deslizador se mueve un valor mínimo.
  UpdateDiscontinuous (Actualización discontinua)onRangeValueChanged sólo se emite cuando el deslizador se ha detenido
  y el usuario ha levantado el botón del ratón.
  UpdateDelayed (Actualización retrasada)onRangeValueChanged se emite cuando el usuario levanta el botón del
  ratón o si el deslizador se para de mover durante un corto periodo de tiempo.
  La política de actualizaciones de un widget range se puede establecer por:
rangeSetUpdatePolicy :: RangeClass self => self -> UpdateType -> IO ()
La obtención y el ajuste de un widget rango se hace sobre la marcha con:
rangeGetAdjustment :: RangeClass self => self -> IO Adjustment rangeSetAdjustment :: RangeClass self => self -> Adjustment -> IO ()
rangeSetAdjustment no hace nada si le pasas el objeto de Adjustment que ya está usando, 
independientemente de que alguno de los valores de sus atributos haya cambiado. 
Si le pasas un nuevo código de Adjustment, desconectará el antiguo, si existía
(posiblemente detruyéndolo), conectará las señales apropiadas al nuevo, y llamará a la función 
privada gtk_range_adjustment_changed(), que (o al menos se supone que...) recalculará
el tamaño y/o posición del deslizador y lo dibujará si fuera necesario.
Como se ha mencionado en la sección de ajustes, si quieres volver a usar el mismo Adjustment, 
cuando modificas sus valores directamente, deberías emitir la señal changed (cambiado) sobre él.
Todos los widgets de rango de Gtk2Hs reaccionan a las pulsaciones de ratón más 
o menos de la misma manera. Pulsando del botón 1 del ratón en el canal originará 
que el ajuste de incrementoPaso se añada o sustraiga de su valor,
y el deslizador se mueva de acuerdo a ello. Pulsando el botón 2 del ratón en el canal
moverá el deslizador al punto en que se pulsó el botón. Pulsando el tercer botón en el 
canal o en las flechas del scroll causará que el valor del Adjustment 
cambie en el valor de incrementoPaso.
Nota: Esto no funciona en Linux Fedora 6 con la configuración estándar del ratón.
No se puede hacer que las barras de scroll tengan el foco, así que no disponen de atajos de teclado. Para los otros widgets de rango, (que sólo están activos cuando el widget tiene el foco) no diferencian entre widgets de rango vertical u horizontal.
Todos los widgets de rango se pueden usar con las flechas de izquierda, derecha, arriba y abajo,
así como con las teclas AvPág y RePág. Las flechas mueven el 
deslizador arriba y abajo en incrementoPaso, mientras AvPág y 
RePág lo mueven en incrementoPágina. Inicio y Fin 
lo mueven al principio y al final del canal.
Este ejemplo crea una ventana con tres widgets de rango conectados al mismo objeto Adjustment,
y un par de controles para ajustar algunos de los parámetros mencionados antes, de modo
que puedas ver como afecta al modo en que dichos widgets trabajan.

Las tres escalas se sitúan de modo que la barra vertical está junto a las dos
horizontales, una sobre la otra. Así que necesitamos una caja horizontal para la escala vertical
y una caja vertical junto a ella para las escalas horizontales. Las escalas y las cajas 
deben empaquetarse con PackGrow de modo que las escalas actualicen su tamaño con el de
la caja principal, que es una caja vertical en la ventana.
Todas las escalas se construyen con el mismo Adjustment, estableciendo el valor inicial en 0.0, 
el valor mínimo en 0.0, el máximo en 101.0, el incremento del paso en 0.1, el incremento de
página en 1.0 y el tamaño de la página en 1.0.
adj1 <- adjustmentNew 0.0 0.0 101.0 0.1 1.0 1.0
El usuario puede controlar cuando se muestran los valores de escalado con un
checkButton. Esto se empaqueta en la caja principal y se establece
para estar activo inicialmente. Un botón check es un botón toggle, así que cuando 
el usuario lo marca o lo desmarca, se envía la señal onToggled. 
Esto origina que la función toggleDisplay 
se evalúe. La función toggleDisplay queda definida así:
toggleDisplay :: ScaleClass self => CheckButton -> [self] -> IO ()
toggleDisplay b scls = sequence_ (map change scls) where
                         change sc = do st <- toggleButtonGetActive b
                                        scaleSetDrawValue sc st
La función tiene un parámetro tipo checkButton, y una lista de instancias
de ScaleClass. Sin embargo, una lista sólo puede contener valores del mismo tipo,
y vScale y hScale son tipos diferentes. Por lo tanto, usamos la función
en listas de escalas horizontales o verticales, pero si la lista contuviera los dos tipos se originaría un 
error de tipado.
El usuario puede elegir el positionType mediante un widget del que todavía no hemos hablado, 
un ComboBox. Esto permite una selección de elecciones como se muestra más abajo. El primero en
establecerse como activo se determina por un índice, 0 aquí (el primero).
makeOpt1 :: IO ComboBox makeOpt1 = do cb <- comboBoxNewText comboBoxAppendText cb "TOP" comboBoxAppendText cb "BOTTOM" comboBoxAppendText cb "LEFT" comboBoxAppendText cb "RIGHT" comboBoxSetActive cb 0 return cb
Un segundo comboBox permite que el usuario seleccione la política de actualizaciones, 
alguno de los tres constructores de UpdateType.
makeOpt2 :: IO ComboBox makeOpt2 = do cb <- comboBoxNewText comboBoxAppendText cb "Continuous" comboBoxAppendText cb "Discontinuous" comboBoxAppendText cb "Delayed" comboBoxSetActive cb 0 return cb
Las cajas combo (Combo box) por si mismas sólo muestran texto. Para seleccionar la posición, definimos:
setScalePos :: ScaleClass self => ComboBox -> self -> IO ()
setScalePos cb sc = do
    ntxt <- comboBoxGetActiveText cb
    let pos = case ntxt of
                (Just "TOP")    -> PosTop
                (Just "BOTTOM") -> PosBottom
                (Just "LEFT")   -> PosLeft
                (Just "RIGHT")  -> PosRight
                Nothing         -> error "setScalePos: no position set"
    scaleSetValuePos sc pos
setUpdatePol :: RangeClass self => ComboBox -> self -> IO ()
setUpdatePol cb sc = do
    ntxt <- comboBoxGetActiveText cb
    let pol = case ntxt of
                (Just "Continuous")    -> UpdateContinuous
                (Just "Discontinuous") -> UpdateDiscontinuous
                (Just "Delayed")       -> UpdateDelayed
                Nothing                -> error "setUpdatePol: no policy set"
    rangeSetUpdatePolicy sc pol
Aquí no hemos usado listas para gestionar las escalas verticales y horizontales, así que accedemos por separado a cada escala horizontal.
El número de precisión mostrado por las tres escalas debe ser manejado con otra escala,
para la que usamos un nuevo objeto Adjustment. La precisión máxima es 5 y cada incremento es 1.
La precisión de la propia escala de control se establece a 1.
adj2 <- adjustmentNew 1.0 0.0 5.0 1.0 1.0 0.0
Cuando cambia el Adjustment de control, se emite la señal onValueChanged y se 
evalúa la función setDigits.
setDigits :: ScaleClass self => self -> Adjustment -> IO ()
setDigits sc adj = do val <- get adj adjustmentValue
                      set sc [scaleDigits := (round val)]
Aquí usamos las funciones generales set y get sobre los
atributos; podríamos haber usado funciones específicas también. fíjate en que el
valor de tipo Double del valor de ajuste, se debe redondear a un valor de
tipo Integral.
Usamos otra escala horizontal para gestionar el tamaño de página de las tres
escalas del ejemplo. Cuando lo ponemos a 0.0, las escalas pueden alcanzar su
máximo inicial de 100.0 y cuando lo ponemos a 100.0 las escalas quedan fijas 
en su menor valor. Esto implica el ajuste del 
adjustment por una señal de onValueChanged desde un tercer 
adjustment mediante este trozo de código:
  onValueChanged adj3 $ do val <- adjustmentGetValue adj3
                           adjustmentSetPageSize adj1 val
La función main es:
import Graphics.UI.Gtk
main :: IO ()
main = do
  initGUI
  window  <- windowNew
  set window [windowTitle := "range controls",
              windowDefaultWidth := 250]
  mainbox <- vBoxNew False 10
  containerAdd window mainbox
  containerSetBorderWidth mainbox 10
  box1 <- hBoxNew False 0
  boxPackStart mainbox box1 PackGrow 0
  adj1 <- adjustmentNew 0.0 0.0 101.0 0.1 1.0 1.0
  vsc  <- vScaleNew adj1
  boxPackStart box1 vsc PackGrow 0
  box2 <- vBoxNew False 0
  boxPackStart box1 box2 PackGrow 0
  hsc1 <- hScaleNew adj1
  boxPackStart box2 hsc1 PackGrow 0
  hsc2 <- hScaleNew adj1
  boxPackStart box2 hsc2 PackGrow 0
  chb <- checkButtonNewWithLabel "Display Value on Scale Widgets"
  boxPackStart mainbox chb PackNatural 10
  toggleButtonSetActive chb True
  box3   <- hBoxNew False 10
  boxPackStart mainbox box3 PackNatural 0
  label1 <- labelNew (Just "Scale Value Position:")
  boxPackStart box3 label1 PackNatural 0
  opt1   <- makeOpt1
  boxPackStart box3 opt1 PackNatural 0
  box4   <- hBoxNew False 10
  boxPackStart mainbox box4 PackNatural 0
  label2 <- labelNew (Just "Scale Update Policy:")
  boxPackStart box4 label2 PackNatural 0
  opt2   <- makeOpt2
  boxPackStart box4 opt2 PackNatural 0
  adj2 <- adjustmentNew 1.0 0.0 5.0 1.0 1.0 0.0
  box5   <- hBoxNew False 0
  containerSetBorderWidth box5 10
  boxPackStart mainbox box5 PackGrow 0
  label3 <- labelNew (Just "Scale Digits:")
  boxPackStart box5 label3 PackNatural 10
  dsc    <- hScaleNew adj2
  boxPackStart box5 dsc PackGrow 0
  scaleSetDigits dsc 0
  adj3 <- adjustmentNew 1.0 1.0 101.0 1.0 1.0 0.0
  box6   <- hBoxNew False 0
  containerSetBorderWidth box6 10
  boxPackStart mainbox box6 PackGrow 0
  label4 <- labelNew (Just "Scrollbar Page Size:")
  boxPackStart box6 label4 PackNatural 10
  psc    <- hScaleNew adj3
  boxPackStart box6 psc PackGrow 0
  scaleSetDigits psc 0
  onToggled chb $ do toggleDisplay chb [hsc1,hsc2]
                     toggleDisplay chb [vsc]
  onChanged opt1 $ do setScalePos opt1 hsc1
                      setScalePos opt1 hsc2
                      setScalePos opt1 vsc
  onChanged opt2 $ do setUpdatePol opt2 hsc1
                      setUpdatePol opt2 hsc2
                      setUpdatePol opt2 vsc
  onValueChanged adj2 $ do setDigits hsc1 adj2
                           setDigits hsc2 adj2
                           setDigits vsc  adj2
  onValueChanged adj3 $ do val <- adjustmentGetValue adj3
                           adjustmentSetPageSize adj1 val
  widgetShowAll window
  onDestroy window mainQuit
  mainGUI
Las funciones no estándar usadas en el listado ya han sido listadas antes.