-- -----------------------------------------------------------------------
--
-- $Source: /repository/uni/htk/widgets/Canvas.hs,v $
--
-- HTk - a GUI toolkit for Haskell - (c) Universitaet Bremen
--
-- $Revision: 1.9 $ from $Date: 2001/12/30 16:31:49 $
-- Last modification by $Author: ludi $
--
-- -----------------------------------------------------------------------
---
-- HTk's canvas widget.
-- A canvas is a drawing pad, that can also contain widgets in embedded
-- windows.
-- A canvas widget contains canvas items.
module Canvas (
HasPostscript(..), -- TD: ps export
ScrollBar,
HasScroller(..),
ScrollUnit,
Canvas,
newCanvas,
closeEnough,
getCloseEnough,
confine,
getConfine,
screenToCanvasCoord,
ScrollRegion,
scrollRegion,
getScrollRegion,
scrollIncrement,
-- getScrollIncrementer
) where
import Core
import BaseClasses(Widget)
import Configuration
import Resources
import Geometry
import Image
import ScrollBar
import Printer
import Computation
import Destructible
import Synchronized
import Packer
import Tooltip
-- -----------------------------------------------------------------------
-- canvas
-- -----------------------------------------------------------------------
---
-- The Canvas datatype.
newtype Canvas = Canvas GUIOBJECT deriving Eq
-- -----------------------------------------------------------------------
-- constructor
-- -----------------------------------------------------------------------
---
-- Constructs a new canvas widget and returns a handler.
-- @param par - the parent widget, which has to be a container widget
-- (an instance of class Container).
-- @param cnf - the list of configuration options for this canvas.
-- @return result - A canvas widget.
newCanvas :: Container par => par -> [Config Canvas] -> IO Canvas
newCanvas par cnf = do
w <- createGUIObject (toGUIObject par) CANVAS canvasMethods
configure (Canvas w) cnf
-- -----------------------------------------------------------------------
-- instances
-- -----------------------------------------------------------------------
---
-- Internal.
instance GUIObject Canvas where
---
-- Internal.
toGUIObject (Canvas w) = w
---
-- Internal.
cname _ = "Canvas"
---
-- A canvas widget can be destroyed.
instance Destroyable Canvas where
---
-- Destroys a canvas widget.
destroy = destroy . toGUIObject
---
-- A canvas widget has standard widget properties
-- (concerning focus, cursor).
instance Widget Canvas
---
-- A canvas is also a container for widgets, because it can contain
-- widgets in embedded windows.
instance Container Canvas
---
-- A canvas widget has a configureable border.
instance HasBorder Canvas
---
-- A canvas widget has a foreground and background colour.
instance HasColour Canvas where
---
-- Internal.
legalColourID = hasBackGroundColour
---
-- A canvas widget is a stateful widget, it can be enabled or disabled.
instance HasEnable Canvas
---
-- You can specify the size of a canvas.
instance HasSize Canvas
---
-- A canvas is a scrollable widget.
instance HasScroller Canvas
---
-- The contents of a canvas is printable.
instance HasPostscript Canvas
---
-- You can synchronize on a canvas object (in JAVA style).
instance Synchronized Canvas where
---
-- Synchronizes on a canvas object.
synchronize = synchronize . toGUIObject
---
-- A canvas can have a tooltip (only displayed if you are using tixwish).
instance HasTooltip Canvas
-- -----------------------------------------------------------------------
-- canvas-specific configuration options
-- -----------------------------------------------------------------------
---
-- Sets the maximum distance from the mouse to an overlapped object.
-- @param dist - the distance to be set.
-- @param cnv - the canvas to apply this configuration.
-- @return result - The concerned canvas.
closeEnough :: Double -> Canvas -> IO Canvas
closeEnough dist cnv = cset cnv "closeenough" dist
---
-- Selector for the maximum distance from the mouse to an overlapped
-- object.
-- @param cnv - the canvas to get this configuration from.
-- @return result - The requested distance.
getCloseEnough :: Canvas -> IO Double
getCloseEnough cnv = cget cnv "closeenough"
---
-- True constraints view to the scroll region.
-- @param b - Bool, see above.
-- @param cnv - the canvas to apply this configuration.
-- @return result - The concerned canvas.
confine :: Bool -> Canvas -> IO Canvas
confine b cnv = cset cnv "confine" b
---
-- Selector for the confine configuration, constraints view
-- to the scroll region if True.
-- @param cnv - the canvas to get this configuration from.
-- @return result - The confine configuration as a Bool
-- value (see confine).
getConfine :: Canvas -> IO Bool
getConfine w = cget w "confine"
-- -----------------------------------------------------------------------
-- bounding boxes
-- -----------------------------------------------------------------------
---
-- You can request the bounding box size of a canvas item (use a canvas
-- tag for the bounding box of a set of items).
instance GUIObject c => HasBBox Canvas c where
---
-- Gets the bounding box of a canvas item.
-- @param cnv - the concerned canvas.
-- @param item - the concerned canvas item.
-- @return result - The requested bounding box (upper left position,
-- lower right position).
bbox cnv item =
do
objnm <- getObjectName (toGUIObject item)
ans <- try (evalMethod cnv (\nm -> tkBBox nm objnm))
case ans of
Left e -> return Nothing
Right a -> return (Just a)
tkBBox :: ObjectName -> ObjectName -> TclScript
tkBBox nm (CanvasItemName _ cid) =
["global " ++ drop 1 (show cid), show nm ++ " bbox " ++ show cid]
tkBBox _ _ = []
{-# INLINE tkBBox #-}
-- -----------------------------------------------------------------------
-- coordinate transformation
-- -----------------------------------------------------------------------
---
-- Maps from screen X or Y coordinates (orientation parameter) to the
-- corresponding coordinates in canvas space.
-- @param cnv - the concerned canvas widget.
-- @param orient - the orientation
-- (Vertical or Horizontal).
-- @param dist - the input coordinate.
-- @param grid - an optional grid (the output can be rounded to
-- multiples of this grid if specified).
-- @return result - The requested distance in the specified orientation.
screenToCanvasCoord :: Canvas -> Orientation -> Distance ->
Maybe Distance -> IO Distance
screenToCanvasCoord cnv orient dist grid =
evalMethod cnv (\nm -> tkCanvas nm orient dist grid)
-- -----------------------------------------------------------------------
-- scrolling
-- -----------------------------------------------------------------------
---
-- The ScrollRegion datatype (scrollable region of the canvas
-- widget).
type ScrollRegion = (Position, Position)
---
-- Sets the scrollable region for a canvas widget.
-- @param reg - the scroll region to set.
-- @param cnv - the canvas widget to apply this scrollregion.
-- @return result - The concerned canvas.
scrollRegion :: ScrollRegion -> Canvas -> IO Canvas
scrollRegion reg@((x1, y1), (x2, y2)) cnv =
let reg = " { " ++ show x1 ++ " " ++ show y1 ++ " " ++ show x2 ++ " " ++
show y2 ++ " }"
in cset cnv ("scrollregion" ++ reg) ([] :: [Position])
---
-- Gets the applied scroll region from a canvas widget.
-- @param cnv - the canvas widget to get the applied scroll region
-- from.
-- @return result - The requested scroll region.
getScrollRegion :: Canvas -> IO ScrollRegion
getScrollRegion cnv =
cget cnv "scrollregion" >>= \reg ->
case reg of
[p1,p2] -> return (p1,p2)
_ -> return ((0,0), (0,0))
---
-- Sets the distance for one scrolling unit.
-- @param orient - the orientation
-- (Vertical or Horizontal).
-- @param dist - the distance to set.
-- @param cnv - the canvas widget to apply this scrolling
-- distance.
-- @return result - The concerned canvas.
scrollIncrement :: Orientation -> Distance -> Canvas -> IO Canvas
scrollIncrement orient dist cnv =
case orient of Horizontal -> cset cnv "xscrollincrement" dist
_ -> cset cnv "yscrollincrement" dist
---
-- Gets the applied minimum scrolling distance from a canvas widget.
-- @param orient - the orientation
-- (Vertical or Horizontal).
-- @param cnv - the canvas widget to get the applied minimum
-- scrolling distance from.
-- @return result - The requested minimum scrolling distance.
getScrollIncrement :: Orientation -> Canvas -> IO Distance
getScrollIncrement orient cnv =
case orient of Horizontal -> cget cnv "xscrollincrement"
Vertical -> cget cnv "yscrollincrement"
-- -----------------------------------------------------------------------
-- canvas methods
-- -----------------------------------------------------------------------
canvasMethods = defMethods { cleanupCmd = tkCleanupCanvas,
createCmd = tkCreateCanvas }
-- -----------------------------------------------------------------------
-- Tk commands
-- -----------------------------------------------------------------------
tkCreateCanvas :: ObjectName -> ObjectKind -> ObjectName -> ObjectID ->
[ConfigOption] -> TclScript
tkCreateCanvas pnm kind name oid confs =
tkDeclVar ("sv" ++ show oid) (show name) ++
(createCmd defMethods) pnm kind name oid confs
{-# INLINE tkCreateCanvas #-}
tkCleanupCanvas :: ObjectID -> ObjectName -> TclScript
tkCleanupCanvas oid _ = tkUndeclVar ("sv" ++ show oid)
{-# INLINE tkCleanupCanvas #-}
tkCanvas :: ObjectName -> Orientation -> Distance -> Maybe Distance ->
TclScript
tkCanvas nm Horizontal d sp =
[show nm ++ " canvasx " ++ show d ++ showGrid sp]
tkCanvas nm Vertical d sp =
[show nm ++ " canvasy " ++ show d ++ showGrid sp]
{-# INLINE tkCanvas #-}
showGrid Nothing = ""
showGrid (Just gs) = " " ++ show gs