-- ----------------------------------------------------------------------- -- -- $Source: /repository/uni/htk/canvasitems/CanvasTag.hs,v $ -- -- HTk - a GUI toolkit for Haskell - (c) Universitaet Bremen -- -- $Revision: 1.5 $ from $Date: 2001/12/10 21:29:27 $ -- Last modification by $Author: ludi $ -- -- ----------------------------------------------------------------------- module CanvasTag ( module CanvasItem, CanvasTag, TaggedCanvasItem(..), SearchSpec, allItems, aboveItem, belowItem, withTag, closest, enclosed, overlapping, createCanvasTag, addCanvasTag, removeCanvasTag ) where import Core import Canvas import CanvasItem import CanvasItemAux import Destructible import Synchronized import Computation import Geometry -- ----------------------------------------------------------------------- -- class TaggedCanvasItem -- ----------------------------------------------------------------------- --- -- A canvas item can have several tags (handlers for a set of canvas -- items). class CanvasItem w => TaggedCanvasItem w where --- -- Sets the tags for the specified canvas item. tags :: [CanvasTag] -> Config w tags cts item = mapM (\ct -> do CanvasItemName name tid <- getObjectName (toGUIObject ct) cset item "tag" (show tid)) cts >> return item -- ----------------------------------------------------------------------- -- tags -- ----------------------------------------------------------------------- --- -- The CanvasTag datatype. newtype CanvasTag = CanvasTag GUIOBJECT deriving Eq -- ----------------------------------------------------------------------- -- configuration options -- ----------------------------------------------------------------------- --- -- Constructs a new canvas tag. -- @param cnv - the parent canvas. -- @param cnf - the list of configuration options for this canvas tag. -- @return result - A canvas tag. createCanvasTag :: Canvas -> [Config CanvasTag] -> IO CanvasTag createCanvasTag cnv cnf = do wid <- createGUIObject (toGUIObject cnv) (CANVASITEM CANVASTAG []) tagMethods configure (CanvasTag wid) cnf -- ----------------------------------------------------------------------- -- instances -- ----------------------------------------------------------------------- {- instance Eq CanvasTag where w1 == w2 = (toGUIObject w1) == (toGUIObject w2) -} --- -- Internal. instance GUIObject CanvasTag where --- -- Internal. toGUIObject (CanvasTag wid) = wid --- -- Internal. cname _ = "CanvasTag" --- -- A canvas tag can be destroyed. instance Destroyable CanvasTag where --- -- Destroys a canvas tag. destroy = destroy . toGUIObject --- -- A canvas tag is a canvas item (any canvas item is an instance of the -- abstract class CanvasItem). instance CanvasItem CanvasTag --- -- You can synchronize on a canvas tag. instance Synchronized CanvasTag where --- -- Synchronizes on a canvas tag. synchronize w = synchronize (toGUIObject w) -- ----------------------------------------------------------------------- -- commands -- ----------------------------------------------------------------------- --- -- Adds the canvas items identified by the SearchSpec to -- the tag. -- @param spec - the search specification. -- @param tag - the tag to add items to. -- @return result - None. addCanvasTag :: SearchSpec -> CanvasTag -> IO () addCanvasTag spec@(SearchSpec cmd) tag = do spec' <- cmd execMethod tag (\tnm -> tkAddTag tnm spec') --- -- Removes a canvas item from a canvas tag. -- @param item - the item to remove from the tag. -- @param tag - the tag to remove the item from. -- @return result - None. removeCanvasTag :: CanvasItem i => i -> CanvasTag -> IO () removeCanvasTag item tag = do tnm <- getObjectName (toGUIObject tag) execMethod item (\cnm -> tkDTag cnm tnm) -- ----------------------------------------------------------------------- -- SearchSpec -- ----------------------------------------------------------------------- --- -- The SearchSpec datatype -- (see CanvasTag.addCanvasTag). data SearchSpec = SearchSpec (IO String) --- -- Adds all objects in the canvas. -- @return result - A SearchSpec object. allItems :: SearchSpec allItems = SearchSpec (return "all") --- -- Adds the item just above the given item in the display list. -- @param item - the item below the item to add. -- @return result - A SearchSpec object. aboveItem :: CanvasItem item => item -> SearchSpec aboveItem item = SearchSpec (do { tid <- getCanvasTagOrID (toGUIObject item); return ("above [" ++ declVar tid ++ "; list " ++ show tid ++ "]") }) --- -- Adds the item just below in the given item in the display list. -- @param item - the item above the item to add. -- @return result - A SearchSpec object. belowItem :: CanvasItem item => item -> SearchSpec belowItem item = SearchSpec (do { tid <- getCanvasTagOrID (toGUIObject item); return ("below [" ++ declVar tid ++ "; list " ++ show tid ++ "]") }) --- -- Adds the item(s) identified by the given handler (which can also be -- another canvas tag). -- @param item - the canvas item handler. -- @return result - A SearchSpec object. withTag :: CanvasItem item => item -> SearchSpec withTag item = SearchSpec (do { tid <- getCanvasTagOrID (toGUIObject item); return ("withtag [" ++ declVar tid ++ "; list " ++ show tid ++ "]") }) --- -- Adds the item closest to the given position. -- @param pos - the concerned position. -- @return result - A SearchSpec object. closest :: Position -> SearchSpec closest pos@(x, y) = SearchSpec (return ("closest " ++ show x ++ " " ++ show y)) --- -- Adds the items enclosed in the specified region. -- @param pos1 - the upper left position of the region. -- @param pos2 - the lower right position of the region. -- @return result - A SearchSpec object. enclosed :: Position -> Position -> SearchSpec enclosed pos1 pos2 = SearchSpec (return ("enclosed " ++ show pos1 ++ " " ++ show pos2)) --- -- Adds the items overpalling the specified region. -- @param pos1 - the upper left position of the region. -- @param pos2 - the lower right position of the region. -- @return result - A SearchSpec object. overlapping :: Position -> Position -> SearchSpec overlapping pos1 pos2 = SearchSpec (return ("overlapping " ++ show pos1 ++ " " ++ show pos2)) getCanvasTagOrID :: GUIOBJECT -> IO CanvasTagOrID getCanvasTagOrID wid = do nm <- getObjectName wid case nm of CanvasItemName name tid -> return tid _ -> error "CanvasTag (getCanvasTagOrID) : not a canvas item name" -- ----------------------------------------------------------------------- -- methods -- ----------------------------------------------------------------------- tagMethods = canvasitemMethods {createCmd = tkCreateTag} -- ----------------------------------------------------------------------- -- unparsing of commands -- ----------------------------------------------------------------------- tkCreateTag :: ObjectName -> ObjectKind -> ObjectName -> ObjectID -> [ConfigOption] -> TclScript tkCreateTag _ (CANVASITEM CANVASTAG []) (CanvasItemName name tid) oid _ = [declVar tid, " set " ++ vname ++ " t" ++ show oid] where vname = (drop 1 (show tid)) tkAddTag :: ObjectName -> String -> TclScript tkAddTag (CanvasItemName name tid) spec = [declVar tid, show name ++ " addtag " ++ show tid ++ " " ++ spec] tkDTag :: ObjectName -> ObjectName -> TclScript tkDTag (CanvasItemName name cid) (CanvasItemName _ tid) = [declVar tid, declVar cid, show name ++ " dtag " ++ show cid ++ " " ++ show tid] declVar :: CanvasTagOrID -> TclCmd declVar tid = "global " ++ (drop 1 (show tid))