{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE OverlappingInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} -- | Basic types and classes concerning toplevel window resources. module HTk.Containers.Window ( Window(..), Display, maxSize, getMaxSize, minSize, getMinSize, raiseWin, lowerWin, WindowState(..), AspectRatio, Whom, isWMConfig, ) where import Util.Computation import HTk.Kernel.Geometry import HTk.Kernel.Configuration import HTk.Kernel.Core import Data.Char type Display = String -- ----------------------------------------------------------------------- -- class Window -- ----------------------------------------------------------------------- -- | Toplevel windows instantiate the @class Window@. class GUIObject w => Window w where -- Iconifies the window. iconify :: w -> IO () -- Deiconifies the window. deiconify :: w -> IO () -- Withdraws the window. withdraw :: w -> IO () -- Puts the window on top. putWinOnTop :: w -> IO () -- Puts the window at bottom. putWinAtBottom :: w -> IO () -- Sets the screen for this window. screen :: Display -> Config w -- Gets the screen from this window. getScreen :: w -> IO (Display) -- Returns the resource class of the given window. getClassName :: w -> IO String -- Gets the current window state. getWindowState :: w -> IO WindowState -- Sets the aspect ratio for the given window. aspectRatio :: AspectRatio -> Config w -- Gets the aspect ratio of the given window. getAspectRatio :: w -> IO AspectRatio -- Set \'@Whom@\' to be @Program@ or -- @User@. positionFrom :: Whom -> Config w -- Gets the current setting. getPositionFrom :: w -> IO Whom -- Set \'@Whom@\' to be @Program@ or sizeFrom :: Whom -> Config w -- Gets the current setting. getSizeFrom :: w -> IO Whom iconify win = cset win "state" Iconified >> done deiconify win = do {cset win "state" Deiconified; done} withdraw win = do {cset win "state" Withdrawn; done} putWinOnTop win = execMethod win (\nm -> [tkPutOnTop nm]) putWinAtBottom win = execMethod win (\nm -> [tkPutAtBottom nm]) screen "" win = cset win "screen" ":0.0" screen scr win = cset win "screen" scr getScreen win = cget win "screen" getClassName win = evalMethod win (\nm -> [tkWInfoClass nm]) getWindowState win = cget win "state" aspectRatio ratio win = cset win "aspect" ratio getAspectRatio win = cget win "aspect" positionFrom w win = cset win "positionfrom" w getPositionFrom win = cget win "positionfrom" sizeFrom w win = cset win "sizefrom" w getSizeFrom win = cget win "sizefrom" -- ----------------------------------------------------------------------- -- instances -- ----------------------------------------------------------------------- -- | A window has a configureable size and anchor position (geometry). instance Window w => HasGeometry w where -- Sets the window\'s geometry. geometry g win = cset win "geometry" g -- Gets the current geometry of the given window. getGeometry win = cget win "geometry" -- | A window has a configureable size. instance Window w => HasSize w where -- Sets the window\'s width. width w win = getGeometry win >>= \(_,h,x,y) -> geometry (w,h,x,y) win -- Gets the window\'s width. getWidth win = getGeometry win >>= \ (w,_,_,_) -> return w -- Sets the window\'s height. height h win = getGeometry win >>= \(w,_,x,y) -> geometry (w,h,x,y) win -- Gets the window\'s height. getHeight win = do (_,h,_, _) <- getGeometry win return h -- Sets the window\'s width and height. size (w,h) win = do (_,_,x,y) <- getGeometry win geometry (w,h,x,y) win -- Gets the window\'s width and height. getSize win = getGeometry win >>= \(w,h,_,_) -> return (w,h) -- | A window has a position on the associated screen. instance Window w => HasPosition w where -- Sets the window\'s position- position (x,y) win = do (w, h, _, _) <- getGeometry win geometry (w, h, x, y) win -- Gets the window\'s position. getPosition win = do (_, _, x, y) <- getGeometry win return (x, y) -- | A window has a title. instance (Window w, GUIValue v) => HasText w v where -- Sets the window\'s title. text s win = cset win "iconname" s >> cset win "title" s -- Gets the window\'s title. getText win = cget win "title" -- ----------------------------------------------------------------------- -- maximum and minimum size's -- ----------------------------------------------------------------------- -- | Constraints the maximum size of the window. maxSize :: Window w => Size -> Config w maxSize s win = cset win "maxsize" s -- | Gets the maximum size of the window. getMaxSize :: Window w => w -> IO Size getMaxSize win = cget win "maxsize" -- | Constraints the minimum size of the window. minSize :: Window w => Size -> Config w minSize s win = cset win "minsize" s -- | Gets the minimum size of the window. getMinSize :: Window w => w -> IO Size getMinSize win = cget win "minsize" -- ----------------------------------------------------------------------- -- stack order -- ----------------------------------------------------------------------- -- | Puts the first given window just above the second given window -- in the stacking order. raiseWin :: (Window w1, Window w2) => w1 -- ^ the first window. -> w2 -- ^ the second window. -> IO () -- ^ None. raiseWin win1 win2 = do nm2 <- getObjectName (toGUIObject win2) execMethod win1 (\nm1 -> [tkRaise nm1 nm2]) -- | Puts the first given window just below the second given window -- in the stacking order. lowerWin :: (Window w1, Window w2) => w1 -- ^ the first window. -> w2 -- ^ the second window. -> IO () -- ^ None. lowerWin win1 win2 = do nm2 <- getObjectName (toGUIObject win2) execMethod win1 (\nm1 -> [tkLower nm1 nm2]) -- ----------------------------------------------------------------------- -- WindowState -- ----------------------------------------------------------------------- -- | The @WindowState@ datatype. data WindowState = Deiconified | Iconified | Withdrawn deriving (Eq,Ord,Enum) -- | Internal. instance GUIValue WindowState where cdefault = Deiconified -- | Internal. instance Read WindowState where readsPrec p b = case dropWhile (isSpace) b of 'n':'o':'r':'m':'a':'l':xs -> [(Deiconified,xs)] 'i':'c':'o':'n':'i':'c':xs -> [(Iconified,xs)] 'w':'i':'t':'h':'d':'r':'a':'w':xs -> [(Withdrawn,xs)] _ -> [] -- | Internal. instance Show WindowState where showsPrec d p r = (case p of Deiconified -> "deiconify" Iconified -> "iconic" Withdrawn -> "withdraw") ++ r -- ----------------------------------------------------------------------- -- AspectRatio -- ----------------------------------------------------------------------- -- | The @AspectRatio@ datatype. data AspectRatio = AspectRatio Int Int Int Int deriving Eq -- | Internal. instance GUIValue AspectRatio where cdefault = AspectRatio 0 0 0 0 toGUIValue v = GUIVALUE HaskellTk (show v) maybeGUIValue (GUIVALUE _ s) = case [x | (x,t) <- reads s, ("","") <- lex t] of [x] -> Just x _ -> Nothing -- | Internal. instance Show AspectRatio where showsPrec d c r = cshow c ++ r where cshow (AspectRatio xt yt xf yf) = (show xt) ++ " " ++ (show yt) ++ " " ++ (show xf) ++ " " ++ (show yf) -- | Internal. instance Read AspectRatio where readsPrec p str = [(cread str,[])] where cread str = AspectRatio (read xt) (read yt) (read xf) (read yf) [xt,yt,xf,yf] = words str -- ----------------------------------------------------------------------- -- Whom -- ----------------------------------------------------------------------- -- | The @Whom@ datatype. data Whom = Program | User deriving (Eq,Ord,Enum) -- | Internal. instance GUIValue Whom where cdefault = Program -- | Internal. instance Read Whom where readsPrec p b = case dropWhile (isSpace) b of 'u':'s':'e':'r':xs -> [(User,xs)] 'p':'r':'o':'g':'r':'a':'m':xs -> [(Program,xs)] _ -> [] -- | Internal. instance Show Whom where showsPrec d p r = (case p of Program -> "program" User -> "user") ++ r -- ----------------------------------------------------------------------- -- auxiliary functions -- ----------------------------------------------------------------------- -- | Internal. isWMConfig :: ConfigID -> Bool isWMConfig "state" = True isWMConfig "geometry" = True isWMConfig "minsize" = True isWMConfig "maxsize" = True isWMConfig "aspect" = True isWMConfig "sizefrom" = True isWMConfig "positionfrom" = True isWMConfig "title" = True isWMConfig "transient" = True isWMConfig "group" = True isWMConfig "iconname" = True isWMConfig "iconbitmap" = True isWMConfig "iconposition" = True isWMConfig "iconmask" = True isWMConfig "focusmodel" = True isWMConfig _ = False -- ----------------------------------------------------------------------- -- unparsing of commands -- ----------------------------------------------------------------------- tkWInfoClass :: ObjectName -> TclCmd tkWInfoClass nm = "winfo class " ++ show nm {-# INLINE tkWInfoClass #-} tkPutOnTop :: ObjectName -> TclCmd tkPutOnTop win = "raise " ++ show win {-# INLINE tkPutOnTop #-} tkPutAtBottom :: ObjectName -> TclCmd tkPutAtBottom win = "lower " ++ show win {-# INLINE tkPutAtBottom #-} tkRaise :: ObjectName -> ObjectName -> TclCmd tkRaise win1 win2 = "raise " ++ show win1 ++ " " ++ show win2 {-# INLINE tkRaise #-} tkLower :: ObjectName -> ObjectName -> TclCmd tkLower win1 win2 = "lower " ++ show win1 ++ " " ++ show win2 {-# INLINE tkLower #-}