----------------------------------------------------------------------------- -- | -- Module : FRP.UISF.Graphics.Color -- Copyright : (c) Daniel Winograd-Cort 2015 -- License : see the LICENSE file in the distribution -- -- Maintainer : dwc@cs.yale.edu -- Stability : experimental {-# LANGUAGE BangPatterns, FlexibleInstances, TypeSynonymInstances #-} module FRP.UISF.Graphics.Color ( Color(..), RGB, colorToRGB, rgb, rgbE, extractRGB, ) where import Data.Ix (Ix) import Control.DeepSeq -- | We provide a data type for colors to allow users to easily -- and clearly specify common colors. Primary and secondary -- RGB colors are represented along with a few beige colors for use -- in many GUI elements. data Color = Black | Blue | Green | Cyan | Red | Magenta | Yellow | White | Gray | VLightBeige | LightBeige -- ^ This is the default background color for the UI window. | MediumBeige | DarkBeige deriving (Eq, Ord, Bounded, Enum, Ix, Show, Read) instance NFData Color where rnf (!_) = () -- | RGB can be used to specify colors more precisely. Create them with -- one of the two smart constructors 'rgb' or 'rgbE'. newtype RGB = RGB (Int, Int, Int) deriving (Eq) instance Show RGB where show (RGB (r, g, b)) = "{R="++show r++",G="++show g++",B="++show b++"}" instance NFData RGB where rnf (RGB rgb) = rnf rgb -- | Generally used as an internal function for converting Color to RGB, -- but can be used by anyone. colorToRGB :: Color -> RGB colorToRGB Black = RGB (0, 0, 0) colorToRGB Blue = RGB (0, 0, 255) colorToRGB Green = RGB (0, 255, 0) colorToRGB Cyan = RGB (0, 255, 255) colorToRGB Red = RGB (255, 0, 0) colorToRGB Magenta = RGB (255, 0, 255) colorToRGB Yellow = RGB (255, 255, 0) colorToRGB White = RGB (255, 255, 255) colorToRGB Gray = RGB (128, 128, 128) colorToRGB VLightBeige = rgbE 0xf1 0xef 0xe2 colorToRGB LightBeige = rgbE 0xec 0xe9 0xd8 colorToRGB MediumBeige = rgbE 0xac 0xa8 0x99 colorToRGB DarkBeige = rgbE 0x71 0x6f 0x64 -- In previous versions, there was a color called "blue3". -- blue3 = rgbE 0x31 0x3c 0x79 --dark slate blue -- | This function takes three integral values between 0 and 255 -- inclusive and create an RGB value with them. If any of the -- values fall outside the acceptable range, Nothing is returned. rgb :: (Integral r, Integral g, Integral b) => r -> g -> b -> Maybe RGB rgb r g b = do r' <- bound r g' <- bound g b' <- bound b return $ RGB (r',g',b') where bound :: (Integral i, Integral o) => i -> Maybe o bound i = if i > 255 || i < 0 then Nothing else Just (fromIntegral i) -- | This is a version of 'rgb' that throws an error when a given -- value falls outside the acceptable 0-255 range. The error message -- shows the bad input, so the extra Show constraint is necessary. rgbE :: (Integral r, Integral g, Integral b, Show r, Show g, Show b) => r -> g -> b -> RGB rgbE r g b = case rgb r g b of Just x -> x Nothing -> error $ "Invalid values given to rgbE: " ++ show (r,g,b) -- | Use this to extract the values from an RGB color. extractRGB :: (Integral r, Integral g, Integral b) => RGB -> (r,g,b) extractRGB (RGB (r, g, b)) = (fromIntegral r, fromIntegral g, fromIntegral b)