-- | This module provides functionality on the current focus. module HTk.Components.Focus ( CurrentFocus, FocusModel(..), focusModel, getFocusModel, getFocus, setFocus, forceFocus, getRecentFocus, GrabStatus(..), CurrentGrab(..), grabLocal, grabGlobal, releaseGrab, returnGrab, getGrabStatus, getCurrentGrab ) where import HTk.Kernel.Core import HTk.Kernel.BaseClasses(Widget) import Data.Char(isSpace) import Util.Computation import HTk.Containers.Window -- ----------------------------------------------------------------------- -- Grab Status -- ----------------------------------------------------------------------- -- | The @GrabStatus@ datatype. data GrabStatus = Local | Global deriving (Eq,Ord,Enum) -- ----------------------------------------------------------------------- -- instantiations -- ----------------------------------------------------------------------- -- | Internal. instance GUIValue GrabStatus where cdefault = Local -- | Internal. instance Read GrabStatus where readsPrec p b = case dropWhile (isSpace) b of 'l':'o':'c':'a':'l':xs -> [(Local,xs)] 'g':'l':'o':'b':'a':'l':xs -> [(Global,xs)] _ -> [] -- | Internal. instance Show GrabStatus where showsPrec d p r = (case p of Local -> "local" Global -> "global") ++ r -- ----------------------------------------------------------------------- -- current grab -- ----------------------------------------------------------------------- -- | The @CurrentGrab@ datatype. data CurrentGrab = CurrentGrab GUIOBJECT deriving Eq -- ----------------------------------------------------------------------- -- instantiations -- ----------------------------------------------------------------------- -- | Internal. instance Object CurrentGrab where objectID (CurrentGrab obj) = objectID obj -- | Internal. instance GUIObject CurrentGrab where toGUIObject (CurrentGrab obj) = obj cname _ = "" -- | The current grab has standard widget properties -- (concerning focus, cursor). instance Widget CurrentGrab -- ----------------------------------------------------------------------- -- window grabs -- ----------------------------------------------------------------------- -- | Grabs the focus local. grabLocal :: Widget w => w -- ^ the concerned widget. -> IO () -- ^ None. grabLocal wid = execMethod wid (\name -> [tkGrabLocal name]) -- | Grabs the focus global. grabGlobal :: Widget w => w -- ^ the concerned widget. -> IO () -- ^ None. grabGlobal wid = execMethod wid (\name -> ["grab set -global " ++ show name]) -- | Releases a focus grab. releaseGrab :: Widget w => w -- ^ the concerned widget. -> IO () -- ^ None. releaseGrab wid = execMethod wid (\name -> ["grab release " ++ show name]) -- | Gets the grab status from a widget. getGrabStatus :: Widget w => w -- ^ the concerned widget. -> IO (Maybe GrabStatus) -- ^ The current grab status (if available). getGrabStatus wid = do (RawData str) <- evalMethod wid (\nm -> ["grab status " ++ show nm]) case dropWhile isSpace str of ('n':'o':'n':'e':_) -> return Nothing s -> do {v <- creadTk s; return (Just v)} -- | Gets the current grab. getCurrentGrab :: IO (Maybe CurrentGrab) -- ^ The current grab (if available). getCurrentGrab = evalTclScript ["grab current "] >>= toCurrentGrab . WidgetName returnGrab :: Maybe CurrentGrab -> IO () returnGrab Nothing = done returnGrab (Just g) = execMethod g (\name -> [tkGrabLocal name]) toCurrentGrab :: WidgetName -> IO (Maybe CurrentGrab) toCurrentGrab name = do { obj <- lookupGUIObjectByName name; case obj of Nothing -> return Nothing (Just o) -> (return . Just . CurrentGrab) o } -- ----------------------------------------------------------------------- -- Tk Commands -- ----------------------------------------------------------------------- tkGrabLocal :: ObjectName -> TclCmd tkGrabLocal name = "grab set " ++ show name {-# INLINE tkGrabLocal #-} -- ----------------------------------------------------------------------- -- FocusModel -- ----------------------------------------------------------------------- -- | The @FocusModel@ datatype (focus model of a toplevel -- window). data FocusModel = ActiveFocus | PassiveFocus deriving (Eq,Ord,Enum) -- | Internal. instance GUIValue FocusModel where cdefault = PassiveFocus -- | Internal. instance Read FocusModel where readsPrec p b = case dropWhile (isSpace) b of 'a':'c':'t':'i':'v':'e':xs -> [(ActiveFocus,xs)] 'p':'a':'s':'s':'i':'v':'e':xs -> [(PassiveFocus,xs)] _ -> [] -- | Internal. instance Show FocusModel where showsPrec d p r = (case p of ActiveFocus -> "active" PassiveFocus -> "passive" ) ++ r -- ----------------------------------------------------------------------- -- window focus -- ----------------------------------------------------------------------- -- | Sets a window\'s focus model. focusModel :: Window w => FocusModel -> Config w focusModel fm win = cset win "focusmodel" fm -- | Gets a window\'s focus model. getFocusModel :: Window w => w -> IO FocusModel getFocusModel win = cget win "focusmodel" -- ----------------------------------------------------------------------- -- current focus -- ----------------------------------------------------------------------- -- | The @CurrentFocus@ datatype. data CurrentFocus = CurrentFocus GUIOBJECT -- ----------------------------------------------------------------------- -- instantiations -- ----------------------------------------------------------------------- -- | Internal. instance Object CurrentFocus where objectID (CurrentFocus obj) = objectID obj -- | Internal. instance GUIObject CurrentFocus where toGUIObject (CurrentFocus obj) = obj cname _ = "" -- | The current focus is always a widget and has standard widget properties -- (concerning focus, cursor). instance Widget CurrentFocus -- ----------------------------------------------------------------------- -- input focus -- ----------------------------------------------------------------------- -- | Gets the current focus inside a window. getFocus :: Window w => w -- ^ the concerned window. -> IO (Maybe CurrentFocus) -- ^ The current focus (if available). getFocus win = evalMethod win (\wn -> ["focus -displayof " ++ show wn]) >>= toCurrentFocus . WidgetName -- | Sets the current for the containing window. setFocus :: Widget w => w -- ^ The widget to focus. -> IO () -- ^ None. setFocus w = execMethod w (\wn -> ["focus " ++ show wn]) -- | Forces the current focus for the containing window. forceFocus :: Widget w => w -- ^ The widget to focus. -> IO () -- ^ None. forceFocus w = execMethod w (\wn -> ["focus -force " ++ show wn]) -- | Gets the last focused widget inside a window. getRecentFocus :: Window w => w -- ^ the concerned window. -> IO (Maybe CurrentFocus) -- ^ The recent focus (if available). getRecentFocus w = evalMethod w (\wn -> ["focus -lastfor " ++ show wn]) >>= toCurrentFocus . WidgetName toCurrentFocus :: WidgetName -> IO (Maybe CurrentFocus) toCurrentFocus name = do obj <- lookupGUIObjectByName name case obj of Nothing -> return Nothing (Just o) -> (return . Just . CurrentFocus) o