-- ----------------------------------------------------------------------- -- -- $Source: /repository/uni/htk/canvasitems/CanvasItem.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 $ -- -- ----------------------------------------------------------------------- --- -- The module CanvasItem exports basic classes and -- general functionality on canvas items. module CanvasItem ( Canvas, BitMapHandle(..), BitMap, HasCoords(..), CanvasItem, FilledCanvasItem(..), SegmentedCanvasItem(..), moveItem, scaleItem, raiseItem, lowerItem, putItemOnTop, putItemAtBottom, itemsNotOnSameCanvas ) where import Core import Configuration import Geometry import Colour import Image import BitMap import Canvas import Char(isSpace) import Computation import Synchronized -- ----------------------------------------------------------------------- -- class CanvasItem, etc. -- ----------------------------------------------------------------------- --- -- Any canvas item is an instance of the abstract -- class CanvasItem. class GUIObject w => CanvasItem w --- -- You can set the coords (position / size) of a canvas item on the -- parent canvas. class HasCoords w where --- -- Sets the coord(s) of a canvas item on the parent canvas. coord :: Coord -> Config w --- -- Gets the coord(s) of a canvas item on the parent canvas. getCoord :: w -> IO Coord --- -- Any canvas item has coords on the parent canvas. instance CanvasItem w => HasCoords w where --- -- Sets the coord(s) of a canvas item on the parent canvas. coord co item = do try (execMethod item (\nm -> tkCoordItem nm co)) return item --- -- Gets the coord(s) of a canvas item on the parent canvas. getCoord item = evalMethod item (\nm -> tkGetCoordItem nm) --- -- Any canvas item has a filling, outline, outline width and stipple -- configuration. class CanvasItem w => FilledCanvasItem w where --- -- Sets the filling of a canvas item. filling :: ColourDesignator c => c -> Config w --- -- Gets the filling of a canvas item. getFilling :: w -> IO Colour --- -- Sets the outline colour of a canvas item. outline :: ColourDesignator c => c -> Config w --- -- Gets the outline colour of a canvas item. getOutline :: w -> IO Colour --- -- Sets the stipple configuration of a canvas item. stipple :: BitMapHandle -> Config w --- -- Gets the stipple configuration of a canvas item. getStipple :: w -> IO BitMapHandle --- -- Sets the outline width of a canvas item. outlinewidth :: Distance -> Config w --- -- Gets the outline width of a canvas item. getOutlineWidth :: w -> IO Distance filling c w = cset w "fill" (toColour c) getFilling w = cget w "fill" outline c w = cset w "outline" (toColour c) getOutline w = cget w "outline" stipple b w = setBitMapHandle w "stipple" b True getStipple w = getBitMapHandle w "stipple" outlinewidth b w = cset w "width" b getOutlineWidth w = cget w "width" --- -- Segmented canvas items have a splinesteps and smooth configuration. class CanvasItem w => SegmentedCanvasItem w where --- -- Sets the number of line segments that approximate the spline. splinesteps :: Int -> Config w --- -- Gets the number of line segments that approximate the spline. getSplinesteps :: w -> IO Int --- -- Sets the smooth configuration (if true a spline curve is -- drawn around the points). smooth :: Bool -> Config w --- -- Gets the actual smooth setting. getSmooth :: w -> IO Bool splinesteps c w = cset w "splinesteps" c getSplinesteps w = cget w "splinesteps" smooth c w = cset w "smooth" c getSmooth w = cget w "smooth" -- ----------------------------------------------------------------------- -- canvas item operations -- ----------------------------------------------------------------------- --- -- Moves a canvas item horizontally and vertically by the given -- distances. moveItem :: (Synchronized w, CanvasItem w) => w -> Distance -> Distance -> IO () moveItem item x y = synchronize item (execMethod item (\nm -> tkMoveItem nm x y)) --- -- Scales a canvas item horizontally and vertically by the given -- distances. scaleItem :: (Synchronized w, CanvasItem w) => w -> Distance -> Distance -> Double -> Double -> IO () scaleItem item x y xs ys = synchronize item (execMethod item (\nm -> tkScaleItem nm x y xs ys)) -- ----------------------------------------------------------------------- -- layering operations -- ----------------------------------------------------------------------- --- -- Moves an item above another item in the display list. raiseItem :: (CanvasItem ci,CanvasItem w) => ci -> w -> IO () raiseItem item1 item2 = do onSameCanvas item1 item2 nm2 <- getObjectName (toGUIObject item2) execMethod item1 (\nm1 -> tkRaiseItem nm1 (Just nm2)) --- -- Moves an item below another item in the display list. lowerItem :: (CanvasItem ci,CanvasItem w) => ci -> w -> IO () lowerItem item1 item2 = do onSameCanvas item1 item2 nm2 <- getObjectName (toGUIObject item2) execMethod item1 (\nm1 -> tkLowerItem nm1 (Just nm2)) --- -- Puts an item on top of the display list. putItemOnTop :: CanvasItem w => w -> IO () putItemOnTop item = execMethod item (\nm -> tkRaiseItem nm Nothing) --- -- Puts an items at bottom of the display list. putItemAtBottom :: CanvasItem ci => ci -> IO () putItemAtBottom item = execMethod item (\nm -> tkLowerItem nm Nothing) -- ----------------------------------------------------------------------- -- utility -- ----------------------------------------------------------------------- --- -- Raises an exception if two given items do not have the same parent -- canvas. onSameCanvas :: (CanvasItem i1,CanvasItem i2) => i1 -> i2 -> IO () onSameCanvas i1 i2 = do c1 <- getParentObjectID (toGUIObject i1) c2 <- getParentObjectID (toGUIObject i2) unless (c1 == c2) (raise itemsNotOnSameCanvas) --- -- Exception raised by CanasItem.onSameCanvas. itemsNotOnSameCanvas :: IOError itemsNotOnSameCanvas = userError "the two canvas items are not on the same canvas" -- ----------------------------------------------------------------------- -- unparsing of commands -- ----------------------------------------------------------------------- tkMoveItem :: ObjectName -> Distance -> Distance -> TclScript tkMoveItem (CanvasItemName nm item) x y = [declVar item, show nm ++ " move " ++ show item ++ " " ++ show x ++ " " ++ show y {-, show nm ++ " coords " ++ show item-}] tkMoveItem _ _ _ = [] {-# INLINE tkMoveItem #-} tkScaleItem :: ObjectName -> Distance -> Distance -> Double -> Double -> TclScript tkScaleItem (CanvasItemName nm item) x y xs ys = [declVar item, show nm ++ " scale " ++ show item ++ " " ++ show x ++ " " ++ show y ++ " " ++ show xs ++ " " ++ show ys, show nm ++ " coords " ++ show item] tkScaleItem _ _ _ _ _ = [] {-# INLINE tkScaleItem #-} tkCoordItem :: ObjectName -> Coord -> TclScript tkCoordItem (CanvasItemName nm item) co = [declVar item, show nm ++ " coords " ++ show item ++ " " ++ show (toGUIValue co)] tkCoordItem _ _ = [] {-# INLINE tkCoordItem #-} tkGetCoordItem :: ObjectName -> TclScript tkGetCoordItem (CanvasItemName nm item) = [declVar item, show nm ++ " coords " ++ show item] tkGetCoordItem _ = [] tkRaiseItem :: ObjectName -> Maybe ObjectName -> TclScript tkRaiseItem (CanvasItemName nm item) Nothing = [declVar item, show nm ++ " raise " ++ show item] tkRaiseItem (CanvasItemName nm item1) (Just (CanvasItemName _ item2)) = [declVar item1, declVar item2, show nm ++ " raise " ++ show item1 ++ " " ++ show item2] tkRaiseItem _ _ = [] {-# INLINE tkRaiseItem #-} tkLowerItem :: ObjectName -> Maybe ObjectName -> TclScript tkLowerItem (CanvasItemName nm item) Nothing =[ declVar item,show nm ++ " lower " ++ show item] tkLowerItem (CanvasItemName nm item1) (Just (CanvasItemName _ item2)) = [declVar item1, declVar item2, show nm ++ " lower " ++ show item1 ++ " " ++ show item2] tkLowerItem _ _ = [] {-# INLINE tkLowerItem #-} declVar tid = "global " ++ (drop 1 (show tid))