Selection handler for color picker
First, Simplify the function to a pattern match form.

updateColorPickerState :: ColorPicker -&gt; (GLfloat, GLfloat) -&gt; Bool -&gt; ColorPicker              
updateColorPickerState c (x,y) mouseClicked = 
  case isPointWithinColorPicker c (x, y) of
    True -&gt; case mouseClicked of
      True -&gt; case state c of
        Opened -&gt; c {state = Idle, selectedColor = getColorAt (x',y')}
        _      -&gt; c {state = Opened}
      False -&gt; case state c of
        Opened -&gt; c
        _      -&gt; c {state = Hovered}
    False -&gt; case state c of
      Opened -&gt; case mouseClicked of
        True -&gt; c {state = Idle}
        _    -&gt; c
      _      -&gt; c {state = Idle}
  where
    (posX, posY) = pos c
    (sizeX, sizeY) = openedSize c
    x' = truncate ((x - posX) * 25 / sizeX)
    y' = truncate (((-y) - posY) * 11 / sizeY)


Then, convert case-based pattern matches to function-based pattern matches.

updateColorPickerState :: ColorPicker -&gt; (GLfloat, GLfloat) -&gt; Bool -&gt; ColorPicker              
updateColorPickerState c (x,y) mouseClicked
    | isPointWithinColorPicker c (x, y) = mouseInside (state c) mouseClicked
    | otherwise                         = mouseOutside (state c) mouseClicked
  where
    -- mouse is inside bounding box
    mouseInside Opened True  = c {state = Idle, selectedColor = getColorAt (x',y')}
    mouseInside Opened False = c
    mouseInside _      True  = c {state = Opened}
    mouseInside _      False = c {state = Hovered}
    -- mouse is outside bounding box
    mouseOutside Opened False = c
    mouseOutside _      _     = c {state = Idle}
    (posX, posY) = pos c
    (sizeX, sizeY) = openedSize c
    x' = truncate ((x - posX) * 25 / sizeX)
    y' = truncate (((-y) - posY) * 11 / sizeY)